Netflix / astyanax

Cassandra Java Client
Apache License 2.0
1.04k stars 355 forks source link

prepared statement executed against incorrect keyspace #563

Open jcetkov opened 9 years ago

jcetkov commented 9 years ago
private static final ColumnFamily<UUID, String> CF = ColumnFamily.newColumnFamily("notimportant", UUIDSerializer.get(), StringSerializer.get());

    public static void main(String[] args) throws InterruptedException, ConnectionException {
        AstyanaxContext<Cluster> context = new AstyanaxContext.Builder()
                .forCluster("")
                .withAstyanaxConfiguration(new AstyanaxConfigurationImpl()
                        .setDiscoveryType(NodeDiscoveryType.RING_DESCRIBE)
                        .setCqlVersion("3.0.0")
                        .setTargetCassandraVersion("1.2")
                        .setDefaultReadConsistencyLevel(ConsistencyLevel.CL_ONE)
                        .setDefaultWriteConsistencyLevel(ConsistencyLevel.CL_QUORUM)
                        .setRetryPolicy(new RetryNTimes(2))
                )
                .withConnectionPoolConfiguration(new ConnectionPoolConfigurationImpl("MyConnectionPool")
                        .setPort(9160)
                        .setInitConnsPerHost(2)
                        .setMaxConnsPerHost(2)
                        .setSeeds("127.0.0.1")
                        .setConnectTimeout(2000)
                )
                .withConnectionPoolMonitor(new CountingConnectionPoolMonitor())
                .buildCluster(ThriftFamilyFactory.getInstance());

        context.start();

        Map<String, Object> keyspaceProps = new HashMap<>();

        keyspaceProps.put("strategy_options", ImmutableMap.<String, Object>builder()
                .put("replication_factor", "1")
                .build());
        keyspaceProps.put("strategy_class", "SimpleStrategy");

        Keyspace keyspace = context.getClient().getKeyspace("k3");
        keyspace.createKeyspace(keyspaceProps);

        keyspace = context.getClient().getKeyspace("k2");
        keyspace.createKeyspace(keyspaceProps);

        context.getClient().getKeyspace("k3").prepareQuery(CF).withCql("create table test ( id uuid primary key)").asPreparedStatement().execute();

        context.getClient().getKeyspace("k3").dropKeyspace();

        context.getClient().getKeyspace("k2").prepareQuery(CF).withCql("create table test ( id uuid primary key)").asPreparedStatement().execute();

    }

fails on the last line with exception

Caused by: InvalidRequestException(why:Cannot add column family 'test' to non existing keyspace 'k3'.)
    at org.apache.cassandra.thrift.Cassandra$execute_prepared_cql3_query_result.read(Cassandra.java:41868)
    at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:78)
    at org.apache.cassandra.thrift.Cassandra$Client.recv_execute_prepared_cql3_query(Cassandra.java:1689)
    at org.apache.cassandra.thrift.Cassandra$Client.execute_prepared_cql3_query(Cassandra.java:1674)
    at com.netflix.astyanax.thrift.ThriftCql3Query.execute_prepared_cql_query(ThriftCql3Query.java:29)
    at com.netflix.astyanax.thrift.AbstractThriftCqlQuery$3$1.internalExecute(AbstractThriftCqlQuery.java:93)
    at com.netflix.astyanax.thrift.AbstractThriftCqlQuery$3$1.internalExecute(AbstractThriftCqlQuery.java:83)
    at com.netflix.astyanax.thrift.AbstractOperationImpl.execute(AbstractOperationImpl.java:60)

i.e. the statement is executed against keyspace 'k3' instead of specified 'k2'. Seems to be related to prepared statements, removing .asPreparedStatement() resolves it.

tested with

        <dependency>
            <groupId>com.netflix.astyanax</groupId>
            <artifactId>astyanax</artifactId>
            <version>1.56.48</version>
        </dependency>

and

        <dependency>
            <groupId>com.netflix.astyanax</groupId>
            <artifactId>astyanax</artifactId>
            <version>2.0.2</version>
        </dependency>
./nodetool  version
ReleaseVersion: 2.0.8.39
jcetkov commented 9 years ago

workaround exists to include the keyspace name in the query: create table k2.test ( id uuid primary key)

jcetkov commented 9 years ago

it is possible the issue is with the execute_prepared_cql3_query @ C* side - it seems the set_keyspace is called correctly before the execute_prepared_cql3_query (but I am not sure how the session is maintained in thrift (tcp stream?)) - so it would be great if someone more experienced with the protocol workings could confirm it