Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CASSADNRA-19966 trunk UDT for CREATE TABLE LIKE suggestions #3807

Merged
merged 1 commit into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
5.1
* Fail CREATE TABLE LIKE statement if UDTs in target keyspace do not exist or they have different structure from ones in source keyspace (CASSANDRA-19966)
* Support octet_length and length functions (CASSANDRA-20102)
* Make JsonUtils serialize Instant always with the same format (CASSANDRA-20209)
* Port Harry v2 to trunk (CASSANDRA-20200)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@

package org.apache.cassandra.cql3.statements.schema;

import java.nio.ByteBuffer;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import com.google.common.collect.Sets;

import org.apache.cassandra.audit.AuditLogContext;
import org.apache.cassandra.audit.AuditLogEntryType;
import org.apache.cassandra.auth.Permission;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.QualifiedName;
import org.apache.cassandra.db.guardrails.Guardrails;
import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.db.marshal.UserType;
import org.apache.cassandra.db.marshal.VectorType;
import org.apache.cassandra.exceptions.AlreadyExistsException;
import org.apache.cassandra.schema.Indexes;
Expand Down Expand Up @@ -114,14 +123,39 @@ public Keyspaces apply(ClusterMetadata metadata)

if (targetKeyspaceMeta.hasTable(targetTableName))
{
if(ifNotExists)
if (ifNotExists)
return schema;

throw new AlreadyExistsException(targetKeyspace, targetTableName);
}
// todo support udt for differenet ks latter
if (!sourceKeyspace.equalsIgnoreCase(targetKeyspace) && !sourceTableMeta.getReferencedUserTypes().isEmpty())
throw ire("Cannot use CREATE TABLE LIKE across different keyspace when source table have UDTs.");

if (!sourceKeyspace.equalsIgnoreCase(targetKeyspace))
{
Set<String> missingUserTypes = Sets.newHashSet();
// for different keyspace, if source table used some udts and the target table also need them
for (ByteBuffer sourceUserTypeName : sourceTableMeta.getReferencedUserTypes())
{
Optional<UserType> targetUserType = targetKeyspaceMeta.types.get(sourceUserTypeName);
Optional<UserType> sourceUserType = sourceKeyspaceMeta.types.get(sourceUserTypeName);
if (targetUserType.isPresent() && sourceUserType.isPresent())
{
if (!sourceUserType.get().equalsWithOutKs(targetUserType.get()))
throw ire("Target keyspace '%s' has same UDT name '%s' as source keyspace '%s' but with different structure.",
targetKeyspace,
UTF8Type.instance.getString(targetUserType.get().name),
sourceKeyspace);
}
else
{
missingUserTypes.add(UTF8Type.instance.compose(sourceUserTypeName));
}
}

if (!missingUserTypes.isEmpty())
throw ire("UDTs %s do not exist in target keyspace '%s'.",
missingUserTypes.stream().sorted().collect(Collectors.joining(", ")),
targetKeyspace);
}

// Guardrail on columns per table
Guardrails.columnsPerTable.guard(sourceTableMeta.columns().size(), targetTableName, false, state);
Expand All @@ -130,7 +164,7 @@ public Keyspaces apply(ClusterMetadata metadata)
if (columnMetadata.type.isVector())
{
Guardrails.vectorTypeEnabled.ensureEnabled(columnMetadata.name.toString(), state);
int dimensions = ((VectorType)columnMetadata.type).dimension;
int dimensions = ((VectorType) columnMetadata.type).dimension;
Guardrails.vectorDimensions.guard(dimensions, columnMetadata.name.toString(), false, state);
}
});
Expand Down
8 changes: 8 additions & 0 deletions src/java/org/apache/cassandra/db/marshal/UserType.java
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,14 @@ private boolean equalsWithoutTypes(UserType other)
&& isMultiCell == other.isMultiCell;
}

public boolean equalsWithOutKs(UserType other)
{
return name.equals(other.name)
&& fieldNames.equals(other.fieldNames)
&& types.equals(other.types)
&& isMultiCell == other.isMultiCell;
}

public Optional<Difference> compare(UserType other)
{
if (!equalsWithoutTypes(other))
Expand Down
Loading