Skip to content
This repository was archived by the owner on Jun 22, 2025. It is now read-only.

Commit e5d7dc2

Browse files
authored
Fixed json object support (#606)
1 parent 13e0d34 commit e5d7dc2

File tree

5 files changed

+49
-4
lines changed

5 files changed

+49
-4
lines changed

ClickHouse.Client.Tests/BulkCopy/BulkCopyTests.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,5 +470,31 @@ public async Task ShouldNotAffectSharedArrayPool()
470470
Assert.DoesNotThrow(() => { rentedArray[0] = 1; });
471471
ArrayPool<object>.Shared.Return(rentedArray);
472472
}
473+
474+
[Test]
475+
[RequiredFeature(Feature.Json)]
476+
public async Task ShouldInsertJson()
477+
{
478+
var targetTable = "test." + SanitizeTableName($"bulk_json");
479+
await connection.ExecuteStatementAsync($"DROP TABLE IF EXISTS {targetTable}");
480+
await connection.ExecuteStatementAsync($"CREATE TABLE IF NOT EXISTS {targetTable} (value JSON) ENGINE Memory");
481+
482+
using var bulkCopy = new ClickHouseBulkCopy(connection)
483+
{
484+
DestinationTableName = targetTable,
485+
};
486+
487+
var jsonString = "{\"string\": \"value\"}";
488+
var jsonObject = (JsonObject)JsonNode.Parse(jsonString);
489+
490+
await bulkCopy.InitAsync();
491+
await bulkCopy.WriteToServerAsync([[jsonString], [jsonObject]]);
492+
493+
using var reader = await connection.ExecuteReaderAsync($"SELECT * from {targetTable}");
494+
while(reader.Read())
495+
{
496+
Assert.That(reader.GetValue(0), Is.EqualTo(jsonObject).UsingPropertiesComparer());
497+
}
498+
}
473499
}
474500

ClickHouse.Client.Tests/TestUtilities.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ public static IEnumerable<DataTypeSample> GetDataTypeSamples()
249249
"{\"val\": 1.5}",
250250
"{\"val\": [1,2]}",
251251
"{ \"nested\": { \"double\": 1.23456, \"int\": 123456, \"string\": \"stringValue\" } }",
252-
//"{ \"nested1\": { \"nested2\": {\"nested3\": {\"a\": 1, \"b\": \"c\", \"d\": null}} } }",
252+
"{ \"nestedArray\": [{\"val\": 1}, {\"val\": 2}] }",
253253
};
254254

255255
foreach (var example in jsonExamples)

ClickHouse.Client/ADO/Readers/ClickHouseDataReader.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public override int GetOrdinal(string name)
135135
return index;
136136
}
137137

138-
public override string GetString(int ordinal) => (string)GetValue(ordinal);
138+
public override string GetString(int ordinal) => GetValue(ordinal)?.ToString();
139139

140140
public override object GetValue(int ordinal) => CurrentRow[ordinal];
141141

ClickHouse.Client/Types/JsonType.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ public override void Write(ExtendedBinaryWriter writer, object value)
6464

6565

6666
// Simple depth-first search to flatten the JSON object into a dictionary
67+
WriteJsonObject(writer, rootObject);
68+
}
69+
70+
internal static void WriteJsonObject(ExtendedBinaryWriter writer, JsonObject rootObject)
71+
{
6772
Dictionary<string, JsonNode> fields = new();
6873
StringBuilder currentPath = new();
6974
FlattenJson(rootObject, ref currentPath, ref fields);
@@ -191,6 +196,12 @@ internal static void WriteJsonArray(ExtendedBinaryWriter writer, JsonArray array
191196
case JsonValueKind.Null:
192197
writer.Write((byte)0x00);
193198
break;
199+
case JsonValueKind.Object:
200+
writer.Write((byte)0x30);
201+
writer.Write((byte)0);
202+
writer.Write7BitEncodedInt(256);
203+
writer.Write((int)16);
204+
break;
194205
default:
195206
throw new SerializationException($"Unsupported JSON value kind: {kind}");
196207
}
@@ -222,6 +233,9 @@ internal static void WriteJsonArray(ExtendedBinaryWriter writer, JsonArray array
222233
case JsonValueKind.Null:
223234
writer.Write((byte)0x00);
224235
break;
236+
case JsonValueKind.Object:
237+
WriteJsonObject(writer, (JsonObject)value);
238+
break;
225239
default:
226240
throw new SerializationException($"Unsupported JSON value kind: {value.GetValueKind()}");
227241
}

ClickHouse.Client/Types/TypeConverter.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,15 @@ internal static ClickHouseType FromByteCode(ExtendedBinaryReader reader)
342342
case 0x2D: return new BooleanType();
343343
// case 0x2E: return new SimpleAggregateFunctionType(); // TODO function
344344
// case 0x2F: return new NestedType(); // TODO nested types
345-
case 0x30: return new JsonType(); // TODO JSON settings
345+
case 0x30:
346+
var _serializationVersion = reader.ReadByte(); // <uint8_serialization_version>
347+
var _maxDynamicPaths = reader.Read7BitEncodedInt(); // <var_int_max_dynamic_paths>
348+
var _maxDynamicTypes = reader.ReadInt32(); // <uint8_max_dynamic_types>
349+
return new JsonType(); // TODO JSON settings
346350
default:
347351
break;
348-
};
352+
}
353+
;
349354
throw new ArgumentOutOfRangeException(nameof(value), $"Unknown type: {value}");
350355
}
351356
}

0 commit comments

Comments
 (0)