Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Support ClickHouse driver #221

Merged
merged 9 commits into from
Jul 7, 2023
11 changes: 10 additions & 1 deletion labs/playground1/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ start: build test-data/moma.db ../../node_modules
@vulcan start

# build the required packages
build: pkg-core pkg-build pkg-serve pkg-catalog-server pkg-cli pkg-extension-driver-duckdb pkg-extension-authenticator-canner
build: pkg-core pkg-build pkg-serve pkg-catalog-server pkg-cli pkg-extension-driver-duckdb pkg-extension-authenticator-canner pkg-extension-driver-clickhouse


# build for core pakge
Expand Down Expand Up @@ -56,6 +56,15 @@ pkg-extension-authenticator-canner: ../../node_modules
rm -rf ./labs/playground1/node_modules/@vulcan-sql/extension-authenticator-canner; \
cp -R ./dist/packages/extension-authenticator-canner ./labs/playground1/node_modules/@vulcan-sql

pkg-extension-driver-clickhouse: ../../node_modules
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this necessary? It seems like the vulcan.yaml didn't use the clickhouse extension

@cd ../..; \
yarn nx build extension-driver-clickhouse; \
mkdir -p ./labs/playground1/node_modules/@vulcan-sql; \
rm -rf ./labs/playground1/node_modules/@vulcan-sql/extension-driver-clickhouse; \
cp -R ./dist/packages/extension-driver-clickhouse ./labs/playground1/node_modules/@vulcan-sql; \
cp -R ./packages/extension-driver-clickhouse/node_modules/@clickhouse ./labs/playground1/node_modules


# build and install for cli pakge
pkg-cli: ../../node_modules
@cd ../..; \
Expand Down
82 changes: 82 additions & 0 deletions packages/doc/docs/connect/clickhouse.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# ClickHouse

## Installation

1. Install the package:

**If you are developing with binary, the package is already bundled in the binary. You can skip this step.**

```bash
npm i @vulcan-sql/extension-driver-clickhouse
```

2. Update your `vulcan.yaml` file to enable the extension:

```yaml
extensions:
...
// highlight-next-line
ch: '@vulcan-sql/extension-driver-clickhouse' # Add this line
```

3. Create a new profile in your `profiles.yaml` file or in the designated profile paths. For example:

```yaml
- name: ch # profile name
type: clickhouse
connection:
host: www.example.com:8123
request_timeout: 60000
compression:
request: true
max_open_connections: 10
username: user
password: pass
database: hello-clickhouse
allow: '*'
```

## Configuration

For more information, please refer to the [ClickHouse Client documentation](https://clickhouse.com/docs/en/integrations/language-clients/nodejs) to learn about the available arguments for the ClickHouse Client.

| Name | Required | Default | Description |
| -------------------- | -------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| host | N | http://localhost:8123 | ClickHouse instance URL. |
| request_timeout | N | 30000 | Request timeout in milliseconds. |
| max_open_connections | N | Infinity | Maximum number of sockets to allow per host. |
| compression | N | | Compression settings for data transfer. Currently, only GZIP compression using zlib is supported. See [Compression docs](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#compression) for details. |
| username | N | default | The name of the user on whose behalf requests are made. |
| password | N | | The user's password. |
| application | N | VulcanSQL | The name of the application using the Node.js client. |
| database | N | default | Database name to use. |
| clickhouse_settings | N | | ClickHouse settings to apply to all requests. For all available settings, see [Advance Settings](https://clickhouse.com/docs/en/operations/settings), and For the definition, see [Definition](https://github.com/ClickHouse/clickhouse-js/blob/0.1.1/src/settings.ts) |
| tls | N | | Configure TLS certificates. See [TLS docs](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#tls-certificates). |
| session_id | N | | ClickHouse Session ID to send with every request. |
| keep_alive | N | | HTTP Keep-Alive related settings. See [Keep Alive docs](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#keep-alive) |

The `log` option is not included above because it requires defining a Logger class and assigning it. Therefore, it cannot be set through `profiles.yaml`.

## Note

ClickHouse supports parameterized queries to prevent SQL injection using prepared statements. Named placeholders are defined using the `{name:type}` syntax. For more information, refer to the [Query with Parameters](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#queries-with-parameters) section in the ClickHouse documentation.

However, the VulcanSQL API supports JSON format for API query parameters and does not support the full range of types available in ClickHouse. VulcanSQL only supports the conversion of the following types:

- `boolean` to ClickHouse type `Bool`
- `number` to ClickHouse types `Int` or `Float`
- `string` to ClickHouse type `String`

Therefore, if you need to query data with special types in ClickHouse, such as `Array(Unit8)`, `Record<K, V>`, `Date`, `DateTime`, and so on, you can use ClickHouse [Regular Functions](https://clickhouse.com/docs/en/sql-reference/functions) or [Type Conversion Functions](https://clickhouse.com/docs/en/sql-reference/functions/type-conversion-functions) to handle them.

Example:

```sql
-- If the `val` from the API query parameter is '1990-11-01' and the `born_date` column is of type `Date32`,
-- you can use the toDate function to convert the value. See https://clickhouse.com/docs/en/sql-reference/functions/type-conversion-functions#todate
SELECT * FROM users WHERE born_date = toDate({val:String});
```

## ⚠️ Caution

The ClickHouse driver currently does not support caching datasets. If you use the ClickHouse driver with caching dataset features, it will result in failure.
22 changes: 13 additions & 9 deletions packages/doc/docs/connect/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@ pagination_next: connect/bigquery
# Overview

We support the following data warehouses to connect with, you can choose multiple connectors in a single project, please check the connectors’ document for the installation guide.
* [PostgreSQL](./postgresql)
* [DuckDB](./duckdb)
* [Snowflake](./snowflake)
* [BigQuery](./bigquery)

- [PostgreSQL](./postgresql)
- [DuckDB](./duckdb)
- [Snowflake](./snowflake)
- [BigQuery](./bigquery)
- [ClickHouse](./clickhouse)

## How to use

Setting up a data warehouse connector is easy, you can follow the steps below to set up a connector.

1. Once you install the connector package, update the `extensions` section in `vulcan.yaml` to include the connector package. For example:
```yaml

```yaml
extensions:
...
// highlight-next-line
pg: '@vulcan-sql/extension-driver-pg' # Add this line
...
// highlight-next-line
pg: '@vulcan-sql/extension-driver-pg' # Add this line
```

2. Create a new profile in `profiles.yaml` or in your profile files.
Expand All @@ -42,4 +46,4 @@ Setting up a data warehouse connector is easy, you can follow the steps below to
- pg # profile name
```

Then, you can query the data warehouse in your APIs.
Then, you can query the data warehouse in your APIs.
1 change: 1 addition & 0 deletions packages/doc/docs/connectors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ We support the following data warehouses to connect with, you can choose multipl
| [DuckDB](./connectors/duckdb) | ✅ Yes | ✅ Yes | ❌ No |
| [Snowflake](./connectors/snowflake) | ✅ Yes | ✅ Yes | ❌ No |
| [BigQuery](./connectors/bigquery) | ✅ Yes | ✅ Yes | ❌ No |
| [ClickHouse](./connectors/clickhouse) | ✅ Yes | ✅ Yes | ❌ No |

\* Fetching rows only when we need them, it has better performance with large query results.

Expand Down
95 changes: 95 additions & 0 deletions packages/doc/docs/connectors/clickhouse.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# ClickHouse

Connect to your ClickHouse servers using the official [Node.js Driver](https://clickhouse.com/docs/en/integrations/language-clients/nodejs).

## Installation

1. Install package

```bash
npm i @vulcan-sql/extension-driver-clickhouse
```

:::info
If you run VulcanSQL with Docker, you should use the command `vulcan-install @vulcan-sql/extension-driver-clickhouse` instead.

:::

2. Update `vulcan.yaml`, and enable the extension.

```yaml
extensions:
...
// highlight-next-line
ch: '@vulcan-sql/extension-driver-clickhouse' # Add this line
```

3. Create a new profile in `profiles.yaml` or in your profile files. For example:

```yaml
- name: ch # profile name
type: clickhouse
connection:
host: www.example.com:8123
request_timeout: 60000
compression:
request: true
max_open_connections: 10
username: user
password: pass
database: hello-clickhouse
allow: '*'
```

## Configuration

For more information, please refer to the [ClickHouse Client documentation](https://clickhouse.com/docs/en/integrations/language-clients/nodejs) to learn about the available arguments for the ClickHouse Client.

| Name | Required | Default | Description |
| -------------------- | -------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| host | N | http://localhost:8123 | ClickHouse instance URL. |
| request_timeout | N | 30000 | Request timeout in milliseconds. |
| max_open_connections | N | Infinity | Maximum number of sockets to allow per host. |
| compression | N | | Compression settings for data transfer. Currently, only GZIP compression using zlib is supported. See [Compression docs](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#compression) for details. |
| username | N | default | The name of the user on whose behalf requests are made. |
| password | N | | The user's password. |
| application | N | VulcanSQL | The name of the application using the Node.js client. |
| database | N | default | Database name to use. |
| clickhouse_settings | N | | ClickHouse settings to apply to all requests. For all available settings, see [Advance Settings](https://clickhouse.com/docs/en/operations/settings), and For the definition, see [Definition](https://github.com/ClickHouse/clickhouse-js/blob/0.1.1/src/settings.ts) |
| tls | N | | Configure TLS certificates. See [TLS docs](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#tls-certificates). |
| session_id | N | | ClickHouse Session ID to send with every request. |
| keep_alive | N | | HTTP Keep-Alive related settings. See [Keep Alive docs](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#keep-alive) |

The `log` option is not included above because it requires defining a Logger class and assigning it. Therefore, it cannot be set through `profiles.yaml`.

## Note

ClickHouse supports parameterized queries to prevent SQL injection using prepared statements. Named placeholders are defined using the `{name:type}` syntax. For more information, refer to the [Query with Parameters](https://clickhouse.com/docs/en/integrations/language-clients/nodejs#queries-with-parameters) section in the ClickHouse documentation.

However, the VulcanSQL API supports JSON format for API query parameters and does not support the full range of types available in ClickHouse. VulcanSQL only supports the conversion of the following types:

- `boolean` to ClickHouse type `Bool`
- `number` to ClickHouse types `Int` or `Float`
- `string` to ClickHouse type `String`

Therefore, if you need to query data with special types in ClickHouse, such as `Array(Unit8)`, `Record<K, V>`, `Date`, `DateTime`, and so on, you can use ClickHouse [Regular Functions](https://clickhouse.com/docs/en/sql-reference/functions) or [Type Conversion Functions](https://clickhouse.com/docs/en/sql-reference/functions/type-conversion-functions) to handle them.

Example:

```sql
-- If the `val` from the API query parameter is '1990-11-01' and the `born_date` column is of type `Date32`,
-- you can use the toDate function to convert the value. See https://clickhouse.com/docs/en/sql-reference/functions/type-conversion-functions#todate
SELECT * FROM users WHERE born_date = toDate({val:String});
```

## ⚠️ Caution

The ClickHouse driver currently does not support caching datasets. If you use the ClickHouse driver with caching dataset features, it will result in failure.

## Testing

To run tests for the `extension-driver-clickhouse` module, use the following command:

```bash
nx test extension-driver-clickhouse
```
23 changes: 16 additions & 7 deletions packages/doc/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const sidebars = {
tutorialSidebar: [
{
type: 'html',
value: '<img src="/img/launch.svg" width="20em" class="menu_icon" /> Getting Started',
value:
'<img src="/img/launch.svg" width="20em" class="menu_icon" /> Getting Started',
className: 'sidebar-title',
},
{
Expand All @@ -38,7 +39,8 @@ const sidebars = {
},
{
type: 'html',
value: '<img src="/img/lightning.svg" width="20em" class="menu_icon" /> Building Data API',
value:
'<img src="/img/lightning.svg" width="20em" class="menu_icon" /> Building Data API',
className: 'sidebar-title',
},
{
Expand Down Expand Up @@ -69,7 +71,11 @@ const sidebars = {
{
type: 'doc',
id: 'connect/duckdb',
}
},
{
type: 'doc',
id: 'connect/clickhouse',
},
],
},
{
Expand Down Expand Up @@ -97,7 +103,7 @@ const sidebars = {
type: 'doc',
id: 'develop/advance',
},
]
],
},
{
type: 'doc',
Expand Down Expand Up @@ -144,7 +150,8 @@ const sidebars = {
},
{
type: 'html',
value: '<img src="/img/doc.svg" width="20em" class="menu_icon" /> API Catalog & Documentation',
value:
'<img src="/img/doc.svg" width="20em" class="menu_icon" /> API Catalog & Documentation',
className: 'sidebar-title',
},
{
Expand All @@ -164,7 +171,8 @@ const sidebars = {
},
{
type: 'html',
value: '<img src="/img/settings.svg" width="20em" class="menu_icon" /> API Configuration',
value:
'<img src="/img/settings.svg" width="20em" class="menu_icon" /> API Configuration',
className: 'sidebar-title',
},
{
Expand Down Expand Up @@ -319,7 +327,8 @@ const sidebars = {
// },
{
type: 'html',
value: '<img src="/img/deploy.svg" width="20em" class="menu_icon" /> Deployment and Maintenance',
value:
'<img src="/img/deploy.svg" width="20em" class="menu_icon" /> Deployment and Maintenance',
className: 'sidebar-title',
},
'deployment',
Expand Down
Loading