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

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

There is a newer version: 3.19.16
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
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * Apache-2.0 license and offer limited warranties, support, maintenance, and
 * commercial database integrations.
 *
 * For more information, please visit: http://www.jooq.org/licenses
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq.impl;

import static org.jooq.Clause.TABLE;
import static org.jooq.JoinType.CROSS_APPLY;
import static org.jooq.JoinType.CROSS_JOIN;
import static org.jooq.JoinType.FULL_OUTER_JOIN;
import static org.jooq.JoinType.JOIN;
import static org.jooq.JoinType.LEFT_ANTI_JOIN;
import static org.jooq.JoinType.LEFT_OUTER_JOIN;
import static org.jooq.JoinType.LEFT_SEMI_JOIN;
import static org.jooq.JoinType.NATURAL_FULL_OUTER_JOIN;
import static org.jooq.JoinType.NATURAL_JOIN;
import static org.jooq.JoinType.NATURAL_LEFT_OUTER_JOIN;
import static org.jooq.JoinType.NATURAL_RIGHT_OUTER_JOIN;
import static org.jooq.JoinType.OUTER_APPLY;
import static org.jooq.JoinType.RIGHT_OUTER_JOIN;
import static org.jooq.JoinType.STRAIGHT_JOIN;
import static org.jooq.impl.DSL.and;
import static org.jooq.impl.DSL.condition;
import static org.jooq.impl.DSL.exists;
// ...
import static org.jooq.impl.DSL.notExists;
import static org.jooq.impl.DSL.sql;
import static org.jooq.impl.DSL.table;
import static org.jooq.impl.DSL.val;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.EMPTY_NAME;
import static org.jooq.impl.Tools.EMPTY_TABLE_FIELD;
import static org.jooq.impl.Tools.anyMatch;
import static org.jooq.impl.Tools.map;
import static org.jooq.impl.Tools.traverseJoins;
import static org.jooq.impl.Tools.unwrap;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Stream;

import org.jooq.Binding;
import org.jooq.Catalog;
import org.jooq.Check;
import org.jooq.Clause;
import org.jooq.Comment;
import org.jooq.Comparator;
import org.jooq.Condition;
import org.jooq.Configuration;
import org.jooq.Context;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.DivideByOnStep;
import org.jooq.Field;
import org.jooq.ForeignKey;
import org.jooq.Generator;
import org.jooq.Identity;
import org.jooq.Index;
import org.jooq.JoinType;
// ...
import org.jooq.Name;
import org.jooq.Package;
// ...
// ...
// ...
import org.jooq.QualifiedAsterisk;
import org.jooq.QueryPart;
import org.jooq.Record;
import org.jooq.RecordType;
import org.jooq.Result;
import org.jooq.Row;
import org.jooq.RowId;
import org.jooq.SQL;
import org.jooq.Schema;
import org.jooq.Select;
import org.jooq.SelectField;
import org.jooq.Table;
import org.jooq.TableField;
import org.jooq.TableLike;
import org.jooq.TableOnStep;
import org.jooq.TableOptionalOnStep;
import org.jooq.TableOptions;
import org.jooq.TableOptions.TableType;
import org.jooq.TableOuterJoinStep;
import org.jooq.TablePartitionByStep;
import org.jooq.UniqueKey;
// ...
// ...
import org.jooq.impl.QOM.GenerationLocation;
import org.jooq.tools.JooqLogger;

import org.jetbrains.annotations.NotNull;


/**
 * @author Lukas Eder
 */
abstract class AbstractTable extends AbstractNamed implements Table, FieldsTrait {

    private static final JooqLogger  log              = JooqLogger.getLogger(AbstractTable.class);
    private static final Clause[]    CLAUSES          = { TABLE };

    private final TableOptions       options;
    private Schema                   tableschema;
    private transient DataType    tabletype;
    private transient Identity identity;
    private transient Row            fieldsRow;

    AbstractTable(TableOptions options, Name name) {
        this(options, name, null, null);
    }

    AbstractTable(TableOptions options, Name name, Schema schema) {
        this(options, name, schema, null);
    }

    AbstractTable(TableOptions options, Name name, Schema schema, Comment comment) {
        super(qualify(schema, name), comment);

        this.options = options;
        this.tableschema = schema;
    }

    // ------------------------------------------------------------------------
    // XXX: SelectField API
    // ------------------------------------------------------------------------

    @Override
    public final Class getType() {
        return getDataType().getType();
    }

    @Override
    public final DataType getDataType(Configuration configuration) {
        return getDataType();
    }

    @Override
    public final DataType $dataType() {
        return getDataType();
    }

    @Override
    public final Binding getBinding() {
        return getDataType().getBinding();
    }

    @Override
    public final Converter getConverter() {
        return getDataType().getConverter();
    }

    @Override
    public final  SelectField convert(Binding binding) {
        return tf().convert(binding);
    }

    @Override
    public final  SelectField convert(Converter converter) {
        return tf().convert(converter);
    }

    @Override
    public final  SelectField convert(Class toType, Function from, Function to) {
        return tf().convert(toType, from, to);
    }

    @Override
    public final  SelectField convertFrom(Class toType, Function from) {
        return tf().convertFrom(toType, from);
    }

    @Override
    public final  SelectField convertFrom(Function from) {
        return tf().convertFrom(from);
    }

    @Override
    public final  SelectField convertTo(Class toType, Function to) {
        return tf().convertTo(toType, to);
    }

    @Override
    public final  SelectField convertTo(Function to) {
        return tf().convertTo(to);
    }

    @Override
    public final SelectField as(Field otherField) {
        return as(otherField.getUnqualifiedName());
    }

    final TableAsField tf() {
        return new TableAsField<>(this);
    }

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

    @Override
    public Clause[] clauses(Context ctx) {
        return CLAUSES;
    }

    // ------------------------------------------------------------------------
    // [#5518] Record method inversions, e.g. for use as method references
    // ------------------------------------------------------------------------

    @Override
    public final R from(Record record) {
        return record.into(this);
    }

    // -------------------------------------------------------------------------
    // XXX: Expressions based on this table
    // -------------------------------------------------------------------------

    @Override
    public final QualifiedAsterisk asterisk() {
        return new QualifiedAsteriskImpl(this);
    }

    // ------------------------------------------------------------------------
    // XXX: TableLike API
    // ------------------------------------------------------------------------

    /**
     * Subclasses should override this method to provide the set of fields
     * contained in the concrete table implementation. For example, a
     * TableAlias contains aliased fields of its
     * AliasProvider table.
     */
    abstract FieldsImpl fields0();

    @Override
    public final DataType getDataType() {
        if (tabletype == null)
            tabletype = new TableDataType<>(this);

        return tabletype;
    }

    @Override
    public final RecordType recordType() {
        return fields0();
    }

    @Override
    public final R newRecord() {
        return DSL.using(new DefaultConfiguration()).newRecord(this);
    }

    /*
     * Subclasses may override this method
     */
    @Override
    public Row fieldsRow() {
        if (fieldsRow == null)
            fieldsRow = Tools.row0(fields0());

        return fieldsRow;
    }

    @Override
    public final Field[] fields() {
        return fieldsRow().fields();
    }

    @Override
    public final Field> asMultiset() {
        return DSL.multiset(this);
    }

    @Override
    public final Field> asMultiset(String alias) {
        return DSL.multiset(this).as(alias);
    }

    @Override
    public final Field> asMultiset(Name alias) {
        return DSL.multiset(this).as(alias);
    }

    @Override
    public final Field> asMultiset(Field alias) {
        return DSL.multiset(this).as(alias);
    }

    @Override
    public final Table asTable() {
        return this;
    }

    @Override
    public final Table asTable(String alias) {
        return as(alias);
    }

    @Override
    public final Table asTable(String alias, String... fieldAliases) {
        return as(alias, fieldAliases);
    }

    @Override
    public final Table asTable(String alias, Collection fieldAliases) {
        return as(alias, fieldAliases);
    }

    @Override
    public final Table asTable(Name alias) {
        return as(alias);
    }

    @Override
    public final Table asTable(Name alias, Name... fieldAliases) {
        return as(alias, fieldAliases);
    }

    @Override
    public final Table asTable(Name alias, Collection fieldAliases) {
        return as(alias, fieldAliases);
    }

    @Override
    public final Table asTable(Table alias) {
        return as(alias);
    }

    @Override
    public final Table asTable(Table alias, Field... fieldAliases) {
        return as(alias, fieldAliases);
    }

    @Override
    public final Table asTable(Table alias, Collection> fieldAliases) {
        return as(alias, fieldAliases);
    }

    @Override
    public final Table asTable(String alias, Function, ? extends String> aliasFunction) {
        return as(alias, aliasFunction);
    }

    @Override
    public final Table asTable(String alias, BiFunction, ? super Integer, ? extends String> aliasFunction) {
        return as(alias, aliasFunction);
    }

    @Override
    public /* non-final for covariant overriding */ Table as(String alias) {
        return as(DSL.name(alias));
    }

    @Override
    public final Table as(String alias, String... fieldAliases) {
        return as(DSL.name(alias), Tools.names(fieldAliases));
    }

    @Override
    public final Table as(String alias, Collection fieldAliases) {
        return as(DSL.name(alias), Tools.names(fieldAliases));
    }

    @Override
    public final Table as(String alias, Function, ? extends String> aliasFunction) {
        return as(alias, map(fields(), f -> aliasFunction.apply(f), String[]::new));
    }

    @Override
    public final Table as(String alias, BiFunction, ? super Integer, ? extends String> aliasFunction) {
        return as(alias, map(fields(), (f, i) -> aliasFunction.apply(f, i), String[]::new));
    }

    @Override
    public /* non-final for covariant overriding */ Table as(Name alias) {
        return new TableAlias<>(this, alias);
    }

    @Override
    public /* non-final for covariant overriding */ Table as(Name alias, Name... fieldAliases) {
        return new TableAlias<>(this, alias, fieldAliases);
    }

    @Override
    public final Table as(Name alias, Collection fieldAliases) {
        return as(alias, fieldAliases == null ? null : fieldAliases.toArray(EMPTY_NAME));
    }

    @Override
    public final Table as(Name alias, Function, ? extends Name> aliasFunction) {
        return as(alias, map(fields(), f -> aliasFunction.apply(f), Name[]::new));
    }

    @Override
    public final Table as(Name alias, BiFunction, ? super Integer, ? extends Name> aliasFunction) {
        return as(alias, map(fields(), (f, i) -> aliasFunction.apply(f, i), Name[]::new));
    }

    // ------------------------------------------------------------------------
    // XXX: Table API
    // ------------------------------------------------------------------------

    @Override
    public final TableType getTableType() {
        return options.type();
    }

    @Override
    public final TableOptions getOptions() {
        return options;
    }

    @Override
    public final Catalog getCatalog() {
        return getSchema() == null ? null : getSchema().getCatalog();
    }

    @Override
    public final Package getPackage() {
        return null;
    }

    @Override
    public /* non-final */ Schema getSchema() {
        if (tableschema == null)
            tableschema = getQualifiedName().qualified()
                        ? DSL.schema(getQualifiedName().qualifier())
                        : null;

        return tableschema;
    }

    /**
     * {@inheritDoc}
     * 

* Subclasses should override this method */ @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public Identity getIdentity() { if (identity == null) { for (Field f : fields()) if (f instanceof TableField && f.getDataType().identity()) if (identity == null) identity = new IdentityImpl(this, (TableField) f); else log.info("Multiple identities", "There are multiple identity fields in table " + this + ", which is not supported by jOOQ"); if (identity == null) identity = (Identity) IdentityImpl.NULL; } return identity == IdentityImpl.NULL ? null : identity; } /** * {@inheritDoc} *

* Subclasses may override this method */ @Override public UniqueKey getPrimaryKey() { return null; } static final record PrimaryKeyWithEmbeddables(UniqueKey primaryKey) {} transient PrimaryKeyWithEmbeddables primaryKeyWithEmbeddables; /** * [#15873] [#15875] Embeddable keys are currently listing their embedded * columns, which may have been replaced. */ @SuppressWarnings("unchecked") final UniqueKey getPrimaryKeyWithEmbeddables() { if (primaryKeyWithEmbeddables == null) { UniqueKey uniqueKey = getPrimaryKey(); primaryKeyWithEmbeddables = new PrimaryKeyWithEmbeddables<>(uniqueKey); } return primaryKeyWithEmbeddables.primaryKey; } /** * {@inheritDoc} *

* Subclasses may override this method */ @Override public TableField getRecordVersion() { return null; } /** * {@inheritDoc} *

* Subclasses may override this method */ @Override public TableField getRecordTimestamp() { return null; } /** * {@inheritDoc} *

* Subclasses should override this method */ @Override public List getIndexes() { return Collections.emptyList(); } /** * {@inheritDoc} *

* Subclasses should no longer override this method, which may be made final * in the future. */ @Override public List> getKeys() { List> result = new ArrayList<>(); UniqueKey pk = getPrimaryKey(); if (pk != null) result.add(pk); result.addAll(getUniqueKeys()); return result; } /** * {@inheritDoc} *

* Subclasses should override this method */ @Override public List> getUniqueKeys() { return Collections.emptyList(); } @Override public final List> getReferencesFrom(Table other) { return other.getReferencesTo(this); } /** * {@inheritDoc} *

* Subclasses should override this method */ @Override public List> getReferences() { return Collections.emptyList(); } @SuppressWarnings("unchecked") @Override public final List> getReferencesTo(Table other) { List> result = new ArrayList<>(); for (ForeignKey reference : getReferences()) { traverseJoins(other, o -> { // [#1460] [#6304] [#14387] In case the other table was aliased or otherwise wrapped if (unwrap(o).equals(reference.getKey().getTable())) result.add((ForeignKey) reference); }); } return Collections.unmodifiableList(result); } /** * {@inheritDoc} *

* Subclasses should override this method */ @Override public List> getChecks() { return Collections.emptyList(); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link AbstractTable#createField(Name, DataType, Table)} instead. */ @Deprecated protected static final TableField createField(String name, DataType type, Table table) { return createField(DSL.name(name), type, table, null, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link AbstractTable#createField(Name, DataType, Table, String)} instead. */ @Deprecated protected static final TableField createField(String name, DataType type, Table table, String comment) { return createField(DSL.name(name), type, table, comment, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link AbstractTable#createField(Name, DataType, Table, String, Converter)} * instead. */ @Deprecated protected static final TableField createField(String name, DataType type, Table table, String comment, Converter converter) { return createField(DSL.name(name), type, table, comment, converter, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link AbstractTable#createField(Name, DataType, Table, String, Binding)} * instead. */ @Deprecated protected static final TableField createField(String name, DataType type, Table table, String comment, Binding binding) { return createField(DSL.name(name), type, table, comment, null, binding); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link AbstractTable#createField(Name, DataType, Table, String, Converter, Binding)} * instead. */ @Deprecated protected static final TableField createField(String name, DataType type, Table table, String comment, Converter converter, Binding binding) { return createField(DSL.name(name), type, table, comment, converter, binding); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link #createField(Name, DataType)} * instead. */ @Deprecated protected final TableField createField(String name, DataType type) { return createField(DSL.name(name), type, this, null, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link #createField(Name, DataType, String)} * instead. */ @Deprecated protected final TableField createField(String name, DataType type, String comment) { return createField(DSL.name(name), type, this, comment, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link #createField(Name, DataType, String, Converter)} * instead. */ @Deprecated protected final TableField createField(String name, DataType type, String comment, Converter converter) { return createField(DSL.name(name), type, this, comment, converter, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link #createField(Name, DataType, String, Binding)} * instead. */ @Deprecated protected final TableField createField(String name, DataType type, String comment, Binding binding) { return createField(DSL.name(name), type, this, comment, null, binding); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field * @deprecated - 3.12.0 - [#8000] - Use * {@link #createField(Name, DataType, String, Converter, Binding)} * instead. */ @Deprecated protected final TableField createField(String name, DataType type, String comment, Converter converter, Binding binding) { return createField(DSL.name(name), type, this, comment, converter, binding); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final TableField createField(Name name, DataType type, Table table) { return createField(name, type, table, null, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final TableField createField(Name name, DataType type, Table table, String comment) { return createField(name, type, table, comment, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final TableField createField(Name name, DataType type, Table table, String comment, Converter converter) { return createField(name, type, table, comment, converter, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final TableField createField(Name name, DataType type, Table table, String comment, Binding binding) { return createField(name, type, table, comment, null, binding, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final TableField createField(Name name, DataType type, Table table, String comment, Converter converter, Binding binding) { return createField(name, type, table, comment, converter, binding, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final , T> TableField createField(Name name, DataType type, TR table, String comment, Generator generator) { return createField(name, type, table, comment, null, null, generator); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final , T, U> TableField createField(Name name, DataType type, TR table, String comment, Converter converter, Generator generator) { return createField(name, type, table, comment, converter, null, generator); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected static final , T, U> TableField createField(Name name, DataType type, TR table, String comment, Binding binding, Generator generator) { return createField(name, type, table, comment, null, binding, generator); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ @SuppressWarnings("unchecked") protected static final , T, X, U> TableField createField(Name name, DataType type, TR table, String comment, Converter converter, Binding binding, Generator generator) { Binding actualBinding = DefaultBinding.newBinding(converter, type, binding); DataType actualType = converter == null && binding == null ? (DataType) type : type.asConvertedDataType(actualBinding); if (generator != null) actualType = actualType.generatedAlwaysAs(generator).generationLocation(GenerationLocation.CLIENT); // [#5999] TODO: Allow for user-defined Names TableFieldImpl tableField = new TableFieldImpl<>(name, actualType, table, DSL.comment(comment), actualBinding); // [#1199] The public API of Table returns immutable field lists if (table instanceof TableImpl t) t.fields0().add(tableField); return tableField; } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final TableField createField(Name name, DataType type) { return createField(name, type, this, null, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final TableField createField(Name name, DataType type, String comment) { return createField(name, type, this, comment, null, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final TableField createField(Name name, DataType type, String comment, Converter converter) { return createField(name, type, this, comment, converter, null, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final TableField createField(Name name, DataType type, String comment, Binding binding) { return createField(name, type, this, comment, null, binding, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final TableField createField(Name name, DataType type, String comment, Converter converter, Binding binding) { return createField(name, type, this, comment, converter, binding, null); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final , T> TableField createField0(Name name, DataType type, TR table, String comment, Generator generator) { return createField(name, type, table, comment, null, null, generator); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final , T, U> TableField createField0(Name name, DataType type, TR table, String comment, Converter converter, Generator generator) { return createField(name, type, table, comment, converter, null, generator); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final , T, U> TableField createField0(Name name, DataType type, TR table, String comment, Binding binding, Generator generator) { return createField(name, type, table, comment, null, binding, generator); } /** * Subclasses may call this method to create {@link TableField} objects that * are linked to this table. * * @param name The name of the field (case-sensitive!) * @param type The data type of the field */ protected final , T, X, U> TableField createField0(Name name, DataType type, TR table, String comment, Converter converter, Binding binding, Generator generator) { return createField(name, type, table, comment, converter, binding, generator); } // ------------------------------------------------------------------------- // Generic predicates // ------------------------------------------------------------------------- @Override public final Condition eq(Table arg2) { return new TableEq(this, arg2); } @Override public final Condition equal(Table arg2) { return eq(arg2); } @Override public final Condition ne(Table arg2) { return new TableNe(this, arg2); } @Override public final Condition notEqual(Table arg2) { return ne(arg2); } // ------------------------------------------------------------------------- // Table functions // ------------------------------------------------------------------------- @Override public /* non-final */ Field rowid() { return new QualifiedRowid(this); } // ------------------------------------------------------------------------ // XXX: Other API // ------------------------------------------------------------------------ @Override public final Table useIndex(String... indexes) { return new HintedTable<>(this, "use index", indexes); } @Override public final Table useIndexForJoin(String... indexes) { return new HintedTable<>(this, "use index for join", indexes); } @Override public final Table useIndexForOrderBy(String... indexes) { return new HintedTable<>(this, "use index for order by", indexes); } @Override public final Table useIndexForGroupBy(String... indexes) { return new HintedTable<>(this, "use index for group by", indexes); } @Override public final Table ignoreIndex(String... indexes) { return new HintedTable<>(this, "ignore index", indexes); } @Override public final Table ignoreIndexForJoin(String... indexes) { return new HintedTable<>(this, "ignore index for join", indexes); } @Override public final Table ignoreIndexForOrderBy(String... indexes) { return new HintedTable<>(this, "ignore index for order by", indexes); } @Override public final Table ignoreIndexForGroupBy(String... indexes) { return new HintedTable<>(this, "ignore index for group by", indexes); } @Override public final Table forceIndex(String... indexes) { return new HintedTable<>(this, "force index", indexes); } @Override public final Table forceIndexForJoin(String... indexes) { return new HintedTable<>(this, "force index for join", indexes); } @Override public final Table forceIndexForOrderBy(String... indexes) { return new HintedTable<>(this, "force index for order by", indexes); } @Override public final Table forceIndexForGroupBy(String... indexes) { return new HintedTable<>(this, "force index for group by", indexes); } // ------------------------------------------------------------------------ // XXX: aliasing API // ------------------------------------------------------------------------ @Override public /* non-final for covariant overriding */ Table as(Table otherTable) { return as(otherTable.getUnqualifiedName()); } @Override public final Table as(Table otherTable, Field... otherFields) { return as(otherTable.getUnqualifiedName(), Tools.map(otherFields, Field::getUnqualifiedName, Name[]::new)); } @Override public final Table as(Table otherTable, Collection> otherFields) { return as(otherTable.getUnqualifiedName(), Tools.map(otherFields, Field::getUnqualifiedName)); } @Override public final Table as(Table otherTable, Function, ? extends Field> aliasFunction) { return as(otherTable.getUnqualifiedName(), f -> aliasFunction.apply(f).getUnqualifiedName()); } @Override public final Table as(Table otherTable, BiFunction, ? super Integer, ? extends Field> aliasFunction) { return as(otherTable.getUnqualifiedName(), (f, i) -> aliasFunction.apply(f, i).getUnqualifiedName()); } // ------------------------------------------------------------------------ // XXX: DIVISION API // ------------------------------------------------------------------------ @Override public final DivideByOnStep divideBy(Table divisor) { return new DivideBy(this, divisor); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public final TableOnStep leftSemiJoin(TableLike table) { return (TableOnStep) join(table, LEFT_SEMI_JOIN); } @SuppressWarnings({ "unchecked", "rawtypes" }) @Override public final TableOnStep leftAntiJoin(TableLike table) { return (TableOnStep) join(table, LEFT_ANTI_JOIN); } // ------------------------------------------------------------------------ // XXX: WHERE API // ------------------------------------------------------------------------ @Override public /* non-final */ Table where(Condition condition) { return new InlineDerivedTable<>(this, condition); } @Override public /* non-final */ Table where(Condition... conditions) { return where(and(conditions)); } @Override public /* non-final */ Table where(Collection conditions) { return where(and(conditions)); } @Override public /* non-final */ Table where(Field field) { return where(condition(field)); } @Override public /* non-final */ Table where(SQL sql) { return where(condition(sql)); } @Override public /* non-final */ Table where(String sql) { return where(condition(sql)); } @Override public /* non-final */ Table where(String sql, Object... bindings) { return where(condition(sql, bindings)); } @Override public /* non-final */ Table where(String sql, QueryPart... parts) { return where(condition(sql, parts)); } @Override public /* non-final */ Table whereExists(Select select) { return where(exists(select)); } @Override public /* non-final */ Table whereNotExists(Select select) { return where(notExists(select)); } // ------------------------------------------------------------------------ // XXX: JOIN API // ------------------------------------------------------------------------ @Override public final TableOptionalOnStep join(TableLike table, JoinType type) { return new JoinTable(this, table, type); } @Override public final TableOnStep join(TableLike table) { return innerJoin(table); } @Override public final TableOnStep join(SQL sql) { return innerJoin(sql); } @Override public final TableOnStep join(String sql) { return innerJoin(sql); } @Override public final TableOnStep join(String sql, Object... bindings) { return innerJoin(sql, bindings); } @Override public final TableOnStep join(String sql, QueryPart... parts) { return innerJoin(sql, parts); } @Override public final TableOnStep join(Name name) { return innerJoin(table(name)); } @Override public final TableOnStep innerJoin(TableLike table) { return join(table, JOIN); } @Override public final TableOnStep innerJoin(SQL sql) { return innerJoin(table(sql)); } @Override public final TableOnStep innerJoin(String sql) { return innerJoin(table(sql)); } @Override public final TableOnStep innerJoin(String sql, Object... bindings) { return innerJoin(table(sql, bindings)); } @Override public final TableOnStep innerJoin(String sql, QueryPart... parts) { return innerJoin(table(sql, parts)); } @Override public final TableOnStep innerJoin(Name name) { return innerJoin(table(name)); } @Override public final TablePartitionByStep leftJoin(TableLike table) { return leftOuterJoin(table); } @Override public final TablePartitionByStep leftJoin(SQL sql) { return leftOuterJoin(sql); } @Override public final TablePartitionByStep leftJoin(String sql) { return leftOuterJoin(sql); } @Override public final TablePartitionByStep leftJoin(String sql, Object... bindings) { return leftOuterJoin(sql, bindings); } @Override public final TablePartitionByStep leftJoin(String sql, QueryPart... parts) { return leftOuterJoin(sql, parts); } @Override public final TablePartitionByStep leftJoin(Name name) { return leftOuterJoin(table(name)); } @SuppressWarnings("unchecked") @Override public final TablePartitionByStep leftOuterJoin(TableLike table) { return (TablePartitionByStep) join(table, LEFT_OUTER_JOIN); } @Override public final TablePartitionByStep leftOuterJoin(SQL sql) { return leftOuterJoin(table(sql)); } @Override public final TablePartitionByStep leftOuterJoin(String sql) { return leftOuterJoin(table(sql)); } @Override public final TablePartitionByStep leftOuterJoin(String sql, Object... bindings) { return leftOuterJoin(table(sql, bindings)); } @Override public final TablePartitionByStep leftOuterJoin(String sql, QueryPart... parts) { return leftOuterJoin(table(sql, parts)); } @Override public final TablePartitionByStep leftOuterJoin(Name name) { return leftOuterJoin(table(name)); } @Override public final TablePartitionByStep rightJoin(TableLike table) { return rightOuterJoin(table); } @Override public final TablePartitionByStep rightJoin(SQL sql) { return rightOuterJoin(sql); } @Override public final TablePartitionByStep rightJoin(String sql) { return rightOuterJoin(sql); } @Override public final TablePartitionByStep rightJoin(String sql, Object... bindings) { return rightOuterJoin(sql, bindings); } @Override public final TablePartitionByStep rightJoin(String sql, QueryPart... parts) { return rightOuterJoin(sql, parts); } @Override public final TablePartitionByStep rightJoin(Name name) { return rightOuterJoin(table(name)); } @SuppressWarnings("unchecked") @Override public final TablePartitionByStep rightOuterJoin(TableLike table) { return (TablePartitionByStep) join(table, RIGHT_OUTER_JOIN); } @Override public final TablePartitionByStep rightOuterJoin(SQL sql) { return rightOuterJoin(table(sql)); } @Override public final TablePartitionByStep rightOuterJoin(String sql) { return rightOuterJoin(table(sql)); } @Override public final TablePartitionByStep rightOuterJoin(String sql, Object... bindings) { return rightOuterJoin(table(sql, bindings)); } @Override public final TablePartitionByStep rightOuterJoin(String sql, QueryPart... parts) { return rightOuterJoin(table(sql, parts)); } @Override public final TablePartitionByStep rightOuterJoin(Name name) { return rightOuterJoin(table(name)); } @Override public final TableOnStep fullOuterJoin(TableLike table) { return join(table, FULL_OUTER_JOIN); } @Override public final TableOnStep fullOuterJoin(SQL sql) { return fullOuterJoin(table(sql)); } @Override public final TableOnStep fullOuterJoin(String sql) { return fullOuterJoin(table(sql)); } @Override public final TableOnStep fullOuterJoin(String sql, Object... bindings) { return fullOuterJoin(table(sql, bindings)); } @Override public final TableOnStep fullOuterJoin(String sql, QueryPart... parts) { return fullOuterJoin(table(sql, parts)); } @Override public final TableOnStep fullOuterJoin(Name name) { return fullOuterJoin(table(name)); } @Override public final TableOnStep fullJoin(TableLike table) { return fullOuterJoin(table); } @Override public final TableOnStep fullJoin(SQL sql) { return fullOuterJoin(sql); } @Override public final TableOnStep fullJoin(String sql) { return fullOuterJoin(sql); } @Override public final TableOnStep fullJoin(String sql, Object... bindings) { return fullOuterJoin(sql, bindings); } @Override public final TableOnStep fullJoin(String sql, QueryPart... parts) { return fullOuterJoin(sql, parts); } @Override public final TableOnStep fullJoin(Name name) { return fullOuterJoin(name); } @Override public final Table crossJoin(TableLike table) { return join(table, CROSS_JOIN); } @Override public final Table crossJoin(SQL sql) { return crossJoin(table(sql)); } @Override public final Table crossJoin(String sql) { return crossJoin(table(sql)); } @Override public final Table crossJoin(String sql, Object... bindings) { return crossJoin(table(sql, bindings)); } @Override public final Table crossJoin(String sql, QueryPart... parts) { return crossJoin(table(sql, parts)); } @Override public final Table crossJoin(Name name) { return crossJoin(table(name)); } @Override public final Table naturalJoin(TableLike table) { return join(table, NATURAL_JOIN); } @Override public final Table naturalJoin(SQL sql) { return naturalJoin(table(sql)); } @Override public final Table naturalJoin(String sql) { return naturalJoin(table(sql)); } @Override public final Table naturalJoin(String sql, Object... bindings) { return naturalJoin(table(sql, bindings)); } @Override public final Table naturalJoin(String sql, QueryPart... parts) { return naturalJoin(table(sql, parts)); } @Override public final Table naturalJoin(Name name) { return naturalJoin(table(name)); } @Override public final Table naturalLeftOuterJoin(TableLike table) { return join(table, NATURAL_LEFT_OUTER_JOIN); } @Override public final Table naturalLeftOuterJoin(SQL sql) { return naturalLeftOuterJoin(table(sql)); } @Override public final Table naturalLeftOuterJoin(String sql) { return naturalLeftOuterJoin(table(sql)); } @Override public final Table naturalLeftOuterJoin(String sql, Object... bindings) { return naturalLeftOuterJoin(table(sql, bindings)); } @Override public final Table naturalLeftOuterJoin(String sql, QueryPart... parts) { return naturalLeftOuterJoin(table(sql, parts)); } @Override public final Table naturalLeftOuterJoin(Name name) { return naturalLeftOuterJoin(table(name)); } @Override public final Table naturalRightOuterJoin(TableLike table) { return join(table, NATURAL_RIGHT_OUTER_JOIN); } @Override public final Table naturalRightOuterJoin(SQL sql) { return naturalRightOuterJoin(table(sql)); } @Override public final Table naturalRightOuterJoin(String sql) { return naturalRightOuterJoin(table(sql)); } @Override public final Table naturalRightOuterJoin(String sql, Object... bindings) { return naturalRightOuterJoin(table(sql, bindings)); } @Override public final Table naturalRightOuterJoin(String sql, QueryPart... parts) { return naturalRightOuterJoin(table(sql, parts)); } @Override public final Table naturalRightOuterJoin(Name name) { return naturalRightOuterJoin(table(name)); } @Override public final Table naturalFullOuterJoin(TableLike table) { return join(table, NATURAL_FULL_OUTER_JOIN); } @Override public final Table naturalFullOuterJoin(SQL sql) { return naturalFullOuterJoin(table(sql)); } @Override public final Table naturalFullOuterJoin(String sql) { return naturalFullOuterJoin(table(sql)); } @Override public final Table naturalFullOuterJoin(String sql, Object... bindings) { return naturalFullOuterJoin(table(sql, bindings)); } @Override public final Table naturalFullOuterJoin(String sql, QueryPart... parts) { return naturalFullOuterJoin(table(sql, parts)); } @Override public final Table naturalFullOuterJoin(Name name) { return naturalFullOuterJoin(table(name)); } @Override public final Table crossApply(TableLike table) { return join(table, CROSS_APPLY); } @Override public final Table crossApply(SQL sql) { return crossApply(table(sql)); } @Override public final Table crossApply(String sql) { return crossApply(table(sql)); } @Override public final Table crossApply(String sql, Object... bindings) { return crossApply(table(sql, bindings)); } @Override public final Table crossApply(String sql, QueryPart... parts) { return crossApply(table(sql, parts)); } @Override public final Table crossApply(Name name) { return crossApply(table(name)); } @Override public final Table outerApply(TableLike table) { return join(table, OUTER_APPLY); } @Override public final Table outerApply(SQL sql) { return outerApply(table(sql)); } @Override public final Table outerApply(String sql) { return outerApply(table(sql)); } @Override public final Table outerApply(String sql, Object... bindings) { return outerApply(table(sql, bindings)); } @Override public final Table outerApply(String sql, QueryPart... parts) { return outerApply(table(sql, parts)); } @Override public final Table outerApply(Name name) { return outerApply(table(name)); } @Override public final TableOptionalOnStep straightJoin(TableLike table) { return join(table, STRAIGHT_JOIN); } @Override public final TableOptionalOnStep straightJoin(SQL sql) { return straightJoin(table(sql)); } @Override public final TableOptionalOnStep straightJoin(String sql) { return straightJoin(table(sql)); } @Override public final TableOptionalOnStep straightJoin(String sql, Object... bindings) { return straightJoin(table(sql, bindings)); } @Override public final TableOptionalOnStep straightJoin(String sql, QueryPart... parts) { return straightJoin(table(sql, parts)); } @Override public final TableOptionalOnStep straightJoin(Name name) { return straightJoin(table(name)); } // ------------------------------------------------------------------------- // XXX: Query Object Model // ------------------------------------------------------------------------- @Override public final Schema $schema() { return getSchema(); } }