use of org.jooq.DataType in project jOOQ by jOOQ.
the class Interpreter method accept0.
private final void accept0(AlterTableImpl query) {
Table<?> table = query.$table();
MutableSchema schema = getSchema(table.getSchema());
MutableTable existing = schema.table(table);
if (existing == null) {
if (!query.$ifExists())
throw notExists(table);
return;
} else if (!existing.options.type().isTable())
throw objectNotTable(table);
if (query.$add() != null) {
for (TableElement fc : query.$add()) if (fc instanceof Field && find(existing.fields, (Field<?>) fc) != null)
throw alreadyExists(fc);
else if (fc instanceof Constraint && !fc.getUnqualifiedName().empty() && existing.constraint((Constraint) fc) != null)
throw alreadyExists(fc);
// TODO: ReverseIterable is not a viable approach if we also allow constraints to be added this way
if (query.$addFirst()) {
for (Field<?> f : assertFields(query, reverseIterable(query.$add()))) addField(existing, 0, (UnqualifiedName) f.getUnqualifiedName(), f.getDataType());
} else if (query.$addBefore() != null) {
int index = indexOrFail(existing.fields, query.$addBefore());
for (Field<?> f : assertFields(query, reverseIterable(query.$add()))) addField(existing, index, (UnqualifiedName) f.getUnqualifiedName(), f.getDataType());
} else if (query.$addAfter() != null) {
int index = indexOrFail(existing.fields, query.$addAfter()) + 1;
for (Field<?> f : assertFields(query, reverseIterable(query.$add()))) addField(existing, index, (UnqualifiedName) f.getUnqualifiedName(), f.getDataType());
} else {
for (TableElement fc : query.$add()) if (fc instanceof Field)
addField(existing, Integer.MAX_VALUE, (UnqualifiedName) fc.getUnqualifiedName(), ((Field<?>) fc).getDataType());
else if (fc instanceof ConstraintImpl)
addConstraint(query, (ConstraintImpl) fc, existing);
else
throw unsupportedQuery(query);
}
} else if (query.$addColumn() != null) {
if (find(existing.fields, query.$addColumn()) != null)
if (!query.$ifNotExistsColumn())
throw alreadyExists(query.$addColumn());
else
return;
UnqualifiedName name = (UnqualifiedName) query.$addColumn().getUnqualifiedName();
DataType<?> dataType = query.$addColumnType();
if (query.$addFirst())
addField(existing, 0, name, dataType);
else if (query.$addBefore() != null)
addField(existing, indexOrFail(existing.fields, query.$addBefore()), name, dataType);
else if (query.$addAfter() != null)
addField(existing, indexOrFail(existing.fields, query.$addAfter()) + 1, name, dataType);
else
addField(existing, Integer.MAX_VALUE, name, dataType);
} else if (query.$addConstraint() != null) {
addConstraint(query, (ConstraintImpl) query.$addConstraint(), existing);
} else if (query.$alterColumn() != null) {
MutableField existingField = find(existing.fields, query.$alterColumn());
if (existingField == null)
if (!query.$ifExistsColumn())
throw notExists(query.$alterColumn());
else
return;
if (query.$alterColumnNullability() != null)
existingField.type = existingField.type.nullability(query.$alterColumnNullability());
else if (query.$alterColumnType() != null)
existingField.type = query.$alterColumnType().nullability(query.$alterColumnType().nullability() == Nullability.DEFAULT ? existingField.type.nullability() : query.$alterColumnType().nullability());
else if (query.$alterColumnDefault() != null)
existingField.type = existingField.type.default_((Field) query.$alterColumnDefault());
else if (query.$alterColumnDropDefault())
existingField.type = existingField.type.default_((Field) null);
else
throw unsupportedQuery(query);
} else if (query.$renameTo() != null && checkNotExists(schema, query.$renameTo())) {
existing.name((UnqualifiedName) query.$renameTo().getUnqualifiedName());
} else if (query.$renameColumn() != null) {
MutableField mf = find(existing.fields, query.$renameColumn());
if (mf == null)
throw notExists(query.$renameColumn());
else if (find(existing.fields, query.$renameColumnTo()) != null)
throw alreadyExists(query.$renameColumnTo());
else
mf.name((UnqualifiedName) query.$renameColumnTo().getUnqualifiedName());
} else if (query.$renameConstraint() != null) {
MutableConstraint mc = existing.constraint(query.$renameConstraint(), true);
if (existing.constraint(query.$renameConstraintTo()) != null)
throw alreadyExists(query.$renameConstraintTo());
else
mc.name((UnqualifiedName) query.$renameConstraintTo().getUnqualifiedName());
} else if (query.$alterConstraint() != null) {
existing.constraint(query.$alterConstraint(), true).enforced = query.$alterConstraintEnforced();
} else if (query.$dropColumns() != null) {
List<MutableField> fields = existing.fields(query.$dropColumns().toArray(EMPTY_FIELD), false);
if (fields.size() < query.$dropColumns().size() && !query.$ifExistsColumn())
existing.fields(query.$dropColumns().toArray(EMPTY_FIELD), true);
dropColumns(existing, fields, query.$dropCascade());
} else if (query.$dropConstraint() != null)
dropConstraint: {
ConstraintImpl impl = (ConstraintImpl) query.$dropConstraint();
if (impl.getUnqualifiedName().empty()) {
if (impl.$foreignKey() != null) {
throw new DataDefinitionException("Cannot drop unnamed foreign key");
} else if (impl.$check() != null) {
throw new DataDefinitionException("Cannot drop unnamed check constraint");
} else if (impl.$unique() != null) {
Iterator<MutableUniqueKey> uks = existing.uniqueKeys.iterator();
while (uks.hasNext()) {
MutableUniqueKey key = uks.next();
if (key.fieldsEquals(impl.$unique())) {
cascade(key, null, query.$dropCascade());
uks.remove();
break dropConstraint;
}
}
}
} else {
Iterator<MutableForeignKey> fks = existing.foreignKeys.iterator();
while (fks.hasNext()) {
if (fks.next().nameEquals((UnqualifiedName) impl.getUnqualifiedName())) {
fks.remove();
break dropConstraint;
}
}
if (query.$dropConstraintType() != FOREIGN_KEY) {
Iterator<MutableUniqueKey> uks = existing.uniqueKeys.iterator();
while (uks.hasNext()) {
MutableUniqueKey key = uks.next();
if (key.nameEquals((UnqualifiedName) impl.getUnqualifiedName())) {
cascade(key, null, query.$dropCascade());
uks.remove();
break dropConstraint;
}
}
Iterator<MutableCheck> chks = existing.checks.iterator();
while (chks.hasNext()) {
MutableCheck check = chks.next();
if (check.nameEquals((UnqualifiedName) impl.getUnqualifiedName())) {
chks.remove();
break dropConstraint;
}
}
if (existing.primaryKey != null) {
if (existing.primaryKey.nameEquals((UnqualifiedName) impl.getUnqualifiedName())) {
cascade(existing.primaryKey, null, query.$dropCascade());
existing.primaryKey = null;
break dropConstraint;
}
}
}
}
Iterator<DelayedForeignKey> it = delayedForeignKeyDeclarations.iterator();
while (it.hasNext()) {
DelayedForeignKey key = it.next();
if (existing.equals(key.table) && key.constraint.getUnqualifiedName().equals(impl.getUnqualifiedName())) {
it.remove();
break dropConstraint;
}
}
if (!query.$ifExistsConstraint())
throw notExists(query.$dropConstraint());
}
else if (query.$dropConstraintType() == PRIMARY_KEY) {
if (existing.primaryKey != null)
existing.primaryKey = null;
else
throw primaryKeyNotExists(table);
} else
throw unsupportedQuery(query);
}
use of org.jooq.DataType in project jOOQ by jOOQ.
the class DefaultParseContext method parseFieldJSONArrayConstructorIf.
private final Field<?> parseFieldJSONArrayConstructorIf() {
boolean jsonb = false;
if (parseFunctionNameIf("JSON_ARRAY", "JSON_BUILD_ARRAY") || (jsonb = parseFunctionNameIf("JSONB_BUILD_ARRAY"))) {
parse('(');
if (parseIf(')'))
return jsonb ? jsonbArray() : jsonArray();
List<Field<?>> result = null;
JSONOnNull onNull = parseJSONNullTypeIf();
DataType<?> returning = parseJSONReturningIf();
if (onNull == null && returning == null) {
result = parseList(',', c -> c.parseField());
onNull = parseJSONNullTypeIf();
returning = parseJSONReturningIf();
}
parse(')');
JSONArrayNullStep<?> s1 = result == null ? jsonb ? jsonbArray() : jsonArray() : jsonb ? jsonbArray(result) : jsonArray(result);
JSONArrayReturningStep<?> s2 = onNull == NULL_ON_NULL ? s1.nullOnNull() : onNull == ABSENT_ON_NULL ? s1.absentOnNull() : s1;
return returning == null ? s2 : s2.returning(returning);
}
return null;
}
use of org.jooq.DataType in project jOOQ by jOOQ.
the class ParserImpl method parseAlterTable.
private static final DDLQuery parseAlterTable(ParserContext ctx) {
boolean ifExists = parseKeywordIf(ctx, "IF EXISTS");
Table<?> tableName = parseTableName(ctx);
parseWhitespaceIf(ctx);
AlterTableStep s1 = ifExists ? ctx.dsl.alterTableIfExists(tableName) : ctx.dsl.alterTable(tableName);
switch(ctx.character()) {
case 'a':
case 'A':
if (parseKeywordIf(ctx, "ADD")) {
ConstraintTypeStep constraint = null;
if (parseKeywordIf(ctx, "CONSTRAINT"))
constraint = constraint(parseIdentifier(ctx));
if (parseKeywordIf(ctx, "PRIMARY KEY")) {
parse(ctx, '(');
Field<?>[] fieldNames = parseFieldNames(ctx).toArray(EMPTY_FIELD);
parse(ctx, ')');
return constraint == null ? s1.add(primaryKey(fieldNames)) : s1.add(constraint.primaryKey(fieldNames));
} else if (parseKeywordIf(ctx, "UNIQUE")) {
parse(ctx, '(');
Field<?>[] fieldNames = parseFieldNames(ctx).toArray(EMPTY_FIELD);
parse(ctx, ')');
return constraint == null ? s1.add(unique(fieldNames)) : s1.add(constraint.unique(fieldNames));
} else if (parseKeywordIf(ctx, "FOREIGN KEY")) {
parse(ctx, '(');
Field<?>[] referencing = parseFieldNames(ctx).toArray(EMPTY_FIELD);
parse(ctx, ')');
parseKeyword(ctx, "REFERENCES");
Table<?> referencedTable = parseTableName(ctx);
parse(ctx, '(');
Field<?>[] referencedFields = parseFieldNames(ctx).toArray(EMPTY_FIELD);
parse(ctx, ')');
if (referencing.length != referencedFields.length)
throw ctx.exception();
return constraint == null ? s1.add(foreignKey(referencing).references(referencedTable, referencedFields)) : s1.add(constraint.foreignKey(referencing).references(referencedTable, referencedFields));
} else if (parseKeywordIf(ctx, "CHECK")) {
parse(ctx, '(');
Condition condition = parseCondition(ctx);
parse(ctx, ')');
return constraint == null ? s1.add(check(condition)) : s1.add(constraint.check(condition));
} else if (constraint != null) {
throw ctx.unexpectedToken();
} else {
parseKeywordIf(ctx, "COLUMN");
// 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.
String fieldName = parseIdentifier(ctx);
DataType type = parseDataType(ctx);
boolean nullable = false;
boolean defaultValue = false;
boolean unique = false;
for (; ; ) {
if (!nullable) {
if (parseKeywordIf(ctx, "NULL")) {
type = type.nullable(true);
nullable = true;
continue;
} else if (parseKeywordIf(ctx, "NOT NULL")) {
type = type.nullable(false);
nullable = true;
continue;
}
}
if (!defaultValue) {
if (parseKeywordIf(ctx, "DEFAULT")) {
type = type.defaultValue(parseField(ctx));
defaultValue = true;
continue;
}
}
if (!unique) {
if (parseKeywordIf(ctx, "PRIMARY KEY")) {
throw ctx.unexpectedToken();
} else if (parseKeywordIf(ctx, "UNIQUE")) {
throw ctx.unexpectedToken();
}
}
if (parseKeywordIf(ctx, "CHECK")) {
throw ctx.unexpectedToken();
}
break;
}
return s1.add(field(name(fieldName), type), type);
}
}
break;
case 'd':
case 'D':
if (parseKeywordIf(ctx, "DROP")) {
if (parseKeywordIf(ctx, "COLUMN")) {
Field<?> field = parseFieldName(ctx);
boolean cascade = parseKeywordIf(ctx, "CASCADE");
boolean restrict = !cascade && parseKeywordIf(ctx, "RESTRICT");
AlterTableDropStep s2 = s1.dropColumn(field);
AlterTableFinalStep s3 = cascade ? s2.cascade() : restrict ? s2.restrict() : s2;
return s3;
} else if (parseKeywordIf(ctx, "CONSTRAINT")) {
String constraint = parseIdentifier(ctx);
return s1.dropConstraint(constraint);
}
}
break;
case 'r':
case 'R':
if (parseKeywordIf(ctx, "RENAME")) {
if (parseKeywordIf(ctx, "TO")) {
String newName = parseIdentifier(ctx);
return s1.renameTo(newName);
} else if (parseKeywordIf(ctx, "COLUMN")) {
String oldName = parseIdentifier(ctx);
parseKeyword(ctx, "TO");
String newName = parseIdentifier(ctx);
return s1.renameColumn(oldName).to(newName);
} else if (parseKeywordIf(ctx, "CONSTRAINT")) {
String oldName = parseIdentifier(ctx);
parseKeyword(ctx, "TO");
String newName = parseIdentifier(ctx);
return s1.renameConstraint(oldName).to(newName);
}
}
break;
}
throw ctx.unexpectedToken();
}
use of org.jooq.DataType in project jOOQ by jOOQ.
the class DefaultParseContext method parseJSONArrayAggFunctionIf.
private final AggregateFilterStep<?> parseJSONArrayAggFunctionIf() {
boolean jsonb = false;
if (parseFunctionNameIf("JSON_ARRAYAGG", "JSON_AGG", "JSON_GROUP_ARRAY") || (jsonb = parseFunctionNameIf("JSONB_AGG"))) {
AggregateFilterStep<?> result;
JSONArrayAggOrderByStep<?> s1;
JSONArrayAggNullStep<?> s2;
JSONArrayAggReturningStep<?> s3;
JSONOnNull onNull;
DataType<?> returning;
parse('(');
result = s3 = s2 = s1 = jsonb ? jsonbArrayAgg(parseField()) : jsonArrayAgg(parseField());
if (parseKeywordIf("ORDER BY"))
result = s3 = s2 = s1.orderBy(parseList(',', c -> c.parseSortField()));
if ((onNull = parseJSONNullTypeIf()) != null)
result = s3 = onNull == ABSENT_ON_NULL ? s2.absentOnNull() : s2.nullOnNull();
if ((returning = parseJSONReturningIf()) != null)
result = s3.returning(returning);
parse(')');
return result;
}
return null;
}
use of org.jooq.DataType in project jOOQ by jOOQ.
the class DefaultParseContext method parseFieldJSONObjectConstructorIf.
private final Field<?> parseFieldJSONObjectConstructorIf() {
boolean jsonb = false;
if (parseFunctionNameIf("JSON_OBJECT", "JSON_BUILD_OBJECT") || (jsonb = parseFunctionNameIf("JSONB_BUILD_OBJECT"))) {
parse('(');
if (parseIf(')'))
return jsonb ? jsonbObject() : jsonObject();
List<JSONEntry<?>> result;
JSONOnNull onNull = parseJSONNullTypeIf();
DataType<?> returning = parseJSONReturningIf();
if (onNull == null && returning == null) {
result = parseList(',', c -> parseJSONEntry());
onNull = parseJSONNullTypeIf();
returning = parseJSONReturningIf();
} else
result = new ArrayList<>();
parse(')');
JSONObjectNullStep<?> s1 = jsonb ? jsonbObject(result) : jsonObject(result);
JSONObjectReturningStep<?> s2 = onNull == NULL_ON_NULL ? s1.nullOnNull() : onNull == ABSENT_ON_NULL ? s1.absentOnNull() : s1;
return returning == null ? s2 : s2.returning(returning);
}
return null;
}
Aggregations