Search in sources :

Example 6 with DataType

use of org.jooq.DataType in project jOOQ by jOOQ.

the class DefaultParseContext method parseAlterTableAddField.

private final Field<?> parseAlterTableAddField(List<TableElement> list) {
    // The below code is taken from CREATE TABLE, with minor modifications as
    // https://github.com/jOOQ/jOOQ/issues/5317 has not yet been implemented
    // Once implemented, we might be able to factor out the common logic into
    // a new parseXXX() method.
    Name fieldName = parseIdentifier();
    DataType type = parseDataTypeIf(true);
    if (type == null)
        type = SQLDataType.OTHER;
    int p = list == null ? -1 : list.size();
    ParseInlineConstraints inline = parseInlineConstraints(fieldName, type, list, false, false, false);
    Field<?> result = field(fieldName, inline.type, inline.fieldComment);
    if (list != null)
        list.add(p, result);
    return result;
}
Also used : DataType(org.jooq.DataType) Constraint(org.jooq.Constraint) DSL.constraint(org.jooq.impl.DSL.constraint) Name(org.jooq.Name) DSL.systemName(org.jooq.impl.DSL.systemName)

Example 7 with DataType

use of org.jooq.DataType in project jOOQ by jOOQ.

the class DefaultParseContext method toCondition.

private final Condition toCondition(QueryPart part) {
    if (part == null)
        return null;
    else if (part instanceof Condition)
        return (Condition) part;
    else if (part instanceof Field) {
        Field f = (Field) part;
        DataType dataType = f.getDataType();
        Class<?> type = dataType.getType();
        if (type == Boolean.class)
            return condition(f);
        else // [#11631] [#12394] Numeric expressions are booleans in MySQL
        if (dataType.isNumeric())
            return f.ne(zero());
        else // [#7266] Support parsing column references as predicates
        if (type == Object.class && (part instanceof TableFieldImpl || part instanceof Val))
            return condition((Field) part);
        else
            throw expected("Boolean field");
    } else
        throw expected("Condition");
}
Also used : Condition(org.jooq.Condition) GroupField(org.jooq.GroupField) TableField(org.jooq.TableField) Field(org.jooq.Field) SortField(org.jooq.SortField) SelectField(org.jooq.SelectField) DataType(org.jooq.DataType) DSL.jsonbObject(org.jooq.impl.DSL.jsonbObject) DSL.jsonObject(org.jooq.impl.DSL.jsonObject)

Example 8 with DataType

use of org.jooq.DataType in project jOOQ by jOOQ.

the class InformationSchemaMetaImpl method init.

@SuppressWarnings({ "unchecked", "rawtypes" })
private final void init(InformationSchema meta) {
    List<String> errors = new ArrayList<>();
    // Catalogs
    // -------------------------------------------------------------------------------------------------------------
    boolean hasCatalogs = false;
    for (org.jooq.util.xml.jaxb.Catalog xc : meta.getCatalogs()) {
        InformationSchemaCatalog ic = new InformationSchemaCatalog(xc.getCatalogName(), xc.getComment());
        catalogs.add(ic);
        catalogsByName.put(name(xc.getCatalogName()), ic);
        hasCatalogs = true;
    }
    // -------------------------------------------------------------------------------------------------------------
    schemaLoop: for (org.jooq.util.xml.jaxb.Schema xs : meta.getSchemata()) {
        // [#6662] This is kept for backwards compatibility reasons
        if (!hasCatalogs) {
            InformationSchemaCatalog ic = new InformationSchemaCatalog(xs.getCatalogName(), null);
            if (!catalogs.contains(ic)) {
                catalogs.add(ic);
                catalogsByName.put(name(xs.getCatalogName()), ic);
            }
        }
        Name catalogName = name(xs.getCatalogName());
        Catalog catalog = catalogsByName.get(catalogName);
        if (catalog == null) {
            errors.add("Catalog " + catalogName + " not defined for schema " + xs.getSchemaName());
            continue schemaLoop;
        }
        InformationSchemaSchema is = new InformationSchemaSchema(xs.getSchemaName(), catalog, xs.getComment());
        schemas.add(is);
        schemasByName.put(name(xs.getCatalogName(), xs.getSchemaName()), is);
    }
    // -------------------------------------------------------------------------------------------------------------
    domainLoop: for (org.jooq.util.xml.jaxb.Domain d : meta.getDomains()) {
        Name schemaName = name(d.getDomainCatalog(), d.getDomainSchema());
        Schema schema = schemasByName.get(schemaName);
        if (schema == null) {
            errors.add("Schema " + schemaName + " not defined for domain " + d.getDomainName());
            continue domainLoop;
        }
        Name domainName = name(d.getDomainCatalog(), d.getDomainSchema(), d.getDomainName());
        int length = d.getCharacterMaximumLength() == null ? 0 : d.getCharacterMaximumLength();
        int precision = d.getNumericPrecision() == null ? 0 : d.getNumericPrecision();
        int scale = d.getNumericScale() == null ? 0 : d.getNumericScale();
        // TODO [#10239] Support NOT NULL constraints
        boolean nullable = true;
        List<Check<?>> checks = new ArrayList<>();
        for (org.jooq.util.xml.jaxb.DomainConstraint dc : meta.getDomainConstraints()) {
            if (domainName.equals(name(dc.getDomainCatalog(), dc.getDomainSchema(), dc.getDomainName()))) {
                Name constraintName = name(dc.getConstraintCatalog(), dc.getConstraintSchema(), dc.getConstraintName());
                for (org.jooq.util.xml.jaxb.CheckConstraint cc : meta.getCheckConstraints()) if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName())))
                    checks.add(new CheckImpl<>(null, constraintName, DSL.condition(cc.getCheckClause()), true));
            }
        }
        InformationSchemaDomain<?> id = new InformationSchemaDomain<Object>(schema, name(d.getDomainName()), (DataType) type(d.getDataType(), length, precision, scale, nullable, false, null, null), checks.toArray(EMPTY_CHECK));
        domains.add(id);
        domainsByName.put(domainName, id);
    }
    // -------------------------------------------------------------------------------------------------------------
    tableLoop: for (org.jooq.util.xml.jaxb.Table xt : meta.getTables()) {
        Name schemaName = name(xt.getTableCatalog(), xt.getTableSchema());
        Schema schema = schemasByName.get(schemaName);
        if (schema == null) {
            errors.add("Schema " + schemaName + " not defined for table " + xt.getTableName());
            continue tableLoop;
        }
        TableType tableType;
        switch(xt.getTableType()) {
            case GLOBAL_TEMPORARY:
                tableType = TableType.TEMPORARY;
                break;
            case VIEW:
                tableType = TableType.VIEW;
                break;
            case BASE_TABLE:
            default:
                tableType = TableType.TABLE;
                break;
        }
        String sql = null;
        if (tableType == TableType.VIEW) {
            viewLoop: for (org.jooq.util.xml.jaxb.View vt : meta.getViews()) {
                if (StringUtils.equals(defaultIfNull(xt.getTableCatalog(), ""), defaultIfNull(vt.getTableCatalog(), "")) && StringUtils.equals(defaultIfNull(xt.getTableSchema(), ""), defaultIfNull(vt.getTableSchema(), "")) && StringUtils.equals(defaultIfNull(xt.getTableName(), ""), defaultIfNull(vt.getTableName(), ""))) {
                    sql = vt.getViewDefinition();
                    break viewLoop;
                }
            }
        }
        InformationSchemaTable it = new InformationSchemaTable(xt.getTableName(), schema, xt.getComment(), tableType, sql);
        tables.add(it);
        tablesByName.put(name(xt.getTableCatalog(), xt.getTableSchema(), xt.getTableName()), it);
    }
    // Columns
    // -------------------------------------------------------------------------------------------------------------
    List<Column> columns = new ArrayList<>(meta.getColumns());
    columns.sort((o1, o2) -> {
        Integer p1 = o1.getOrdinalPosition();
        Integer p2 = o2.getOrdinalPosition();
        if (Objects.equals(p1, p2))
            return 0;
        if (p1 == null)
            return -1;
        if (p2 == null)
            return 1;
        return p1.compareTo(p2);
    });
    columnLoop: for (Column xc : columns) {
        String typeName = xc.getDataType();
        int length = xc.getCharacterMaximumLength() == null ? 0 : xc.getCharacterMaximumLength();
        int precision = xc.getNumericPrecision() == null ? 0 : xc.getNumericPrecision();
        int scale = xc.getNumericScale() == null ? 0 : xc.getNumericScale();
        boolean nullable = !FALSE.equals(xc.isIsNullable());
        boolean readonly = TRUE.equals(xc.isReadonly());
        Field<?> generatedAlwaysAs = TRUE.equals(xc.isIsGenerated()) ? DSL.field(xc.getGenerationExpression()) : null;
        GenerationOption generationOption = TRUE.equals(xc.isIsGenerated()) ? "STORED".equalsIgnoreCase(xc.getGenerationOption()) ? STORED : "VIRTUAL".equalsIgnoreCase(xc.getGenerationOption()) ? VIRTUAL : null : null;
        // TODO: Exception handling should be moved inside SQLDataType
        Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
        InformationSchemaTable table = tablesByName.get(tableName);
        if (table == null) {
            errors.add("Table " + tableName + " not defined for column " + xc.getColumnName());
            continue columnLoop;
        }
        AbstractTable.createField(name(xc.getColumnName()), type(typeName, length, precision, scale, nullable, readonly, generatedAlwaysAs, generationOption), table, xc.getComment());
    }
    // Indexes
    // -------------------------------------------------------------------------------------------------------------
    Map<Name, List<SortField<?>>> columnsByIndex = new HashMap<>();
    List<IndexColumnUsage> indexColumnUsages = new ArrayList<>(meta.getIndexColumnUsages());
    indexColumnUsages.sort(comparingInt(IndexColumnUsage::getOrdinalPosition));
    indexColumnLoop: for (IndexColumnUsage ic : indexColumnUsages) {
        Name indexName = name(ic.getIndexCatalog(), ic.getIndexSchema(), ic.getTableName(), ic.getIndexName());
        List<SortField<?>> fields = columnsByIndex.computeIfAbsent(indexName, k -> new ArrayList<>());
        Name tableName = name(ic.getTableCatalog(), ic.getTableSchema(), ic.getTableName());
        InformationSchemaTable table = tablesByName.get(tableName);
        if (table == null) {
            errors.add("Table " + tableName + " not defined for index " + indexName);
            continue indexColumnLoop;
        }
        TableField<Record, ?> field = (TableField<Record, ?>) table.field(ic.getColumnName());
        if (field == null) {
            errors.add("Column " + ic.getColumnName() + " not defined for table " + tableName);
            continue indexColumnLoop;
        }
        fields.add(Boolean.TRUE.equals(ic.isIsDescending()) ? field.desc() : field.asc());
    }
    indexLoop: for (org.jooq.util.xml.jaxb.Index i : meta.getIndexes()) {
        Name tableName = name(i.getTableCatalog(), i.getTableSchema(), i.getTableName());
        Name indexName = name(i.getIndexCatalog(), i.getIndexSchema(), i.getTableName(), i.getIndexName());
        InformationSchemaTable table = tablesByName.get(tableName);
        if (table == null) {
            errors.add("Table " + tableName + " not defined for index " + indexName);
            continue indexLoop;
        }
        List<SortField<?>> c = columnsByIndex.get(indexName);
        if (c == null || c.isEmpty()) {
            errors.add("No columns defined for index " + indexName);
            continue indexLoop;
        }
        IndexImpl index = (IndexImpl) Internal.createIndex(i.getIndexName(), table, c.toArray(EMPTY_SORTFIELD), Boolean.TRUE.equals(i.isIsUnique()));
        table.indexes.add(index);
        indexesByName.put(indexName, index);
    }
    // Constraints
    // -------------------------------------------------------------------------------------------------------------
    Map<Name, List<TableField<Record, ?>>> columnsByConstraint = new HashMap<>();
    List<KeyColumnUsage> keyColumnUsages = new ArrayList<>(meta.getKeyColumnUsages());
    keyColumnUsages.sort(comparing(KeyColumnUsage::getOrdinalPosition));
    keyColumnLoop: for (KeyColumnUsage xc : keyColumnUsages) {
        Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
        List<TableField<Record, ?>> fields = columnsByConstraint.computeIfAbsent(constraintName, k -> new ArrayList<>());
        Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
        InformationSchemaTable table = tablesByName.get(tableName);
        if (table == null) {
            errors.add("Table " + tableName + " not defined for constraint " + constraintName);
            continue keyColumnLoop;
        }
        TableField<Record, ?> field = (TableField<Record, ?>) table.field(xc.getColumnName());
        if (field == null) {
            errors.add("Column " + xc.getColumnName() + " not defined for table " + tableName);
            continue keyColumnLoop;
        }
        fields.add(field);
    }
    tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
        switch(xc.getConstraintType()) {
            case PRIMARY_KEY:
            case UNIQUE:
                {
                    Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
                    Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
                    InformationSchemaTable table = tablesByName.get(tableName);
                    if (table == null) {
                        errors.add("Table " + tableName + " not defined for constraint " + constraintName);
                        continue tableConstraintLoop;
                    }
                    List<TableField<Record, ?>> c = columnsByConstraint.get(constraintName);
                    if (c == null || c.isEmpty()) {
                        errors.add("No columns defined for constraint " + constraintName);
                        continue tableConstraintLoop;
                    }
                    UniqueKeyImpl<Record> key = (UniqueKeyImpl<Record>) Internal.createUniqueKey(table, xc.getConstraintName(), c.toArray(new TableField[0]));
                    if (xc.getConstraintType() == PRIMARY_KEY) {
                        table.primaryKey = key;
                        primaryKeys.add(key);
                    } else
                        table.uniqueKeys.add(key);
                    keysByName.put(constraintName, key);
                    break;
                }
        }
    }
    for (ReferentialConstraint xr : meta.getReferentialConstraints()) {
        referentialKeys.put(name(xr.getConstraintCatalog(), xr.getConstraintSchema(), xr.getConstraintName()), name(xr.getUniqueConstraintCatalog(), xr.getUniqueConstraintSchema(), xr.getUniqueConstraintName()));
    }
    tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
        switch(xc.getConstraintType()) {
            case FOREIGN_KEY:
                {
                    Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
                    Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
                    InformationSchemaTable table = tablesByName.get(tableName);
                    if (table == null) {
                        errors.add("Table " + tableName + " not defined for constraint " + constraintName);
                        continue tableConstraintLoop;
                    }
                    List<TableField<Record, ?>> c = columnsByConstraint.get(constraintName);
                    if (c == null || c.isEmpty()) {
                        errors.add("No columns defined for constraint " + constraintName);
                        continue tableConstraintLoop;
                    }
                    UniqueKeyImpl<Record> uniqueKey = keysByName.get(referentialKeys.get(constraintName));
                    if (uniqueKey == null) {
                        errors.add("No unique key defined for foreign key " + constraintName);
                        continue tableConstraintLoop;
                    }
                    ForeignKey<Record, Record> key = Internal.createForeignKey(uniqueKey, table, xc.getConstraintName(), c.toArray(new TableField[0]));
                    table.foreignKeys.add(key);
                    break;
                }
        }
    }
    tableConstraintLoop: for (TableConstraint xc : meta.getTableConstraints()) {
        switch(xc.getConstraintType()) {
            case CHECK:
                {
                    Name tableName = name(xc.getTableCatalog(), xc.getTableSchema(), xc.getTableName());
                    Name constraintName = name(xc.getConstraintCatalog(), xc.getConstraintSchema(), xc.getConstraintName());
                    InformationSchemaTable table = tablesByName.get(tableName);
                    if (table == null) {
                        errors.add("Table " + tableName + " not defined for constraint " + constraintName);
                        continue tableConstraintLoop;
                    }
                    for (CheckConstraint cc : meta.getCheckConstraints()) {
                        if (constraintName.equals(name(cc.getConstraintCatalog(), cc.getConstraintSchema(), cc.getConstraintName()))) {
                            table.checks.add(new CheckImpl<>(table, constraintName, DSL.condition(cc.getCheckClause()), true));
                            continue tableConstraintLoop;
                        }
                    }
                    errors.add("No check clause found for check constraint " + constraintName);
                    continue tableConstraintLoop;
                }
        }
    }
    // -------------------------------------------------------------------------------------------------------------
    sequenceLoop: for (org.jooq.util.xml.jaxb.Sequence xs : meta.getSequences()) {
        Name schemaName = name(xs.getSequenceCatalog(), xs.getSequenceSchema());
        Schema schema = schemasByName.get(schemaName);
        if (schema == null) {
            errors.add("Schema " + schemaName + " not defined for sequence " + xs.getSequenceName());
            continue sequenceLoop;
        }
        String typeName = xs.getDataType();
        int length = xs.getCharacterMaximumLength() == null ? 0 : xs.getCharacterMaximumLength();
        int precision = xs.getNumericPrecision() == null ? 0 : xs.getNumericPrecision();
        int scale = xs.getNumericScale() == null ? 0 : xs.getNumericScale();
        boolean nullable = true;
        BigInteger startWith = xs.getStartValue();
        BigInteger incrementBy = xs.getIncrement();
        BigInteger minvalue = xs.getMinimumValue();
        BigInteger maxvalue = xs.getMaximumValue();
        Boolean cycle = xs.isCycleOption();
        BigInteger cache = xs.getCache();
        InformationSchemaSequence is = new InformationSchemaSequence(xs.getSequenceName(), schema, type(typeName, length, precision, scale, nullable, false, null, null), startWith, incrementBy, minvalue, maxvalue, cycle, cache);
        sequences.add(is);
    }
    // -------------------------------------------------------------------------------------------------------------
    for (Schema s : schemas) initLookup(schemasPerCatalog, s.getCatalog(), s);
    for (InformationSchemaDomain<?> d : domains) initLookup(domainsPerSchema, d.getSchema(), d);
    for (InformationSchemaTable t : tables) initLookup(tablesPerSchema, t.getSchema(), t);
    for (Sequence<?> q : sequences) initLookup(sequencesPerSchema, q.getSchema(), q);
    if (!errors.isEmpty())
        throw new IllegalArgumentException(errors.toString());
}
Also used : UniqueKey(org.jooq.UniqueKey) EMPTY_SORTFIELD(org.jooq.impl.Tools.EMPTY_SORTFIELD) Table(org.jooq.Table) HashMap(java.util.HashMap) STORED(org.jooq.impl.QOM.GenerationOption.STORED) ForeignKey(org.jooq.ForeignKey) Sequence(org.jooq.Sequence) ArrayList(java.util.ArrayList) InformationSchema(org.jooq.util.xml.jaxb.InformationSchema) Index(org.jooq.Index) Map(java.util.Map) Schema(org.jooq.Schema) BigInteger(java.math.BigInteger) Comparator.comparing(java.util.Comparator.comparing) KeyColumnUsage(org.jooq.util.xml.jaxb.KeyColumnUsage) EMPTY_CHECK(org.jooq.impl.Tools.EMPTY_CHECK) Domain(org.jooq.Domain) FALSE(java.lang.Boolean.FALSE) Record(org.jooq.Record) Comparator.comparingInt(java.util.Comparator.comparingInt) DataType(org.jooq.DataType) DSL.name(org.jooq.impl.DSL.name) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) Collections.emptyList(java.util.Collections.emptyList) Name(org.jooq.Name) CheckConstraint(org.jooq.util.xml.jaxb.CheckConstraint) ReferentialConstraint(org.jooq.util.xml.jaxb.ReferentialConstraint) Check(org.jooq.Check) Field(org.jooq.Field) StringUtils(org.jooq.tools.StringUtils) PRIMARY_KEY(org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY) GenerationOption(org.jooq.impl.QOM.GenerationOption) Objects(java.util.Objects) TableType(org.jooq.TableOptions.TableType) Configuration(org.jooq.Configuration) List(java.util.List) Catalog(org.jooq.Catalog) SortField(org.jooq.SortField) VIRTUAL(org.jooq.impl.QOM.GenerationOption.VIRTUAL) TableField(org.jooq.TableField) TableConstraint(org.jooq.util.xml.jaxb.TableConstraint) TableOptions(org.jooq.TableOptions) StringUtils.defaultIfNull(org.jooq.tools.StringUtils.defaultIfNull) IndexColumnUsage(org.jooq.util.xml.jaxb.IndexColumnUsage) TRUE(java.lang.Boolean.TRUE) Collections(java.util.Collections) Column(org.jooq.util.xml.jaxb.Column) HashMap(java.util.HashMap) InformationSchema(org.jooq.util.xml.jaxb.InformationSchema) Schema(org.jooq.Schema) ArrayList(java.util.ArrayList) Index(org.jooq.Index) Name(org.jooq.Name) KeyColumnUsage(org.jooq.util.xml.jaxb.KeyColumnUsage) GenerationOption(org.jooq.impl.QOM.GenerationOption) ArrayList(java.util.ArrayList) Collections.emptyList(java.util.Collections.emptyList) List(java.util.List) CheckConstraint(org.jooq.util.xml.jaxb.CheckConstraint) Sequence(org.jooq.Sequence) TableField(org.jooq.TableField) Catalog(org.jooq.Catalog) BigInteger(java.math.BigInteger) Domain(org.jooq.Domain) IndexColumnUsage(org.jooq.util.xml.jaxb.IndexColumnUsage) Field(org.jooq.Field) SortField(org.jooq.SortField) TableField(org.jooq.TableField) Column(org.jooq.util.xml.jaxb.Column) DataType(org.jooq.DataType) Record(org.jooq.Record) Table(org.jooq.Table) TableType(org.jooq.TableOptions.TableType) ReferentialConstraint(org.jooq.util.xml.jaxb.ReferentialConstraint) BigInteger(java.math.BigInteger) TableConstraint(org.jooq.util.xml.jaxb.TableConstraint)

Aggregations

DataType (org.jooq.DataType)8 Field (org.jooq.Field)7 SortField (org.jooq.SortField)7 TableField (org.jooq.TableField)7 Constraint (org.jooq.Constraint)5 FALSE (java.lang.Boolean.FALSE)4 TRUE (java.lang.Boolean.TRUE)4 BigInteger (java.math.BigInteger)4 ArrayList (java.util.ArrayList)4 Collections.emptyList (java.util.Collections.emptyList)4 List (java.util.List)4 Map (java.util.Map)4 Condition (org.jooq.Condition)4 GroupField (org.jooq.GroupField)4 Name (org.jooq.Name)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)3 BigDecimal (java.math.BigDecimal)3 Date (java.sql.Date)3 Time (java.sql.Time)3 Timestamp (java.sql.Timestamp)3