mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-2.2' into cassandra-3.0
Conflicts: CHANGES.txt
This commit is contained in:
commit
9b5af911c9
|
|
@ -9,7 +9,8 @@
|
|||
* Hadoop integration is incompatible with Cassandra Driver 3.0.0 (CASSANDRA-11001)
|
||||
* Add dropped_columns to the list of schema table so it gets handled
|
||||
properly (CASSANDRA-11050)
|
||||
Merged from 2.2.6:
|
||||
Merged from 2.2:
|
||||
* Make SELECT JSON and toJson() threadsafe (CASSANDRA-11048)
|
||||
* Fix SELECT on tuple relations for mixed ASC/DESC clustering order (CASSANDRA-7281)
|
||||
* (cqlsh) Support utf-8/cp65001 encoding on Windows (CASSANDRA-11030)
|
||||
* Fix paging on DISTINCT queries repeats result when first row in partition changes (CASSANDRA-10010)
|
||||
|
|
|
|||
|
|
@ -35,10 +35,16 @@ public class Json
|
|||
{
|
||||
public static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
public static final JsonStringEncoder JSON_STRING_ENCODER = new JsonStringEncoder();
|
||||
|
||||
public static final ColumnIdentifier JSON_COLUMN_ID = new ColumnIdentifier("[json]", true);
|
||||
|
||||
/**
|
||||
* Quotes string contents using standard JSON quoting.
|
||||
*/
|
||||
public static String quoteAsJsonString(String s)
|
||||
{
|
||||
return new String(JsonStringEncoder.getInstance().quoteAsString(s));
|
||||
}
|
||||
|
||||
public static Object decodeJson(String json)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ public abstract class Selection
|
|||
|
||||
ByteBuffer buffer = row.get(i);
|
||||
sb.append('"');
|
||||
sb.append(Json.JSON_STRING_ENCODER.quoteAsString(columnName));
|
||||
sb.append(Json.quoteAsJsonString(columnName));
|
||||
sb.append("\": ");
|
||||
if (buffer == null)
|
||||
sb.append("null");
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ public class AsciiType extends AbstractType<String>
|
|||
{
|
||||
try
|
||||
{
|
||||
return '"' + new String(Json.JSON_STRING_ENCODER.quoteAsString(ByteBufferUtil.string(buffer, Charset.forName("US-ASCII")))) + '"';
|
||||
return '"' + Json.quoteAsJsonString(ByteBufferUtil.string(buffer, Charset.forName("US-ASCII"))) + '"';
|
||||
}
|
||||
catch (CharacterCodingException exc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ public class MapType<K, V> extends CollectionType<Map<K, V>>
|
|||
if (key.startsWith("\""))
|
||||
sb.append(key);
|
||||
else
|
||||
sb.append('"').append(Json.JSON_STRING_ENCODER.quoteAsString(key)).append('"');
|
||||
sb.append('"').append(Json.quoteAsJsonString(key)).append('"');
|
||||
|
||||
sb.append(": ");
|
||||
sb.append(values.toJSONString(CollectionSerializer.readValue(buffer, protocolVersion), protocolVersion));
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class UTF8Type extends AbstractType<String>
|
|||
{
|
||||
try
|
||||
{
|
||||
return '"' + new String(Json.JSON_STRING_ENCODER.quoteAsString(ByteBufferUtil.string(buffer, Charset.forName("UTF-8")))) + '"';
|
||||
return '"' + Json.quoteAsJsonString(ByteBufferUtil.string(buffer, Charset.forName("UTF-8"))) + '"';
|
||||
}
|
||||
catch (CharacterCodingException exc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ public class UserType extends TupleType
|
|||
name = "\"" + name + "\"";
|
||||
|
||||
sb.append('"');
|
||||
sb.append(Json.JSON_STRING_ENCODER.quoteAsString(name));
|
||||
sb.append(Json.quoteAsJsonString(name));
|
||||
sb.append("\": ");
|
||||
|
||||
ByteBuffer valueBuffer = buffers[i];
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import org.apache.cassandra.serializers.SimpleDateSerializer;
|
|||
import org.apache.cassandra.serializers.TimeSerializer;
|
||||
import org.apache.cassandra.utils.ByteBufferUtil;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
|
|
@ -32,11 +33,12 @@ import java.math.BigDecimal;
|
|||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class JsonTest extends CQLTester
|
||||
|
|
@ -927,11 +929,11 @@ public class JsonTest extends CQLTester
|
|||
|
||||
// map<set<text>, text> keys
|
||||
String innerKey1 = "[\"0\", \"1\"]";
|
||||
String fullKey1 = String.format("{\"%s\": \"%s\"}", new String(Json.JSON_STRING_ENCODER.quoteAsString(innerKey1)), "a");
|
||||
String stringKey1 = new String(Json.JSON_STRING_ENCODER.quoteAsString(fullKey1));
|
||||
String fullKey1 = String.format("{\"%s\": \"%s\"}", Json.quoteAsJsonString(innerKey1), "a");
|
||||
String stringKey1 = Json.quoteAsJsonString(fullKey1);
|
||||
String innerKey2 = "[\"3\", \"4\"]";
|
||||
String fullKey2 = String.format("{\"%s\": \"%s\"}", new String(Json.JSON_STRING_ENCODER.quoteAsString(innerKey2)), "b");
|
||||
String stringKey2 = new String(Json.JSON_STRING_ENCODER.quoteAsString(fullKey2));
|
||||
String fullKey2 = String.format("{\"%s\": \"%s\"}", Json.quoteAsJsonString(innerKey2), "b");
|
||||
String stringKey2 = Json.quoteAsJsonString(fullKey2);
|
||||
execute("INSERT INTO %s JSON ?", "{\"k\": 0, \"nestedsetmap\": {\"" + stringKey1 + "\": true, \"" + stringKey2 + "\": false}}");
|
||||
assertRows(execute("SELECT JSON k, nestedsetmap FROM %s"), row("{\"k\": 0, \"nestedsetmap\": {\"" + stringKey1 + "\": true, \"" + stringKey2 + "\": false}}"));
|
||||
|
||||
|
|
@ -955,4 +957,56 @@ public class JsonTest extends CQLTester
|
|||
execute("INSERT INTO %s JSON ?", "{\"k\": 0, \"a\": {\"a\": 0, \"b\": [1, 2, 3], \"c\": null}, \"b\": null}");
|
||||
assertRows(execute("SELECT k, a.a, a.b, a.c, b FROM %s"), row(0, 0, set(1, 2, 3), null, null));
|
||||
}
|
||||
|
||||
// done for CASSANDRA-11048
|
||||
@Test
|
||||
public void testJsonTreadSafety() throws Throwable
|
||||
{
|
||||
int numThreads = 10;
|
||||
final int numRows = 10000;
|
||||
|
||||
createTable("CREATE TABLE %s (" +
|
||||
"k text PRIMARY KEY, " +
|
||||
"v text)");
|
||||
|
||||
for (int i = 0; i < numRows; i++)
|
||||
execute("INSERT INTO %s (k, v) VALUES (?, ?)", "" + i, "" + i);
|
||||
|
||||
long seed = System.nanoTime();
|
||||
System.out.println("Seed " + seed);
|
||||
final Random rand = new Random(seed);
|
||||
|
||||
final Runnable worker = new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < numRows; i++)
|
||||
{
|
||||
String key = "" + rand.nextInt(numRows);
|
||||
assertRows(execute("SELECT JSON * FROM %s WHERE k = ?", key),
|
||||
row(String.format("{\"k\": \"%s\", \"v\": \"%s\"}", key, key)));
|
||||
}
|
||||
}
|
||||
catch (Throwable exc)
|
||||
{
|
||||
exc.printStackTrace();
|
||||
fail(exc.getMessage());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ExecutorService executor = Executors.newFixedThreadPool(numThreads);
|
||||
List<Future> futures = new ArrayList<>();
|
||||
for (int i = 0; i < numThreads; i++)
|
||||
futures.add(executor.submit(worker));
|
||||
|
||||
for (Future future : futures)
|
||||
future.get(10, TimeUnit.SECONDS);
|
||||
|
||||
executor.shutdown();
|
||||
Assert.assertTrue(executor.awaitTermination(10, TimeUnit.SECONDS));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue