'WITH WITH' in alter keyspace statements causes NPE

patch by Benjamin Lerer; reviewed by Robert Stupp for CASSANDRA-9565
This commit is contained in:
Benjamin Lerer 2015-06-22 16:40:36 +02:00 committed by Robert Stupp
parent f778c1f88f
commit c939422637
3 changed files with 92 additions and 2 deletions

View File

@ -1,4 +1,5 @@
2.0.17
* 'WITH WITH' in alter keyspace statements causes NPE (CASSANDRA-9565)
* Display min timestamp in sstablemetadata viewer (CASSANDRA-6767)

View File

@ -891,8 +891,8 @@ properties[PropertyDefinitions props]
;
property[PropertyDefinitions props]
: k=ident '=' (simple=propertyValue { try { $props.addProperty(k.toString(), simple); } catch (SyntaxException e) { addRecognitionError(e.getMessage()); } }
| map=map_literal { try { $props.addProperty(k.toString(), convertPropertyMap(map)); } catch (SyntaxException e) { addRecognitionError(e.getMessage()); } })
: k=ident '=' simple=propertyValue { try { $props.addProperty(k.toString(), simple); } catch (SyntaxException e) { addRecognitionError(e.getMessage()); } }
| k=ident '=' map=map_literal { try { $props.addProperty(k.toString(), convertPropertyMap(map)); } catch (SyntaxException e) { addRecognitionError(e.getMessage()); } }
;
propertyValue returns [String str]

View File

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.gms.Gossiper;
import static org.apache.cassandra.cql3.QueryProcessor.process;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class CreateAndAlterKeyspaceTest
{
@BeforeClass
public static void setUpClass() throws Throwable
{
SchemaLoader.loadSchema();
}
@AfterClass
public static void stopGossiper()
{
Gossiper.instance.stop();
}
@Test
// tests CASSANDRA-9565
public void testCreateAndAlterWithDoubleWith() throws Throwable
{
String[] stmts = new String[] {"ALTER KEYSPACE WITH WITH DURABLE_WRITES = true",
"ALTER KEYSPACE ks WITH WITH DURABLE_WRITES = true",
"CREATE KEYSPACE WITH WITH DURABLE_WRITES = true",
"CREATE KEYSPACE ks WITH WITH DURABLE_WRITES = true"};
for (String stmt : stmts) {
assertInvalidSyntax(stmt, "no viable alternative at input 'WITH'");
}
}
/**
* Checks that the specified statement result in a <code>SyntaxException</code> containing the specified message.
*
* @param stmt the statement to check
*/
private static void assertInvalidSyntax(String stmt, String msg) throws Throwable {
try {
process(stmt, ConsistencyLevel.ONE);
fail();
} catch (RuntimeException e) {
assertSyntaxException(e.getCause(), msg);
}
}
/**
* Asserts that the specified exception is a <code>SyntaxException</code> for which the error message contains
* the specified text.
*
* @param exception the exception to test
* @param expectedContent the expected content of the error message
*/
private static void assertSyntaxException(Throwable exception, String expectedContent) {
assertTrue("The exception should be a SyntaxException but is not", exception instanceof SyntaxException);
String msg = exception.getMessage();
assertTrue(String.format("The error message was expected to contains: %s but was %s", expectedContent, msg),
msg.contains(expectedContent));
}
}