-
Notifications
You must be signed in to change notification settings - Fork 32
Revert "Upgrade to Cassandra Java Driver 4.x" #301
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -13,27 +13,25 @@ | |||||||||||||||||||
| */ | ||||||||||||||||||||
| package io.prestodb.tempto.internal.query; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import com.datastax.oss.driver.api.core.CqlSession; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.cql.ColumnDefinition; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.cql.ResultSet; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.cql.Row; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.metadata.Metadata; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.metadata.schema.ColumnMetadata; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.metadata.schema.KeyspaceMetadata; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.metadata.schema.TableMetadata; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.type.DataType; | ||||||||||||||||||||
| import com.datastax.oss.driver.api.core.type.DataTypes; | ||||||||||||||||||||
| import com.datastax.driver.core.Cluster; | ||||||||||||||||||||
| import com.datastax.driver.core.ColumnDefinitions; | ||||||||||||||||||||
| import com.datastax.driver.core.ColumnMetadata; | ||||||||||||||||||||
| import com.datastax.driver.core.DataType; | ||||||||||||||||||||
| import com.datastax.driver.core.KeyspaceMetadata; | ||||||||||||||||||||
| import com.datastax.driver.core.Metadata; | ||||||||||||||||||||
| import com.datastax.driver.core.ResultSet; | ||||||||||||||||||||
| import com.datastax.driver.core.Row; | ||||||||||||||||||||
| import com.datastax.driver.core.Session; | ||||||||||||||||||||
| import com.datastax.driver.core.TableMetadata; | ||||||||||||||||||||
| import com.google.common.collect.ImmutableList; | ||||||||||||||||||||
| import com.google.common.collect.ImmutableMap; | ||||||||||||||||||||
| import io.prestodb.tempto.configuration.Configuration; | ||||||||||||||||||||
| import io.prestodb.tempto.query.QueryExecutionException; | ||||||||||||||||||||
| import io.prestodb.tempto.query.QueryResult; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import java.net.InetSocketAddress; | ||||||||||||||||||||
| import java.sql.JDBCType; | ||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||
| import java.util.Optional; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| import static com.google.common.base.Preconditions.checkState; | ||||||||||||||||||||
| import static com.google.common.collect.Lists.newArrayList; | ||||||||||||||||||||
|
|
@@ -44,25 +42,27 @@ public class CassandraQueryExecutor | |||||||||||||||||||
| implements AutoCloseable | ||||||||||||||||||||
| { | ||||||||||||||||||||
| private static final Map<DataType, JDBCType> typeMapping; | ||||||||||||||||||||
| private final CqlSession session; | ||||||||||||||||||||
| private final Cluster cluster; | ||||||||||||||||||||
| private Session session; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| static { | ||||||||||||||||||||
| typeMapping = ImmutableMap.<DataType, JDBCType>builder() | ||||||||||||||||||||
| .put(DataTypes.ASCII, JDBCType.VARCHAR) | ||||||||||||||||||||
| .put(DataTypes.BIGINT, JDBCType.BIGINT) | ||||||||||||||||||||
| .put(DataTypes.BLOB, JDBCType.BLOB) | ||||||||||||||||||||
| .put(DataTypes.BOOLEAN, JDBCType.BOOLEAN) | ||||||||||||||||||||
| .put(DataTypes.COUNTER, JDBCType.BIGINT) | ||||||||||||||||||||
| .put(DataTypes.DATE, JDBCType.DATE) | ||||||||||||||||||||
| .put(DataTypes.DECIMAL, JDBCType.DECIMAL) | ||||||||||||||||||||
| .put(DataTypes.DOUBLE, JDBCType.DOUBLE) | ||||||||||||||||||||
| .put(DataTypes.FLOAT, JDBCType.REAL) | ||||||||||||||||||||
| .put(DataTypes.INT, JDBCType.INTEGER) | ||||||||||||||||||||
| .put(DataTypes.SMALLINT, JDBCType.SMALLINT) | ||||||||||||||||||||
| .put(DataTypes.TEXT, JDBCType.VARCHAR) | ||||||||||||||||||||
| .put(DataTypes.TIME, JDBCType.TIME) | ||||||||||||||||||||
| .put(DataTypes.TIMESTAMP, JDBCType.TIMESTAMP) | ||||||||||||||||||||
| .put(DataTypes.TINYINT, JDBCType.TINYINT) | ||||||||||||||||||||
| .put(DataType.ascii(), JDBCType.VARCHAR) | ||||||||||||||||||||
| .put(DataType.bigint(), JDBCType.BIGINT) | ||||||||||||||||||||
| .put(DataType.blob(), JDBCType.BLOB) | ||||||||||||||||||||
| .put(DataType.cboolean(), JDBCType.BOOLEAN) | ||||||||||||||||||||
| .put(DataType.counter(), JDBCType.BIGINT) | ||||||||||||||||||||
| .put(DataType.date(), JDBCType.DATE) | ||||||||||||||||||||
| .put(DataType.decimal(), JDBCType.DECIMAL) | ||||||||||||||||||||
| .put(DataType.cdouble(), JDBCType.DOUBLE) | ||||||||||||||||||||
| .put(DataType.cfloat(), JDBCType.REAL) | ||||||||||||||||||||
| .put(DataType.cint(), JDBCType.INTEGER) | ||||||||||||||||||||
| .put(DataType.smallint(), JDBCType.SMALLINT) | ||||||||||||||||||||
| //.put(DataType.text(), JDBCType.NVARCHAR) | ||||||||||||||||||||
| .put(DataType.time(), JDBCType.TIME) | ||||||||||||||||||||
| .put(DataType.timestamp(), JDBCType.TIMESTAMP) | ||||||||||||||||||||
| .put(DataType.tinyint(), JDBCType.TINYINT) | ||||||||||||||||||||
| .put(DataType.varchar(), JDBCType.VARCHAR) | ||||||||||||||||||||
| .build(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -77,106 +77,93 @@ public static class TypeNotSupportedException | |||||||||||||||||||
|
|
||||||||||||||||||||
| public CassandraQueryExecutor(Configuration configuration) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| String host = configuration.getStringMandatory("databases.cassandra.host"); | ||||||||||||||||||||
| int port = configuration.getIntMandatory("databases.cassandra.port"); | ||||||||||||||||||||
| String dc = configuration.getString("databases.cassandra.datacenter").orElse("datacenter1"); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Driver 4.x requires a local datacenter to be specified | ||||||||||||||||||||
| // Using "datacenter1" as the default, which is the standard for single-datacenter deployments | ||||||||||||||||||||
| session = CqlSession.builder() | ||||||||||||||||||||
| .addContactPoint(new InetSocketAddress(host, port)) | ||||||||||||||||||||
| .withLocalDatacenter(dc) | ||||||||||||||||||||
| cluster = Cluster.builder() | ||||||||||||||||||||
| .addContactPoint(configuration.getStringMandatory("databases.cassandra.host")) | ||||||||||||||||||||
| .withPort(configuration.getIntMandatory("databases.cassandra.port")) | ||||||||||||||||||||
| .build(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| public QueryResult executeQuery(String sql) | ||||||||||||||||||||
| throws QueryExecutionException | ||||||||||||||||||||
| { | ||||||||||||||||||||
| checkState(!session.isClosed(), "Trying to execute query using closed Session"); | ||||||||||||||||||||
| ensureConnected(); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| ResultSet rs = session.execute(sql); | ||||||||||||||||||||
| List<ColumnDefinition> definitions = newArrayList(); | ||||||||||||||||||||
| for (ColumnDefinition def : rs.getColumnDefinitions()) { | ||||||||||||||||||||
| definitions.add(def); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| List<ColumnDefinitions.Definition> definitions = rs.getColumnDefinitions().asList(); | ||||||||||||||||||||
| List<JDBCType> types = definitions.stream() | ||||||||||||||||||||
| .map(definition -> getJDBCType(definition.getType())) | ||||||||||||||||||||
| .collect(toList()); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| List<String> columnNames = definitions.stream() | ||||||||||||||||||||
| .map(ColumnDefinition::getName) | ||||||||||||||||||||
| .map(Object::toString) | ||||||||||||||||||||
| .map(ColumnDefinitions.Definition::getName) | ||||||||||||||||||||
| .collect(toList()); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| QueryResult.QueryResultBuilder resultBuilder = new QueryResult.QueryResultBuilder(types, columnNames); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| for (Row row : rs) { | ||||||||||||||||||||
| List<Object> builderRow = newArrayList(); | ||||||||||||||||||||
| for (int i = 0; i < types.size(); ++i) { | ||||||||||||||||||||
| builderRow.add(row.getObject(i)); | ||||||||||||||||||||
| builderRow.add(row.getToken(i).getValue()); | ||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): Using
|
||||||||||||||||||||
| } | ||||||||||||||||||||
| resultBuilder.addRow(builderRow); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| return resultBuilder.build(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| public CqlSession getSession() | ||||||||||||||||||||
| public Session getSession() | ||||||||||||||||||||
| { | ||||||||||||||||||||
| return session; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
Comment on lines
+114
to
117
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (bug_risk): With the previous eager construction,
Suggested change
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| public List<String> getColumnNames(String keyspaceName, String tableName) | ||||||||||||||||||||
| public List<String> getColumnNames(String keySpace, String tableName) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| Optional<KeyspaceMetadata> keyspaceMetadata = session.getMetadata().getKeyspace(keyspaceName); | ||||||||||||||||||||
| if (!keyspaceMetadata.isPresent()) { | ||||||||||||||||||||
| throw new IllegalStateException(format("Keyspace %s does not exist", keyspaceName)); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| Optional<TableMetadata> tableMetadata = keyspaceMetadata.get().getTable(tableName); | ||||||||||||||||||||
| if (!tableMetadata.isPresent()) { | ||||||||||||||||||||
| throw new IllegalStateException(format("Table %s.%s does not exist", keyspaceName, tableName)); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return tableMetadata.get().getColumns().values().stream() | ||||||||||||||||||||
| .map(ColumnMetadata::getName) | ||||||||||||||||||||
| .map(Object::toString) | ||||||||||||||||||||
| .collect(toList()); | ||||||||||||||||||||
| checkState(tableExists(keySpace, tableName), "table %s.%s does not exist", keySpace, tableName); | ||||||||||||||||||||
| KeyspaceMetadata keyspaceMetadata = session.getCluster().getMetadata().getKeyspace(keySpace); | ||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk):
|
||||||||||||||||||||
| TableMetadata tableMetadata = keyspaceMetadata.getTable(tableName); | ||||||||||||||||||||
| return tableMetadata.getColumns().stream().map(ColumnMetadata::getName).collect(toList()); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| public boolean tableExists(String keyspaceName, String tableName) | ||||||||||||||||||||
| public boolean tableExists(String keySpace, String tableName) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| Optional<KeyspaceMetadata> keyspaceMetadata = session.getMetadata().getKeyspace(keyspaceName); | ||||||||||||||||||||
| if (!keyspaceMetadata.isPresent()) { | ||||||||||||||||||||
| KeyspaceMetadata keyspaceMetadata = cluster.getMetadata().getKeyspace(keySpace); | ||||||||||||||||||||
| if (keyspaceMetadata == null) { | ||||||||||||||||||||
| return false; | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return keyspaceMetadata.get().getTable(tableName).isPresent(); | ||||||||||||||||||||
| return keyspaceMetadata.getTable(tableName) != null; | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| public List<String> getTableNames(String keyspaceName) | ||||||||||||||||||||
| public List<String> getTableNames(String keySpace) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| Metadata clusterMetadata = session.getMetadata(); | ||||||||||||||||||||
| Optional<KeyspaceMetadata> keyspaceMetadata = clusterMetadata.getKeyspace(keyspaceName); | ||||||||||||||||||||
| if (!keyspaceMetadata.isPresent()) { | ||||||||||||||||||||
| Metadata clusterMetadata = cluster.getMetadata(); | ||||||||||||||||||||
| KeyspaceMetadata keyspaceMetadata = clusterMetadata.getKeyspace(keySpace); | ||||||||||||||||||||
| if (keyspaceMetadata == null) { | ||||||||||||||||||||
| return ImmutableList.of(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| return keyspaceMetadata.get().getTables().values().stream() | ||||||||||||||||||||
| return keyspaceMetadata.getTables().stream() | ||||||||||||||||||||
| .map(TableMetadata::getName) | ||||||||||||||||||||
| .map(Object::toString) | ||||||||||||||||||||
| .collect(toList()); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| @Override | ||||||||||||||||||||
| public void close() | ||||||||||||||||||||
| { | ||||||||||||||||||||
| if (session != null && !session.isClosed()) { | ||||||||||||||||||||
| session.close(); | ||||||||||||||||||||
| cluster.close(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| private void ensureConnected() | ||||||||||||||||||||
| { | ||||||||||||||||||||
| checkState(!cluster.isClosed(), "Trying to connect using closed Cluster"); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| if (session == null || session.isClosed()) { | ||||||||||||||||||||
| session = cluster.connect(); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| private static JDBCType getJDBCType(DataType type) | ||||||||||||||||||||
| { | ||||||||||||||||||||
| JDBCType jdbcType = typeMapping.get(type); | ||||||||||||||||||||
| if (jdbcType == null) { | ||||||||||||||||||||
| if (type == null) { | ||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. issue (bug_risk): The null check in The original logic correctly used |
||||||||||||||||||||
| throw new TypeNotSupportedException(type); | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (bug_risk): Dropping the mapping for
DataType.text()may cause unsupported-type failures fortextcolumns.The old mapping handled
textviaDataTypes.TEXT, but the new version removesDataType.text()entirely. Even though Cassandra treatstextandvarcharas aliases, schemas may still declaretext, and the driver may treatDataType.text()separately fromDataType.varchar(). In that case,textcolumns would fail withTypeNotSupportedException. Consider mapping bothDataType.text()andDataType.varchar()to the same JDBC type (e.g.,JDBCType.VARCHARorNVARCHAR, depending on the intent) rather than droppingtextsupport.