Skip to content

Commit

Permalink
Add minimal Variant/Dynamic/JSON examples and tests using JSONEachRow…
Browse files Browse the repository at this point in the history
… format (#305)
  • Loading branch information
slvrtrn authored Sep 2, 2024
1 parent 9b5270b commit 78816e6
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .docker/clickhouse/single_node_tls/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM clickhouse/clickhouse-server:24.3-alpine
FROM clickhouse/clickhouse-server:24.8-alpine
COPY .docker/clickhouse/single_node_tls/certificates /etc/clickhouse-server/certs
RUN chown clickhouse:clickhouse -R /etc/clickhouse-server/certs \
&& chmod 600 /etc/clickhouse-server/certs/* \
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ version: '2.3'

services:
clickhouse1:
image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-24.3-alpine}'
image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-24.8-alpine}'
ulimits:
nofile:
soft: 262144
Expand All @@ -19,7 +19,7 @@ services:
- './.docker/clickhouse/users.xml:/etc/clickhouse-server/users.xml'

clickhouse2:
image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-24.3-alpine}'
image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-24.8-alpine}'
ulimits:
nofile:
soft: 262144
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
version: '3.8'
services:
clickhouse:
image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-24.3-alpine}'
image: 'clickhouse/clickhouse-server:${CLICKHOUSE_VERSION-24.8-alpine}'
container_name: 'clickhouse-js-clickhouse-server'
ports:
- '8123:8123'
Expand Down
4 changes: 4 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ If something is missing, or you found a mistake in one of these examples, please
- [select_streaming_json_each_row_for_await.ts](node/select_streaming_json_each_row_for_await.ts) - (Node.js only) similar to [select_streaming_json_each_row.ts](node/select_streaming_json_each_row.ts), but using the `for await` loop syntax.
- [select_streaming_text_line_by_line.ts](node/select_streaming_text_line_by_line.ts) - (Node.js only) streaming text formats from ClickHouse and processing it line by line. In this example, CSV format is used.

#### Data types

- [dynamic_variant_json.ts](./dynamic_variant_json.ts) - using experimental [Dynamic](https://clickhouse.com/docs/en/sql-reference/data-types/dynamic)/[Variant](https://clickhouse.com/docs/en/sql-reference/data-types/variant)/[JSON](https://clickhouse.com/docs/en/sql-reference/data-types/newjson) data types with [JSONEachRow](https://clickhouse.com/docs/en/interfaces/formats#jsoneachrow) format.

#### Special cases

- [default_format_setting.ts](default_format_setting.ts) - sending queries using `exec` method without a `FORMAT` clause; the default format will be set from the client settings.
Expand Down
68 changes: 68 additions & 0 deletions examples/dynamic_variant_json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { createClient } from '@clickhouse/client' // or '@clickhouse/client-web'

void (async () => {
const tableName = `chjs_dynamic_variant_json`
const client = createClient({
clickhouse_settings: {
// Since ClickHouse 24.1
allow_experimental_variant_type: 1,
// Since ClickHouse 24.5
allow_experimental_dynamic_type: 1,
// Since ClickHouse 24.8
allow_experimental_json_type: 1,
},
})
await client.command({
query: `
CREATE OR REPLACE TABLE ${tableName}
(
id UInt64,
var Variant(Int64, String),
dynamic Dynamic,
json JSON
)
ENGINE MergeTree
ORDER BY id
`,
})
// Sample representation in JSONEachRow format
const values = [
{
id: 1,
var: 42,
dynamic: 'foo',
json: {
foo: 'x',
},
},
{
id: 2,
var: 'str',
// defaults to Int64; will be represented as a string in JSON* family formats
// this behavior can be changed with `output_format_json_quote_64bit_integers` setting (default is 1).
// see https://clickhouse.com/docs/en/operations/settings/formats#output_format_json_quote_64bit_integers
dynamic: 144,
json: {
bar: 10,
},
},
]
await client.insert({
table: tableName,
format: 'JSONEachRow',
values,
})
const rs = await client.query({
query: `
SELECT *,
variantType(var),
dynamicType(dynamic),
dynamicType(json.foo),
dynamicType(json.bar)
FROM ${tableName}
`,
format: 'JSONEachRow',
})
console.log(await rs.json())
await client.close()
})()
87 changes: 70 additions & 17 deletions packages/client-common/__tests__/integration/data_types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,9 @@ describe('data types', () => {
})
const result = await client
.query({
query: `SELECT * FROM ${table} ORDER BY id ASC`,
query: `SELECT *
FROM ${table}
ORDER BY id ASC`,
format: 'TabSeparated',
})
.then((r) => r.text())
Expand Down Expand Up @@ -238,7 +240,9 @@ describe('data types', () => {
await insertData(table, values)
const result = await client
.query({
query: `SELECT CAST(e1, 'Int8') AS e1, CAST(e2, 'Int8') AS e2 FROM ${table} ORDER BY id ASC`,
query: `SELECT CAST(e1, 'Int8') AS e1, CAST(e2, 'Int8') AS e2
FROM ${table}
ORDER BY id ASC`,
format: 'JSONEachRow',
})
.then((r) => r.json())
Expand Down Expand Up @@ -426,23 +430,26 @@ describe('data types', () => {
expect(
await client
.query({
query: `SELECT sum(distance) FROM ${table}`,
query: `SELECT sum(distance)
FROM ${table}`,
format: 'TabSeparated',
})
.then((r) => r.text()),
).toEqual('125.53\n')
expect(
await client
.query({
query: `SELECT max(distance) FROM ${table}`,
query: `SELECT max(distance)
FROM ${table}`,
format: 'TabSeparated',
})
.then((r) => r.text()),
).toEqual('100.52\n')
expect(
await client
.query({
query: `SELECT uniqExact(distance) FROM ${table}`,
query: `SELECT uniqExact(distance)
FROM ${table}`,
format: 'TabSeparated',
})
.then((r) => r.text()),
Expand Down Expand Up @@ -504,9 +511,10 @@ describe('data types', () => {
await insertAndAssert(table, values)
})

// JSON cannot be used on a "modern" Cloud instance
whenOnEnv(TestEnv.LocalSingleNode, TestEnv.LocalCluster, TestEnv.Cloud).it(
'should work with JSON',
// New experimental JSON type
// https://clickhouse.com/docs/en/sql-reference/data-types/newjson
whenOnEnv(TestEnv.LocalSingleNode, TestEnv.LocalCluster).it(
'should work with (new) JSON',
async () => {
const values = [
{
Expand All @@ -516,8 +524,40 @@ describe('data types', () => {
o: { a: 2, b: { c: 3, d: [4, 5, 6] } },
},
]
const table = await createTableWithFields(client, `o Object('json')`, {
allow_experimental_object_type: 1,
const table = await createTableWithFields(client, `o JSON`, {
allow_experimental_json_type: 1,
})
await insertAndAssert(table, values, {
output_format_json_quote_64bit_integers: 0,
})
},
)

// New experimental Variant type
// https://clickhouse.com/docs/en/sql-reference/data-types/variant
whenOnEnv(TestEnv.LocalSingleNode, TestEnv.LocalCluster).it(
'should work with Variant',
async () => {
const values = [{ var: 'foo' }, { var: 42 }]
const table = await createTableWithFields(
client,
`var Variant(String, Int32)`,
{
allow_experimental_variant_type: 1,
},
)
await insertAndAssert(table, values)
},
)

// New experimental Dynamic type
// https://clickhouse.com/docs/en/sql-reference/data-types/dynamic
whenOnEnv(TestEnv.LocalSingleNode, TestEnv.LocalCluster).it(
'should work with Dynamic',
async () => {
const values = [{ dyn: 'foo' }, { dyn: { bar: 'qux' } }]
const table = await createTableWithFields(client, `dyn Dynamic`, {
allow_experimental_dynamic_type: 1,
})
await insertAndAssert(table, values)
},
Expand Down Expand Up @@ -655,7 +695,9 @@ describe('data types', () => {
})
const result = await client
.query({
query: `SELECT n.id, n.name, n.createdAt, n.roles FROM ${table} ORDER BY id ASC`,
query: `SELECT n.id, n.name, n.createdAt, n.roles
FROM ${table}
ORDER BY id ASC`,
format: 'JSONEachRow',
})
.then((r) => r.json())
Expand Down Expand Up @@ -683,25 +725,36 @@ describe('data types', () => {
) {
const values = data.map((v, i) => ({ ...v, id: i + 1 }))
await client.insert({
format: 'JSONEachRow',
table,
values,
format: 'JSONEachRow',
clickhouse_settings,
})
}

async function assertData<T>(table: string, data: T[]) {
async function assertData<T>(
table: string,
data: T[],
clickhouse_settings: ClickHouseSettings = {},
) {
const result = await client
.query({
query: `SELECT * EXCEPT (id) FROM ${table} ORDER BY id ASC`,
query: `SELECT * EXCEPT (id)
FROM ${table}
ORDER BY id ASC`,
format: 'JSONEachRow',
clickhouse_settings,
})
.then((r) => r.json())
expect(result).toEqual(data)
}

async function insertAndAssert<T>(table: string, data: T[]) {
await insertData(table, data)
await assertData(table, data)
async function insertAndAssert<T>(
table: string,
data: T[],
clickhouse_settings: ClickHouseSettings = {},
) {
await insertData(table, data, clickhouse_settings)
await assertData(table, data, clickhouse_settings)
}
})

0 comments on commit 78816e6

Please sign in to comment.