|
|
@ -41,7 +41,7 @@ import javax.annotation.CheckReturnValue;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.LinkedHashSet;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.LinkedList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Map;
|
|
|
@ -50,8 +50,6 @@ import java.util.Optional;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
import java.util.stream.IntStream;
|
|
|
|
import java.util.stream.IntStream;
|
|
|
|
|
|
|
|
|
|
|
|
import static org.apache.flink.cdc.common.utils.Preconditions.checkState;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Utils for {@link Schema} to perform the ability of evolution. */
|
|
|
|
/** Utils for {@link Schema} to perform the ability of evolution. */
|
|
|
|
@PublicEvolving
|
|
|
|
@PublicEvolving
|
|
|
|
public class SchemaUtils {
|
|
|
|
public class SchemaUtils {
|
|
|
@ -455,42 +453,54 @@ public class SchemaUtils {
|
|
|
|
return lSchema.copy(mergedColumns);
|
|
|
|
return lSchema.copy(mergedColumns);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void validateMetaSchemaCompatibility(LinkedHashSet<Schema> schemas) {
|
|
|
|
public static void validateMetaSchemaCompatibility(Collection<Schema> schemas) {
|
|
|
|
if (schemas.size() > 1) {
|
|
|
|
if (schemas.size() > 1) {
|
|
|
|
Schema outputSchema = null;
|
|
|
|
Schema outputSchema = null;
|
|
|
|
for (Schema schema : schemas) {
|
|
|
|
for (Schema schema : schemas) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
validateMetaSchemaCompatible(outputSchema, schema);
|
|
|
|
validateMetaSchemaCompatible(outputSchema, schema);
|
|
|
|
|
|
|
|
} catch (SchemaValidationException e) {
|
|
|
|
|
|
|
|
throw new IllegalStateException("Schema validation failed.", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
outputSchema = schema;
|
|
|
|
outputSchema = schema;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static void validateMetaSchemaCompatible(
|
|
|
|
public static void validateMetaSchemaCompatible(
|
|
|
|
@Nullable Schema currentSchema, Schema upcomingSchema) {
|
|
|
|
@Nullable Schema currentSchema, Schema upcomingSchema)
|
|
|
|
|
|
|
|
throws SchemaValidationException {
|
|
|
|
if (currentSchema == null) {
|
|
|
|
if (currentSchema == null) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
checkState(
|
|
|
|
|
|
|
|
currentSchema.primaryKeys().equals(upcomingSchema.primaryKeys()),
|
|
|
|
if (!currentSchema.primaryKeys().equals(upcomingSchema.primaryKeys())) {
|
|
|
|
|
|
|
|
throw new SchemaValidationException(
|
|
|
|
String.format(
|
|
|
|
String.format(
|
|
|
|
"Unable to merge schema %s and %s with different primary keys.",
|
|
|
|
"Unable to merge schema %s and %s with different primary keys.",
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
checkState(
|
|
|
|
}
|
|
|
|
currentSchema.partitionKeys().equals(upcomingSchema.partitionKeys()),
|
|
|
|
|
|
|
|
|
|
|
|
if (!currentSchema.partitionKeys().equals(upcomingSchema.partitionKeys())) {
|
|
|
|
|
|
|
|
throw new SchemaValidationException(
|
|
|
|
String.format(
|
|
|
|
String.format(
|
|
|
|
"Unable to merge schema %s and %s with different partition keys.",
|
|
|
|
"Unable to merge schema %s and %s with different partition keys.",
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
checkState(
|
|
|
|
}
|
|
|
|
currentSchema.options().equals(upcomingSchema.options()),
|
|
|
|
if (!currentSchema.options().equals(upcomingSchema.options())) {
|
|
|
|
|
|
|
|
throw new SchemaValidationException(
|
|
|
|
String.format(
|
|
|
|
String.format(
|
|
|
|
"Unable to merge schema %s and %s with different options.",
|
|
|
|
"Unable to merge schema %s and %s with different options.",
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
checkState(
|
|
|
|
}
|
|
|
|
Objects.equals(currentSchema.comment(), upcomingSchema.comment()),
|
|
|
|
|
|
|
|
|
|
|
|
if (!Objects.equals(currentSchema.comment(), upcomingSchema.comment())) {
|
|
|
|
|
|
|
|
throw new SchemaValidationException(
|
|
|
|
String.format(
|
|
|
|
String.format(
|
|
|
|
"Unable to merge schema %s and %s with different comments.",
|
|
|
|
"Unable to merge schema %s and %s with different comments.",
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
currentSchema, upcomingSchema));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* Try to combine two columns with potential incompatible type.
|
|
|
|
* Try to combine two columns with potential incompatible type.
|
|
|
@ -629,4 +639,11 @@ public class SchemaUtils {
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
throw new IllegalArgumentException(
|
|
|
|
"Failed to get precision of non-exact decimal type " + dataType);
|
|
|
|
"Failed to get precision of non-exact decimal type " + dataType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Thrown to indicate that schema validation has failed due to incompatible schema. */
|
|
|
|
|
|
|
|
public static class SchemaValidationException extends Exception {
|
|
|
|
|
|
|
|
public SchemaValidationException(String message) {
|
|
|
|
|
|
|
|
super(message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|