main cde00c5982f5 cached
293 files
1.9 MB
514.6k tokens
766 symbols
1 requests
Download .txt
Showing preview only (2,090K chars total). Download the full file or copy to clipboard to get everything.
Repository: grafana/clickhouse-datasource
Branch: main
Commit: cde00c5982f5
Files: 293
Total size: 1.9 MB

Directory structure:
gitextract_uixxn39k/

├── .config/
│   ├── .cprc.json
│   ├── .prettierrc.js
│   ├── Dockerfile
│   ├── README.md
│   ├── bundler/
│   │   └── externals.ts
│   ├── docker-compose-base.yaml
│   ├── entrypoint.sh
│   ├── eslint.config.mjs
│   ├── jest/
│   │   ├── mocks/
│   │   │   └── react-inlinesvg.tsx
│   │   └── utils.js
│   ├── jest-setup.js
│   ├── jest.config.js
│   ├── supervisord/
│   │   └── supervisord.conf
│   ├── tsconfig.json
│   ├── types/
│   │   ├── bundler-rules.d.ts
│   │   ├── custom.d.ts
│   │   ├── setupTests.d.ts
│   │   └── webpack-plugins.d.ts
│   └── webpack/
│       ├── BuildModeWebpackPlugin.ts
│       ├── constants.ts
│       ├── utils.ts
│       └── webpack.config.ts
├── .cprc.json
├── .cursor/
│   └── rules/
│       └── word-list.mdc
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1-bug_report.md
│   │   └── config.yml
│   ├── issue_commands.json
│   ├── pull_request_template.md
│   ├── release.yml
│   ├── renovate.json
│   ├── workflows/
│   │   ├── cron.yml
│   │   ├── detect-breaking-changes.yml
│   │   ├── integration.yml
│   │   ├── issue_commands.yml
│   │   ├── publish.yml
│   │   ├── push.yml
│   │   └── stale.yml
│   └── zizmor.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.js
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DEV_GUIDE.md
├── LICENSE
├── Magefile.go
├── README.md
├── config/
│   ├── admin.xml
│   ├── config-preprocessed.xml
│   ├── config.xml
│   ├── custom.xml
│   ├── server.crt
│   ├── server.key
│   └── users.xml
├── config-secure/
│   ├── config.xml
│   ├── my-own-ca.crt
│   ├── my-own-ca.key
│   ├── my-own-ca.srl
│   ├── server.crt
│   ├── server.csr
│   ├── server.ext
│   ├── server.key
│   └── users.xml
├── cspell.config.json
├── docker-compose.yml
├── docs/
│   ├── Makefile
│   ├── docs.mk
│   ├── make-docs
│   ├── sources/
│   │   ├── _index.md
│   │   ├── alerting.md
│   │   ├── annotations.md
│   │   ├── configure.md
│   │   ├── query-editor.md
│   │   ├── template-variables.md
│   │   └── troubleshooting.md
│   └── variables.mk
├── eslint.config.mjs
├── gen-db-dashboards.js
├── go.mod
├── go.sum
├── jest-runner-serial.js
├── jest-setup.js
├── jest.config.js
├── otel-semconv.yaml
├── package.json
├── pkg/
│   ├── converters/
│   │   ├── converters.go
│   │   └── converters_test.go
│   ├── macros/
│   │   ├── macros.go
│   │   └── macros_test.go
│   ├── main.go
│   └── plugin/
│       ├── connection_error.go
│       ├── connection_error_test.go
│       ├── datasource.go
│       ├── driver.go
│       ├── driver_integration_test.go
│       ├── driver_test.go
│       ├── errors.go
│       ├── schema.go
│       ├── schema_test.go
│       ├── schemacache/
│       │   ├── cache.go
│       │   ├── cache_bench_test.go
│       │   └── cache_test.go
│       ├── settings.go
│       └── settings_test.go
├── playwright.config.ts
├── provisioning/
│   └── datasources/
│       └── clickhouse.yml
├── scripts/
│   ├── ca-cert.sh
│   ├── ca.ext
│   ├── ca.sh
│   └── certs.sh
├── src/
│   ├── __mocks__/
│   │   ├── ConfigEditor.ts
│   │   └── datasource.ts
│   ├── ch-parser/
│   │   ├── helpers.ts
│   │   ├── lexer.ts
│   │   ├── parser.ts
│   │   ├── pluginMacros.ts
│   │   └── types.ts
│   ├── components/
│   │   ├── Divider.tsx
│   │   ├── LogContextPanel.test.tsx
│   │   ├── LogsContextPanel.tsx
│   │   ├── QueryToolbox.tsx
│   │   ├── SqlEditor.test.tsx
│   │   ├── SqlEditor.tsx
│   │   ├── configEditor/
│   │   │   ├── AliasTableConfig.test.tsx
│   │   │   ├── AliasTableConfig.tsx
│   │   │   ├── DefaultDatabaseTableConfig.test.tsx
│   │   │   ├── DefaultDatabaseTableConfig.tsx
│   │   │   ├── HttpHeadersConfig.test.tsx
│   │   │   ├── HttpHeadersConfig.tsx
│   │   │   ├── LabeledInput.test.tsx
│   │   │   ├── LabeledInput.tsx
│   │   │   ├── LogsConfig.test.tsx
│   │   │   ├── LogsConfig.tsx
│   │   │   ├── QuerySettingsConfig.test.tsx
│   │   │   ├── QuerySettingsConfig.tsx
│   │   │   ├── TracesConfig.test.tsx
│   │   │   └── TracesConfig.tsx
│   │   ├── experimental/
│   │   │   └── ConfigSection/
│   │   │       ├── ConfigSection.test.tsx
│   │   │       ├── ConfigSection.tsx
│   │   │       ├── ConfigSubSection.test.tsx
│   │   │       ├── ConfigSubSection.tsx
│   │   │       ├── DataSourceDescription.test.tsx
│   │   │       ├── DataSourceDescription.tsx
│   │   │       ├── GenericConfigSection.test.tsx
│   │   │       ├── GenericConfigSection.tsx
│   │   │       └── index.ts
│   │   ├── queryBuilder/
│   │   │   ├── AggregateEditor.test.tsx
│   │   │   ├── AggregateEditor.tsx
│   │   │   ├── ColumnRolesHelp.tsx
│   │   │   ├── ColumnSelect.test.tsx
│   │   │   ├── ColumnSelect.tsx
│   │   │   ├── ColumnsEditor.test.tsx
│   │   │   ├── ColumnsEditor.tsx
│   │   │   ├── DatabaseTableSelect.test.tsx
│   │   │   ├── DatabaseTableSelect.tsx
│   │   │   ├── DurationUnitSelect.tsx
│   │   │   ├── EditorTypeSwitcher.test.tsx
│   │   │   ├── EditorTypeSwitcher.tsx
│   │   │   ├── FilterEditor.test.tsx
│   │   │   ├── FilterEditor.tsx
│   │   │   ├── GroupByEditor.test.tsx
│   │   │   ├── GroupByEditor.tsx
│   │   │   ├── LimitEditor.test.tsx
│   │   │   ├── LimitEditor.tsx
│   │   │   ├── ModeSwitch.test.tsx
│   │   │   ├── ModeSwitch.tsx
│   │   │   ├── OrderByEditor.test.tsx
│   │   │   ├── OrderByEditor.tsx
│   │   │   ├── OtelVersionSelect.test.tsx
│   │   │   ├── OtelVersionSelect.tsx
│   │   │   ├── QueryBuilder.test.tsx
│   │   │   ├── QueryBuilder.tsx
│   │   │   ├── QueryTypeSwitcher.test.tsx
│   │   │   ├── QueryTypeSwitcher.tsx
│   │   │   ├── SqlPreview.test.tsx
│   │   │   ├── SqlPreview.tsx
│   │   │   ├── Switch.test.tsx
│   │   │   ├── Switch.tsx
│   │   │   ├── TraceIdInput.test.tsx
│   │   │   ├── TraceIdInput.tsx
│   │   │   ├── utils.test.ts
│   │   │   ├── utils.ts
│   │   │   └── views/
│   │   │       ├── LogsQueryBuilder.tsx
│   │   │       ├── TableQueryBuilder.tsx
│   │   │       ├── TimeSeriesQueryBuilder.tsx
│   │   │       ├── TraceQueryBuilder.tsx
│   │   │       ├── logsQueryBuilderHooks.test.ts
│   │   │       ├── logsQueryBuilderHooks.ts
│   │   │       ├── timeSeriesQueryBuilderHooks.test.ts
│   │   │       ├── timeSeriesQueryBuilderHooks.ts
│   │   │       ├── traceQueryBuilderHooks.test.ts
│   │   │       └── traceQueryBuilderHooks.ts
│   │   ├── sqlProvider.test.ts
│   │   ├── sqlProvider.ts
│   │   ├── suggestions.test.ts
│   │   ├── suggestions.ts
│   │   └── ui/
│   │       └── CertificationKey.tsx
│   ├── dashboards/
│   │   ├── cluster-analysis.json
│   │   ├── data-analysis.json
│   │   ├── opentelemetry-clickhouse.json
│   │   ├── query-analysis.json
│   │   └── system-dashboards.json
│   ├── data/
│   │   ├── CHDatasource.test.ts
│   │   ├── CHDatasource.ts
│   │   ├── adHocFilter.test.ts
│   │   ├── adHocFilter.ts
│   │   ├── ast.test.ts
│   │   ├── ast.ts
│   │   ├── columnFilters.test.ts
│   │   ├── columnFilters.ts
│   │   ├── logs.test.ts
│   │   ├── logs.ts
│   │   ├── migration.test.ts
│   │   ├── migration.ts
│   │   ├── sqlGenerator.test.ts
│   │   ├── sqlGenerator.ts
│   │   ├── utils.test.ts
│   │   ├── utils.ts
│   │   ├── validate.test.ts
│   │   └── validate.ts
│   ├── hooks/
│   │   ├── useBuilderOptionChanges.test.ts
│   │   ├── useBuilderOptionChanges.ts
│   │   ├── useBuilderOptionsState.test.ts
│   │   ├── useBuilderOptionsState.ts
│   │   ├── useColumns.test.ts
│   │   ├── useColumns.ts
│   │   ├── useDatabases.test.ts
│   │   ├── useDatabases.ts
│   │   ├── useIsNewQuery.test.ts
│   │   ├── useIsNewQuery.ts
│   │   ├── useSchemaSuggestionsProvider.ts
│   │   ├── useTables.test.ts
│   │   ├── useTables.ts
│   │   ├── useUniqueMapKeys.test.ts
│   │   └── useUniqueMapKeys.ts
│   ├── labels.ts
│   ├── module.ts
│   ├── otel.ts
│   ├── plugin.json
│   ├── selectors.ts
│   ├── styles.ts
│   ├── test/
│   │   └── setupTests.ts
│   ├── tracking.test.ts
│   ├── tracking.ts
│   ├── types/
│   │   ├── config.ts
│   │   ├── queryBuilder.ts
│   │   └── sql.ts
│   ├── utils/
│   │   ├── version.test.ts
│   │   └── version.ts
│   └── views/
│       ├── CHConfigEditor.test.tsx
│       ├── CHConfigEditor.tsx
│       ├── CHConfigEditorHooks.test.ts
│       ├── CHConfigEditorHooks.ts
│       ├── CHQueryEditor.test.tsx
│       ├── CHQueryEditor.tsx
│       ├── config-v2/
│       │   ├── AdditionalSettingsSection.tsx
│       │   ├── AliasTableConfigV2.test.tsx
│       │   ├── AliasTableConfigV2.tsx
│       │   ├── CHConfigEditor.test.tsx
│       │   ├── CHConfigEditor.tsx
│       │   ├── DatabaseCredentialsSection.test.tsx
│       │   ├── DatabaseCredentialsSection.tsx
│       │   ├── HttpHeadersConfigV2.test.tsx
│       │   ├── HttpHeadersConfigV2.tsx
│       │   ├── HttpProtocolSettingsSection.test.tsx
│       │   ├── HttpProtocolSettingsSection.tsx
│       │   ├── LeftSidebar.test.tsx
│       │   ├── LeftSidebar.tsx
│       │   ├── ServerAndEncryptionSection.test.tsx
│       │   ├── ServerAndEncryptionSection.tsx
│       │   ├── TLSSSLSettingsSection.test.tsx
│       │   ├── TLSSSLSettingsSection.tsx
│       │   ├── constants.ts
│       │   ├── helpers.ts
│       │   ├── labelsV2.ts
│       │   └── tracking.ts
│       └── trackingV1.ts
├── tests/
│   ├── benchmarks/
│   │   ├── README.md
│   │   └── trace-id-query.sh
│   ├── e2e/
│   │   ├── adhocRegexFilter.spec.ts
│   │   ├── columnRoles.spec.ts
│   │   ├── configEditor.spec.ts
│   │   ├── fixtures/
│   │   │   ├── seed.sql
│   │   │   └── trace_spans.sql
│   │   ├── queryEditor.spec.ts
│   │   ├── sqlAutocomplete.spec.ts
│   │   ├── sqlValidation.spec.ts
│   │   └── traceLimit.spec.ts
│   └── fixtures/
│       └── property-prices.sql
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .config/.cprc.json
================================================
{
  "version": "6.4.4",
  "features": {}
}


================================================
FILE: .config/.prettierrc.js
================================================
/*
 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
 *
 * In order to extend the configuration follow the steps in .config/README.md
 */

module.exports = {
  endOfLine: 'auto',
  printWidth: 120,
  trailingComma: 'es5',
  semi: true,
  jsxSingleQuote: false,
  singleQuote: true,
  useTabs: false,
  tabWidth: 2,
};


================================================
FILE: .config/Dockerfile
================================================
ARG grafana_version=latest
ARG grafana_image=grafana-enterprise

FROM grafana/${grafana_image}:${grafana_version}

ARG anonymous_auth_enabled=true
ARG development=false
ARG TARGETARCH

ARG GO_VERSION=1.21.6
ARG GO_ARCH=${TARGETARCH:-amd64}

ENV DEV "${development}"

# Make it as simple as possible to access the grafana instance for development purposes
# Do NOT enable these settings in a public facing / production grafana instance
ENV GF_AUTH_ANONYMOUS_ORG_ROLE "Admin"
ENV GF_AUTH_ANONYMOUS_ENABLED "${anonymous_auth_enabled}"
ENV GF_AUTH_BASIC_ENABLED "false"
# Set development mode so plugins can be loaded without the need to sign
ENV GF_DEFAULT_APP_MODE "development"


LABEL maintainer="Grafana Labs <hello@grafana.com>"

ENV GF_PATHS_HOME="/usr/share/grafana"
WORKDIR $GF_PATHS_HOME

USER root

# Installing supervisor and inotify-tools
RUN if [ "${development}" = "true" ]; then \
    if grep -i -q alpine /etc/issue; then \
    apk add supervisor inotify-tools git; \
    elif grep -i -q ubuntu /etc/issue; then \
    DEBIAN_FRONTEND=noninteractive && \
    apt-get update && \
    apt-get install -y supervisor inotify-tools git && \
    rm -rf /var/lib/apt/lists/*; \
    else \
    echo 'ERROR: Unsupported base image' && /bin/false; \
    fi \
    fi

COPY supervisord/supervisord.conf /etc/supervisor.d/supervisord.ini
COPY supervisord/supervisord.conf /etc/supervisor/conf.d/supervisord.conf


# Installing Go
RUN if [ "${development}" = "true" ]; then \
    curl -O -L https://golang.org/dl/go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && \
    rm -rf /usr/local/go && \
    tar -C /usr/local -xzf go${GO_VERSION}.linux-${GO_ARCH}.tar.gz && \
    echo "export PATH=$PATH:/usr/local/go/bin:~/go/bin" >> ~/.bashrc && \
    rm -f go${GO_VERSION}.linux-${GO_ARCH}.tar.gz; \
    fi

# Installing delve for debugging
RUN if [ "${development}" = "true" ]; then \
    /usr/local/go/bin/go install github.com/go-delve/delve/cmd/dlv@latest; \
    fi

# Installing mage for plugin (re)building
RUN if [ "${development}" = "true" ]; then \
    git clone https://github.com/magefile/mage; \
    cd mage; \
    export PATH=$PATH:/usr/local/go/bin; \
    go run bootstrap.go; \
    fi

# Inject livereload script into grafana index.html
RUN sed -i 's|</body>|<script src="http://localhost:35729/livereload.js"></script></body>|g' /usr/share/grafana/public/views/index.html


COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]


================================================
FILE: .config/README.md
================================================
# Default build configuration by Grafana

**This is an auto-generated directory and is not intended to be changed! ⚠️**

The `.config/` directory holds basic configuration for the different tools
that are used to develop, test and build the project. In order to make it updates easier we ask you to
not edit files in this folder to extend configuration.

## How to extend the basic configs?

Bear in mind that you are doing it at your own risk, and that extending any of the basic configuration can lead
to issues around working with the project.

### Extending the ESLint config

Edit the `.eslintrc` file in the project root in order to extend the ESLint configuration.

**Example:**

```json
{
  "extends": "./.config/.eslintrc",
  "rules": {
    "react/prop-types": "off"
  }
}
```

---

### Extending the Prettier config

Edit the `.prettierrc.js` file in the project root in order to extend the Prettier configuration.

**Example:**

```javascript
module.exports = {
  // Prettier configuration provided by Grafana scaffolding
  ...require('./.config/.prettierrc.js'),

  semi: false,
};
```

---

### Extending the Jest config

There are two configuration in the project root that belong to Jest: `jest-setup.js` and `jest.config.js`.

**`jest-setup.js`:** A file that is run before each test file in the suite is executed. We are using it to
set up the Jest DOM for the testing library and to apply some polyfills. ([link to Jest docs](https://jestjs.io/docs/configuration#setupfilesafterenv-array))

**`jest.config.js`:** The main Jest configuration file that extends the Grafana recommended setup. ([link to Jest docs](https://jestjs.io/docs/configuration))

#### ESM errors with Jest

A common issue with the current jest config involves importing an npm package that only offers an ESM build. These packages cause jest to error with `SyntaxError: Cannot use import statement outside a module`. To work around this, we provide a list of known packages to pass to the `[transformIgnorePatterns](https://jestjs.io/docs/configuration#transformignorepatterns-arraystring)` jest configuration property. If need be, this can be extended in the following way:

```javascript
process.env.TZ = 'UTC';
const { grafanaESModules, nodeModulesToTransform } = require('./config/jest/utils');

module.exports = {
  // Jest configuration provided by Grafana
  ...require('./.config/jest.config'),
  // Inform jest to only transform specific node_module packages.
  transformIgnorePatterns: [nodeModulesToTransform([...grafanaESModules, 'packageName'])],
};
```

---

### Extending the TypeScript config

Edit the `tsconfig.json` file in the project root in order to extend the TypeScript configuration.

**Example:**

```json
{
  "extends": "./.config/tsconfig.json",
  "compilerOptions": {
    "preserveConstEnums": true
  }
}
```

---

### Extending the Webpack config

Follow these steps to extend the basic Webpack configuration that lives under `.config/`:

#### 1. Create a new Webpack configuration file

Create a new config file that is going to extend the basic one provided by Grafana.
It can live in the project root, e.g. `webpack.config.ts`.

#### 2. Merge the basic config provided by Grafana and your custom setup

We are going to use [`webpack-merge`](https://github.com/survivejs/webpack-merge) for this.

```typescript
// webpack.config.ts
import type { Configuration } from 'webpack';
import { merge } from 'webpack-merge';
import grafanaConfig, { type Env } from './.config/webpack/webpack.config';

const config = async (env: Env): Promise<Configuration> => {
  const baseConfig = await grafanaConfig(env);

  return merge(baseConfig, {
    // Add custom config here...
    output: {
      asyncChunks: true,
    },
  });
};

export default config;
```

#### 3. Update the `package.json` to use the new Webpack config

We need to update the `scripts` in the `package.json` to use the extended Webpack configuration.

**Update for `build`:**

```diff
-"build": "webpack -c ./.config/webpack/webpack.config.ts --env production",
+"build": "webpack -c ./webpack.config.ts --env production",
```

**Update for `dev`:**

```diff
-"dev": "webpack -w -c ./.config/webpack/webpack.config.ts --env development",
+"dev": "webpack -w -c ./webpack.config.ts --env development",
```

### Configure grafana image to use when running docker

By default, `grafana-enterprise` will be used as the docker image for all docker related commands. If you want to override this behavior, simply alter the `docker-compose.yaml` by adding the following build arg `grafana_image`.

**Example:**

```yaml
version: '3.7'

services:
  grafana:
    extends:
      file: .config/docker-compose-base.yaml
      service: grafana
    build:
      args:
        grafana_version: ${GRAFANA_VERSION:-9.1.2}
        grafana_image: ${GRAFANA_IMAGE:-grafana}
```

In this example, we assign the environment variable `GRAFANA_IMAGE` to the build arg `grafana_image` with a default value of `grafana`. This will allow you to set the value while running the docker compose commands, which might be convenient in some scenarios.

---


================================================
FILE: .config/bundler/externals.ts
================================================
import type { Configuration, ExternalItemFunctionData } from 'webpack';

type ExternalsType = Configuration['externals'];

export const externals: ExternalsType = [
  // Required for dynamic publicPath resolution
  { 'amd-module': 'module' },
  'lodash',
  'jquery',
  'moment',
  'slate',
  'emotion',
  '@emotion/react',
  '@emotion/css',
  'prismjs',
  'slate-plain-serializer',
  '@grafana/slate-react',
  'react',
  'react-dom',
  'react-redux',
  'redux',
  'rxjs',
  'i18next',
  'react-router',
  'react-router-dom',
  'd3',
  'angular',
  /^@grafana\/ui/i,
  /^@grafana\/runtime/i,
  /^@grafana\/data/i,

  // Mark legacy SDK imports as external if their name starts with the "grafana/" prefix
  ({ request }: ExternalItemFunctionData, callback: (error?: Error, result?: string) => void) => {
    const prefix = 'grafana/';
    const hasPrefix = (request: string) => request.indexOf(prefix) === 0;
    const stripPrefix = (request: string) => request.slice(prefix.length);

    if (request && hasPrefix(request)) {
      return callback(undefined, stripPrefix(request));
    }

    callback();
  },
];


================================================
FILE: .config/docker-compose-base.yaml
================================================
services:
  grafana:
    user: root
    container_name: 'grafana-clickhouse-datasource'

    build:
      context: .
      args:
        grafana_image: ${GRAFANA_IMAGE:-grafana-enterprise}
        grafana_version: ${GRAFANA_VERSION:-12.2.0}
        development: ${DEVELOPMENT:-false}
        anonymous_auth_enabled: ${ANONYMOUS_AUTH_ENABLED:-true}
    ports:
      - 3000:3000/tcp
      - 2345:2345/tcp # delve
    security_opt:
      - 'apparmor:unconfined'
      - 'seccomp:unconfined'
    cap_add:
      - SYS_PTRACE
    volumes:
      - ../dist:/var/lib/grafana/plugins/grafana-clickhouse-datasource
      - ../provisioning:/etc/grafana/provisioning
      - ..:/root/grafana-clickhouse-datasource

    environment:
      NODE_ENV: development
      GF_LOG_FILTERS: plugin.grafana-clickhouse-datasource:debug
      GF_LOG_LEVEL: debug
      GF_DATAPROXY_LOGGING: 1
      GF_PLUGINS_ALLOW_LOADING_UNSIGNED_PLUGINS: grafana-clickhouse-datasource


================================================
FILE: .config/entrypoint.sh
================================================
#!/bin/sh

if [ "${DEV}" = "false" ]; then
    echo "Starting test mode"
    exec /run.sh
fi

echo "Starting development mode"

if grep -i -q alpine /etc/issue; then
    exec /usr/bin/supervisord -c /etc/supervisord.conf
elif grep -i -q ubuntu /etc/issue; then
    exec /usr/bin/supervisord -c /etc/supervisor/supervisord.conf
else
    echo 'ERROR: Unsupported base image'
    exit 1
fi



================================================
FILE: .config/eslint.config.mjs
================================================
import { defineConfig } from 'eslint/config';
import grafanaConfig from '@grafana/eslint-config/flat.js';

export default defineConfig([
  ...grafanaConfig,
  {
    rules: {
      'react/prop-types': 'off',
    },
  },
  {
    files: ['src/**/*.{ts,tsx}'],

    languageOptions: {
      parserOptions: {
        project: './tsconfig.json',
      },
    },

    rules: {
      '@typescript-eslint/no-deprecated': 'warn',
    },
  },
  {
    files: ['./tests/**/*'],

    rules: {
      'react-hooks/rules-of-hooks': 'off',
    },
  },
]);


================================================
FILE: .config/jest/mocks/react-inlinesvg.tsx
================================================
// Due to the grafana/ui Icon component making fetch requests to
// `/public/img/icon/<icon_name>.svg` we need to mock react-inlinesvg to prevent
// the failed fetch requests from displaying errors in console.

import React from 'react';

type Callback = (...args: any[]) => void;

export interface StorageItem {
  content: string;
  queue: Callback[];
  status: string;
}

export const cacheStore: { [key: string]: StorageItem } = Object.create(null);

const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;

const InlineSVG = ({ src }: { src: string }) => {
  // testId will be the file name without extension (e.g. `public/img/icons/angle-double-down.svg` -> `angle-double-down`)
  const testId = src.replace(SVG_FILE_NAME_REGEX, '$2');
  return <svg xmlns="http://www.w3.org/2000/svg" data-testid={testId} viewBox="0 0 24 24" />;
};

export default InlineSVG;


================================================
FILE: .config/jest/utils.js
================================================
/*
 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
 *
 * In order to extend the configuration follow the steps in .config/README.md
 */

/*
 * This utility function is useful in combination with jest `transformIgnorePatterns` config
 * to transform specific packages (e.g.ES modules) in a projects node_modules folder.
 */
const nodeModulesToTransform = (moduleNames) => `node_modules\/(?!.*(${moduleNames.join('|')})\/.*)`;

// Array of known nested grafana package dependencies that only bundle an ESM version
const grafanaESModules = [
  '.pnpm', // Support using pnpm symlinked packages
  '@grafana/schema',
  '@wojtekmaj/date-utils',
  'd3',
  'd3-color',
  'd3-force',
  'd3-interpolate',
  'd3-scale-chromatic',
  'get-user-locale',
  'marked',
  'memoize',
  'mimic-function',
  'ol',
  'react-calendar',
  'react-colorful',
  'rxjs',
  'uuid',
];

module.exports = {
  nodeModulesToTransform,
  grafanaESModules,
};


================================================
FILE: .config/jest-setup.js
================================================
/*
 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
 *
 * In order to extend the configuration follow the steps in
 * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-jest-config
 */

import '@testing-library/jest-dom';
import { TextEncoder, TextDecoder } from 'util';

Object.assign(global, { TextDecoder, TextEncoder });

// https://jestjs.io/docs/manual-mocks#mocking-methods-which-are-not-implemented-in-jsdom
Object.defineProperty(global, 'matchMedia', {
  writable: true,
  value: (query) => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // deprecated
    removeListener: jest.fn(), // deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  }),
});

HTMLCanvasElement.prototype.getContext = () => {};


================================================
FILE: .config/jest.config.js
================================================
/*
 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
 *
 * In order to extend the configuration follow the steps in
 * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-jest-config
 */

const path = require('path');
const { grafanaESModules, nodeModulesToTransform } = require('./jest/utils');

module.exports = {
  moduleNameMapper: {
    '\\.(css|scss|sass)$': 'identity-obj-proxy',
    'react-inlinesvg': path.resolve(__dirname, 'jest', 'mocks', 'react-inlinesvg.tsx'),
  },
  modulePaths: ['<rootDir>/src'],
  setupFilesAfterEnv: ['<rootDir>/jest-setup.js'],
  testEnvironment: 'jest-environment-jsdom',
  testMatch: [
    '<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}',
    '<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
    '<rootDir>/src/**/*.{spec,test,jest}.{js,jsx,ts,tsx}',
  ],
  transform: {
    '^.+\\.(t|j)sx?$': [
      '@swc/jest',
      {
        sourceMaps: 'inline',
        jsc: {
          parser: {
            syntax: 'typescript',
            tsx: true,
            decorators: false,
            dynamicImport: true,
          },
        },
      },
    ],
  },
  // Jest will throw `Cannot use import statement outside module` if it tries to load an
  // ES module without it being transformed first. ./config/README.md#esm-errors-with-jest
  transformIgnorePatterns: [nodeModulesToTransform(grafanaESModules)],
  watchPathIgnorePatterns: ['<rootDir>/node_modules', '<rootDir>/dist'],
};


================================================
FILE: .config/supervisord/supervisord.conf
================================================
[supervisord]
nodaemon=true
user=root

[program:grafana]
user=root
directory=/var/lib/grafana
command=bash -c 'while [ ! -f /root/grafana-clickhouse-datasource/dist/gpx_clickhouse* ]; do sleep 1; done; /run.sh'
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
killasgroup=true
stopasgroup=true
autostart=true

[program:delve]
user=root
command=/bin/bash -c 'pid=""; while [ -z "$pid" ]; do pid=$(pgrep -f gpx_clickhouse); done; /root/go/bin/dlv attach --api-version=2 --headless --continue --accept-multiclient --listen=:2345 $pid'
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
killasgroup=false
stopasgroup=false
autostart=true
autorestart=true

[program:build-watcher]
user=root
command=/bin/bash -c 'while inotifywait -e modify,create,delete -r /var/lib/grafana/plugins/grafana-clickhouse-datasource; do echo "Change detected, restarting delve...";supervisorctl restart delve; done'
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
killasgroup=true
stopasgroup=true
autostart=true

[program:mage-watcher]
user=root
environment=PATH="/usr/local/go/bin:/root/go/bin:%(ENV_PATH)s"
directory=/root/grafana-clickhouse-datasource
command=/bin/bash -c 'git config --global --add safe.directory /root/grafana-clickhouse-datasource && mage -v watch'
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
redirect_stderr=true
killasgroup=true
stopasgroup=true
autostart=true


================================================
FILE: .config/tsconfig.json
================================================
/*
 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
 *
 * In order to extend the configuration follow the steps in
 * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-typescript-config
 */
{
  "compilerOptions": {
    "alwaysStrict": true,
    "declaration": false,
    "rootDir": "../src",
    "baseUrl": "../src",
    "typeRoots": ["../node_modules/@types"],
    "resolveJsonModule": true
  },
  "ts-node": {
    "compilerOptions": {
      "module": "commonjs",
      "target": "es5",
      "esModuleInterop": true
    },
    "transpileOnly": true
  },
  "include": ["../src", "./types"],
  "extends": "@grafana/tsconfig"
}


================================================
FILE: .config/types/bundler-rules.d.ts
================================================
// Image declarations
declare module '*.gif' {
  const src: string;
  export default src;
}

declare module '*.jpg' {
  const src: string;
  export default src;
}

declare module '*.jpeg' {
  const src: string;
  export default src;
}

declare module '*.png' {
  const src: string;
  export default src;
}

declare module '*.webp' {
  const src: string;
  export default src;
}

declare module '*.svg' {
  const src: string;
  export default src;
}

// Font declarations
declare module '*.woff';
declare module '*.woff2';
declare module '*.eot';
declare module '*.ttf';
declare module '*.otf';


================================================
FILE: .config/types/custom.d.ts
================================================
// Image declarations
declare module '*.gif' {
  const src: string;
  export default src;
}

declare module '*.jpg' {
  const src: string;
  export default src;
}

declare module '*.jpeg' {
  const src: string;
  export default src;
}

declare module '*.png' {
  const src: string;
  export default src;
}

declare module '*.webp' {
  const src: string;
  export default src;
}

declare module '*.svg' {
  const content: string;
  export default content;
}

// Font declarations
declare module '*.woff';
declare module '*.woff2';
declare module '*.eot';
declare module '*.ttf';
declare module '*.otf';


================================================
FILE: .config/types/setupTests.d.ts
================================================
import '@testing-library/jest-dom';


================================================
FILE: .config/types/webpack-plugins.d.ts
================================================
declare module 'replace-in-file-webpack-plugin' {
  import { Compiler, Plugin } from 'webpack';

  interface ReplaceRule {
    search: string | RegExp;
    replace: string | ((match: string) => string);
  }

  interface ReplaceOption {
    dir?: string;
    files?: string[];
    test?: RegExp | RegExp[];
    rules: ReplaceRule[];
  }

  class ReplaceInFilePlugin extends Plugin {
    constructor(options?: ReplaceOption[]);
    options: ReplaceOption[];
    apply(compiler: Compiler): void;
  }

  export = ReplaceInFilePlugin;
}

declare module 'webpack-livereload-plugin' {
  import { ServerOptions } from 'https';
  import { Compiler, Plugin, Stats, Compilation } from 'webpack';

  interface Options extends Pick<ServerOptions, 'cert' | 'key' | 'pfx'> {
    /**
     * protocol for livereload `<script>` src attribute value
     * @default protocol of the page, either `http` or `https`
     */
    protocol?: string | undefined;
    /**
     * The desired port for the livereload server.
     * If you define port 0, an available port will be searched for, starting from 35729.
     * @default 35729
     */
    port?: number | undefined;
    /**
     * he desired hostname for the appended `<script>` (if present) to point to
     * @default hostname of the page, like `localhost` or 10.0.2.2
     */
    hostname?: string | undefined;
    /**
     * livereload `<script>` automatically to `<head>`.
     * @default false
     */
    appendScriptTag?: boolean | undefined;
    /**
     * RegExp of files to ignore. Null value means ignore nothing.
     * It is also possible to define an array and use multiple anymatch patterns
     */
    ignore?: RegExp | RegExp[] | null | undefined;
    /**
     * amount of milliseconds by which to delay the live reload (in case build takes longer)
     * @default 0
     */
    delay?: number | undefined;
    /**
     * create hash for each file source and only notify livereload if hash has changed
     * @default false
     */
    useSourceHash?: boolean | undefined;
  }

  class LiveReloadPlugin extends Plugin {
    readonly isRunning: boolean;
    constructor(options?: Options);

    apply(compiler: Compiler): void;

    start(watching: any, cb: () => void): void;
    done(stats: Stats): void;
    failed(): void;
    autoloadJs(): string;
    scriptTag(source: string): string;
    applyCompilation(compilation: Compilation): void;
  }

  export = LiveReloadPlugin;
}


================================================
FILE: .config/webpack/BuildModeWebpackPlugin.ts
================================================
import webpack, { type Compiler } from 'webpack';

const PLUGIN_NAME = 'BuildModeWebpack';

export class BuildModeWebpackPlugin {
  apply(compiler: webpack.Compiler) {
    compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
      compilation.hooks.processAssets.tap(
        {
          name: PLUGIN_NAME,
          stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
        },
        async () => {
          const assets = compilation.getAssets();
          for (const asset of assets) {
            if (asset.name.endsWith('plugin.json')) {
              const pluginJsonString = asset.source.source().toString();
              const pluginJsonWithBuildMode = JSON.stringify(
                {
                  ...JSON.parse(pluginJsonString),
                  buildMode: compilation.options.mode,
                },
                null,
                4
              );
              compilation.updateAsset(asset.name, new webpack.sources.RawSource(pluginJsonWithBuildMode));
            }
          }
        }
      );
    });
  }
}


================================================
FILE: .config/webpack/constants.ts
================================================
export const SOURCE_DIR = 'src';
export const DIST_DIR = 'dist';


================================================
FILE: .config/webpack/utils.ts
================================================
import fs from 'fs';
import process from 'process';
import os from 'os';
import path from 'path';
import { glob } from 'glob';
import { SOURCE_DIR } from './constants.ts';

export function isWSL() {
  if (process.platform !== 'linux') {
    return false;
  }

  if (os.release().toLowerCase().includes('microsoft')) {
    return true;
  }

  try {
    return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
  } catch {
    return false;
  }
}

function loadJson(path: string) {
  const rawJson = fs.readFileSync(path, 'utf8');
  return JSON.parse(rawJson);
}

export function getPackageJson() {
  return loadJson(path.resolve(process.cwd(), 'package.json'));
}

export function getPluginJson() {
  return loadJson(path.resolve(process.cwd(), `${SOURCE_DIR}/plugin.json`));
}

export function getCPConfigVersion() {
  const cprcJson = path.resolve(process.cwd(), './.config', '.cprc.json');
  return fs.existsSync(cprcJson) ? loadJson(cprcJson).version : { version: 'unknown' };
}

export function hasReadme() {
  return fs.existsSync(path.resolve(process.cwd(), SOURCE_DIR, 'README.md'));
}

// Support bundling nested plugins by finding all plugin.json files in src directory
// then checking for a sibling module.[jt]sx? file.
export async function getEntries() {
  const pluginsJson = await glob('**/src/**/plugin.json', { absolute: true });

  const plugins = await Promise.all(
    pluginsJson.map((pluginJson) => {
      const folder = path.dirname(pluginJson);
      return glob(`${folder}/module.{ts,tsx,js,jsx}`, { absolute: true });
    })
  );

  return plugins.reduce<Record<string, string>>((result, modules) => {
    return modules.reduce((innerResult, module) => {
      const pluginPath = path.dirname(module);
      const pluginName = path.relative(process.cwd(), pluginPath).replace(/src\/?/i, '');
      const entryName = pluginName === '' ? 'module' : `${pluginName}/module`;

      innerResult[entryName] = module;
      return innerResult;
    }, result);
  }, {});
}


================================================
FILE: .config/webpack/webpack.config.ts
================================================
/*
 * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️
 *
 * In order to extend the configuration follow the steps in
 * https://grafana.com/developers/plugin-tools/how-to-guides/extend-configurations#extend-the-webpack-config
 */

import CopyWebpackPlugin from 'copy-webpack-plugin';
import ESLintPlugin from 'eslint-webpack-plugin';
import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin';
import path from 'path';
import ReplaceInFileWebpackPlugin from 'replace-in-file-webpack-plugin';
import TerserPlugin from 'terser-webpack-plugin';
import { SubresourceIntegrityPlugin } from 'webpack-subresource-integrity';
import webpack, { type Configuration } from 'webpack';
import LiveReloadPlugin from 'webpack-livereload-plugin';
import VirtualModulesPlugin from 'webpack-virtual-modules';

import { BuildModeWebpackPlugin } from './BuildModeWebpackPlugin.ts';
import { DIST_DIR, SOURCE_DIR } from './constants.ts';
import { getCPConfigVersion, getEntries, getPackageJson, getPluginJson, hasReadme, isWSL } from './utils.ts';
import { externals } from '../bundler/externals.ts';

const pluginJson = getPluginJson();
const cpVersion = getCPConfigVersion();
const pluginVersion = getPackageJson().version;

const virtualPublicPath = new VirtualModulesPlugin({
  'node_modules/grafana-public-path.js': `
import amdMetaModule from 'amd-module';

__webpack_public_path__ =
  amdMetaModule && amdMetaModule.uri
    ? amdMetaModule.uri.slice(0, amdMetaModule.uri.lastIndexOf('/') + 1)
    : 'public/plugins/${pluginJson.id}/';
`,
});

export type Env = {
  [key: string]: true | string | Env;
};

const config = async (env: Env): Promise<Configuration> => {
  const baseConfig: Configuration = {
    cache: {
      type: 'filesystem',
      buildDependencies: {
        // __filename doesn't work in Node 24
        config: [path.resolve(process.cwd(), '.config', 'webpack', 'webpack.config.ts')],
      },
    },

    context: path.join(process.cwd(), SOURCE_DIR),

    devtool: env.production ? 'source-map' : 'eval-source-map',

    entry: await getEntries(),

    externals,

    // Support WebAssembly according to latest spec - makes WebAssembly module async
    experiments: {
      asyncWebAssembly: true,
    },

    mode: env.production ? 'production' : 'development',

    module: {
      rules: [
        // This must come first in the rules array otherwise it breaks sourcemaps.
        {
          test: /src\/(?:.*\/)?module\.tsx?$/,
          use: [
            {
              loader: 'imports-loader',
              options: {
                imports: `side-effects grafana-public-path`,
              },
            },
          ],
        },
        {
          exclude: /(node_modules)/,
          test: /\.[tj]sx?$/,
          use: {
            loader: 'swc-loader',
            options: {
              jsc: {
                baseUrl: path.resolve(process.cwd(), SOURCE_DIR),
                target: 'es2015',
                loose: false,
                parser: {
                  syntax: 'typescript',
                  tsx: true,
                  decorators: false,
                  dynamicImport: true,
                },
              },
            },
          },
        },
        {
          test: /\.css$/,
          use: ['style-loader', 'css-loader'],
        },
        {
          test: /\.s[ac]ss$/,
          use: ['style-loader', 'css-loader', 'sass-loader'],
        },
        {
          test: /\.(png|jpe?g|gif|svg)$/,
          type: 'asset/resource',
          generator: {
            filename: Boolean(env.production) ? '[hash][ext]' : '[file]',
          },
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)(\?v=\d+\.\d+\.\d+)?$/,
          type: 'asset/resource',
          generator: {
            filename: Boolean(env.production) ? '[hash][ext]' : '[file]',
          },
        },
      ],
    },

    optimization: {
      minimize: Boolean(env.production),
      minimizer: [
        new TerserPlugin({
          terserOptions: {
            format: {
              comments: (_, { type, value }) => type === 'comment2' && value.trim().startsWith('[create-plugin]'),
            },
            compress: {
              drop_console: ['log', 'info'],
            },
          },
        }),
      ],
    },

    output: {
      clean: {
        keep: new RegExp(`(.*?_(amd64|arm(64)?)(.exe)?|go_plugin_build_manifest)`),
      },
      filename: '[name].js',
      chunkFilename: env.production ? '[name].js?_cache=[contenthash]' : '[name].js',
      library: {
        type: 'amd',
      },
      path: path.resolve(process.cwd(), DIST_DIR),
      publicPath: `public/plugins/${pluginJson.id}/`,
      uniqueName: pluginJson.id,
      crossOriginLoading: 'anonymous',
    },

    plugins: [
      new BuildModeWebpackPlugin(),
      virtualPublicPath,
      // Insert create plugin version information into the bundle
      new webpack.BannerPlugin({
        banner: `/* [create-plugin] version: ${cpVersion} */
          /* [create-plugin] plugin: ${pluginJson.id}@${pluginVersion} */`,
        raw: true,
        entryOnly: true,
      }),
      new CopyWebpackPlugin({
        patterns: [
          // If src/README.md exists use it; otherwise the root README
          // To `compiler.options.output`
          { from: hasReadme() ? 'README.md' : '../README.md', to: '.', force: true },
          { from: 'plugin.json', to: '.' },
          { from: '../LICENSE', to: '.' },
          { from: '../CHANGELOG.md', to: '.', force: true },
          { from: '**/*.json', to: '.' },
          { from: '**/*.svg', to: '.', noErrorOnMissing: true },
          { from: '**/*.png', to: '.', noErrorOnMissing: true },
          { from: '**/*.html', to: '.', noErrorOnMissing: true },
          { from: 'img/**/*', to: '.', noErrorOnMissing: true },
          { from: 'libs/**/*', to: '.', noErrorOnMissing: true },
          { from: 'static/**/*', to: '.', noErrorOnMissing: true },
          { from: '**/query_help.md', to: '.', noErrorOnMissing: true },
        ],
      }),
      // Replace certain template-variables in the README and plugin.json
      new ReplaceInFileWebpackPlugin([
        {
          dir: DIST_DIR,
          test: [/(^|\/)plugin\.json$/, /(^|\/)README\.md$/],

          rules: [
            {
              search: /\%VERSION\%/g,
              replace: pluginVersion,
            },
            {
              search: /\%TODAY\%/g,
              replace: new Date().toISOString().substring(0, 10),
            },
            {
              search: /\%PLUGIN_ID\%/g,
              replace: pluginJson.id,
            },
          ],
        },
      ]),
      new SubresourceIntegrityPlugin({
        hashFuncNames: ['sha256'],
      }),
      ...(env.development
        ? [
            new LiveReloadPlugin(),
            new ForkTsCheckerWebpackPlugin({
              async: Boolean(env.development),
              issue: {
                include: [{ file: '**/*.{ts,tsx}' }],
              },
              typescript: { configFile: path.join(process.cwd(), 'tsconfig.json') },
            }),
            new ESLintPlugin({
              extensions: ['.ts', '.tsx'],
              lintDirtyModulesOnly: Boolean(env.development), // don't lint on start, only lint changed files
              failOnError: Boolean(env.production),
            }),
          ]
        : []),
    ],

    resolve: {
      extensions: ['.js', '.jsx', '.ts', '.tsx'],
      // handle resolving "rootDir" paths
      modules: [path.resolve(process.cwd(), 'src'), 'node_modules'],
      unsafeCache: true,
    },
  };

  if (isWSL()) {
    baseConfig.watchOptions = {
      poll: 3000,
      ignored: /node_modules/,
    };
  }

  return baseConfig;
};

export default config;


================================================
FILE: .cprc.json
================================================
{
  "features": {
    "bundleGrafanaUI": false,
    "useReactRouterV6": false,
    "useExperimentalRspack": false
  }
}


================================================
FILE: .cursor/rules/word-list.mdc
================================================
---
description: Project word list and preferred spelling
alwaysApply: true
---

# Word list

Use these spellings in this project (docs and code):

- **drop-down** (not "dropdown") — e.g. "the filter drop-down", "drop-downs and filters"


================================================
FILE: .github/CODEOWNERS
================================================
# Lines starting with '#' are comments.
# Each line is a file pattern followed by one or more owners.

# More details are here: https://help.github.com/articles/about-codeowners/

# The '*' pattern is global owners.

# Order is important. The last matching pattern has the most precedence.
# The folders are ordered as follows:

# In each subsection folders are ordered first by depth, then alphabetically.
# This should make it easy to add new rules without breaking existing ones.

* @grafana/data-sources-plugins


================================================
FILE: .github/ISSUE_TEMPLATE/1-bug_report.md
================================================
---
name: Bug report
about: Report a bug you found when using this plugin
labels: ['datasource/ClickHouse', 'type/bug']
---

<!--
Please use this template to create your bug report. By providing as much info as possible you help us understand the issue, reproduce it and resolve it for you quicker. Therefore, take a couple of extra minutes to make sure you have provided all info needed.

PROTIP: record your screen and attach it as a gif to showcase the issue.

- Use query inspector to troubleshoot issues: https://bit.ly/2XNF6YS
- How to record and attach gif: https://bit.ly/2Mi8T6K
-->

**What happened**:

**What you expected to happen**:

**How to reproduce it (as minimally and precisely as possible)**:

<!--
Example:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
-->

**Screenshots**

<!--
If applicable, add screenshots to help explain your problem.
-->

**Anything else we need to know?**:

**Environment**:

- Grafana version:
- Plugin version:
- OS Grafana is installed on:
- User OS & Browser:
- Others:


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: Feature Request
    url: https://github.com/grafana/clickhouse-datasource/discussions/new
    about: Discuss ideas for new features or changes
  - name: Questions & Help
    url: https://community.grafana.com
    about: Please ask and answer questions here


================================================
FILE: .github/issue_commands.json
================================================
[
  {
    "type": "label",
    "name": "datasource/ClickHouse",
    "action": "addToProject",
    "addToProject": {
      "url": "https://github.com/orgs/grafana/projects/190"
    }
  },
  {
    "type": "label",
    "name": "datasource/ClickHouse",
    "action": "removeFromProject",
    "addToProject": {
      "url": "https://github.com/orgs/grafana/projects/190"
    }
  },
  {
    "type": "label",
    "name": "type/docs",
    "action": "addToProject",
    "addToProject": {
      "url": "https://github.com/orgs/grafana/projects/69"
    }
  },
  {
    "type": "label",
    "name": "type/docs",
    "action": "removeFromProject",
    "addToProject": {
      "url": "https://github.com/orgs/grafana/projects/69"
    }
  }
]


================================================
FILE: .github/pull_request_template.md
================================================
<!-- Please take time to fill out the below template appropriately, deleting sections where necessary. -->
<!-- Doing so will aid our reviewers in providing timely feedback and allow us to reach an outcome faster. Thanks! -->
<!-- Please delete all sections that do not apply. -->
<!-- To surface this PR in the changelog add the label: changelog -->
<!-- If this PR is going in the changelog please make sure the title of the PR explains the feature in a user-centric way: -->
<!-- Bad: fix state bug in hooks -->
<!-- Good: Fix crash when switching from Query Builder -->

## Type of Change

_Please check the relevant option._

- [ ] 🚀 Feature
- [ ] 🐛 Bug Fix
- [ ] 📝 Documentation
- [ ] 🧹 Refactor / Chore

---

## Feature

_If this is a feature, please complete this section. Otherwise, delete it._

### What is this feature?

_Provide a clear and concise description of the feature._

### Why is this feature needed?

_Explain the problem this feature solves or the value it provides._

### Who is this feature for?

_Describe the target users or use cases for this feature._

### How to test this feature

_Provide step-by-step instructions for reviewers to test the feature._

1.
2.
3.

---

## Bug Fix

_If this is a bug fix, please complete this section. Otherwise, delete it._

### What is the bug?

_Provide a clear and concise description of the bug._

### How to reproduce

_Provide step-by-step instructions to reproduce the bug._

1.
2.
3.

### Related Issues

_Link to any open issues this PR will close. Use "Closes #123" or "Fixes #123" syntax._

Closes #

### Environment (if no related issue)

_If there is no open issue, please specify the versions where the bug occurs._

- **ClickHouse version**:
- **Grafana version**:
- **Plugin version**:

---

## Screenshots / Videos

_Please provide screenshots or videos demonstrating the bug or the feature working. This helps reviewers understand the change visually and speeds up the review process._

| Before | After |
| ------ | ----- |
|        |       |

---

## Please check that:

- [ ] Tests for this change have been added/updated.
- [ ] Documentation has been added/updated (where applicable).

## Special notes for your reviewer

_Use this section for any additional information that may help the reviewer, such as implementation decisions, areas of concern, or context that doesn't fit elsewhere. If you'd like to request review or feedback on a specific part of your changes, please note that here._


================================================
FILE: .github/release.yml
================================================
changelog:
  categories:
    - title: Copy the following lines for the CHANGELOG
      labels:
        - changelog
    - title: Hidden
      exclude:
        labels:
          - '*'


================================================
FILE: .github/renovate.json
================================================
{
    "$schema": "https://docs.renovatebot.com/renovate-schema.json",
    "extends": [
        "github>grafana/grafana-renovate-config//presets/automerge"
    ],
    "platformAutomerge": true,
    "packageRules": [
        {
            "description": "Disable minimum release age for Grafana owned npm packages (@grafana/*)",
            "matchDatasources": [
                "npm"
            ],
            "matchPackageNames": [
                "@grafana/*"
            ],
            "minimumReleaseAge": null
        },
        {
            "description": "Disable minimum release age for Grafana owned Go modules (github.com/grafana/*)",
            "matchManagers": [
                "gomod"
            ],
            "matchPackageNames": [
                "github.com/grafana/*"
            ],
            "minimumReleaseAge": null
        },
        {
            "description": "Disable minimum release age for Grafana owned GitHub Actions (grafana/*)",
            "matchManagers": [
                "github-actions"
            ],
            "matchPackageNames": [
                "grafana/*"
            ],
            "minimumReleaseAge": null
        },
        {
            "description": "Ignore major updates for dependencies that need to be kept in sync with Grafana",
            "matchDatasources": [
                "npm"
            ],
            "matchPackageNames": [
                "react",
                "react-dom",
                "react-router-dom",
                "react-router-dom-v5-compat"
            ],
            "matchUpdateTypes": [
                "major"
            ],
            "enabled": false
        },
        {
            "description": "Ignore major updates for dependencies that need to be kept in sync with the Node version defined in .nvmrc",
            "matchDatasources": [
                "npm"
            ],
            "matchPackageNames": [
                "@types/node"
            ],
            "matchUpdateTypes": [
                "major"
            ],
            "enabled": false
        },
        {
            "description": "Keep rxjs in sync with the version used by @grafana/* packages",
            "matchDatasources": [
                "npm"
            ],
            "matchPackageNames": [
                "rxjs"
            ],
            "enabled": false
        },
        {
            "description": "Automerge minor dependencies",
            "matchUpdateTypes": [
                "minor"
            ],
            "automerge": true,
            "labels": [
                "automerge-minor"
            ]
        }
    ]
}

================================================
FILE: .github/workflows/cron.yml
================================================
name: Scheduled Cloud E2E tests

on:
  # Run nightly against the shared Cloud instance
  schedule:
    - cron: '0 9 * * *' # Daily at 09:00 UTC

  # Allow engineers to run Cloud E2E on-demand (useful for debugging)
  workflow_dispatch:

jobs:
  playwright-cloud:
    uses: grafana/data-sources-ci-workflows/.github/workflows/playwright-cloud.yml@main
    secrets: inherit
    with:
      pdc-network-name: datasources-pdc-network-aws-datasourcese2e
      repo-secrets: |
        DS_INSTANCE_HOST=ds-instance:host
        DS_INSTANCE_PASSWORD=ds-instance:password
        DS_INSTANCE_PORT=ds-instance:port
        DS_INSTANCE_USERNAME=ds-instance:username


================================================
FILE: .github/workflows/detect-breaking-changes.yml
================================================
name: Compatibility check
on: [push, pull_request]

jobs:
  compatibilitycheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
        with:
          persist-credentials: false

      - uses: actions/setup-node@v6
        with:
          node-version-file: '.nvmrc'
      - name: Install dependencies
        run: npm install
      - name: Build plugin
        run: npm run build
      - name: Compatibility check
        uses: grafana/plugin-actions/is-compatible@4698961fa64137fcac207108397ebe8a738a33d1
        with:
          module: './src/module.ts'
          comment-pr: 'yes'
          skip-comment-if-compatible: 'yes'
          fail-if-incompatible: 'no'
          targets: '@grafana/data,@grafana/ui,@grafana/runtime,@grafana/e2e-selectors'


================================================
FILE: .github/workflows/integration.yml
================================================
name: Integration tests

on:
  push:
    branches:
      - v1
      - main
  pull_request:
    branches:
      - v1
      - main
  schedule:
    - cron: '0 9 1 * *'

jobs:
  run:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: true
      matrix:
        clickhouse:
          - 24.8
          - 25.3
          - 25.5
          - 25.6
          - 25.7
          - latest

    steps:
      - uses: actions/checkout@v6
        with:
          persist-credentials: false

      - name: Install Go
        uses: actions/setup-go@v6
        with:
          go-version-file: 'go.mod'

      - name: Build backend
        uses: magefile/mage-action@07f03e200d4d168576899f4d31ffebfa8fb195ff
        with:
          args: buildAll
          version: latest

      - name: Run integration tests
        run: CLICKHOUSE_VERSION=${{ matrix.clickhouse }} go test -v -tags=integration ./...


================================================
FILE: .github/workflows/issue_commands.yml
================================================
name: Run commands when issues are labeled
on:
  issues:
    types: [labeled]
jobs:
  main:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Actions
        uses: actions/checkout@v6
        with:
          repository: 'grafana/grafana-github-actions'
          path: ./actions
          ref: main
          persist-credentials: false
      - name: Install Actions
        run: npm install --production --prefix ./actions
      - name: Run Commands
        uses: ./actions/commands
        with:
          token: ${{secrets.ISSUE_COMMANDS_TOKEN}}
          configPath: issue_commands


================================================
FILE: .github/workflows/publish.yml
================================================
name: Plugins - CD
run-name: Deploy ${{ inputs.branch }} to ${{ inputs.environment }} by @${{ github.actor }}

on:
  workflow_dispatch:
    inputs:
      branch:
        description: Branch to publish from. Can be used to deploy PRs to dev
        default: main
      environment:
        description: Environment will always publish to all waves (dev + ops + prod). Cloud will publish scoped only to Grafana Cloud, On Prem will publish with Universal scope. Please use Cloud unless emergency fix needed for On Prem customer.
        required: true
        type: choice
        default: "cloud (recommended)"
        options:
          - "cloud (recommended)"
          - "on-prem (for emergencies fix to On Prem customers)"
      docs-only:
        description: Only publish docs, do not publish the plugin
        default: false
        type: boolean

permissions: {}

jobs:
  cd:
    strategy:
      fail-fast: false
      matrix:
        environment: [dev, ops, prod]
    name: CD
    uses: grafana/plugin-ci-workflows/.github/workflows/cd.yml@ci-cd-workflows/v7.3.1
    permissions:
      contents: write
      id-token: write
      attestations: write
      pull-requests: read
    with:
      branch: ${{ github.event.inputs.branch }}
      environment: ${{ matrix.environment }}
      docs-only: ${{ fromJSON(github.event.inputs.docs-only) }}
      scopes: ${{ github.event.inputs.environment == 'cloud (recommended)' && 'grafana_cloud' || github.event.inputs.environment == 'on-prem (for emergencies fix to On Prem customers)' && 'universal' }}
      run-playwright: false
      github-draft-release: false


================================================
FILE: .github/workflows/push.yml
================================================
name: Plugins - CI

on:
  # Run CI on all PRs
  pull_request:

  # Also run on pushes to main (used for publish + downstream automation)
  push:
    branches: [main]

  # Allow manual re-runs from the Actions UI (useful for debugging failures)
  workflow_dispatch:

# Minimal top-level permissions; jobs can extend as needed
permissions:
  contents: read
  id-token: write # Required for OIDC (Vault / shared workflows)

# Prevent duplicate runs on the same ref.
# For PRs: cancel older in-progress runs when new commits are pushed.
# For main: do NOT cancel (publishing should complete once started).
concurrency:
  group: plugins-ci-${{ github.ref }}
  cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}

jobs:
  ci:
    name: CI

    uses: grafana/plugin-ci-workflows/.github/workflows/ci.yml@ci-cd-workflows/v7.3.1

    # Only run CI job for PRs / non-main refs.
    # Main publishing is handled by the CD workflow below.
    if: github.ref != 'refs/heads/main'

    # Required for checkout + OIDC in shared workflows
    permissions:
      contents: read
      id-token: write

    with:
      # Ensure PR builds produce unique plugin versions.
      # For PR events, suffix with the head SHA; otherwise leave empty.
      plugin-version-suffix: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || '' }}

  publish-and-deploy:
    name: Publish to Dev Catalog and Deploy

    # Main-only: publish the latest build and trigger Argo deployment
    if: github.ref == 'refs/heads/main'

    uses: grafana/data-sources-ci-workflows/.github/workflows/cd-dev.yml@main

    permissions:
      attestations: write
      contents: write
      id-token: write
      pull-requests: read

    with:
      go-version: "1.26.0"
      golangci-lint-version: "2.10.1"


================================================
FILE: .github/workflows/stale.yml
================================================
name: 'Close stale issues and PRs'

on:
  schedule:
    - cron: '30 1 * * *'
  workflow_dispatch:

permissions:
  contents: write
  issues: write
  pull-requests: write

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v10
        with:
          repo-token: ${{ secrets.GITHUB_TOKEN }}
          operations-per-run: 750
          # start from the oldest issues/PRs when performing stale operations
          ascending: true
          days-before-issue-stale: 365
          days-before-issue-close: 30
          stale-issue-label: stale
          exempt-issue-labels: no stalebot,type/epic
          stale-issue-message: >
            This issue has been automatically marked as stale because it has not had
            activity in the last year. It will be closed in 30 days if no further activity occurs. Please
            feel free to leave a comment if you believe the issue is still relevant.
            Thank you for your contributions!
          close-issue-message: >
            This issue has been automatically closed because it has not had any further
            activity in the last 30 days. Thank you for your contributions!
          days-before-pr-stale: 30
          days-before-pr-close: 14
          stale-pr-label: stale
          exempt-pr-labels: no stalebot
          stale-pr-message: >
            This pull request has been automatically marked as stale because it has not had
            activity in the last 30 days. It will be closed in 2 weeks if no further activity occurs. Please
            feel free to give a status update or ping for review. Thank you for your contributions!
          close-pr-message: >
            This pull request has been automatically closed because it has not had any further
            activity in the last 2 weeks. Thank you for your contributions!
          # Remove the PR head branch when the stale workflow closes the PR (requires contents: write)
          delete-branch: true


================================================
FILE: .github/zizmor.yml
================================================
# This is also used as the default configuration for the Zizmor reusable
# workflow.

rules:
  unpinned-uses:
    config:
      policies:
        actions/*: any # trust GitHub
        grafana/*: any # trust Grafana

================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

node_modules/

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# Compiled binary addons (https://nodejs.org/api/addons.html)
dist/
artifacts/
work/
ci/
e2e-results/
test_summary.json

# Editor
.idea

pkg/__debug_bin

**/.DS_Store
.eslintcache
/test-results/
/playwright-report/
/blob-report/
/playwright/.cache/
/playwright/.auth/


================================================
FILE: .nvmrc
================================================
22


================================================
FILE: .prettierrc.js
================================================
module.exports = {
  // Prettier configuration provided by Grafana scaffolding
  ...require('./.config/.prettierrc.js'),
};


================================================
FILE: .vscode/launch.json
================================================
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Run standalone plugin",
      "type": "go",
      "request": "launch",
      "mode": "auto",
      "program": "${workspaceFolder}/pkg/",
      "env": {},
      "args": ["--standalone=true"]
    },
    {
      "name": "Debug in Container",
      "type": "go",
      "request": "attach",
      "mode": "remote",
      "remotePath": "/var/lib/grafana/plugins/grafana-k6-app/",
      "port": 2345,
      "host": "127.0.0.1",
      "apiVersion": 1,
      "trace": "verbose"
    },
    {
      "name": "Debug Jest test",
      "type": "node",
      "request": "launch",
      "runtimeExecutable": "npm",
      "runtimeArgs": ["run", "jest", "--runInBand", "${file}"],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "port": 9229
    }
  ]
}


================================================
FILE: .vscode/settings.json
================================================
{
  "gopls": {
    "buildFlags": ["-tags=integration"]
  },
  "specstory.cloudSync.enabled": "never"
}


================================================
FILE: CHANGELOG.md
================================================
# Changelog

## 4.17.1

### Fixes

- Dependency updates

## 4.17.0

### Features

- Allow `$__adhocFilters` macro to work with multiple tables (#1757)

### Performance

- Hold a single `*sql.DB` on `SchemaProvider` and dispose it with the instance (#1819)

### Fixes

- Dedupe autocomplete suggestions and dispose Monaco providers on unmount (#1820)
- Map adhoc regex operators to `REGEXP` instead of `ILIKE` (#1794)
- Close `*sql.DB` after each schema introspection query (#1818)
- Dependency updates

## 4.16.0

### Features

- Explain column roles in logs/traces/timeseries query builders (#1790)
- Cache system.tables/columns schema introspection with single flight (#1787)

### Fixes

- Drop LIMIT from single-trace span query (#1795)
- Forward X-Grafana-User header to ClickHouse when enabled (#1797)
- Fix slow traceId lookup (#1705)
- Replace `js-sql-parser` with existing ClickHouse lexer for SQL validation (#1778)
- Match column suggestions case-insensitively in autocomplete (#1779)
- Dependency updates

## 4.15.0

### Features

- Add LogsSample supplemental query, remove deprecated getDataProvider (#1744)
- Add Grafana query metadata support (#1743)
- Allow disabling logs and trace links (#1754)
- Improve query modification (#1738)
- Add initial support for SQL abstractions (dsAbstraction) (#1756)
- Add OpenTelemetry instrumentation (#1734)
- Add field config to trace search results for better default display (#1733)
- Add filterQuery method to datasource (#1732)
- Support grouping orderBy columns by their column hint values (#1695)
- Bump Grafana minimum version to v11.6.0 (#1753)

### Fixes

- Fix log context field returning labels (#1737)
- Fix additional settings config bug (#1630)
- Dependency updates

## 4.14.1

### Features

- Extract `Map` value type for `mapKey` filter in `getFilters` (#1694)

### Fixes

- Dependency updates
  
## 4.14.0

### Features

- Add FilterTime hint to enable multi-timestamp log filtering/sorting (#1642)
- Skip OTel trace time range optimization when trace timestamp table does not exist (#1663)

### Fixes

- Dependency updates
- Add separate columns for Resource/Scope/Log Attributes (#1560)
- Fix panic when configuring datasource with numeric timeout values (#1559)

## 4.13.0

### Features

- Support for hiding table names in ad-hoc filters (#1493)
- Allow manual placement of ad-hoc filters (#1488)
- Add support for Nullable(Enum8/16) column types (#1523)
- Add dashboard variable to control AdHoc filter syntax (#1464)

### Fixes

- Fix generating query with column names containing colons (#1538)
- Update config HTTPS language (#1537)
- Dependency updates

## 4.12.0

### Features

- Support log volume queries for the SQL editor. Note that this will only work for Grafana versions >= 12.4.0 (#1475)
- Support columns with `.` in ad-hoc filters (#1481)

### Fixes

- Dependency updates

## 4.11.4

## Fixes

- Fix view logs link in Explore and Dashboards (#1462)
- Fix filter for map type LogLabels (#1456)
- Temporarily disable slow JSON suggestions function (#1468)
- Dependency updates

## 4.11.3

### Fixes

- Fix config UI bugs (#1409) and update design (#1422)
- Dependency updates

## 4.11.2

### Features

- Second part of redesigned ClickHouse config page (behind newClickhouseConfigPageDesign) (#1387)

### Fixes

- Improved error classification to mark all ClickHouse errors as downstream errors, including errors wrapped in HTTP response bodies and multi-error chains (#1405)
- Dependency updates

## 4.11.1

### Fixes

- All Clickhouse errors are marked as downstream errors for Grafana (#1378)

## 4.11.0

### Features

- Merge OpenTelemetry resource/scope/log attributes into a unified Labels column in Logs (#1369)
- First part of redesigned ClickHouse config page with sidebar navigation and collapsible sections (behind newClickhouseConfigPageDesign) (#1370)

### Fixes

- Fix ad-hoc filter application with templated target tables (#1241)
- Fix column sorting by formatting bytes in Grafana (#1352)
- Fix events and links not displaying correctly for table view queries (#1345)
- Dependency updates

## 4.10.2

### Fixes

- Fix Ad-Hoc filters for variable datasources #1330
- Fix switching between SQL Editor and Query Builder #1337
- Fix large JSON objects + complex JSON types #1326
- Configuration fixes related to row limit implementation #1294
- Fix bug where switched to logs query type errored #1341
- Dependency updates

## 4.10.1

### Fixes

- Bump grafana/plugin-actions from ff169fa386880e34ca85a49414e5a0ff84c3f7ad to b788be6746403ff9bae26d5e800794f2a5620b4c (#1286)
- Bump cspell from 9.0.2 to 9.1.1 (#1278)

## 4.10.0

### Features

- Ad-hoc queries: Allow to filter by values inside the map (#1265)

### Fixes

- Fix ad-hoc filter application with templated target tables (#1241)
- Dependency updates

## 4.9.1

### Fixes

- Error logging fix

## 4.9.0

### Features

- Add support for the Grafana `row_limit` [configuration setting](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#row_limit).
- Add support for kind, status, instrumentation library, links, events and state data for traces (#1043, #1208)
- Cancel JSON paths query after 10s (#1206)
- SQL Editor now suggests database, table, column, and function names while typing (#1204)
- Add SQL Formatter button + shortcut for making long queries more readable in the editor (#1205)

### Fixes

- Fixed "run query" shortcut from running stale query (#1205)
- Dependency updates

## 4.8.2

### Fixes

- Dependency updates

## 4.8.1

### Fixes

- Dependency updates

## 4.8.0

### Features

- Enable CtrlCmd + Enter keyboard shortcut to Run Query (#1158)

### Fixes

- Refactor `MutateResponse` function and PDC dialler creation (#1155)
- Refactor `clickhouse.Connect` to improve context cancellation handling (#1154)
- Prevent usage of failed connections and improve connection management (#1156). Please note that following this change, the following limits will be set. Although we believe these limits are reasonable, you can adjust them in the datasource settings if needed:
  - `MaxOpenConns` to 50.
  - `MaxIdleConns` to 25.
  - `ConnMaxLifetime` to 5 minutes.
- Dependency updates

## 4.7.0

### Features

- Add JSON column sub-paths to column selection in query builder
- Added events support in trace detail view.(https://github.com/grafana/clickhouse-datasource/pull/1128)

## 4.6.0

### Features

- Add support for new Variant, Dynamic, and JSON types (https://github.com/grafana/clickhouse-datasource/pull/1108)

### Fixes

- Optimized performance for log volumes processing using ClickHouse `multiSearchAny`

## 4.5.1

### Fixes

- Dependency updates

## 4.5.0

### Features

- Implemented log context for log queries
- Added configuration options for log context columns
- Queries parsed from the SQL editor will now attempt to re-map columns into their correct fields for Log and Trace queries.
- Added support for IN operator in adhoc filters

### Fixes

- Fixed and enhanced the logic for parsing a query back into the query builder.

## 4.4.0

### Features

- Added "Labels" column selector to the log query builder
- Datasource OTel configuration will now set default table names for logs and traces.

### Fixes

- Added warning for when `uid` is missing in provisioned datasources.
- Map filters in the query builder now correctly show the key instead of the column name
- Updated and fixed missing `system.dashboards` dashboard in list of dashboards
- Updated the duration value in example traces dashboard to provide useful information
- Fix to display status codes from spans in trace queries (#950)

## 4.3.2

### Fixes

- Optimized performance for types dependent on the JSON converter
- Dependency updates

## 4.3.1

### Features

- Added preset dashboard from `system.dashboards` table

### Fixes

- Fix trace start times in trace ID mode (#900)
- Fixed OTel dashboard that waa failing to import (#908)

## 4.3.0

### Features

- Added OpenTelemetry dashboard (#884)

### Fixes

- Fix support for LowCardinality strings (#857)
- Update trace queries to better handle time fields (#890)
- Dependency bumps

## 4.2.0

### Features

- Added `$__dateTimeFilter()` macro for conveniently filtering a PRIMARY KEY composed of Date and DateTime columns.

## 4.1.0

### Features

- Added the ability to define column alias tables in the config, which simplifies query syntax for tables with a known schema.

## 4.0.8

### Fixes

- Fixed `IN` operator escaping the entire string (specifically with `Nullable(String)`), also added `FixedString(N)` (#830)
- Fixed query builder filter editor on alert rules page (#828)

## 4.0.7

- Upgrade dependencies

## 4.0.6

### Fixes

- Add support for configuring proxy options from context rather than environment variables (supported by updating `sqlds`) (#799)

## 4.0.5

### Fixes

- Fixed converter regex for `Nullable(IP)` and `Nullable(String)`. It won't match to `Array(Nullable(IP))` or `Array(Nullable(String))` any more. (#783)
- Updated `grafana-plugin-sdk-go` to fix a PDC issue. More details [here](https://github.com/grafana/grafana-plugin-sdk-go/releases/tag/v0.217.0) (#790)

## 4.0.4

### Fixes

- Changed trace timestamp table from the constant `otel_traces_trace_id_ts` to a suffix `_trace_id_ts` applied to the current table name.

## 4.0.3

### Features

- Added `$__fromTime_ms` macro that represents the dashboard "from" time in milliseconds using a `DateTime64(3)`
- Added `$__toTime_ms` macro that represents the dashboard "to" time in milliseconds using a `DateTime64(3)`
- Added `$__timeFilter_ms` macro that uses `DateTime64(3)` for millisecond precision time filtering
- Re-added query type selector in dashboard view. This was only visible in explore view, but somehow it affects dashboard view, and so it has been re-added. (#730)
- When OTel is enabled, Trace ID queries now use a skip index to optimize exact ID lookups on large trace datasets (#724)

### Fixes

- Fixed performance issues caused by `$__timeFilter` using a `DateTime64(3)` instead of `DateTime` (#699)
- Fixed trace queries from rounding span durations under 1ms to `0` (#720)
- Fixed AST error when including Grafana macros/variables in SQL (#714)
- Fixed empty builder options when switching from SQL Editor back to Query Editor
- Fix SQL Generator including "undefined" in `FROM` when database isn't defined
- Allow adding spaces in multi filters (such as `WHERE .. IN`)
- Fixed missing `AND` keyword when adding a filter to a Trace ID query

## 4.0.2

### Fixes

- Fixed migration script not running when opening an existing v3 config

## 4.0.1

### Fixes

- Set `protocol` to `native` by default in config view. Fixes the "default port" description.

## 4.0.0

### Features

Version 4.0.0 contains major revisions to the query builder and datasource configuration settings.

#### Query Builder

- Completely rebuilt query builder to have specialized editors for Table, Logs, Time Series, and Traces.
- Completely rebuilt SQL generator to support more complicated and dynamic queries.
- Updated query builder options structure to be clearer and support more complex queries.
- Updated database/table selector to be in a more convenient location. Database and table options are automatically selected on initial load.
- Upgraded query builder state management so queries stay consistent when saving/editing/sharing queries.
- Separated Table and Time Series query builders. Table view operates as a catch-all for queries that don't fit the other query types.
- Combined "format" into the query type switcher for simplicity. The query tab now changes the builder view and the display format when on the Explore page. This includes the raw SQL editor.
- Added an OTEL switch for logs and trace views. This will allow for quicker query building for those using the OTEL exporter for ClickHouse.
- Updated Time Series query builder with dedicated Time column. Default filters are added on-load.
- Added an `IS ANYTHING` filter that acts as a placeholder for easily editing later (useful for query templates/bookmarks on the Explore page.)
- Added better support for Map types on the Filter editor.
- LIMIT editor can now be set to 0 to be excluded from the query.
- Table and Time Series views now have a simple / aggregate mode, depending on the query complexity.
- Updated the logs histogram query to use the new query builder options and column hints.
- Added Logs query builder with dedicated Time, Level, and Message columns. Includes OTEL switch for automatically loading OTEL schema columns. Default filters are added on-load.
- Added Trace query builder with dedicated trace columns. Includes OTEL switch for automatically loading OTEL schema columns. Default filters are added on-load.
- Updated data panel filtering to append filters with column hints. Visible in logs view when filtering by a specific level. Instead of referencing a column by name, it will use its hint.
- Order By now lists aggregates by their full name + alias.
- Order By column allows for custom value to be typed in.
- Aggregate column name allows for custom value to be typed in.
- Filter editor allows for custom column names to be typed in.
- Increased width of filter value text input.
- Columns with the `Map*` type now show a `[]` at the end to indicate they are complex types. For example, `SpanAttributes[]`.
- Filter editor now has a dedicated field for map key. You can now select a map column and its key separately. For example, `SpanAttributes['key']`.
- Map types now load a sample of options when editing the `key` for the map. This doesn't include all unique values, but for most datasets it should be a convenience.
- Added column hints, which offers better linking across query components when working with columns and filters. For example, a filter can be added for the `Time` column, even without knowing what the time column name is yet. This enables better SQL generation that is "aware" of a column's intended use.

### Plugin Backend

- Added migration logic for `v3` configs going to `v4+`. This is applied when the config is loaded when building a database connection.
- `$__timeFilter`, `$__fromTime`, and `$__toTime` macros now convert to `DateTime64(3)` for better server-side type conversion. Also enables millisecond precision time range filtering.

#### Datasource Configuration

- Added migration script for `v3.x` configurations to `v4+`. This runs automatically when opening/saving the datasource configuration.
- Renamed config value `server` to `host`.
- Renamed config value `timeout` to the more specific `dial_timeout`.
- Updated labeling for port selection. The default port will now change depending on native/http and secure/unsecure setting.
- Rearranged fields and sections to flow better for initial setup of a new datasource.
- Added plugin version to config data for easier config version migrations in the future.
- Added fields for setting default values for database/table.
- Added section for setting default log database/table/columns. Includes OTEL. These are used when using the log query builder.
- Added section for setting default trace database/table/columns. Includes OTEL. These are used when using the trace query builder.
- Added OTEL switches for logs/traces for quicker query building. OTEL defaults to the latest version, and will auto update if kept on this setting.
- Increased width of inputs for typically long values (server URL, path, etc.)
- Allow adding custom HTTP headers with either plain text or secure credentials. [#633](https://github.com/grafana/clickhouse-datasource/pull/633)
- Add `path` setting to specify an additional URL path when using the HTTP protocol. [#512](https://github.com/grafana/clickhouse-datasource/pull/512)

### Fixes

- Queries will now remain consistent when reloading/editing a previously saved query.
- Fixed default Ad-Hoc filters. [#650](https://github.com/grafana/clickhouse-datasource/pull/650)
- Fixed Ad-Hoc filters parsing numeric fields. [#629](https://github.com/grafana/clickhouse-datasource/pull/629)
- Fixed majority of usability quirks with redesigned query builder.

### Upgrades

- Updated all dependencies to latest compatible versions (Includes Dependabot PRs)

## 3.3.0

### Features

- Support Point geo data type.

### Fixes

- Fix timeInterval_ms macro.
- Fix Table summary and Parts over time panels in Data Analysis dashboard.

### Upgrades

- Upgrade [grafana-plugin-sdk-go](https://github.com/grafana/grafana-plugin-sdk-go).

## 3.2.0

### Features

- Add `timeInterval_ms` macro to allow higher precision queries on DateTime64 columns. [#462](https://github.com/grafana/clickhouse-datasource/pull/462).

### Fixes

- Ensure databases, tables, and columns are escaped correctly. [#460](https://github.com/grafana/clickhouse-datasource/pull/460).
- Fix conditionAll handling. [#459](https://github.com/grafana/clickhouse-datasource/pull/459).
- Fix support for ad-hoc regexp filters: `=~`, `!~` [#414](https://github.com/grafana/clickhouse-datasource/pull/414).
- Do not create malformed adhoc filters [#451](https://github.com/grafana/clickhouse-datasource/pull/451). invalid values will be ignored.
- Fix auto formatting by reverting to table correctly. [#469](https://github.com/grafana/clickhouse-datasource/pull/469).
- Fix parsing of numeric configuration values in `yaml` file. [#456](https://github.com/grafana/clickhouse-datasource/pull/456).

## 3.1.0

- Stable release of v3.0.4-beta

## 3.0.4-beta

- Update Grafana dependencies to >=v9.0.0
- **Feature** - [Add support for the secure socks proxy](https://github.com/grafana/clickhouse-datasource/pull/389)

## 3.0.3-beta

- Update ClickHouse driver to v2.9.2

## 3.0.2-beta

- Custom ClickHouse settings can be set in data source settings. [Allow passing custom ClickHouse settings in datasource](https://github.com/grafana/clickhouse-datasource/pull/366)
- Histogram UI fixes [Histogram UI fixes](https://github.com/grafana/clickhouse-datasource/pull/363)
  - Support filter/filter out logs view actions
  - Fix undefined database name by default
  - Reset level and time field properly on table/database change
  - Make it possible to clear the level field (so the histogram will render without grouping by level)
  - Fix filter value that gets stuck in the UI
- Tracing dashboard added to default dashboards. [Tracing dashboard ](https://github.com/grafana/clickhouse-datasource/pull/336)

## 3.0.1-beta

- Users on v8.x of Grafana are encouraged to continue to use v2.2.0 of the plugin.
- Users of Grafana v9.x can use v3 however it is beta and may contain bugs.

## 3.0.0

- **Feature** - [Logs volume histogram support](https://github.com/grafana/clickhouse-datasource/pull/352)
- **Chore** - Update clickhouse-go to v2.8.1

## 2.2.1

- **Chore** - Backend binaries compiled with latest go version 1.20.4
- Custom ClickHouse settings can be set in data source settings. Allow passing custom [ClickHouse settings in datasource](https://github.com/grafana/clickhouse-datasource/pull/371)
- Standard Golang HTTP proxy environment variables support (`HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY`). See [FromEnvironment](https://pkg.go.dev/golang.org/x/net/http/httpproxy#FromEnvironment) for more information. If the Grafana instance is started with one of these env variables, the driver will automatically load them now.

## 2.2.0

- **Feature** - [Support format dropdown and support for rendering traces](https://github.com/grafana/clickhouse-datasource/pull/329)

## 2.1.1

- **Fix** - [Date and Date32 type normalization with user's timezone](https://github.com/grafana/clickhouse-datasource/pull/314)

## 2.1.0

- **Fix** - Quote table names with dots by @slvrtrn in https://github.com/grafana/clickhouse-datasource/pull/298
- Add a predefined TimeRange filter if there is at least one DateTime\* column by @slvrtrn in https://github.com/grafana/clickhouse-datasource/pull/304

## 2.0.7

- **Fix** - Empty template variables used with the conditionalAll macro work the same as selecting All. [Allow empty Inputs for $\_\_conditionalAll](https://github.com/grafana/clickhouse-datasource/issues/262)
- **Fix** - Intervals are limited to 1 second. [limit $\_\_interval_s to at least 1 second](https://github.com/grafana/clickhouse-datasource/pull/270)
- **Chore** - Bump ClickHouse go API to v2.5.1 [Bump github.com/ClickHouse/clickhouse-go/v2 from 2.4.3 to 2.5.1](https://github.com/grafana/clickhouse-datasource/pull/283)

## 2.0.6

- **Chore** - Backend binaries compiled with latest go version 1.19.4
- **Chore** - Backend grafana dependencies updated to latest version
- **Chore** - Clickhouse-go client updated to [v2.4.3](https://github.com/ClickHouse/clickhouse-go/blob/main/CHANGELOG.md#243-2022-11-30)

## 2.0.5

- **Chore** - Update sqlds to 2.3.17 which fixes complex macro queries
- **Chore** - Backend grafana dependency updated
- **Fix** - Allow default protocol toggle value when saving in settings

## 2.0.4

- **Fix** - Query builder: allow custom filter values for fields with [`Map`](https://clickhouse.com/docs/en/sql-reference/data-types/map/) type

## 2.0.3

- **Chore** - Backend binaries compiled with latest go version 1.19.3
- **Chore** - Backend grafana dependencies updated

## 2.0.2

- **Feature** - Update sqlds to 2.3.13 which fixes some macro queries

## 2.0.1

- **Bug** - Now works with Safari. Safari does not support regex look aheads

## 2.0.0

- **Feature** - Upgrade driver to support HTTP
- **Feature** - Changed how ad hoc filters work with a settings option provided in CH 22.7
- **Feature** - Conditional alls are now handled with a conditional all function. The function checks if the second parameter is a template var set to all, if it then replaces the function with 1=1, and if not set the function to the first parameter.
- **Bug** - Visual query builder can use any date type for time field
- **Fix** - 'any' is now an aggregation type in the visual query builder
- **Fix** - Time filter macros can be used in the adhoc query
- **Bug** - Time interval macro cannot have an interval of 0
- **Fix** - Update drive to v2.1.0
- **Bug** - Expand query button works with grafana 8.0+
- **Fix** - Added adhoc columns macro

## 1.1.2

- **Bug** - Add timerange to metricFindQuery

## 1.1.1

- **Bug** - Add timeout

## 1.1.0

- **Feature** - Add convention for showing logs panel in Explore

## 1.0.0

- Official release

## 0.12.7

- **Fix** - Ignore template vars when validating sql

## 0.12.6

- **Fix** - Time series builder - use time alias when grouping/ordering

## 0.12.5

- **Chore** - Dashboards

## 0.12.4

- **Fix** - timeseries where clause. make default db the default in visual editor

## 0.12.3

- **Fix** - When removing conditional all, check scoped vars (support repeating panels)

## 0.12.2

- **Fix** - When removing conditional all, only remove lines with variables

## 0.12.1

- **Fix** - Handle large decimals properly

## 0.12.0

- **Feature** - Time series builder: use $\_\_timeInterval macro on time field so buckets can be adjusted from query options.

## 0.11.0

- **Feature** - Time series: Hide fields, use group by in select, use time field in group by

## 0.10.0

- **Feature** - Ad-Hoc sourced by database or table

## 0.9.13

- **Fix** - Update sdk to show streaming errors

## 0.9.12

- **Fix** - Format check after ast change

## 0.9.11

- **Feature** - $**timeInterval(column) and $**interval_s macros

## 0.9.10

- **Fix** - Set format when using the new Run Query button.

## 0.9.9

- **Feature** - Query Builder.

## 0.9.8

- **Fix** - Detect Multi-line time series. Handle cases with functions.

## 0.9.7

- **Feature** - Multi-line time series.

## 0.9.6

- **Bug** - Change time template variable names.

## 0.9.5

- **Bug** - Fix global template variables.

## 0.9.4

- **Bug** - Fix query type variables.

## 0.9.3

- **Bug** - Support Array data types.

## 0.9.2

- **Bug** - Fix TLS model.

## 0.9.1

- **Feature** - Add secure toggle to config editor.

## 0.9.0

- Initial Beta release.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to ClickHouse Datasource

Thank you for your interest in contributing to this repository. We are glad you want to help us to improve the project and join our community. Feel free to [browse the open issues](https://github.com/grafana/clickhouse-datasource/issues). If you want more straightforward tasks to complete, [we have some](https://github.com/grafana/clickhouse-datasource/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22). For more details about how you can help, please take a look at [Grafana’s Contributing Guide](https://github.com/grafana/grafana/blob/main/CONTRIBUTING.md).

## Development setup

### Getting started

Clone this repository into your local environment. The frontend code lives in the `src` folder, alongside the [plugin.json file](https://grafana.com/docs/grafana/latest/developers/plugins/metadata/). The backend Go code is in the `pkg` folder. To build this plugin refer to [Build a plugin](https://grafana.com/docs/grafana/latest/developers/plugins/)

### Running the development version

Before you can set up the plugin, you need to set up your environment by following [Set up your environment](https://grafana.com/tutorials/build-a-data-source-backend-plugin/#set-up-your-environment).

#### Compiling the backend

You can use [mage](https://github.com/magefile/mage) to compile and test the Go backend.

```sh
mage test # run all Go test cases
mage build:backend && mage reloadPlugin # builds and reloads the plugin in Grafana
```

#### Compiling the frontend

You can build and test the frontend by using `npm`:

```sh
npm run test # run all test cases
npm run dev # builds and puts the output at ./dist
```

You can also have `npm` watch for changes and automatically recompile them:

```sh
npm run watch
```

#### Running E2E tests locally

1. Install [K6](https://k6.io/docs/get-started/installation/)
2. Run `npm run test:e2e:local`

## Create a pull request

Run `npm run lint` and `npm run prettier:check` to check for any style errors. Any PRs that have linter or `prettier` errors will not pass pull request CI checks. Run `npm run lint:fix && npm run prettier:write` to automatically fix linter or prettier errors.

Once you are ready to make a pull request, please read and follow [Create a pull request](https://github.com/grafana/grafana/blob/master/contribute/create-pull-request.md).

## Build a release for the ClickHouse data source plugin

You need to have commit rights to the GitHub repository to publish a release.

1. Update the version number in the `package.json` file.
2. Update the `CHANGELOG.md` by copy and pasting the relevant PRs
   from [GitHub's Release drafter interface](https://github.com/grafana/clickhouse-datasource/releases/new) or by
   running `npm run generate-release-notes`.
3. PR the changes.
4. Once merged, follow the Drone release process that you can find [here](https://github.com/grafana/integrations-team/wiki/Plugin-Release-Process#drone-release-proces


================================================
FILE: DEV_GUIDE.md
================================================
# Guide to get Clickhouse running

## Add a directory where the database files will mount to from your docker container

mkdir $HOME/workspace/clickhouse/db/db

## run clickhouse - expose ports and add a volume to your folder above

docker run -d -p 8123:8123 -p 9000:9000 --name grafana-clickhouse-server --ulimit nofile=262144:262144 --volume=$HOME/workspace/clickhouse/db/db:/var/lib/clickhouse clickhouse/clickhouse-server

## clickhouse client (optional, if you want to query from the command line)

docker run -it --rm --network=container:grafana-clickhouse-server --entrypoint clickhouse-client clickhouse/clickhouse-server

## Data loading - MGBench test data

### Timeseries data - Brown benchmark using docker clickhouse client

https://clickhouse.com/docs/en/getting-started/example-datasets/brown-benchmark/

### Download and unpack the csv files from the above link

### Create database and tables using commands from above link (can use a SQL Editor like DBeaver: https://dbeaver.io/)

### Load the tables from the downloaded csv files

sudo cat $HOME/workspace/clickhouse/mgbench/mgbench1.csv | docker run -i --rm --network=container:grafana-clickhouse-server --entrypoint clickhouse-client clickhouse/clickhouse-server -m --query="INSERT INTO mgbench.logs1 FORMAT CSVWithNames"

sudo cat $HOME/workspace/clickhouse/mgbench/mgbench2.csv | docker run -i --rm --network=container:grafana-clickhouse-server --entrypoint clickhouse-client clickhouse/clickhouse-server -m --query="INSERT INTO mgbench.logs2 FORMAT CSVWithNames"

sudo cat $HOME/workspace/clickhouse/mgbench/mgbench3.csv | docker run -i --rm --network=container:grafana-clickhouse-server --entrypoint clickhouse-client clickhouse/clickhouse-server -m --query="INSERT INTO mgbench.logs3 FORMAT CSVWithNames"

## Connect from the Plugin (minimum requirements)

server address: localhost
server port: 9000

## With custom config

docker run -d -p 8443:8443 -p 9440:9440 --name secure-clickhouse-server --ulimit nofile=262144:262144 -v $PWD/config:/etc/clickhouse-server clickhouse/clickhouse-server

## With secure config - for testing TLS scenarios

### First setup the certificates

1. Create the CA cert

```
./scripts/ca.sh
```

2. Create the Server cert from the CA

```
./scripts/ca-cert.sh
```

3. The Common/SAN name is "foo". Add an entry to your hosts file on the host.

```
127.0.0.1  foo
```

### Now start the container using the config-secure settings

docker run -d -p 8443:8443 -p 9440:9440 -p 9000:9000 -p 8123:8123 --name secure-clickhouse-server --ulimit nofile=262144:262144 -v $PWD/config-secure:/etc/clickhouse-server clickhouse/clickhouse-server

### Login to the container and add the ca cert to trusted certs

docker exec -it secure-clickhouse-server bash
cp /etc/clickhouse-server/my-own-ca.crt /usr/local/share/ca-certificates/root.ca.crt
update-ca-certificates

# Code Structure / Notes

## Column Hints

Column hints are used within the query builder and SQL generator to enable flexible and dynamic queries.

Here's an example of some column hints:

```js
ColumnHint.Time;
ColumnHint.LogMessage;
ColumnHint.LogLevel;
ColumnHint.TraceId;
```

The easiest example is the time hint (`ColumnHint.Time`). When building a Logs query, we need to know what the primary log time column is:

```ts
const logTimeColumn: SelectedColumn = { name: 'my_time_column_on_my_table', hint: ColumnHint.Time, alias: 'logTime' };
```

Using the column hint, we can add an `ORDER BY` statement to the query without having to know the actual column name:

```ts
const logsOrderBy: OrderBy = { name: '', hint: ColumnHint.Time, dir: OrderByDirection.ASC };
```

Notice how `name` can be left empty, this is because the SQL generator knows to find the final column/alias by the time hint:

```ts
// Input options
const queryBuilderOptions: QueryBuilderOptions = {
  table: 'logs',
  columns: [logTimeColumn],
  orderBy: [logsOrderBy],
  . . .
};
```

```sql
-- Final output from SQL generator
SELECT my_time_column_on_my_table as logTime FROM logs ORDER BY logTime ASC
```

By adding a simple hint, we can apply filters, orderBys, and other behaviors to the SQL generator without having to reference specific columns. This simplifies the UI logic and user experience by reducing the number of places where a column name needs to be updated.


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2022-2023 Grafana Labs

   Licensed 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.


================================================
FILE: Magefile.go
================================================
//+build mage

package main

import (
	"fmt"
	// mage:import
	build "github.com/grafana/grafana-plugin-sdk-go/build"
)

// Hello prints a message (shows that you can define custom Mage targets).
func Hello() {
	fmt.Println("hello plugin developer!")
}

// Default configures the default target.
var Default = build.BuildAll


================================================
FILE: README.md
================================================
### ClickHouse Support

Grafana supports ClickHouse through a plugin. You can perform a variety of simple or complex ClickHouse queries to visualize logs or metrics stored in ClickHouse. You can also annotate your graphs with events stored in ClickHouse.

Read more about it here:  
[Grafana ClickHouse Documentation](https://grafana.com/docs/plugins/grafana-clickhouse-datasource/latest/)


================================================
FILE: config/admin.xml
================================================
<clickhouse>
    <!-- Profiles of settings. -->
    <profiles>
        <!-- Default settings. -->
        <default>
            <!-- Allows us to create replicated databases. -->
            <allow_experimental_database_replicated>1</allow_experimental_database_replicated>
        </default>
    </profiles>
    <users>
        <default>
            <access_management>1</access_management>
        </default>
    </users>
</clickhouse>


================================================
FILE: config/config-preprocessed.xml
================================================
<!-- This file was generated automatically.
     Do not edit it: it is likely to be discarded and generated again before it's read next time.
     Files used to generate this file:
       /etc/clickhouse-server/config.xml      -->

<yandex>
    <https_port>8443</https_port>
    <tcp_port_secure>9440</tcp_port_secure>
    <!--
    <http_port>8123</http_port>
    <tcp_port>9000</tcp_port>
    <interserver_http_port>9009</interserver_http_port> 
    -->
    <listen_host>0.0.0.0</listen_host>

    <openSSL>
      <server>
        <!-- Used for https server AND secure tcp port -->
        <certificateFile>/etc/clickhouse-server/server.crt</certificateFile>
        <privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
        <!-- <dhParamsFile>/etc/clickhouse-server/dhparam.pem</dhParamsFile> -->
        <verificationMode>none</verificationMode>
        <loadDefaultCAFile>true</loadDefaultCAFile>
        <cacheSessions>true</cacheSessions> 
        <disableProtocols>sslv2,sslv3</disableProtocols> 
        <preferServerCiphers>true</preferServerCiphers>
      </server>
    </openSSL>
</yandex>

================================================
FILE: config/config.xml
================================================
<?xml version="1.0"?>
<!--
  NOTE: User and query level settings are set up in "users.xml" file.
  If you have accidentally specified user-level settings here, server won't start.
  You can either move the settings to the right place inside "users.xml" file
   or add <skip_check_for_incorrect_settings>1</skip_check_for_incorrect_settings> here.
-->
<clickhouse>
    <logger>
        <!-- Possible levels [1]:
          - none (turns off logging)
          - fatal
          - critical
          - error
          - warning
          - notice
          - information
          - debug
          - trace
          - test (not for production usage)
            [1]: https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/Logger.h#L105-L114
        -->
        <level>trace</level>
        <log>/etc/clickhouse-server/clickhouse-server.log</log>
        <errorlog>/etc/clickhouse-server/clickhouse-server.err.log</errorlog>
        <!-- Rotation policy
             See https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/FileChannel.h#L54-L85
          -->
        <size>1000M</size>
        <count>10</count>
        <!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) -->

        <!-- Per level overrides (legacy):
        For example to suppress logging of the ConfigReloader you can use:
        NOTE: levels.logger is reserved, see below.
        -->
        <!--
        <levels>
          <ConfigReloader>none</ConfigReloader>
        </levels>
        -->

        <!-- Per level overrides:
        For example to suppress logging of the RBAC for default user you can use:
        (But please note that the logger name maybe changed from version to version, even after minor upgrade)
        -->
        <!--
        <levels>
          <logger>
            <name>ContextAccess (default)</name>
            <level>none</level>
          </logger>
          <logger>
            <name>DatabaseOrdinary (test)</name>
            <level>none</level>
          </logger>
        </levels>
        -->
    </logger>

    <!-- Add headers to response in options request. OPTIONS method is used in CORS preflight requests. -->
    <!-- It is off by default. Next headers are obligate for CORS.-->
    <!-- http_options_response>
        <header>
            <name>Access-Control-Allow-Origin</name>
            <value>*</value>
        </header>
        <header>
            <name>Access-Control-Allow-Headers</name>
            <value>origin, x-requested-with</value>
        </header>
        <header>
            <name>Access-Control-Allow-Methods</name>
            <value>POST, GET, OPTIONS</value>
        </header>
        <header>
            <name>Access-Control-Max-Age</name>
            <value>86400</value>
        </header>
    </http_options_response -->

    <!-- It is the name that will be shown in the clickhouse-client.
         By default, anything with "production" will be highlighted in red in query prompt.
    -->
    <!--display_name>production</display_name-->

    <!-- Port for HTTP API. See also 'https_port' for secure connections.
         This interface is also used by ODBC and JDBC drivers (DataGrip, Dbeaver, ...)
         and by most of web interfaces (embedded UI, Grafana, Redash, ...).
      -->
    <http_port>8123</http_port>

    <!-- Port for interaction by native protocol with:
         - clickhouse-client and other native ClickHouse tools (clickhouse-benchmark, clickhouse-copier);
         - clickhouse-server with other clickhouse-servers for distributed query processing;
         - ClickHouse drivers and applications supporting native protocol
         (this protocol is also informally called as "the TCP protocol");
         See also 'tcp_port_secure' for secure connections.
    -->
    <tcp_port>9000</tcp_port>

    <!-- Compatibility with MySQL protocol.
         ClickHouse will pretend to be MySQL for applications connecting to this port.
    -->
    <mysql_port>9004</mysql_port>

    <!-- Compatibility with PostgreSQL protocol.
         ClickHouse will pretend to be PostgreSQL for applications connecting to this port.
    -->
    <postgresql_port>9005</postgresql_port>

    <!-- HTTP API with TLS (HTTPS).
         You have to configure certificate to enable this interface.
         See the openSSL section below.
    -->
    <https_port>8443</https_port>

    <!-- Native interface with TLS.
         You have to configure certificate to enable this interface.
         See the openSSL section below.
    -->
    <tcp_port_secure>9440</tcp_port_secure>

    <!-- Native interface wrapped with PROXYv1 protocol
         PROXYv1 header sent for every connection.
         ClickHouse will extract information about proxy-forwarded client address from the header.
    -->
    <!-- <tcp_with_proxy_port>9011</tcp_with_proxy_port> -->

    <!-- Port for communication between replicas. Used for data exchange.
         It provides low-level data access between servers.
         This port should not be accessible from untrusted networks.
         See also 'interserver_http_credentials'.
         Data transferred over connections to this port should not go through untrusted networks.
         See also 'interserver_https_port'.
      -->
    <interserver_http_port>9009</interserver_http_port>

    <!-- Port for communication between replicas with TLS.
         You have to configure certificate to enable this interface.
         See the openSSL section below.
         See also 'interserver_http_credentials'.
      -->
    <!-- <interserver_https_port>9010</interserver_https_port> -->

    <!-- Hostname that is used by other replicas to request this server.
         If not specified, than it is determined analogous to 'hostname -f' command.
         This setting could be used to switch replication to another network interface
         (the server may be connected to multiple networks via multiple addresses)
      -->
    <!--
    <interserver_http_host>example.yandex.ru</interserver_http_host>
    -->

    <!-- You can specify credentials for authenthication between replicas.
         This is required when interserver_https_port is accessible from untrusted networks,
         and also recommended to avoid SSRF attacks from possibly compromised services in your network.
      -->
    <!--<interserver_http_credentials>
        <user>interserver</user>
        <password></password>
    </interserver_http_credentials>-->

    <!-- Listen specified address.
         Use :: (wildcard IPv6 address), if you want to accept connections both with IPv4 and IPv6 from everywhere.
         Notes:
         If you open connections from wildcard address, make sure that at least one of the following measures applied:
         - server is protected by firewall and not accessible from untrusted networks;
         - all users are restricted to subset of network addresses (see users.xml);
         - all users have strong passwords, only secure (TLS) interfaces are accessible, or connections are only made via TLS interfaces.
         - users without password have readonly access.
         See also: https://www.shodan.io/search?query=clickhouse
      -->
    <!-- <listen_host>::</listen_host> -->

    <!-- Same for hosts without support for IPv6: -->
    <!-- <listen_host>0.0.0.0</listen_host> -->

    <!-- Default values - try listen localhost on IPv4 and IPv6. -->
    <!--
    <listen_host>::1</listen_host>
    <listen_host>127.0.0.1</listen_host>
    -->

    <listen_host>::</listen_host>
    <listen_host>0.0.0.0</listen_host>
    <listen_try>1</listen_try>

    <!-- Don't exit if IPv6 or IPv4 networks are unavailable while trying to listen. -->
    <!-- <listen_try>0</listen_try> -->

    <!-- Allow multiple servers to listen on the same address:port. This is not recommended.
      -->
    <!-- <listen_reuse_port>0</listen_reuse_port> -->

    <!-- <listen_backlog>4096</listen_backlog> -->

    <max_connections>4096</max_connections>

    <!-- For 'Connection: keep-alive' in HTTP 1.1 -->
    <keep_alive_timeout>3</keep_alive_timeout>

    <!-- gRPC protocol (see src/Server/grpc_protos/clickhouse_grpc.proto for the API) -->
    <!-- <grpc_port>9100</grpc_port> -->
    <grpc>
        <enable_ssl>false</enable_ssl>

        <!-- The following two files are used only if enable_ssl=1 -->
        <ssl_cert_file>/path/to/ssl_cert_file</ssl_cert_file>
        <ssl_key_file>/path/to/ssl_key_file</ssl_key_file>

        <!-- Whether server will request client for a certificate -->
        <ssl_require_client_auth>false</ssl_require_client_auth>

        <!-- The following file is used only if ssl_require_client_auth=1 -->
        <ssl_ca_cert_file>/path/to/ssl_ca_cert_file</ssl_ca_cert_file>

        <!-- Default compression algorithm (applied if client doesn't specify another algorithm, see result_compression in QueryInfo).
             Supported algorithms: none, deflate, gzip, stream_gzip -->
        <compression>deflate</compression>

        <!-- Default compression level (applied if client doesn't specify another level, see result_compression in QueryInfo).
             Supported levels: none, low, medium, high -->
        <compression_level>medium</compression_level>

        <!-- Send/receive message size limits in bytes. -1 means unlimited -->
        <max_send_message_size>-1</max_send_message_size>
        <max_receive_message_size>-1</max_receive_message_size>

        <!-- Enable if you want very detailed logs -->
        <verbose_logs>false</verbose_logs>
    </grpc>

    <!-- Used with https_port and tcp_port_secure. Full ssl options list: https://github.com/ClickHouse-Extras/poco/blob/master/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h#L71 -->
    <openSSL>
        <server> <!-- Used for https server AND secure tcp port -->
            <!-- openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt -->
            <certificateFile>/etc/clickhouse-server/server.crt</certificateFile>
            <privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
            <!-- dhparams are optional. You can delete the <dhParamsFile> element.
                 To generate dhparams, use the following command:
                  openssl dhparam -out /etc/clickhouse-server/dhparam.pem 4096
                 Only file format with BEGIN DH PARAMETERS is supported.
              -->
            <!-- <dhParamsFile>/etc/clickhouse-server/dhparam.pem</dhParamsFile> -->
            <verificationMode>none</verificationMode>
            <loadDefaultCAFile>true</loadDefaultCAFile>
            <cacheSessions>true</cacheSessions>
            <disableProtocols>sslv2,sslv3</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
        </server>

        <client> <!-- Used for connecting to https dictionary source and secured Zookeeper communication -->
            <loadDefaultCAFile>true</loadDefaultCAFile>
            <cacheSessions>true</cacheSessions>
            <disableProtocols>sslv2,sslv3</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
            <!-- Use for self-signed: <verificationMode>none</verificationMode> -->
            <invalidCertificateHandler>
                <!-- Use for self-signed: <name>AcceptCertificateHandler</name> -->
                <name>RejectCertificateHandler</name>
            </invalidCertificateHandler>
        </client>
    </openSSL>

    <!-- Default root page on http[s] server. For example load UI from https://tabix.io/ when opening http://localhost:8123 -->
    <!--
    <http_server_default_response><![CDATA[<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>]]></http_server_default_response>
    -->

    <!-- Maximum number of concurrent queries. -->
    <max_concurrent_queries>100</max_concurrent_queries>

    <!-- Maximum memory usage (resident set size) for server process.
         Zero value or unset means default. Default is "max_server_memory_usage_to_ram_ratio" of available physical RAM.
         If the value is larger than "max_server_memory_usage_to_ram_ratio" of available physical RAM, it will be cut down.
         The constraint is checked on query execution time.
         If a query tries to allocate memory and the current memory usage plus allocation is greater
          than specified threshold, exception will be thrown.
         It is not practical to set this constraint to small values like just a few gigabytes,
          because memory allocator will keep this amount of memory in caches and the server will deny service of queries.
      -->
    <max_server_memory_usage>0</max_server_memory_usage>

    <!-- Maximum number of threads in the Global thread pool.
    This will default to a maximum of 10000 threads if not specified.
    This setting will be useful in scenarios where there are a large number
    of distributed queries that are running concurrently but are idling most
    of the time, in which case a higher number of threads might be required.
    -->

    <max_thread_pool_size>10000</max_thread_pool_size>

    <!-- On memory constrained environments you may have to set this to value larger than 1.
      -->
    <max_server_memory_usage_to_ram_ratio>0.9</max_server_memory_usage_to_ram_ratio>

    <!-- Simple server-wide memory profiler. Collect a stack trace at every peak allocation step (in bytes).
         Data will be stored in system.trace_log table with query_id = empty string.
         Zero means disabled.
      -->
    <total_memory_profiler_step>4194304</total_memory_profiler_step>

    <!-- Collect random allocations and deallocations and write them into system.trace_log with 'MemorySample' trace_type.
         The probability is for every alloc/free regardless to the size of the allocation.
         Note that sampling happens only when the amount of untracked memory exceeds the untracked memory limit,
          which is 4 MiB by default but can be lowered if 'total_memory_profiler_step' is lowered.
         You may want to set 'total_memory_profiler_step' to 1 for extra fine grained sampling.
      -->
    <total_memory_tracker_sample_probability>0</total_memory_tracker_sample_probability>

    <!-- Set limit on number of open files (default: maximum). This setting makes sense on Mac OS X because getrlimit() fails to retrieve
         correct maximum value. -->
    <!-- <max_open_files>262144</max_open_files> -->

    <!-- Size of cache of uncompressed blocks of data, used in tables of MergeTree family.
         In bytes. Cache is single for server. Memory is allocated only on demand.
         Cache is used when 'use_uncompressed_cache' user setting turned on (off by default).
         Uncompressed cache is advantageous only for very short queries and in rare cases.
         Note: uncompressed cache can be pointless for lz4, because memory bandwidth
         is slower than multi-core decompression on some server configurations.
         Enabling it can sometimes paradoxically make queries slower.
      -->
    <uncompressed_cache_size>8589934592</uncompressed_cache_size>

    <!-- Approximate size of mark cache, used in tables of MergeTree family.
         In bytes. Cache is single for server. Memory is allocated only on demand.
         You should not lower this value.
      -->
    <mark_cache_size>5368709120</mark_cache_size>


    <!-- If you enable the `min_bytes_to_use_mmap_io` setting,
         the data in MergeTree tables can be read with mmap to avoid copying from kernel to userspace.
         It makes sense only for large files and helps only if data reside in page cache.
         To avoid frequent open/mmap/munmap/close calls (which are very expensive due to consequent page faults)
         and to reuse mappings from several threads and queries,
         the cache of mapped files is maintained. Its size is the number of mapped regions (usually equal to the number of mapped files).
         The amount of data in mapped files can be monitored
         in system.metrics, system.metric_log by the MMappedFiles, MMappedFileBytes metrics
         and in system.asynchronous_metrics, system.asynchronous_metrics_log by the MMapCacheCells metric,
         and also in system.events, system.processes, system.query_log, system.query_thread_log, system.query_views_log by the
         CreatedReadBufferMMap, CreatedReadBufferMMapFailed, MMappedFileCacheHits, MMappedFileCacheMisses events.
         Note that the amount of data in mapped files does not consume memory directly and is not accounted
         in query or server memory usage - because this memory can be discarded similar to OS page cache.
         The cache is dropped (the files are closed) automatically on removal of old parts in MergeTree,
         also it can be dropped manually by the SYSTEM DROP MMAP CACHE query.
      -->
    <mmap_cache_size>1000</mmap_cache_size>

    <!-- Cache size in bytes for compiled expressions.-->
    <compiled_expression_cache_size>134217728</compiled_expression_cache_size>

    <!-- Cache size in elements for compiled expressions.-->
    <compiled_expression_cache_elements_size>10000</compiled_expression_cache_elements_size>

    <!-- Path to data directory, with trailing slash. -->
    <path>/var/lib/clickhouse/</path>

    <!-- Path to temporary data for processing hard queries. -->
    <tmp_path>/var/lib/clickhouse/tmp/</tmp_path>

    <!-- Policy from the <storage_configuration> for the temporary files.
         If not set <tmp_path> is used, otherwise <tmp_path> is ignored.
         Notes:
         - move_factor              is ignored
         - keep_free_space_bytes    is ignored
         - max_data_part_size_bytes is ignored
         - you must have exactly one volume in that policy
    -->
    <!-- <tmp_policy>tmp</tmp_policy> -->

    <!-- Directory with user provided files that are accessible by 'file' table function. -->
    <user_files_path>/var/lib/clickhouse/user_files/</user_files_path>

    <!-- LDAP server definitions. -->
    <ldap_servers>
        <!-- List LDAP servers with their connection parameters here to later 1) use them as authenticators for dedicated local users,
              who have 'ldap' authentication mechanism specified instead of 'password', or to 2) use them as remote user directories.
             Parameters:
                host - LDAP server hostname or IP, this parameter is mandatory and cannot be empty.
                port - LDAP server port, default is 636 if enable_tls is set to true, 389 otherwise.
                bind_dn - template used to construct the DN to bind to.
                        The resulting DN will be constructed by replacing all '{user_name}' substrings of the template with the actual
                         user name during each authentication attempt.
                user_dn_detection - section with LDAP search parameters for detecting the actual user DN of the bound user.
                        This is mainly used in search filters for further role mapping when the server is Active Directory. The
                         resulting user DN will be used when replacing '{user_dn}' substrings wherever they are allowed. By default,
                         user DN is set equal to bind DN, but once search is performed, it will be updated with to the actual detected
                         user DN value.
                    base_dn - template used to construct the base DN for the LDAP search.
                            The resulting DN will be constructed by replacing all '{user_name}' and '{bind_dn}' substrings
                             of the template with the actual user name and bind DN during the LDAP search.
                    scope - scope of the LDAP search.
                            Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
                    search_filter - template used to construct the search filter for the LDAP search.
                            The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', and '{base_dn}'
                             substrings of the template with the actual user name, bind DN, and base DN during the LDAP search.
                            Note, that the special characters must be escaped properly in XML.
                verification_cooldown - a period of time, in seconds, after a successful bind attempt, during which a user will be assumed
                         to be successfully authenticated for all consecutive requests without contacting the LDAP server.
                        Specify 0 (the default) to disable caching and force contacting the LDAP server for each authentication request.
                enable_tls - flag to trigger use of secure connection to the LDAP server.
                        Specify 'no' for plain text (ldap://) protocol (not recommended).
                        Specify 'yes' for LDAP over SSL/TLS (ldaps://) protocol (recommended, the default).
                        Specify 'starttls' for legacy StartTLS protocol (plain text (ldap://) protocol, upgraded to TLS).
                tls_minimum_protocol_version - the minimum protocol version of SSL/TLS.
                        Accepted values are: 'ssl2', 'ssl3', 'tls1.0', 'tls1.1', 'tls1.2' (the default).
                tls_require_cert - SSL/TLS peer certificate verification behavior.
                        Accepted values are: 'never', 'allow', 'try', 'demand' (the default).
                tls_cert_file - path to certificate file.
                tls_key_file - path to certificate key file.
                tls_ca_cert_file - path to CA certificate file.
                tls_ca_cert_dir - path to the directory containing CA certificates.
                tls_cipher_suite - allowed cipher suite (in OpenSSL notation).
             Example:
                <my_ldap_server>
                    <host>localhost</host>
                    <port>636</port>
                    <bind_dn>uid={user_name},ou=users,dc=example,dc=com</bind_dn>
                    <verification_cooldown>300</verification_cooldown>
                    <enable_tls>yes</enable_tls>
                    <tls_minimum_protocol_version>tls1.2</tls_minimum_protocol_version>
                    <tls_require_cert>demand</tls_require_cert>
                    <tls_cert_file>/path/to/tls_cert_file</tls_cert_file>
                    <tls_key_file>/path/to/tls_key_file</tls_key_file>
                    <tls_ca_cert_file>/path/to/tls_ca_cert_file</tls_ca_cert_file>
                    <tls_ca_cert_dir>/path/to/tls_ca_cert_dir</tls_ca_cert_dir>
                    <tls_cipher_suite>ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384</tls_cipher_suite>
                </my_ldap_server>
             Example (typical Active Directory with configured user DN detection for further role mapping):
                <my_ad_server>
                    <host>localhost</host>
                    <port>389</port>
                    <bind_dn>EXAMPLE\{user_name}</bind_dn>
                    <user_dn_detection>
                        <base_dn>CN=Users,DC=example,DC=com</base_dn>
                        <search_filter>(&amp;(objectClass=user)(sAMAccountName={user_name}))</search_filter>
                    </user_dn_detection>
                    <enable_tls>no</enable_tls>
                </my_ad_server>
        -->
    </ldap_servers>

    <!-- To enable Kerberos authentication support for HTTP requests (GSS-SPNEGO), for those users who are explicitly configured
          to authenticate via Kerberos, define a single 'kerberos' section here.
         Parameters:
            principal - canonical service principal name, that will be acquired and used when accepting security contexts.
                    This parameter is optional, if omitted, the default principal will be used.
                    This parameter cannot be specified together with 'realm' parameter.
            realm - a realm, that will be used to restrict authentication to only those requests whose initiator's realm matches it.
                    This parameter is optional, if omitted, no additional filtering by realm will be applied.
                    This parameter cannot be specified together with 'principal' parameter.
         Example:
            <kerberos />
         Example:
            <kerberos>
                <principal>HTTP/clickhouse.example.com@EXAMPLE.COM</principal>
            </kerberos>
         Example:
            <kerberos>
                <realm>EXAMPLE.COM</realm>
            </kerberos>
    -->

    <!-- Sources to read users, roles, access rights, profiles of settings, quotas. -->
    <user_directories>
        <users_xml>
            <!-- Path to configuration file with predefined users. -->
            <path>/etc/clickhouse-server/users.xml</path>
        </users_xml>
        <local_directory>
            <!-- Path to folder where users created by SQL commands are stored. -->
            <path>/var/lib/clickhouse/access/</path>
        </local_directory>

        <!-- To add an LDAP server as a remote user directory of users that are not defined locally, define a single 'ldap' section
              with the following parameters:
                server - one of LDAP server names defined in 'ldap_servers' config section above.
                        This parameter is mandatory and cannot be empty.
                roles - section with a list of locally defined roles that will be assigned to each user retrieved from the LDAP server.
                        If no roles are specified here or assigned during role mapping (below), user will not be able to perform any
                         actions after authentication.
                role_mapping - section with LDAP search parameters and mapping rules.
                        When a user authenticates, while still bound to LDAP, an LDAP search is performed using search_filter and the
                         name of the logged in user. For each entry found during that search, the value of the specified attribute is
                         extracted. For each attribute value that has the specified prefix, the prefix is removed, and the rest of the
                         value becomes the name of a local role defined in ClickHouse, which is expected to be created beforehand by
                         CREATE ROLE command.
                        There can be multiple 'role_mapping' sections defined inside the same 'ldap' section. All of them will be
                         applied.
                    base_dn - template used to construct the base DN for the LDAP search.
                            The resulting DN will be constructed by replacing all '{user_name}', '{bind_dn}', and '{user_dn}'
                             substrings of the template with the actual user name, bind DN, and user DN during each LDAP search.
                    scope - scope of the LDAP search.
                            Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
                    search_filter - template used to construct the search filter for the LDAP search.
                            The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', '{user_dn}', and
                             '{base_dn}' substrings of the template with the actual user name, bind DN, user DN, and base DN during
                             each LDAP search.
                            Note, that the special characters must be escaped properly in XML.
                    attribute - attribute name whose values will be returned by the LDAP search. 'cn', by default.
                    prefix - prefix, that will be expected to be in front of each string in the original list of strings returned by
                             the LDAP search. Prefix will be removed from the original strings and resulting strings will be treated
                             as local role names. Empty, by default.
             Example:
                <ldap>
                    <server>my_ldap_server</server>
                    <roles>
                        <my_local_role1 />
                        <my_local_role2 />
                    </roles>
                    <role_mapping>
                        <base_dn>ou=groups,dc=example,dc=com</base_dn>
                        <scope>subtree</scope>
                        <search_filter>(&amp;(objectClass=groupOfNames)(member={bind_dn}))</search_filter>
                        <attribute>cn</attribute>
                        <prefix>clickhouse_</prefix>
                    </role_mapping>
                </ldap>
             Example (typical Active Directory with role mapping that relies on the detected user DN):
                <ldap>
                    <server>my_ad_server</server>
                    <role_mapping>
                        <base_dn>CN=Users,DC=example,DC=com</base_dn>
                        <attribute>CN</attribute>
                        <scope>subtree</scope>
                        <search_filter>(&amp;(objectClass=group)(member={user_dn}))</search_filter>
                        <prefix>clickhouse_</prefix>
                    </role_mapping>
                </ldap>
        -->
    </user_directories>

    <!-- Default profile of settings. -->
    <default_profile>default</default_profile>

    <!-- Comma-separated list of prefixes for user-defined settings. -->
    <custom_settings_prefixes></custom_settings_prefixes>

    <!-- System profile of settings. This settings are used by internal processes (Distributed DDL worker and so on). -->
    <!-- <system_profile>default</system_profile> -->

    <!-- Buffer profile of settings.
         This settings are used by Buffer storage to flush data to the underlying table.
         Default: used from system_profile directive.
    -->
    <!-- <buffer_profile>default</buffer_profile> -->

    <!-- Default database. -->
    <default_database>default</default_database>

    <!-- Server time zone could be set here.
         Time zone is used when converting between String and DateTime types,
          when printing DateTime in text formats and parsing DateTime from text,
          it is used in date and time related functions, if specific time zone was not passed as an argument.
         Time zone is specified as identifier from IANA time zone database, like UTC or Africa/Abidjan.
         If not specified, system time zone at server startup is used.
         Please note, that server could display time zone alias instead of specified name.
         Example: W-SU is an alias for Europe/Moscow and Zulu is an alias for UTC.
    -->
    <!-- <timezone>Europe/Moscow</timezone> -->

    <!-- You can specify umask here (see "man umask"). Server will apply it on startup.
         Number is always parsed as octal. Default umask is 027 (other users cannot read logs, data files, etc; group can only read).
    -->
    <!-- <umask>022</umask> -->

    <!-- Perform mlockall after startup to lower first queries latency
          and to prevent clickhouse executable from being paged out under high IO load.
         Enabling this option is recommended but will lead to increased startup time for up to a few seconds.
    -->
    <mlock_executable>true</mlock_executable>

    <!-- Reallocate memory for machine code ("text") using huge pages. Highly experimental. -->
    <remap_executable>false</remap_executable>

    <![CDATA[
         Uncomment below in order to use JDBC table engine and function.
         To install and run JDBC bridge in background:
         * [Debian/Ubuntu]
           export MVN_URL=https://repo1.maven.org/maven2/ru/yandex/clickhouse/clickhouse-jdbc-bridge
           export PKG_VER=$(curl -sL $MVN_URL/maven-metadata.xml | grep '<release>' | sed -e 's|.*>\(.*\)<.*|\1|')
           wget https://github.com/ClickHouse/clickhouse-jdbc-bridge/releases/download/v$PKG_VER/clickhouse-jdbc-bridge_$PKG_VER-1_all.deb
           apt install --no-install-recommends -f ./clickhouse-jdbc-bridge_$PKG_VER-1_all.deb
           clickhouse-jdbc-bridge &
         * [CentOS/RHEL]
           export MVN_URL=https://repo1.maven.org/maven2/ru/yandex/clickhouse/clickhouse-jdbc-bridge
           export PKG_VER=$(curl -sL $MVN_URL/maven-metadata.xml | grep '<release>' | sed -e 's|.*>\(.*\)<.*|\1|')
           wget https://github.com/ClickHouse/clickhouse-jdbc-bridge/releases/download/v$PKG_VER/clickhouse-jdbc-bridge-$PKG_VER-1.noarch.rpm
           yum localinstall -y clickhouse-jdbc-bridge-$PKG_VER-1.noarch.rpm
           clickhouse-jdbc-bridge &
         Please refer to https://github.com/ClickHouse/clickhouse-jdbc-bridge#usage for more information.
    ]]>
    <!--
    <jdbc_bridge>
        <host>127.0.0.1</host>
        <port>9019</port>
    </jdbc_bridge>
    -->

    <!-- Configuration of clusters that could be used in Distributed tables.
         https://clickhouse.com/docs/en/operations/table_engines/distributed/
      -->
    <remote_servers>
        <!-- Test only shard config for testing distributed storage -->
        <test_shard_localhost>
            <!-- Inter-server per-cluster secret for Distributed queries
                 default: no secret (no authentication will be performed)
                 If set, then Distributed queries will be validated on shards, so at least:
                 - such cluster should exist on the shard,
                 - such cluster should have the same secret.
                 And also (and which is more important), the initial_user will
                 be used as current user for the query.
                 Right now the protocol is pretty simple and it only takes into account:
                 - cluster name
                 - query
                 Also it will be nice if the following will be implemented:
                 - source hostname (see interserver_http_host), but then it will depends from DNS,
                   it can use IP address instead, but then the you need to get correct on the initiator node.
                 - target hostname / ip address (same notes as for source hostname)
                 - time-based security tokens
            -->
            <!-- <secret></secret> -->

            <shard>
                <!-- Optional. Whether to write data to just one of the replicas. Default: false (write data to all replicas). -->
                <!-- <internal_replication>false</internal_replication> -->
                <!-- Optional. Shard weight when writing data. Default: 1. -->
                <!-- <weight>1</weight> -->
                <replica>
                    <host>localhost</host>
                    <port>9000</port>
                    <!-- Optional. Priority of the replica for load_balancing. Default: 1 (less value has more priority). -->
                    <!-- <priority>1</priority> -->
                </replica>
            </shard>
        </test_shard_localhost>
        <test_cluster_one_shard_three_replicas_localhost>
            <shard>
                <internal_replication>false</internal_replication>
                <replica>
                    <host>127.0.0.1</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>127.0.0.2</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>127.0.0.3</host>
                    <port>9000</port>
                </replica>
            </shard>
            <!--shard>
                <internal_replication>false</internal_replication>
                <replica>
                    <host>127.0.0.1</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>127.0.0.2</host>
                    <port>9000</port>
                </replica>
                <replica>
                    <host>127.0.0.3</host>
                    <port>9000</port>
                </replica>
            </shard-->
        </test_cluster_one_shard_three_replicas_localhost>
        <test_cluster_two_shards_localhost>
             <shard>
                 <replica>
                     <host>localhost</host>
                     <port>9000</port>
                 </replica>
             </shard>
             <shard>
                 <replica>
                     <host>localhost</host>
                     <port>9000</port>
                 </replica>
             </shard>
        </test_cluster_two_shards_localhost>
        <test_cluster_two_shards>
            <shard>
                <replica>
                    <host>127.0.0.1</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <replica>
                    <host>127.0.0.2</host>
                    <port>9000</port>
                </replica>
            </shard>
        </test_cluster_two_shards>
        <test_cluster_two_shards_internal_replication>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>127.0.0.1</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <internal_replication>true</internal_replication>
                <replica>
                    <host>127.0.0.2</host>
                    <port>9000</port>
                </replica>
            </shard>
        </test_cluster_two_shards_internal_replication>
        <test_shard_localhost_secure>
            <shard>
                <replica>
                    <host>localhost</host>
                    <port>9440</port>
                    <secure>1</secure>
                </replica>
            </shard>
        </test_shard_localhost_secure>
        <test_unavailable_shard>
            <shard>
                <replica>
                    <host>localhost</host>
                    <port>9000</port>
                </replica>
            </shard>
            <shard>
                <replica>
                    <host>localhost</host>
                    <port>1</port>
                </replica>
            </shard>
        </test_unavailable_shard>
    </remote_servers>

    <!-- The list of hosts allowed to use in URL-related storage engines and table functions.
        If this section is not present in configuration, all hosts are allowed.
    -->
    <!--<remote_url_allow_hosts>-->
        <!-- Host should be specified exactly as in URL. The name is checked before DNS resolution.
            Example: "yandex.ru", "yandex.ru." and "www.yandex.ru" are different hosts.
                    If port is explicitly specified in URL, the host:port is checked as a whole.
                    If host specified here without port, any port with this host allowed.
                    "yandex.ru" -> "yandex.ru:443", "yandex.ru:80" etc. is allowed, but "yandex.ru:80" -> only "yandex.ru:80" is allowed.
            If the host is specified as IP address, it is checked as specified in URL. Example: "[2a02:6b8:a::a]".
            If there are redirects and support for redirects is enabled, every redirect (the Location field) is checked.
            Host should be specified using the host xml tag:
                    <host>yandex.ru</host>
        -->

        <!-- Regular expression can be specified. RE2 engine is used for regexps.
            Regexps are not aligned: don't forget to add ^ and $. Also don't forget to escape dot (.) metacharacter
            (forgetting to do so is a common source of error).
        -->
    <!--</remote_url_allow_hosts>-->

    <!-- If element has 'incl' attribute, then for it's value will be used corresponding substitution from another file.
         By default, path to file with substitutions is /etc/metrika.xml. It could be changed in config in 'include_from' element.
         Values for substitutions are specified in /clickhouse/name_of_substitution elements in that file.
      -->

    <!-- ZooKeeper is used to store metadata about replicas, when using Replicated tables.
         Optional. If you don't use replicated tables, you could omit that.
         See https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replication/
      -->

    <!--
    <zookeeper>
        <node>
            <host>example1</host>
            <port>2181</port>
        </node>
        <node>
            <host>example2</host>
            <port>2181</port>
        </node>
        <node>
            <host>example3</host>
            <port>2181</port>
        </node>
    </zookeeper>
    -->

    <!-- Substitutions for parameters of replicated tables.
          Optional. If you don't use replicated tables, you could omit that.
         See https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/replication/#creating-replicated-tables
      -->
    <!--
    <macros>
        <shard>01</shard>
        <replica>example01-01-1</replica>
    </macros>
    -->


    <!-- Reloading interval for embedded dictionaries, in seconds. Default: 3600. -->
    <builtin_dictionaries_reload_interval>3600</builtin_dictionaries_reload_interval>


    <!-- Maximum session timeout, in seconds. Default: 3600. -->
    <max_session_timeout>3600</max_session_timeout>

    <!-- Default session timeout, in seconds. Default: 60. -->
    <default_session_timeout>60</default_session_timeout>

    <!-- Sending data to Graphite for monitoring. Several sections can be defined. -->
    <!--
        interval - send every X second
        root_path - prefix for keys
        hostname_in_path - append hostname to root_path (default = true)
        metrics - send data from table system.metrics
        events - send data from table system.events
        asynchronous_metrics - send data from table system.asynchronous_metrics
    -->
    <!--
    <graphite>
        <host>localhost</host>
        <port>42000</port>
        <timeout>0.1</timeout>
        <interval>60</interval>
        <root_path>one_min</root_path>
        <hostname_in_path>true</hostname_in_path>
        <metrics>true</metrics>
        <events>true</events>
        <events_cumulative>false</events_cumulative>
        <asynchronous_metrics>true</asynchronous_metrics>
    </graphite>
    <graphite>
        <host>localhost</host>
        <port>42000</port>
        <timeout>0.1</timeout>
        <interval>1</interval>
        <root_path>one_sec</root_path>
        <metrics>true</metrics>
        <events>true</events>
        <events_cumulative>false</events_cumulative>
        <asynchronous_metrics>false</asynchronous_metrics>
    </graphite>
    -->

    <!-- Serve endpoint for Prometheus monitoring. -->
    <!--
        endpoint - mertics path (relative to root, statring with "/")
        port - port to setup server. If not defined or 0 than http_port used
        metrics - send data from table system.metrics
        events - send data from table system.events
        asynchronous_metrics - send data from table system.asynchronous_metrics
        status_info - send data from different component from CH, ex: Dictionaries status
    -->
    <!--
    <prometheus>
        <endpoint>/metrics</endpoint>
        <port>9363</port>
        <metrics>true</metrics>
        <events>true</events>
        <asynchronous_metrics>true</asynchronous_metrics>
        <status_info>true</status_info>
    </prometheus>
    -->

    <!-- Query log. Used only for queries with setting log_queries = 1. -->
    <query_log>
        <!-- What table to insert data. If table is not exist, it will be created.
             When query log structure is changed after system update,
              then old table will be renamed and new table will be created automatically.
        -->
        <database>system</database>
        <table>query_log</table>
        <!--
            PARTITION BY expr: https://clickhouse.com/docs/en/table_engines/mergetree-family/custom_partitioning_key/
            Example:
                event_date
                toMonday(event_date)
                toYYYYMM(event_date)
                toStartOfHour(event_time)
        -->
        <partition_by>toYYYYMM(event_date)</partition_by>
        <!--
            Table TTL specification: https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree/#mergetree-table-ttl
            Example:
                event_date + INTERVAL 1 WEEK
                event_date + INTERVAL 7 DAY DELETE
                event_date + INTERVAL 2 WEEK TO DISK 'bbb'
        <ttl>event_date + INTERVAL 30 DAY DELETE</ttl>
        -->

        <!-- Instead of partition_by, you can provide full engine expression (starting with ENGINE = ) with parameters,
             Example: <engine>ENGINE = MergeTree PARTITION BY toYYYYMM(event_date) ORDER BY (event_date, event_time) SETTINGS index_granularity = 1024</engine>
          -->

        <!-- Interval of flushing data. -->
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </query_log>

    <!-- Trace log. Stores stack traces collected by query profilers.
         See query_profiler_real_time_period_ns and query_profiler_cpu_time_period_ns settings. -->
    <trace_log>
        <database>system</database>
        <table>trace_log</table>

        <partition_by>toYYYYMM(event_date)</partition_by>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </trace_log>

    <!-- Query thread log. Has information about all threads participated in query execution.
         Used only for queries with setting log_query_threads = 1. -->
    <query_thread_log>
        <database>system</database>
        <table>query_thread_log</table>
        <partition_by>toYYYYMM(event_date)</partition_by>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </query_thread_log>

    <!-- Query views log. Has information about all dependent views associated with a query.
         Used only for queries with setting log_query_views = 1. -->
    <query_views_log>
        <database>system</database>
        <table>query_views_log</table>
        <partition_by>toYYYYMM(event_date)</partition_by>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </query_views_log>

    <!-- Uncomment if use part log.
         Part log contains information about all actions with parts in MergeTree tables (creation, deletion, merges, downloads).-->
    <part_log>
        <database>system</database>
        <table>part_log</table>
        <partition_by>toYYYYMM(event_date)</partition_by>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </part_log>

    <!-- Uncomment to write text log into table.
         Text log contains all information from usual server log but stores it in structured and efficient way.
         The level of the messages that goes to the table can be limited (<level>), if not specified all messages will go to the table.
    <text_log>
        <database>system</database>
        <table>text_log</table>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
        <level></level>
    </text_log>
    -->

    <!-- Metric log contains rows with current values of ProfileEvents, CurrentMetrics collected with "collect_interval_milliseconds" interval. -->
    <metric_log>
        <database>system</database>
        <table>metric_log</table>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
        <collect_interval_milliseconds>1000</collect_interval_milliseconds>
    </metric_log>

    <!--
        Asynchronous metric log contains values of metrics from
        system.asynchronous_metrics.
    -->
    <asynchronous_metric_log>
        <database>system</database>
        <table>asynchronous_metric_log</table>
        <!--
            Asynchronous metrics are updated once a minute, so there is
            no need to flush more often.
        -->
        <flush_interval_milliseconds>7000</flush_interval_milliseconds>
    </asynchronous_metric_log>

    <!--
        OpenTelemetry log contains OpenTelemetry trace spans.
    -->
    <opentelemetry_span_log>
        <!--
            The default table creation code is insufficient, this <engine> spec
            is a workaround. There is no 'event_time' for this log, but two times,
            start and finish. It is sorted by finish time, to avoid inserting
            data too far away in the past (probably we can sometimes insert a span
            that is seconds earlier than the last span in the table, due to a race
            between several spans inserted in parallel). This gives the spans a
            global order that we can use to e.g. retry insertion into some external
            system.
        -->
        <engine>
            engine MergeTree
            partition by toYYYYMM(finish_date)
            order by (finish_date, finish_time_us, trace_id)
        </engine>
        <database>system</database>
        <table>opentelemetry_span_log</table>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </opentelemetry_span_log>


    <!-- Crash log. Stores stack traces for fatal errors.
         This table is normally empty. -->
    <crash_log>
        <database>system</database>
        <table>crash_log</table>

        <partition_by />
        <flush_interval_milliseconds>1000</flush_interval_milliseconds>
    </crash_log>

    <!-- Session log. Stores user log in (successful or not) and log out events. -->
    <session_log>
        <database>system</database>
        <table>session_log</table>

        <partition_by>toYYYYMM(event_date)</partition_by>
        <flush_interval_milliseconds>7500</flush_interval_milliseconds>
    </session_log>

    <!-- Parameters for embedded dictionaries, used in Yandex.Metrica.
         See https://clickhouse.com/docs/en/dicts/internal_dicts/
    -->

    <!-- Path to file with region hierarchy. -->
    <!-- <path_to_regions_hierarchy_file>/opt/geo/regions_hierarchy.txt</path_to_regions_hierarchy_file> -->

    <!-- Path to directory with files containing names of regions -->
    <!-- <path_to_regions_names_files>/opt/geo/</path_to_regions_names_files> -->


    <!-- <top_level_domains_path>/var/lib/clickhouse/top_level_domains/</top_level_domains_path> -->
    <!-- Custom TLD lists.
         Format: <name>/path/to/file</name>
         Changes will not be applied w/o server restart.
         Path to the list is under top_level_domains_path (see above).
    -->
    <top_level_domains_lists>
        <!--
        <public_suffix_list>/path/to/public_suffix_list.dat</public_suffix_list>
        -->
    </top_level_domains_lists>

    <!-- Configuration of external dictionaries. See:
         https://clickhouse.com/docs/en/sql-reference/dictionaries/external-dictionaries/external-dicts
    -->
    <dictionaries_config>*_dictionary.xml</dictionaries_config>

    <!-- Configuration of user defined executable functions -->
    <user_defined_executable_functions_config>*_function.xml</user_defined_executable_functions_config>

    <!-- Uncomment if you want data to be compressed 30-100% better.
         Don't do that if you just started using ClickHouse.
      -->
    <!--
    <compression>
        <!- - Set of variants. Checked in order. Last matching case wins. If nothing matches, lz4 will be used. - ->
        <case>
            <!- - Conditions. All must be satisfied. Some conditions may be omitted. - ->
            <min_part_size>10000000000</min_part_size>        <!- - Min part size in bytes. - ->
            <min_part_size_ratio>0.01</min_part_size_ratio>   <!- - Min size of part relative to whole table size. - ->
            <!- - What compression method to use. - ->
            <method>zstd</method>
        </case>
    </compression>
    -->

    <!-- Configuration of encryption. The server executes a command to
         obtain an encryption key at startup if such a command is
         defined, or encryption codecs will be disabled otherwise. The
         command is executed through /bin/sh and is expected to write
         a Base64-encoded key to the stdout. -->
    <encryption_codecs>
        <!-- aes_128_gcm_siv -->
            <!-- Example of getting hex key from env -->
            <!-- the code should use this key and throw an exception if its length is not 16 bytes -->
            <!--key_hex from_env="..."></key_hex -->

            <!-- Example of multiple hex keys. They can be imported from env or be written down in config-->
            <!-- the code should use these keys and throw an exception if their length is not 16 bytes -->
            <!-- key_hex id="0">...</key_hex -->
            <!-- key_hex id="1" from_env=".."></key_hex -->
            <!-- key_hex id="2">...</key_hex -->
            <!-- current_key_id>2</current_key_id -->

            <!-- Example of getting hex key from config -->
            <!-- the code should use this key and throw an exception if its length is not 16 bytes -->
            <!-- key>...</key -->

            <!-- example of adding nonce -->
            <!-- nonce>...</nonce -->

        <!-- /aes_128_gcm_siv -->
    </encryption_codecs>

    <!-- Allow to execute distributed DDL queries (CREATE, DROP, ALTER, RENAME) on cluster.
         Works only if ZooKeeper is enabled. Comment it if such functionality isn't required. -->
    <distributed_ddl>
        <!-- Path in ZooKeeper to queue with DDL queries -->
        <path>/clickhouse/task_queue/ddl</path>

        <!-- Settings from this profile will be used to execute DDL queries -->
        <!-- <profile>default</profile> -->

        <!-- Controls how much ON CLUSTER queries can be run simultaneously. -->
        <!-- <pool_size>1</pool_size> -->

        <!--
             Cleanup settings (active tasks will not be removed)
        -->

        <!-- Controls task TTL (default 1 week) -->
        <!-- <task_max_lifetime>604800</task_max_lifetime> -->

        <!-- Controls how often cleanup should be performed (in seconds) -->
        <!-- <cleanup_delay_period>60</cleanup_delay_period> -->

        <!-- Controls how many tasks could be in the queue -->
        <!-- <max_tasks_in_queue>1000</max_tasks_in_queue> -->
    </distributed_ddl>

    <!-- Settings to fine tune MergeTree tables. See documentation in source code, in MergeTreeSettings.h -->
    <!--
    <merge_tree>
        <max_suspicious_broken_parts>5</max_suspicious_broken_parts>
    </merge_tree>
    -->

    <!-- Protection from accidental DROP.
         If size of a MergeTree table is greater than max_table_size_to_drop (in bytes) than table could not be dropped with any DROP query.
         If you want do delete one table and don't want to change clickhouse-server config, you could create special file <clickhouse-path>/flags/force_drop_table and make DROP once.
         By default max_table_size_to_drop is 50GB; max_table_size_to_drop=0 allows to DROP any tables.
         The same for max_partition_size_to_drop.
         Uncomment to disable protection.
    -->
    <!-- <max_table_size_to_drop>0</max_table_size_to_drop> -->
    <!-- <max_partition_size_to_drop>0</max_partition_size_to_drop> -->

    <!-- Example of parameters for GraphiteMergeTree table engine -->
    <graphite_rollup_example>
        <pattern>
            <regexp>click_cost</regexp>
            <function>any</function>
            <retention>
                <age>0</age>
                <precision>3600</precision>
            </retention>
            <retention>
                <age>86400</age>
                <precision>60</precision>
            </retention>
        </pattern>
        <default>
            <function>max</function>
            <retention>
                <age>0</age>
                <precision>60</precision>
            </retention>
            <retention>
                <age>3600</age>
                <precision>300</precision>
            </retention>
            <retention>
                <age>86400</age>
                <precision>3600</precision>
            </retention>
        </default>
    </graphite_rollup_example>

    <!-- Directory in <clickhouse-path> containing schema files for various input formats.
         The directory will be created if it doesn't exist.
      -->
    <format_schema_path>/var/lib/clickhouse/format_schemas/</format_schema_path>

    <!-- Default query masking rules, matching lines would be replaced with something else in the logs
        (both text logs and system.query_log).
        name - name for the rule (optional)
        regexp - RE2 compatible regular expression (mandatory)
        replace - substitution string for sensitive data (optional, by default - six asterisks)
    -->
    <query_masking_rules>
        <rule>
            <name>hide encrypt/decrypt arguments</name>
            <regexp>((?:aes_)?(?:encrypt|decrypt)(?:_mysql)?)\s*\(\s*(?:'(?:\\'|.)+'|.*?)\s*\)</regexp>
            <!-- or more secure, but also more invasive:
                (aes_\w+)\s*\(.*\)
            -->
            <replace>\1(???)</replace>
        </rule>
    </query_masking_rules>

    <!-- Uncomment to use custom http handlers.
        rules are checked from top to bottom, first match runs the handler
            url - to match request URL, you can use 'regex:' prefix to use regex match(optional)
            methods - to match request method, you can use commas to separate multiple method matches(optional)
            headers - to match request headers, match each child element(child element name is header name), you can use 'regex:' prefix to use regex match(optional)
        handler is request handler
            type - supported types: static, dynamic_query_handler, predefined_query_handler
            query - use with predefined_query_handler type, executes query when the handler is called
            query_param_name - use with dynamic_query_handler type, extracts and executes the value corresponding to the <query_param_name> value in HTTP request params
            status - use with static type, response status code
            content_type - use with static type, response content-type
            response_content - use with static type, Response content sent to client, when using the prefix 'file://' or 'config://', find the content from the file or configuration send to client.
    <http_handlers>
        <rule>
            <url>/</url>
            <methods>POST,GET</methods>
            <headers><pragma>no-cache</pragma></headers>
            <handler>
                <type>dynamic_query_handler</type>
                <query_param_name>query</query_param_name>
            </handler>
        </rule>
        <rule>
            <url>/predefined_query</url>
            <methods>POST,GET</methods>
            <handler>
                <type>predefined_query_handler</type>
                <query>SELECT * FROM system.settings</query>
            </handler>
        </rule>
        <rule>
            <handler>
                <type>static</type>
                <status>200</status>
                <content_type>text/plain; charset=UTF-8</content_type>
                <response_content>config://http_server_default_response</response_content>
            </handler>
        </rule>
    </http_handlers>
    -->

    <send_crash_reports>
        <!-- Changing <enabled> to true allows sending crash reports to -->
        <!-- the ClickHouse core developers team via Sentry https://sentry.io -->
        <!-- Doing so at least in pre-production environments is highly appreciated -->
        <enabled>false</enabled>
        <!-- Change <anonymize> to true if you don't feel comfortable attaching the server hostname to the crash report -->
        <anonymize>false</anonymize>
        <!-- Default endpoint should be changed to different Sentry DSN only if you have -->
        <!-- some in-house engineers or hired consultants who're going to debug ClickHouse issues for you -->
        <endpoint>https://6f33034cfe684dd7a3ab9875e57b1c8d@o388870.ingest.sentry.io/5226277</endpoint>
    </send_crash_reports>

    <!-- Uncomment to disable ClickHouse internal DNS caching. -->
    <!-- <disable_internal_dns_cache>1</disable_internal_dns_cache> -->

    <!-- You can also configure rocksdb like this: -->
    <!--
    <rocksdb>
        <options>
            <max_background_jobs>8</max_background_jobs>
        </options>
        <column_family_options>
            <num_levels>2</num_levels>
        </column_family_options>
        <tables>
            <table>
                <name>TABLE</name>
                <options>
                    <max_background_jobs>8</max_background_jobs>
                </options>
                <column_family_options>
                    <num_levels>2</num_levels>
                </column_family_options>
            </table>
        </tables>
    </rocksdb>
    -->
</clickhouse>


================================================
FILE: config/custom.xml
================================================
<?xml version="1.0" ?>
<clickhouse>
    <listen_host>::</listen_host>
    <listen_host>0.0.0.0</listen_host>
    <listen_try>1</listen_try>
    <logger>
        <console>1</console>
    </logger>
    <timezone>UTC</timezone>

</clickhouse>


================================================
FILE: config/server.crt
================================================
-----BEGIN CERTIFICATE-----
MIICqjCCAZICCQCmreUKLiQrrzANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxt
eS5ob3N0Lm5hbWUwHhcNMjExMjE1MjAzMTU2WhcNMjIxMjE1MjAzMTU2WjAXMRUw
EwYDVQQDDAxteS5ob3N0Lm5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQDBt3kbY3SwS89oNQhllMyK+AumX9d01bbU1ZFcLJcn9wyLK+wSFJTe6V8f
hiHPZosnDcOWkspw/SBAVDCyvAx0QgjgkVj4JgCjxdXl25R9Ouz582hhTqqjpBCW
n1ZKRhkau6ASHz4JF0MyemIdYB8DgnUKRfYnWtNrXS91RE/8H0U6s8kO3Msbj8GG
ubTBHOPWEJt6VAnWzVXXAGCNopNLF3Z7UUmJ7IMiTm923eGP0zZzvj5kMFLBiTm3
sHtSN39PJ6evJ7oeO+l+JOtBkuaA3yYuPcAHNHpK+SffPulZpx7VxmY2ot7696xM
kq2wl9uswOLCrn87hum2M+Bhy673AgMBAAEwDQYJKoZIhvcNAQELBQADggEBACA/
VcLExf/XOmbueWvNg7IkBaUWL5waZf+MIlAuwaYjAsKSM/hYSY/g480XXFjN9Urm
LJgIJ2T3EhGzqK+wdOITbEE7O1MM28TUex8giMKrl53XSbz2ni8dClehUJFch99D
+tBVjihLJC+GP+M/jfCiWV45+MOc+Mqkz92MVNmltfhklH00IBz/a0RdD0XqdyqB
Ar/U19CgbZ7D/UAyjXnYjU1ucUBpMOmvfwdIABneeyLCzWQtH0vMaTrNmLsn6QwB
C2nTdEeDIim9SZkRk5Fm1N4Ya6gWdP5PV6+yXdYSw/DtYsjwbNUfQMqiJVdQKQDM
cuG+FV1/eq4dnDOYw3U=
-----END CERTIFICATE-----


================================================
FILE: config/server.key
================================================
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBt3kbY3SwS89o
NQhllMyK+AumX9d01bbU1ZFcLJcn9wyLK+wSFJTe6V8fhiHPZosnDcOWkspw/SBA
VDCyvAx0QgjgkVj4JgCjxdXl25R9Ouz582hhTqqjpBCWn1ZKRhkau6ASHz4JF0My
emIdYB8DgnUKRfYnWtNrXS91RE/8H0U6s8kO3Msbj8GGubTBHOPWEJt6VAnWzVXX
AGCNopNLF3Z7UUmJ7IMiTm923eGP0zZzvj5kMFLBiTm3sHtSN39PJ6evJ7oeO+l+
JOtBkuaA3yYuPcAHNHpK+SffPulZpx7VxmY2ot7696xMkq2wl9uswOLCrn87hum2
M+Bhy673AgMBAAECggEAOOWbs5itoE5T9+aDtdpTjYm3WkGSNeXDkpW74RfTudBN
Jd9bsh/LbgGbh9XMvm7+9hSL2wD4ZuFiBKL1vrmO6uKuWs82E4SN8Yxc++tXnMSe
7/c3NEV3xyKcILFiFeSq4Pg01r3IacEkYoIhqUEfOtepasALwZliuYkgNFBBMeq1
jQWYs5k5h49etBc64ut+J++gFv77uJcmfetacKe4VxabX2iExW5SLmJQXLROC3o+
9+r4bIt/jgufvODWZem0EeHWPSoL8CnT8/YCJCiX/cynyqt/LAEZGnqfHRKW3spI
C/igOqzYM+86XLDG9HnV2jFGVU91euSQyLbAmLYYOQKBgQD7uQBAWCwRM6vb/6tq
tga+wUhaHtynrvuLIg0lw9tUGzSxPIp9/FIGfVKhOuPBaNxRIIrInazorBwQxtFd
cvCE+xTT2wcYRos5WxuSYiszIl4ltXWmzQZDnmcUubCcrJ9qfI3Q+dTFb0C0HYTz
01WQAeqsEh3dALPVruEshHKcIwKBgQDFAiUWglhL/TyxcOZgyISbzJUvb0t1lA05
yE2DsgKaIX8gFHIumCl15G2tqfDb+BfwWRfs/2VX187VYy97MoRNM9Lh4tUyWddV
oyZrE8t/T2MfoMF6QMKX7MU6y9eUdgIsklilJyOu2QFLu06hvF9S43bBxFgMLm3L
W2UJz/x1HQKBgBLLLC6hpqCeJ/2j6AtujbBeQ+WemkDWuqcXor2oEs8DvPpil8By
PzmGz82D1Q9SoehYsqPpycgRWYMTJPyCIVz8VgC/QJdaZPiiSbuzIqCNt1O/aYpL
kmUoBXAxsPLxnHFZ3Ui17mHTPZR1A8EkjSXUTs4MCDjA3axdgyhMtzXbAoGBAI4e
Hv0e6G1g8GCcrkSRQkBWFCTU552ZQPU3Dtv7FS91DIzq0vfT4szeDVTjLBKy5SoI
S183WjdFQjrjQ0RfS9uZj/5NsTiSYOmxOSyzafCcJ0iQoiH8B6SrNBhXJlw9yRG4
PORe2LnwZ6PnKjE4f5d+6ZOcfVvEPoYdl0S92kPtAoGAMrWc/n/0dKAV9CSmLXS0
AAqCtXw4OJNQBjCKks4DncWoopWvGHinVJAQYPrdnDO8iKcDYm6Kg+fVo0MWCha9
opWIu4hgbcsH+wzTrgvUD4VlUdqAXqbDet6iZEu1IkSuGQqathAJk0ePa1swdl10
N4SFUzUUwkhTFWW0BuMH0YU=
-----END PRIVATE KEY-----


================================================
FILE: config/users.xml
================================================
<?xml version="1.0"?>
<clickhouse>
    <!-- See also the files in users.d directory where the settings can be overridden. -->

    <!-- Profiles of settings. -->
    <profiles>
        <!-- Default settings. -->
        <default>
            <!-- Maximum memory usage for processing single query, in bytes. -->
            <max_memory_usage>10000000000</max_memory_usage>

            <!-- How to choose between replicas during distributed query processing.
                 random - choose random replica from set of replicas with minimum number of errors
                 nearest_hostname - from set of replicas with minimum number of errors, choose replica
                  with minimum number of different symbols between replica's hostname and local hostname
                  (Hamming distance).
                 in_order - first live replica is chosen in specified order.
                 first_or_random - if first replica one has higher number of errors, pick a random one from replicas with minimum number of errors.
            -->
            <load_balancing>random</load_balancing>
        </default>

        <!-- Profile that allows only read queries. -->
        <readonly>
            <readonly>1</readonly>
        </readonly>
    </profiles>

    <!-- Users and ACL. -->
    <users>
        <!-- If user name was not specified, 'default' user is used. -->
        <default>
            <!-- See also the files in users.d directory where the password can be overridden.
                 Password could be specified in plaintext or in SHA256 (in hex format).
                 If you want to specify password in plaintext (not recommended), place it in 'password' element.
                 Example: <password>qwerty</password>.
                 Password could be empty.
                 If you want to specify SHA256, place it in 'password_sha256_hex' element.
                 Example: <password_sha256_hex>65e84be33532fb784c48129675f9eff3a682b27168c0ea744b2cf58ee02337c5</password_sha256_hex>
                 Restrictions of SHA256: impossibility to connect to ClickHouse using MySQL JS client (as of July 2019).
                 If you want to specify double SHA1, place it in 'password_double_sha1_hex' element.
                 Example: <password_double_sha1_hex>e395796d6546b1b65db9d665cd43f0e858dd4303</password_double_sha1_hex>
                 If you want to specify a previously defined LDAP server (see 'ldap_servers' in the main config) for authentication,
                  place its name in 'server' element inside 'ldap' element.
                 Example: <ldap><server>my_ldap_server</server></ldap>
                 If you want to authenticate the user via Kerberos (assuming Kerberos is enabled, see 'kerberos' in the main config),
                  place 'kerberos' element instead of 'password' (and similar) elements.
                 The name part of the canonical principal name of the initiator must match the user name for authentication to succeed.
                 You can also place 'realm' element inside 'kerberos' element to further restrict authentication to only those requests
                  whose initiator's realm matches it.
                 Example: <kerberos />
                 Example: <kerberos><realm>EXAMPLE.COM</realm></kerberos>
                 How to generate decent password:
                 Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha256sum | tr -d '-'
                 In first line will be password and in second - corresponding SHA256.
                 How to generate double SHA1:
                 Execute: PASSWORD=$(base64 < /dev/urandom | head -c8); echo "$PASSWORD"; echo -n "$PASSWORD" | sha1sum | tr -d '-' | xxd -r -p | sha1sum | tr -d '-'
                 In first line will be password and in second - corresponding double SHA1.
            -->
            <password></password>

            <!-- List of networks with open access.
                 To open access from everywhere, specify:
                    <ip>::/0</ip>
                 To open access only from localhost, specify:
                    <ip>::1</ip>
                    <ip>127.0.0.1</ip>
                 Each element of list has one of the following forms:
                 <ip> IP-address or network mask. Examples: 213.180.204.3 or 10.0.0.1/8 or 10.0.0.1/255.255.255.0
                     2a02:6b8::3 or 2a02:6b8::3/64 or 2a02:6b8::3/ffff:ffff:ffff:ffff::.
                 <host> Hostname. Example: server01.yandex.ru.
                     To check access, DNS query is performed, and all received addresses compared to peer address.
                 <host_regexp> Regular expression for host names. Example, ^server\d\d-\d\d-\d\.yandex\.ru$
                     To check access, DNS PTR query is performed for peer address and then regexp is applied.
                     Then, for result of PTR query, another DNS query is performed and all received addresses compared to peer address.
                     Strongly recommended that regexp is ends with $
                 All results of DNS requests are cached till server restart.
            -->
            <networks>
                <ip>::/0</ip>
            </networks>

            <!-- Settings profile for user. -->
            <profile>default</profile>

            <!-- Quota for user. -->
            <quota>default</quota>

            <!-- User can create other users and grant rights to them. -->
            <!-- <access_management>1</access_management> -->
        </default>
    </users>

    <!-- Quotas. -->
    <quotas>
        <!-- Name of quota. -->
        <default>
            <!-- Limits for time interval. You could specify many intervals with different limits. -->
            <interval>
                <!-- Length of interval. -->
                <duration>3600</duration>

                <!-- No limits. Just calculate resource usage for time interval. -->
                <queries>0</queries>
                <errors>0</errors>
                <result_rows>0</result_rows>
                <read_rows>0</read_rows>
                <execution_time>0</execution_time>
            </interval>
        </default>
    </quotas>
</clickhouse>

================================================
FILE: config-secure/config.xml
================================================
<?xml version="1.0"?>
<!--
  NOTE: User and query level settings are set up in "users.xml" file.
  If you have accidentally specified user-level settings here, server won't start.
  You can either move the settings to the right place inside "users.xml" file
   or add <skip_check_for_incorrect_settings>1</skip_check_for_incorrect_settings> here.
-->
<clickhouse>
    <logger>
        <!-- Possible levels [1]:
          - none (turns off logging)
          - fatal
          - critical
          - error
          - warning
          - notice
          - information
          - debug
          - trace
          - test (not for production usage)
            [1]: https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/Logger.h#L105-L114
        -->
        <level>trace</level>
        <log>/etc/clickhouse-server/clickhouse-server.log</log>
        <errorlog>/etc/clickhouse-server/clickhouse-server.err.log</errorlog>
        <!-- Rotation policy
             See https://github.com/pocoproject/poco/blob/poco-1.9.4-release/Foundation/include/Poco/FileChannel.h#L54-L85
          -->
        <size>1000M</size>
        <count>10</count>
        <!-- <console>1</console> --> <!-- Default behavior is autodetection (log to console if not daemon mode and is tty) -->

        <!-- Per level overrides (legacy):
        For example to suppress logging of the ConfigReloader you can use:
        NOTE: levels.logger is reserved, see below.
        -->
        <!--
        <levels>
          <ConfigReloader>none</ConfigReloader>
        </levels>
        -->

        <!-- Per level overrides:
        For example to suppress logging of the RBAC for default user you can use:
        (But please note that the logger name maybe changed from version to version, even after minor upgrade)
        -->
        <!--
        <levels>
          <logger>
            <name>ContextAccess (default)</name>
            <level>none</level>
          </logger>
          <logger>
            <name>DatabaseOrdinary (test)</name>
            <level>none</level>
          </logger>
        </levels>
        -->
    </logger>

    <!-- Add headers to response in options request. OPTIONS method is used in CORS preflight requests. -->
    <!-- It is off by default. Next headers are obligate for CORS.-->
    <!-- http_options_response>
        <header>
            <name>Access-Control-Allow-Origin</name>
            <value>*</value>
        </header>
        <header>
            <name>Access-Control-Allow-Headers</name>
            <value>origin, x-requested-with</value>
        </header>
        <header>
            <name>Access-Control-Allow-Methods</name>
            <value>POST, GET, OPTIONS</value>
        </header>
        <header>
            <name>Access-Control-Max-Age</name>
            <value>86400</value>
        </header>
    </http_options_response -->

    <!-- It is the name that will be shown in the clickhouse-client.
         By default, anything with "production" will be highlighted in red in query prompt.
    -->
    <!--display_name>production</display_name-->

    <!-- Port for HTTP API. See also 'https_port' for secure connections.
         This interface is also used by ODBC and JDBC drivers (DataGrip, Dbeaver, ...)
         and by most of web interfaces (embedded UI, Grafana, Redash, ...).
      -->
    <http_port>8123</http_port>

    <!-- Port for interaction by native protocol with:
         - clickhouse-client and other native ClickHouse tools (clickhouse-benchmark, clickhouse-copier);
         - clickhouse-server with other clickhouse-servers for distributed query processing;
         - ClickHouse drivers and applications supporting native protocol
         (this protocol is also informally called as "the TCP protocol");
         See also 'tcp_port_secure' for secure connections.
    -->
    <tcp_port>9000</tcp_port>

    <!-- Compatibility with MySQL protocol.
         ClickHouse will pretend to be MySQL for applications connecting to this port.
    -->
    <mysql_port>9004</mysql_port>

    <!-- Compatibility with PostgreSQL protocol.
         ClickHouse will pretend to be PostgreSQL for applications connecting to this port.
    -->
    <postgresql_port>9005</postgresql_port>

    <!-- HTTP API with TLS (HTTPS).
         You have to configure certificate to enable this interface.
         See the openSSL section below.
    -->
    <https_port>8443</https_port>

    <!-- Native interface with TLS.
         You have to configure certificate to enable this interface.
         See the openSSL section below.
    -->
    <tcp_port_secure>9440</tcp_port_secure>

    <!-- Native interface wrapped with PROXYv1 protocol
         PROXYv1 header sent for every connection.
         ClickHouse will extract information about proxy-forwarded client address from the header.
    -->
    <!-- <tcp_with_proxy_port>9011</tcp_with_proxy_port> -->

    <!-- Port for communication between replicas. Used for data exchange.
         It provides low-level data access between servers.
         This port should not be accessible from untrusted networks.
         See also 'interserver_http_credentials'.
         Data transferred over connections to this port should not go through untrusted networks.
         See also 'interserver_https_port'.
      -->
    <interserver_http_port>9009</interserver_http_port>

    <!-- Port for communication between replicas with TLS.
         You have to configure certificate to enable this interface.
         See the openSSL section below.
         See also 'interserver_http_credentials'.
      -->
    <!-- <interserver_https_port>9010</interserver_https_port> -->

    <!-- Hostname that is used by other replicas to request this server.
         If not specified, than it is determined analogous to 'hostname -f' command.
         This setting could be used to switch replication to another network interface
         (the server may be connected to multiple networks via multiple addresses)
      -->
    <!--
    <interserver_http_host>example.yandex.ru</interserver_http_host>
    -->

    <!-- You can specify credentials for authenthication between replicas.
         This is required when interserver_https_port is accessible from untrusted networks,
         and also recommended to avoid SSRF attacks from possibly compromised services in your network.
      -->
    <!--<interserver_http_credentials>
        <user>interserver</user>
        <password></password>
    </interserver_http_credentials>-->

    <!-- Listen specified address.
         Use :: (wildcard IPv6 address), if you want to accept connections both with IPv4 and IPv6 from everywhere.
         Notes:
         If you open connections from wildcard address, make sure that at least one of the following measures applied:
         - server is protected by firewall and not accessible from untrusted networks;
         - all users are restricted to subset of network addresses (see users.xml);
         - all users have strong passwords, only secure (TLS) interfaces are accessible, or connections are only made via TLS interfaces.
         - users without password have readonly access.
         See also: https://www.shodan.io/search?query=clickhouse
      -->
    <!-- <listen_host>::</listen_host> -->

    <!-- Same for hosts without support for IPv6: -->
    <!-- <listen_host>0.0.0.0</listen_host> -->

    <!-- Default values - try listen localhost on IPv4 and IPv6. -->
    <!--
    <listen_host>::1</listen_host>
    <listen_host>127.0.0.1</listen_host>
    -->

    <listen_host>::</listen_host>
    <listen_host>0.0.0.0</listen_host>
    <listen_try>1</listen_try>

    <!-- Don't exit if IPv6 or IPv4 networks are unavailable while trying to listen. -->
    <!-- <listen_try>0</listen_try> -->

    <!-- Allow multiple servers to listen on the same address:port. This is not recommended.
      -->
    <!-- <listen_reuse_port>0</listen_reuse_port> -->

    <!-- <listen_backlog>4096</listen_backlog> -->

    <max_connections>4096</max_connections>

    <!-- For 'Connection: keep-alive' in HTTP 1.1 -->
    <keep_alive_timeout>3</keep_alive_timeout>

    <!-- gRPC protocol (see src/Server/grpc_protos/clickhouse_grpc.proto for the API) -->
    <!-- <grpc_port>9100</grpc_port> -->
    <grpc>
        <enable_ssl>false</enable_ssl>

        <!-- The following two files are used only if enable_ssl=1 -->
        <ssl_cert_file>/path/to/ssl_cert_file</ssl_cert_file>
        <ssl_key_file>/path/to/ssl_key_file</ssl_key_file>

        <!-- Whether server will request client for a certificate -->
        <ssl_require_client_auth>false</ssl_require_client_auth>

        <!-- The following file is used only if ssl_require_client_auth=1 -->
        <ssl_ca_cert_file>/path/to/ssl_ca_cert_file</ssl_ca_cert_file>

        <!-- Default compression algorithm (applied if client doesn't specify another algorithm, see result_compression in QueryInfo).
             Supported algorithms: none, deflate, gzip, stream_gzip -->
        <compression>deflate</compression>

        <!-- Default compression level (applied if client doesn't specify another level, see result_compression in QueryInfo).
             Supported levels: none, low, medium, high -->
        <compression_level>medium</compression_level>

        <!-- Send/receive message size limits in bytes. -1 means unlimited -->
        <max_send_message_size>-1</max_send_message_size>
        <max_receive_message_size>-1</max_receive_message_size>

        <!-- Enable if you want very detailed logs -->
        <verbose_logs>false</verbose_logs>
    </grpc>

    <!-- Used with https_port and tcp_port_secure. Full ssl options list: https://github.com/ClickHouse-Extras/poco/blob/master/NetSSL_OpenSSL/include/Poco/Net/SSLManager.h#L71 -->
    <openSSL>
        <server> <!-- Used for https server AND secure tcp port -->
            <!-- openssl req -subj "/CN=localhost" -new -newkey rsa:2048 -days 365 -nodes -x509 -keyout /etc/clickhouse-server/server.key -out /etc/clickhouse-server/server.crt -->
            <certificateFile>/etc/clickhouse-server/server.crt</certificateFile>
            <privateKeyFile>/etc/clickhouse-server/server.key</privateKeyFile>
            <!-- dhparams are optional. You can delete the <dhParamsFile> element.
                 To generate dhparams, use the following command:
                  openssl dhparam -out /etc/clickhouse-server/dhparam.pem 4096
                 Only file format with BEGIN DH PARAMETERS is supported.
              -->
            <!-- <dhParamsFile>/etc/clickhouse-server/dhparam.pem</dhParamsFile> -->
            <verificationMode>none</verificationMode>
            <loadDefaultCAFile>true</loadDefaultCAFile>
            <cacheSessions>true</cacheSessions>
            <disableProtocols>sslv2,sslv3</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
        </server>

        <client> <!-- Used for connecting to https dictionary source and secured Zookeeper communication -->
            <loadDefaultCAFile>true</loadDefaultCAFile>
            <cacheSessions>true</cacheSessions>
            <disableProtocols>sslv2,sslv3</disableProtocols>
            <preferServerCiphers>true</preferServerCiphers>
            <!-- Use for self-signed: <verificationMode>none</verificationMode> -->
            <invalidCertificateHandler>
                <!-- Use for self-signed: <name>AcceptCertificateHandler</name> -->
                <name>RejectCertificateHandler</name>
            </invalidCertificateHandler>
        </client>
    </openSSL>

    <!-- Default root page on http[s] server. For example load UI from https://tabix.io/ when opening http://localhost:8123 -->
    <!--
    <http_server_default_response><![CDATA[<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>]]></http_server_default_response>
    -->

    <!-- Maximum number of concurrent queries. -->
    <max_concurrent_queries>100</max_concurrent_queries>

    <!-- Maximum memory usage (resident set size) for server process.
         Zero value or unset means default. Default is "max_server_memory_usage_to_ram_ratio" of available physical RAM.
         If the value is larger than "max_server_memory_usage_to_ram_ratio" of available physical RAM, it will be cut down.
         The constraint is checked on query execution time.
         If a query tries to allocate memory and the current memory usage plus allocation is greater
          than specified threshold, exception will be thrown.
         It is not practical to set this constraint to small values like just a few gigabytes,
          because memory allocator will keep this amount of memory in caches and the server will deny service of queries.
      -->
    <max_server_memory_usage>0</max_server_memory_usage>

    <!-- Maximum number of threads in the Global thread pool.
    This will default to a maximum of 10000 threads if not specified.
    This setting will be useful in scenarios where there are a large number
    of distributed queries that are running concurrently but are idling most
    of the time, in which case a higher number of threads might be required.
    -->

    <max_thread_pool_size>10000</max_thread_pool_size>

    <!-- On memory constrained environments you may have to set this to value larger than 1.
      -->
    <max_server_memory_usage_to_ram_ratio>0.9</max_server_memory_usage_to_ram_ratio>

    <!-- Simple server-wide memory profiler. Collect a stack trace at every peak allocation step (in bytes).
         Data will be stored in system.trace_log table with query_id = empty string.
         Zero means disabled.
      -->
    <total_memory_profiler_step>4194304</total_memory_profiler_step>

    <!-- Collect random allocations and deallocations and write them into system.trace_log with 'MemorySample' trace_type.
         The probability is for every alloc/free regardless to the size of the allocation.
         Note that sampling happens only when the amount of untracked memory exceeds the untracked memory limit,
          which is 4 MiB by default but can be lowered if 'total_memory_profiler_step' is lowered.
         You may want to set 'total_memory_profiler_step' to 1 for extra fine grained sampling.
      -->
    <total_memory_tracker_sample_probability>0</total_memory_tracker_sample_probability>

    <!-- Set limit on number of open files (default: maximum). This setting makes sense on Mac OS X because getrlimit() fails to retrieve
         correct maximum value. -->
    <!-- <max_open_files>262144</max_open_files> -->

    <!-- Size of cache of uncompressed blocks of data, used in tables of MergeTree family.
         In bytes. Cache is single for server. Memory is allocated only on demand.
         Cache is used when 'use_uncompressed_cache' user setting turned on (off by default).
         Uncompressed cache is advantageous only for very short queries and in rare cases.
         Note: uncompressed cache can be pointless for lz4, because memory bandwidth
         is slower than multi-core decompression on some server configurations.
         Enabling it can sometimes paradoxically make queries slower.
      -->
    <uncompressed_cache_size>8589934592</uncompressed_cache_size>

    <!-- Approximate size of mark cache, used in tables of MergeTree family.
         In bytes. Cache is single for server. Memory is allocated only on demand.
         You should not lower this value.
      -->
    <mark_cache_size>5368709120</mark_cache_size>


    <!-- If you enable the `min_bytes_to_use_mmap_io` setting,
         the data in MergeTree tables can be read with mmap to avoid copying from kernel to userspace.
         It makes sense only for large files and helps only if data reside in page cache.
         To avoid frequent open/mmap/munmap/close calls (which are very expensive due to consequent page faults)
         and to reuse mappings from several threads and queries,
         the cache of mapped files is maintained. Its size is the number of mapped regions (usually equal to the number of mapped files).
         The amount of data in mapped files can be monitored
         in system.metrics, system.metric_log by the MMappedFiles, MMappedFileBytes metrics
         and in system.asynchronous_metrics, system.asynchronous_metrics_log by the MMapCacheCells metric,
         and also in system.events, system.processes, system.query_log, system.query_thread_log, system.query_views_log by the
         CreatedReadBufferMMap, CreatedReadBufferMMapFailed, MMappedFileCacheHits, MMappedFileCacheMisses events.
         Note that the amount of data in mapped files does not consume memory directly and is not accounted
         in query or server memory usage - because this memory can be discarded similar to OS page cache.
         The cache is dropped (the files are closed) automatically on removal of old parts in MergeTree,
         also it can be dropped manually by the SYSTEM DROP MMAP CACHE query.
      -->
    <mmap_cache_size>1000</mmap_cache_size>

    <!-- Cache size in bytes for compiled expressions.-->
    <compiled_expression_cache_size>134217728</compiled_expression_cache_size>

    <!-- Cache size in elements for compiled expressions.-->
    <compiled_expression_cache_elements_size>10000</compiled_expression_cache_elements_size>

    <!-- Path to data directory, with trailing slash. -->
    <path>/var/lib/clickhouse/</path>

    <!-- Path to temporary data for processing hard queries. -->
    <tmp_path>/var/lib/clickhouse/tmp/</tmp_path>

    <!-- Policy from the <storage_configuration> for the temporary files.
         If not set <tmp_path> is used, otherwise <tmp_path> is ignored.
         Notes:
         - move_factor              is ignored
         - keep_free_space_bytes    is ignored
         - max_data_part_size_bytes is ignored
         - you must have exactly one volume in that policy
    -->
    <!-- <tmp_policy>tmp</tmp_policy> -->

    <!-- Directory with user provided files that are accessible by 'file' table function. -->
    <user_files_path>/var/lib/clickhouse/user_files/</user_files_path>

    <!-- LDAP server definitions. -->
    <ldap_servers>
        <!-- List LDAP servers with their connection parameters here to later 1) use them as authenticators for dedicated local users,
              who have 'ldap' authentication mechanism specified instead of 'password', or to 2) use them as remote user directories.
             Parameters:
                host - LDAP server hostname or IP, this parameter is mandatory and cannot be empty.
                port - LDAP server port, default is 636 if enable_tls is set to true, 389 otherwise.
                bind_dn - template used to construct the DN to bind to.
                        The resulting DN will be constructed by replacing all '{user_name}' substrings of the template with the actual
                         user name during each authentication attempt.
                user_dn_detection - section with LDAP search parameters for detecting the actual user DN of the bound user.
                        This is mainly used in search filters for further role mapping when the server is Active Directory. The
                         resulting user DN will be used when replacing '{user_dn}' substrings wherever they are allowed. By default,
                         user DN is set equal to bind DN, but once search is performed, it will be updated with to the actual detected
                         user DN value.
                    base_dn - template used to construct the base DN for the LDAP search.
                            The resulting DN will be constructed by replacing all '{user_name}' and '{bind_dn}' substrings
                             of the template with the actual user name and bind DN during the LDAP search.
                    scope - scope of the LDAP search.
                            Accepted values are: 'base', 'one_level', 'children', 'subtree' (the default).
                    search_filter - template used to construct the search filter for the LDAP search.
                            The resulting filter will be constructed by replacing all '{user_name}', '{bind_dn}', and '{base_dn}'
                             substrings of the template with the actual user name, bind DN, and base DN during the LDAP search.
                            Note, that the special characters must be escaped properly in XML.
                verification_cooldown - a period of time, in seconds, after a successful bind attempt, during which a user will be assumed
                         to be successfully authenticated for all consecutive requests without contacting the LDAP server.
                        Specify 0 (the default) to disable caching and force contacting the LDAP server for each authentication request.
                enable_tls - flag to trigger use of secure connection to the LDAP server.
                        Specify 'no' for plain text (ldap://) protocol (not recommended).
                        Specify 'yes' for LDAP over SSL/TLS (ldaps://) protocol (recommended, the default).
                        Specify 'starttls' for legacy StartTLS protocol (plain text (ldap://) protocol, upgraded to TLS).
                tls_minimum_protocol_version - the minimum protocol version of SSL/TLS.
                        Accepted values are: 'ssl2', 'ssl3', 'tls1.0', 'tls1.1', 'tls1.2' (the default).
                tls_require_cert - SSL/TLS peer certificate verification behavior.
                        Accepted values are: 'never', 'allow', 'try', 'demand' (the default).
                tls_cert_file - path to certificate file.
                tls_key_file - path to certificate key file.
                tls_ca_cert_file - path to CA certificate file.
                tls_ca_cert_dir - path to the directory containing CA certificates.
                tls_cipher_suite - allowed cipher suite (in OpenSSL notation).
             Example:
                <my_ldap_server>
                    <host>localhost</host>
                    <port>636</port>
                    <bind_dn>uid={user_name},ou=users,dc=example,dc=com</bind_dn>
                    <verification_cooldown>300</verification_cooldown>
                    <enable_tls>yes</enable_tls>
                    <tls_minimum_protocol_version>tls1.2</tls_minimum_protocol_version>
                    <tls_require_cert>demand</tls_require_cert>
                    <tls_cert_file>/path/to/tls_cert_file</tls_cert_file>
                    <tls_key_file>/path/to/tls_key_file</tls_key_file>
                    <tls_ca_cert_file>/path/to/tls_ca_cert_file</tls_ca_cert_file>
                    <tls_ca_cert_dir>/path/to/tls_ca_cert_dir</tls_ca_cert_dir>
                    <tls_cipher_suite>ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:AES256-GCM-SHA384</tls_cipher_suite>
                </my_ldap_server>
             Example (typical Active Directory with configured user DN detection for further role mapping):
                <my_ad_server>
                    <host>localhost</host>
                    <port>389</port>
                    <bind_dn>EXAMPLE\{user_name}</bind_dn>
                    <user_dn_detection>
                        <base_dn>CN=Users,DC=example,DC=com</base_dn>
                        <search_filter>(&amp;(objectClass=user)(sAMAccountName={user_name}))</search_filter>
                    </user_dn_detection>
                    <enable_tls>no</enable_tls>
                </my_ad_server>
        -->
    </ldap_servers>

    <!-- To enable Kerberos authentication support for HTTP requests (GSS-SPNEGO), for those users who are explicitly configured
          to authenticate via Kerberos, define a single 'kerberos' section here.
         Parameters:
            principal - canonical service principal name, that will be acquired and used when accepting security contexts.
                    This parameter is optional, if omitted, the default principal will be used.
                    This parameter cannot be specified together with 'realm' parameter.
            realm - a realm, that will be used to restrict authentication to only those requests whose initiator's realm matches it.
                    This parameter is optional, if omitted, no additional filtering by realm will be applied.
                    This parameter cannot be specified together with 'principal' parameter.
         Example:
            <kerberos />
         Example:
            <kerberos>
                <principal>HTTP/clickhouse.example.com@EXAMPLE.COM</principal>
            </kerberos>
         Example:
            <kerberos>
                <realm>EXAMPLE.COM</realm>
            </kerberos>
    -->

    <!-- Sources to read users, roles, access rights, profiles of settings, quotas. -->
    <user_directories>
        <users_xml>
            <!-- Path to configuration file with predefined users. -->
            <path>/etc/clickhouse-server/users.xml</path>
        </users_xml>
        <local_directory>
            <!-- Path to folder where users created by SQL commands are stored. -->
            <path>/var/lib/clickhouse/access/</path>
        </local_directory>

        <!-- To add an LDAP server as a remote user directory of users that are not defined locally, define a single 'ldap' section
              with the following parameters:
                server - one of LDAP server names defined in 'ldap_servers' config section above.
                        This parameter is mandatory and cannot be empty.
                roles - section with a list of locally defined roles that will be assigned to each user retrieved from the LDAP server.
                        If no roles are specified here or assigned during role mapping (below), user will not be able to perform any
                         actions after authentication.
                role_mapping - section with LDAP search parameters and mapping rules.
                        When a user authenticates, while still bound to LDAP, an LDAP search is performed using search_filter and the
                         name of the logged in user. For each entry found during that search, the value of the specified attribute is
                         extracted. For each attribute value that has the specified prefix, the prefix is removed, and the rest of the
                         value becomes the name of a local role defined in ClickHouse, which is expected to be created beforehand by
                         CREATE ROLE com
Download .txt
gitextract_uixxn39k/

├── .config/
│   ├── .cprc.json
│   ├── .prettierrc.js
│   ├── Dockerfile
│   ├── README.md
│   ├── bundler/
│   │   └── externals.ts
│   ├── docker-compose-base.yaml
│   ├── entrypoint.sh
│   ├── eslint.config.mjs
│   ├── jest/
│   │   ├── mocks/
│   │   │   └── react-inlinesvg.tsx
│   │   └── utils.js
│   ├── jest-setup.js
│   ├── jest.config.js
│   ├── supervisord/
│   │   └── supervisord.conf
│   ├── tsconfig.json
│   ├── types/
│   │   ├── bundler-rules.d.ts
│   │   ├── custom.d.ts
│   │   ├── setupTests.d.ts
│   │   └── webpack-plugins.d.ts
│   └── webpack/
│       ├── BuildModeWebpackPlugin.ts
│       ├── constants.ts
│       ├── utils.ts
│       └── webpack.config.ts
├── .cprc.json
├── .cursor/
│   └── rules/
│       └── word-list.mdc
├── .github/
│   ├── CODEOWNERS
│   ├── ISSUE_TEMPLATE/
│   │   ├── 1-bug_report.md
│   │   └── config.yml
│   ├── issue_commands.json
│   ├── pull_request_template.md
│   ├── release.yml
│   ├── renovate.json
│   ├── workflows/
│   │   ├── cron.yml
│   │   ├── detect-breaking-changes.yml
│   │   ├── integration.yml
│   │   ├── issue_commands.yml
│   │   ├── publish.yml
│   │   ├── push.yml
│   │   └── stale.yml
│   └── zizmor.yml
├── .gitignore
├── .nvmrc
├── .prettierrc.js
├── .vscode/
│   ├── launch.json
│   └── settings.json
├── CHANGELOG.md
├── CONTRIBUTING.md
├── DEV_GUIDE.md
├── LICENSE
├── Magefile.go
├── README.md
├── config/
│   ├── admin.xml
│   ├── config-preprocessed.xml
│   ├── config.xml
│   ├── custom.xml
│   ├── server.crt
│   ├── server.key
│   └── users.xml
├── config-secure/
│   ├── config.xml
│   ├── my-own-ca.crt
│   ├── my-own-ca.key
│   ├── my-own-ca.srl
│   ├── server.crt
│   ├── server.csr
│   ├── server.ext
│   ├── server.key
│   └── users.xml
├── cspell.config.json
├── docker-compose.yml
├── docs/
│   ├── Makefile
│   ├── docs.mk
│   ├── make-docs
│   ├── sources/
│   │   ├── _index.md
│   │   ├── alerting.md
│   │   ├── annotations.md
│   │   ├── configure.md
│   │   ├── query-editor.md
│   │   ├── template-variables.md
│   │   └── troubleshooting.md
│   └── variables.mk
├── eslint.config.mjs
├── gen-db-dashboards.js
├── go.mod
├── go.sum
├── jest-runner-serial.js
├── jest-setup.js
├── jest.config.js
├── otel-semconv.yaml
├── package.json
├── pkg/
│   ├── converters/
│   │   ├── converters.go
│   │   └── converters_test.go
│   ├── macros/
│   │   ├── macros.go
│   │   └── macros_test.go
│   ├── main.go
│   └── plugin/
│       ├── connection_error.go
│       ├── connection_error_test.go
│       ├── datasource.go
│       ├── driver.go
│       ├── driver_integration_test.go
│       ├── driver_test.go
│       ├── errors.go
│       ├── schema.go
│       ├── schema_test.go
│       ├── schemacache/
│       │   ├── cache.go
│       │   ├── cache_bench_test.go
│       │   └── cache_test.go
│       ├── settings.go
│       └── settings_test.go
├── playwright.config.ts
├── provisioning/
│   └── datasources/
│       └── clickhouse.yml
├── scripts/
│   ├── ca-cert.sh
│   ├── ca.ext
│   ├── ca.sh
│   └── certs.sh
├── src/
│   ├── __mocks__/
│   │   ├── ConfigEditor.ts
│   │   └── datasource.ts
│   ├── ch-parser/
│   │   ├── helpers.ts
│   │   ├── lexer.ts
│   │   ├── parser.ts
│   │   ├── pluginMacros.ts
│   │   └── types.ts
│   ├── components/
│   │   ├── Divider.tsx
│   │   ├── LogContextPanel.test.tsx
│   │   ├── LogsContextPanel.tsx
│   │   ├── QueryToolbox.tsx
│   │   ├── SqlEditor.test.tsx
│   │   ├── SqlEditor.tsx
│   │   ├── configEditor/
│   │   │   ├── AliasTableConfig.test.tsx
│   │   │   ├── AliasTableConfig.tsx
│   │   │   ├── DefaultDatabaseTableConfig.test.tsx
│   │   │   ├── DefaultDatabaseTableConfig.tsx
│   │   │   ├── HttpHeadersConfig.test.tsx
│   │   │   ├── HttpHeadersConfig.tsx
│   │   │   ├── LabeledInput.test.tsx
│   │   │   ├── LabeledInput.tsx
│   │   │   ├── LogsConfig.test.tsx
│   │   │   ├── LogsConfig.tsx
│   │   │   ├── QuerySettingsConfig.test.tsx
│   │   │   ├── QuerySettingsConfig.tsx
│   │   │   ├── TracesConfig.test.tsx
│   │   │   └── TracesConfig.tsx
│   │   ├── experimental/
│   │   │   └── ConfigSection/
│   │   │       ├── ConfigSection.test.tsx
│   │   │       ├── ConfigSection.tsx
│   │   │       ├── ConfigSubSection.test.tsx
│   │   │       ├── ConfigSubSection.tsx
│   │   │       ├── DataSourceDescription.test.tsx
│   │   │       ├── DataSourceDescription.tsx
│   │   │       ├── GenericConfigSection.test.tsx
│   │   │       ├── GenericConfigSection.tsx
│   │   │       └── index.ts
│   │   ├── queryBuilder/
│   │   │   ├── AggregateEditor.test.tsx
│   │   │   ├── AggregateEditor.tsx
│   │   │   ├── ColumnRolesHelp.tsx
│   │   │   ├── ColumnSelect.test.tsx
│   │   │   ├── ColumnSelect.tsx
│   │   │   ├── ColumnsEditor.test.tsx
│   │   │   ├── ColumnsEditor.tsx
│   │   │   ├── DatabaseTableSelect.test.tsx
│   │   │   ├── DatabaseTableSelect.tsx
│   │   │   ├── DurationUnitSelect.tsx
│   │   │   ├── EditorTypeSwitcher.test.tsx
│   │   │   ├── EditorTypeSwitcher.tsx
│   │   │   ├── FilterEditor.test.tsx
│   │   │   ├── FilterEditor.tsx
│   │   │   ├── GroupByEditor.test.tsx
│   │   │   ├── GroupByEditor.tsx
│   │   │   ├── LimitEditor.test.tsx
│   │   │   ├── LimitEditor.tsx
│   │   │   ├── ModeSwitch.test.tsx
│   │   │   ├── ModeSwitch.tsx
│   │   │   ├── OrderByEditor.test.tsx
│   │   │   ├── OrderByEditor.tsx
│   │   │   ├── OtelVersionSelect.test.tsx
│   │   │   ├── OtelVersionSelect.tsx
│   │   │   ├── QueryBuilder.test.tsx
│   │   │   ├── QueryBuilder.tsx
│   │   │   ├── QueryTypeSwitcher.test.tsx
│   │   │   ├── QueryTypeSwitcher.tsx
│   │   │   ├── SqlPreview.test.tsx
│   │   │   ├── SqlPreview.tsx
│   │   │   ├── Switch.test.tsx
│   │   │   ├── Switch.tsx
│   │   │   ├── TraceIdInput.test.tsx
│   │   │   ├── TraceIdInput.tsx
│   │   │   ├── utils.test.ts
│   │   │   ├── utils.ts
│   │   │   └── views/
│   │   │       ├── LogsQueryBuilder.tsx
│   │   │       ├── TableQueryBuilder.tsx
│   │   │       ├── TimeSeriesQueryBuilder.tsx
│   │   │       ├── TraceQueryBuilder.tsx
│   │   │       ├── logsQueryBuilderHooks.test.ts
│   │   │       ├── logsQueryBuilderHooks.ts
│   │   │       ├── timeSeriesQueryBuilderHooks.test.ts
│   │   │       ├── timeSeriesQueryBuilderHooks.ts
│   │   │       ├── traceQueryBuilderHooks.test.ts
│   │   │       └── traceQueryBuilderHooks.ts
│   │   ├── sqlProvider.test.ts
│   │   ├── sqlProvider.ts
│   │   ├── suggestions.test.ts
│   │   ├── suggestions.ts
│   │   └── ui/
│   │       └── CertificationKey.tsx
│   ├── dashboards/
│   │   ├── cluster-analysis.json
│   │   ├── data-analysis.json
│   │   ├── opentelemetry-clickhouse.json
│   │   ├── query-analysis.json
│   │   └── system-dashboards.json
│   ├── data/
│   │   ├── CHDatasource.test.ts
│   │   ├── CHDatasource.ts
│   │   ├── adHocFilter.test.ts
│   │   ├── adHocFilter.ts
│   │   ├── ast.test.ts
│   │   ├── ast.ts
│   │   ├── columnFilters.test.ts
│   │   ├── columnFilters.ts
│   │   ├── logs.test.ts
│   │   ├── logs.ts
│   │   ├── migration.test.ts
│   │   ├── migration.ts
│   │   ├── sqlGenerator.test.ts
│   │   ├── sqlGenerator.ts
│   │   ├── utils.test.ts
│   │   ├── utils.ts
│   │   ├── validate.test.ts
│   │   └── validate.ts
│   ├── hooks/
│   │   ├── useBuilderOptionChanges.test.ts
│   │   ├── useBuilderOptionChanges.ts
│   │   ├── useBuilderOptionsState.test.ts
│   │   ├── useBuilderOptionsState.ts
│   │   ├── useColumns.test.ts
│   │   ├── useColumns.ts
│   │   ├── useDatabases.test.ts
│   │   ├── useDatabases.ts
│   │   ├── useIsNewQuery.test.ts
│   │   ├── useIsNewQuery.ts
│   │   ├── useSchemaSuggestionsProvider.ts
│   │   ├── useTables.test.ts
│   │   ├── useTables.ts
│   │   ├── useUniqueMapKeys.test.ts
│   │   └── useUniqueMapKeys.ts
│   ├── labels.ts
│   ├── module.ts
│   ├── otel.ts
│   ├── plugin.json
│   ├── selectors.ts
│   ├── styles.ts
│   ├── test/
│   │   └── setupTests.ts
│   ├── tracking.test.ts
│   ├── tracking.ts
│   ├── types/
│   │   ├── config.ts
│   │   ├── queryBuilder.ts
│   │   └── sql.ts
│   ├── utils/
│   │   ├── version.test.ts
│   │   └── version.ts
│   └── views/
│       ├── CHConfigEditor.test.tsx
│       ├── CHConfigEditor.tsx
│       ├── CHConfigEditorHooks.test.ts
│       ├── CHConfigEditorHooks.ts
│       ├── CHQueryEditor.test.tsx
│       ├── CHQueryEditor.tsx
│       ├── config-v2/
│       │   ├── AdditionalSettingsSection.tsx
│       │   ├── AliasTableConfigV2.test.tsx
│       │   ├── AliasTableConfigV2.tsx
│       │   ├── CHConfigEditor.test.tsx
│       │   ├── CHConfigEditor.tsx
│       │   ├── DatabaseCredentialsSection.test.tsx
│       │   ├── DatabaseCredentialsSection.tsx
│       │   ├── HttpHeadersConfigV2.test.tsx
│       │   ├── HttpHeadersConfigV2.tsx
│       │   ├── HttpProtocolSettingsSection.test.tsx
│       │   ├── HttpProtocolSettingsSection.tsx
│       │   ├── LeftSidebar.test.tsx
│       │   ├── LeftSidebar.tsx
│       │   ├── ServerAndEncryptionSection.test.tsx
│       │   ├── ServerAndEncryptionSection.tsx
│       │   ├── TLSSSLSettingsSection.test.tsx
│       │   ├── TLSSSLSettingsSection.tsx
│       │   ├── constants.ts
│       │   ├── helpers.ts
│       │   ├── labelsV2.ts
│       │   └── tracking.ts
│       └── trackingV1.ts
├── tests/
│   ├── benchmarks/
│   │   ├── README.md
│   │   └── trace-id-query.sh
│   ├── e2e/
│   │   ├── adhocRegexFilter.spec.ts
│   │   ├── columnRoles.spec.ts
│   │   ├── configEditor.spec.ts
│   │   ├── fixtures/
│   │   │   ├── seed.sql
│   │   │   └── trace_spans.sql
│   │   ├── queryEditor.spec.ts
│   │   ├── sqlAutocomplete.spec.ts
│   │   ├── sqlValidation.spec.ts
│   │   └── traceLimit.spec.ts
│   └── fixtures/
│       └── property-prices.sql
└── tsconfig.json
Download .txt
SYMBOL INDEX (766 symbols across 117 files)

FILE: .config/bundler/externals.ts
  type ExternalsType (line 3) | type ExternalsType = Configuration['externals'];

FILE: .config/jest/mocks/react-inlinesvg.tsx
  type Callback (line 7) | type Callback = (...args: any[]) => void;
  type StorageItem (line 9) | interface StorageItem {
  constant SVG_FILE_NAME_REGEX (line 17) | const SVG_FILE_NAME_REGEX = /(.+)\/(.+)\.svg$/;

FILE: .config/types/webpack-plugins.d.ts
  type ReplaceRule (line 4) | interface ReplaceRule {
  type ReplaceOption (line 9) | interface ReplaceOption {
  class ReplaceInFilePlugin (line 16) | class ReplaceInFilePlugin extends Plugin {
  type Options (line 29) | interface Options extends Pick<ServerOptions, 'cert' | 'key' | 'pfx'> {
  class LiveReloadPlugin (line 68) | class LiveReloadPlugin extends Plugin {

FILE: .config/webpack/BuildModeWebpackPlugin.ts
  constant PLUGIN_NAME (line 3) | const PLUGIN_NAME = 'BuildModeWebpack';
  class BuildModeWebpackPlugin (line 5) | class BuildModeWebpackPlugin {
    method apply (line 6) | apply(compiler: webpack.Compiler) {

FILE: .config/webpack/constants.ts
  constant SOURCE_DIR (line 1) | const SOURCE_DIR = 'src';
  constant DIST_DIR (line 2) | const DIST_DIR = 'dist';

FILE: .config/webpack/utils.ts
  function isWSL (line 8) | function isWSL() {
  function loadJson (line 24) | function loadJson(path: string) {
  function getPackageJson (line 29) | function getPackageJson() {
  function getPluginJson (line 33) | function getPluginJson() {
  function getCPConfigVersion (line 37) | function getCPConfigVersion() {
  function hasReadme (line 42) | function hasReadme() {
  function getEntries (line 48) | async function getEntries() {

FILE: .config/webpack/webpack.config.ts
  type Env (line 39) | type Env = {

FILE: Magefile.go
  function Hello (line 12) | func Hello() {

FILE: gen-db-dashboards.js
  constant OUTPUT_FILE (line 8) | const OUTPUT_FILE = './src/dashboards/system-dashboards.json';
  constant CLICKHOUSE_ADDRESS (line 9) | const CLICKHOUSE_ADDRESS = 'localhost:8123';
  function fetchDashboardsFromClickHouse (line 11) | async function fetchDashboardsFromClickHouse() {
  function generatePanels (line 31) | function generatePanels(clickHouseDashboards) {
  function generateDashboard (line 57) | function generateDashboard(panels) {
  function preprocessQuery (line 132) | function preprocessQuery(rawQuery) {
  function generatePanel (line 146) | function generatePanel(id, name, rawQuery, width, height, x, y) {
  function generateRowPanel (line 256) | function generateRowPanel(rowName, positionY) {
  function main (line 272) | async function main() {

FILE: jest-runner-serial.js
  class SerialJestRunner (line 3) | class SerialJestRunner extends JestRunner {
    method constructor (line 4) | constructor(...args) {

FILE: pkg/converters/converters.go
  type Converter (line 20) | type Converter struct
  function ClickHouseConverters (line 373) | func ClickHouseConverters() []sqlutil.Converter {
  function GetConverter (line 382) | func GetConverter(columnType string) sqlutil.Converter {
  constant lowCardinalityPrefix (line 400) | lowCardinalityPrefix = "LowCardinality("
  constant lowCardinalitySuffix (line 401) | lowCardinalitySuffix = ")"
  function extractLowCardinalityType (line 405) | func extractLowCardinalityType(columnType string) (string, bool) {
  function findConverterWithRegex (line 414) | func findConverterWithRegex(columnType string) sqlutil.Converter {
  function createConverter (line 424) | func createConverter(converter Converter) sqlutil.Converter {
  function jsonConverter (line 441) | func jsonConverter(in any) (any, error) {
  function defaultConvert (line 469) | func defaultConvert(in interface{}) (interface{}, error) {
  function decimalConvert (line 491) | func decimalConvert(in interface{}) (interface{}, error) {
  function decimalNullConvert (line 503) | func decimalNullConvert(in interface{}) (interface{}, error) {
  function bigIntConvert (line 518) | func bigIntConvert(in interface{}) (interface{}, error) {
  function bigIntNullableConvert (line 530) | func bigIntNullableConvert(in interface{}) (interface{}, error) {
  function ipConverter (line 545) | func ipConverter(in interface{}) (interface{}, error) {
  function ipNullConverter (line 560) | func ipNullConverter(in interface{}) (interface{}, error) {
  function pointConverter (line 575) | func pointConverter(in interface{}) (interface{}, error) {

FILE: pkg/converters/converters_test.go
  function TestDate (line 18) | func TestDate(t *testing.T) {
  function TestNullableDate (line 29) | func TestNullableDate(t *testing.T) {
  function TestNullableDateShouldBeNil (line 41) | func TestNullableDateShouldBeNil(t *testing.T) {
  function TestNullableDecimal (line 50) | func TestNullableDecimal(t *testing.T) {
  function TestNullableDecimalShouldBeNull (line 61) | func TestNullableDecimalShouldBeNull(t *testing.T) {
  function TestDecimal (line 70) | func TestDecimal(t *testing.T) {
  function TestNullableString (line 80) | func TestNullableString(t *testing.T) {
  function TestEnum8 (line 89) | func TestEnum8(t *testing.T) {
  function TestEnum16 (line 99) | func TestEnum16(t *testing.T) {
  function TestNullableEnum8 (line 109) | func TestNullableEnum8(t *testing.T) {
  function TestNullableEnum8ShouldBeNil (line 120) | func TestNullableEnum8ShouldBeNil(t *testing.T) {
  function TestNullableEnum16 (line 130) | func TestNullableEnum16(t *testing.T) {
  function TestNullableEnum16ShouldBeNil (line 141) | func TestNullableEnum16ShouldBeNil(t *testing.T) {
  function TestBool (line 151) | func TestBool(t *testing.T) {
  function TestNullableBool (line 160) | func TestNullableBool(t *testing.T) {
  function TestFloat64 (line 169) | func TestFloat64(t *testing.T) {
  function TestNullableFloat64 (line 178) | func TestNullableFloat64(t *testing.T) {
  function TestFloat32 (line 187) | func TestFloat32(t *testing.T) {
  function TestInt64 (line 196) | func TestInt64(t *testing.T) {
  function TestNullableInt64 (line 205) | func TestNullableInt64(t *testing.T) {
  function TestInt32 (line 214) | func TestInt32(t *testing.T) {
  function TestNullableInt32 (line 223) | func TestNullableInt32(t *testing.T) {
  function TestInt8 (line 232) | func TestInt8(t *testing.T) {
  function TestNullableInt8 (line 241) | func TestNullableInt8(t *testing.T) {
  function TestInt16 (line 250) | func TestInt16(t *testing.T) {
  function TestNullableInt16 (line 259) | func TestNullableInt16(t *testing.T) {
  function TestUInt8 (line 268) | func TestUInt8(t *testing.T) {
  function TestNullableUInt8 (line 277) | func TestNullableUInt8(t *testing.T) {
  function TestNullableUInt8ShouldBeNil (line 287) | func TestNullableUInt8ShouldBeNil(t *testing.T) {
  function TestUInt16 (line 297) | func TestUInt16(t *testing.T) {
  function TestNullableUInt16 (line 307) | func TestNullableUInt16(t *testing.T) {
  function TestNullableUInt16ShouldBeNil (line 317) | func TestNullableUInt16ShouldBeNil(t *testing.T) {
  function TestUInt32 (line 327) | func TestUInt32(t *testing.T) {
  function TestNullableUInt32 (line 337) | func TestNullableUInt32(t *testing.T) {
  function TestNullableUInt32ShouldBeNil (line 347) | func TestNullableUInt32ShouldBeNil(t *testing.T) {
  function TestUInt64 (line 357) | func TestUInt64(t *testing.T) {
  function TestNullableUInt64 (line 367) | func TestNullableUInt64(t *testing.T) {
  function TestNullableUInt64ShouldBeNil (line 377) | func TestNullableUInt64ShouldBeNil(t *testing.T) {
  function TestInt128 (line 387) | func TestInt128(t *testing.T) {
  function TestNullableInt128 (line 397) | func TestNullableInt128(t *testing.T) {
  function TestNullableInt128ShouldBeNil (line 408) | func TestNullableInt128ShouldBeNil(t *testing.T) {
  function TestInt256 (line 418) | func TestInt256(t *testing.T) {
  function TestNullableInt256 (line 428) | func TestNullableInt256(t *testing.T) {
  function TestNullableInt256ShouldBeNil (line 439) | func TestNullableInt256ShouldBeNil(t *testing.T) {
  function TestUInt128 (line 449) | func TestUInt128(t *testing.T) {
  function TestNullableUInt128 (line 459) | func TestNullableUInt128(t *testing.T) {
  function TestNullableUInt128ShouldBeNil (line 470) | func TestNullableUInt128ShouldBeNil(t *testing.T) {
  function TestUInt256 (line 480) | func TestUInt256(t *testing.T) {
  function TestNullableUInt256 (line 490) | func TestNullableUInt256(t *testing.T) {
  function TestNullableUInt256ShouldBeNil (line 501) | func TestNullableUInt256ShouldBeNil(t *testing.T) {
  function toJson (line 511) | func toJson(obj interface{}) (json.RawMessage, error) {
  function TestTuple (line 524) | func TestTuple(t *testing.T) {
  function TestNested (line 539) | func TestNested(t *testing.T) {
  function TestMap (line 556) | func TestMap(t *testing.T) {
  function TestJSONObject (line 571) | func TestJSONObject(t *testing.T) {
  function TestJSONString (line 583) | func TestJSONString(t *testing.T) {
  function TestNullableFixedString (line 593) | func TestNullableFixedString(t *testing.T) {
  function TestArray (line 601) | func TestArray(t *testing.T) {
  function TestIPv4 (line 611) | func TestIPv4(t *testing.T) {
  function TestIPv6 (line 619) | func TestIPv6(t *testing.T) {
  function TestNullableIPv4 (line 627) | func TestNullableIPv4(t *testing.T) {
  function TestNullableIPv4ShouldBeNull (line 637) | func TestNullableIPv4ShouldBeNull(t *testing.T) {
  function TestNullableIPv6 (line 645) | func TestNullableIPv6(t *testing.T) {
  function TestNullableIPv6ShouldBeNull (line 655) | func TestNullableIPv6ShouldBeNull(t *testing.T) {
  function TestSimpleAggregateFunction (line 663) | func TestSimpleAggregateFunction(t *testing.T) {
  function TestPoint (line 673) | func TestPoint(t *testing.T) {
  function TestLowCardinality (line 683) | func TestLowCardinality(t *testing.T) {
  function TestLowCardinalityNullable (line 691) | func TestLowCardinalityNullable(t *testing.T) {
  function TestExtractLowCardinality (line 699) | func TestExtractLowCardinality(t *testing.T) {

FILE: pkg/macros/macros.go
  function timeToDate (line 16) | func timeToDate(t time.Time) string {
  function timeToDateTime (line 21) | func timeToDateTime(t time.Time) string {
  function timeToDateTime64 (line 26) | func timeToDateTime64(t time.Time) string {
  function FromTimeFilter (line 31) | func FromTimeFilter(query *sqlutil.Query, args []string) (string, error) {
  function ToTimeFilter (line 36) | func ToTimeFilter(query *sqlutil.Query, args []string) (string, error) {
  function FromTimeFilterMs (line 41) | func FromTimeFilterMs(query *sqlutil.Query, args []string) (string, erro...
  function ToTimeFilterMs (line 46) | func ToTimeFilterMs(query *sqlutil.Query, args []string) (string, error) {
  function TimeFilter (line 50) | func TimeFilter(query *sqlutil.Query, args []string) (string, error) {
  function TimeFilterMs (line 64) | func TimeFilterMs(query *sqlutil.Query, args []string) (string, error) {
  function DateFilter (line 78) | func DateFilter(query *sqlutil.Query, args []string) (string, error) {
  function DateTimeFilter (line 91) | func DateTimeFilter(query *sqlutil.Query, args []string) (string, error) {
  function TimeInterval (line 107) | func TimeInterval(query *sqlutil.Query, args []string) (string, error) {
  function TimeIntervalMs (line 116) | func TimeIntervalMs(query *sqlutil.Query, args []string) (string, error) {
  function IntervalSeconds (line 125) | func IntervalSeconds(query *sqlutil.Query, args []string) (string, error) {
  function RemoveQuotesInArgs (line 131) | func RemoveQuotesInArgs(args []string) []string {
  function IsValidComparisonPredicates (line 144) | func IsValidComparisonPredicates(comparison_predicates string) bool {

FILE: pkg/macros/macros_test.go
  type ClickhouseDriver (line 15) | type ClickhouseDriver struct
    method Macros (line 23) | func (h *ClickhouseDriver) Macros() sqlds.Macros {
  type MockDB (line 19) | type MockDB struct
  function TestTimeToDate (line 27) | func TestTimeToDate(t *testing.T) {
  function TestTimeToDateTime (line 38) | func TestTimeToDateTime(t *testing.T) {
  function TestTimeToDateTime64 (line 49) | func TestTimeToDateTime64(t *testing.T) {
  function TestMacroFromTimeFilter (line 60) | func TestMacroFromTimeFilter(t *testing.T) {
  function TestMacroToTimeFilter (line 92) | func TestMacroToTimeFilter(t *testing.T) {
  function TestMacroFromTimeFilterMs (line 124) | func TestMacroFromTimeFilterMs(t *testing.T) {
  function TestMacroToTimeFilterMs (line 156) | func TestMacroToTimeFilterMs(t *testing.T) {
  function TestMacroDateFilter (line 188) | func TestMacroDateFilter(t *testing.T) {
  function TestMacroDateTimeFilter (line 202) | func TestMacroDateTimeFilter(t *testing.T) {
  function TestMacroTimeInterval (line 216) | func TestMacroTimeInterval(t *testing.T) {
  function TestMacroTimeIntervalMs (line 226) | func TestMacroTimeIntervalMs(t *testing.T) {
  function TestMacroIntervalSeconds (line 236) | func TestMacroIntervalSeconds(t *testing.T) {
  function TestInterpolate (line 247) | func TestInterpolate(t *testing.T) {

FILE: pkg/main.go
  function main (line 11) | func main() {

FILE: pkg/plugin/connection_error.go
  type ConnectionErrorCategory (line 15) | type ConnectionErrorCategory
  constant ConnectionErrorCategoryAuth (line 18) | ConnectionErrorCategoryAuth    ConnectionErrorCategory = "auth"
  constant ConnectionErrorCategoryNetwork (line 19) | ConnectionErrorCategoryNetwork ConnectionErrorCategory = "network"
  constant ConnectionErrorCategoryTLS (line 20) | ConnectionErrorCategoryTLS     ConnectionErrorCategory = "tls"
  constant ConnectionErrorCategoryTimeout (line 21) | ConnectionErrorCategoryTimeout ConnectionErrorCategory = "timeout"
  constant ConnectionErrorCategoryConfig (line 22) | ConnectionErrorCategoryConfig  ConnectionErrorCategory = "config"
  constant ConnectionErrorCategoryServer (line 23) | ConnectionErrorCategoryServer  ConnectionErrorCategory = "server"
  constant ConnectionErrorCategoryUnknown (line 24) | ConnectionErrorCategoryUnknown ConnectionErrorCategory = "unknown"
  function httpStatusCode (line 47) | func httpStatusCode(errStr string) int {
  function CategorizeConnectionError (line 67) | func CategorizeConnectionError(err error) ConnectionErrorCategory {

FILE: pkg/plugin/connection_error_test.go
  function TestCategorizeConnectionError (line 16) | func TestCategorizeConnectionError(t *testing.T) {

FILE: pkg/plugin/datasource.go
  type clickhouseInstance (line 16) | type clickhouseInstance struct
    method Dispose (line 21) | func (i *clickhouseInstance) Dispose() {
  function NewDatasource (line 28) | func NewDatasource(ctx context.Context, settings backend.DataSourceInsta...

FILE: pkg/plugin/driver.go
  type grafanaHeadersKeyType (line 33) | type grafanaHeadersKeyType struct
  type grafanaHeaders (line 37) | type grafanaHeaders struct
  type Clickhouse (line 44) | type Clickhouse struct
    method Connect (line 151) | func (h *Clickhouse) Connect(
    method Converters (line 294) | func (h *Clickhouse) Converters() []sqlutil.Converter {
    method Macros (line 299) | func (h *Clickhouse) Macros() sqlds.Macros {
    method MutateQueryError (line 304) | func (h *Clickhouse) MutateQueryError(err error) backend.ErrorWithSour...
    method Settings (line 357) | func (h *Clickhouse) Settings(ctx context.Context, config backend.Data...
    method MutateQueryData (line 377) | func (h *Clickhouse) MutateQueryData(
    method MutateQuery (line 470) | func (h *Clickhouse) MutateQuery(ctx context.Context, req backend.Data...
    method MutateResponse (line 523) | func (h *Clickhouse) MutateResponse(ctx context.Context, res data.Fram...
  function getTLSConfig (line 50) | func getTLSConfig(settings Settings) (*tls.Config, error) {
  function getPDCDialContext (line 75) | func getPDCDialContext(settings Settings) (func(context.Context, string)...
  function getClientInfoProducts (line 97) | func getClientInfoProducts(ctx context.Context) (products []struct{ Name...
  function CheckMinServerVersion (line 117) | func CheckMinServerVersion(conn *sql.DB, major, minor, patch uint64) (bo...
  function wrapCategorizedConnectionError (line 144) | func wrapCategorizedConnectionError(err error) error {
  function containsClickHouseException (line 314) | func containsClickHouseException(err error) bool {
  function injectGrafanaUserHeader (line 403) | func injectGrafanaUserHeader(ctx context.Context, req *backend.QueryData...
  function preprocessGrafanaSQL (line 421) | func preprocessGrafanaSQL(req *backend.QueryDataRequest) *backend.QueryD...
  function shouldConvertFields (line 548) | func shouldConvertFields(visType data.VisType) bool {
  function convertNullableJSONFields (line 553) | func convertNullableJSONFields(frame *data.Frame) error {
  function convertFieldToString (line 573) | func convertFieldToString(field *data.Field) (*data.Field, error) {
  function extractForwardedHeadersFromMessage (line 595) | func extractForwardedHeadersFromMessage(message json.RawMessage) (map[st...
  function mergeOpenTelemetryLabels (line 639) | func mergeOpenTelemetryLabels(frame *data.Frame) error {
  function assignFlattenedPath (line 714) | func assignFlattenedPath(flatMap map[string]any, pathPrefix, pathKey str...

FILE: pkg/plugin/driver_integration_test.go
  constant defaultClickHouseVersion (line 38) | defaultClickHouseVersion = "latest"
  function GetClickHouseTestVersion (line 40) | func GetClickHouseTestVersion() string {
  function GetEnv (line 44) | func GetEnv(key, fallback string) string {
  function TestMain (line 51) | func TestMain(m *testing.M) {
  function TestConnect (line 141) | func TestConnect(t *testing.T) {
  function TestHTTPConnect (line 174) | func TestHTTPConnect(t *testing.T) {
  function getEnv (line 197) | func getEnv(key, fallback string) string {
  function setupConnection (line 204) | func setupConnection(t *testing.T, protocol clickhouse_sql.Protocol, set...
  function setupTest (line 235) | func setupTest(t *testing.T, ddl string, protocol clickhouse_sql.Protoco...
  function insertData (line 247) | func insertData(t *testing.T, conn *sql.DB, data ...interface{}) {
  function toJson (line 259) | func toJson(obj interface{}) (json.RawMessage, error) {
  function checkFieldValue (line 272) | func checkFieldValue(t *testing.T, field *data.Field, expected ...interf...
  function checkRows (line 297) | func checkRows(t *testing.T, conn *sql.DB, rowLimit int64, expectedValue...
  function TestConvertUInt8 (line 306) | func TestConvertUInt8(t *testing.T) {
  function TestConvertUInt16 (line 318) | func TestConvertUInt16(t *testing.T) {
  function TestConvertUInt32 (line 329) | func TestConvertUInt32(t *testing.T) {
  function TestConvertUInt64 (line 340) | func TestConvertUInt64(t *testing.T) {
  function TestConvertNullableUInt8 (line 351) | func TestConvertNullableUInt8(t *testing.T) {
  function TestConvertNullableUInt16 (line 363) | func TestConvertNullableUInt16(t *testing.T) {
  function TestConvertNullableUInt32 (line 375) | func TestConvertNullableUInt32(t *testing.T) {
  function TestConvertNullableUInt64 (line 387) | func TestConvertNullableUInt64(t *testing.T) {
  function TestConvertNullableInt8 (line 399) | func TestConvertNullableInt8(t *testing.T) {
  function TestConvertNullableInt16 (line 411) | func TestConvertNullableInt16(t *testing.T) {
  function TestConvertNullableInt32 (line 423) | func TestConvertNullableInt32(t *testing.T) {
  function TestConvertNullableInt64 (line 435) | func TestConvertNullableInt64(t *testing.T) {
  function TestConvertInt8 (line 447) | func TestConvertInt8(t *testing.T) {
  function TestConvertInt16 (line 459) | func TestConvertInt16(t *testing.T) {
  function TestConvertInt32 (line 470) | func TestConvertInt32(t *testing.T) {
  function TestConvertInt64 (line 481) | func TestConvertInt64(t *testing.T) {
  function TestConvertFloat32 (line 492) | func TestConvertFloat32(t *testing.T) {
  function TestConvertFloat64 (line 503) | func TestConvertFloat64(t *testing.T) {
  function TestConvertNullableFloat32 (line 514) | func TestConvertNullableFloat32(t *testing.T) {
  function TestConvertNullableFloat64 (line 526) | func TestConvertNullableFloat64(t *testing.T) {
  function TestConvertBool (line 538) | func TestConvertBool(t *testing.T) {
  function TestConvertNullableBool (line 558) | func TestConvertNullableBool(t *testing.T) {
  function TestConvertInt128 (line 580) | func TestConvertInt128(t *testing.T) {
  function TestConvertNullableInt128 (line 591) | func TestConvertNullableInt128(t *testing.T) {
  function TestConvertInt256 (line 603) | func TestConvertInt256(t *testing.T) {
  function TestConvertNullableInt256 (line 614) | func TestConvertNullableInt256(t *testing.T) {
  function TestConvertUInt128 (line 626) | func TestConvertUInt128(t *testing.T) {
  function TestConvertNullableUInt128 (line 637) | func TestConvertNullableUInt128(t *testing.T) {
  function TestConvertUInt256 (line 649) | func TestConvertUInt256(t *testing.T) {
  function TestConvertNullableUInt256 (line 660) | func TestConvertNullableUInt256(t *testing.T) {
  function TestConvertDate (line 674) | func TestConvertDate(t *testing.T) {
  function TestConvertNullableDate (line 685) | func TestConvertNullableDate(t *testing.T) {
  function TestConvertDateTime (line 698) | func TestConvertDateTime(t *testing.T) {
  function TestConvertNullableDateTime (line 711) | func TestConvertNullableDateTime(t *testing.T) {
  function TestConvertDateTime64 (line 724) | func TestConvertDateTime64(t *testing.T) {
  function TestConvertNullableDateTime64 (line 738) | func TestConvertNullableDateTime64(t *testing.T) {
  function TestConvertString (line 752) | func TestConvertString(t *testing.T) {
  function TestConvertNullableString (line 763) | func TestConvertNullableString(t *testing.T) {
  function TestConvertDecimal (line 775) | func TestConvertDecimal(t *testing.T) {
  function TestConvertNullableDecimal (line 787) | func TestConvertNullableDecimal(t *testing.T) {
  function TestTuple (line 799) | func TestTuple(t *testing.T) {
  function TestNested (line 811) | func TestNested(t *testing.T) {
  function TestArrayTuple (line 825) | func TestArrayTuple(t *testing.T) {
  function TestArrayInt64 (line 839) | func TestArrayInt64(t *testing.T) {
  function TestArrayNullableInt64 (line 851) | func TestArrayNullableInt64(t *testing.T) {
  function TestArrayUInt256 (line 864) | func TestArrayUInt256(t *testing.T) {
  function TestArrayNullableUInt256 (line 876) | func TestArrayNullableUInt256(t *testing.T) {
  function TestArrayNullableString (line 888) | func TestArrayNullableString(t *testing.T) {
  function TestArrayNullableIPv4 (line 902) | func TestArrayNullableIPv4(t *testing.T) {
  function TestArrayNullableIPv6 (line 915) | func TestArrayNullableIPv6(t *testing.T) {
  function TestMap (line 929) | func TestMap(t *testing.T) {
  function TestFixedString (line 941) | func TestFixedString(t *testing.T) {
  function TestNullableFixedString (line 953) | func TestNullableFixedString(t *testing.T) {
  function TestLowCardinalityString (line 966) | func TestLowCardinalityString(t *testing.T) {
  function TestLowCardinalityNullableString (line 978) | func TestLowCardinalityNullableString(t *testing.T) {
  function TestConvertDate32 (line 990) | func TestConvertDate32(t *testing.T) {
  function TestConvertEnum (line 1011) | func TestConvertEnum(t *testing.T) {
  function TestConvertEnum8 (line 1022) | func TestConvertEnum8(t *testing.T) {
  function TestConvertNullableEnum8 (line 1033) | func TestConvertNullableEnum8(t *testing.T) {
  function TestConvertNullableEnum8WithNull (line 1045) | func TestConvertNullableEnum8WithNull(t *testing.T) {
  function TestConvertEnum16 (line 1056) | func TestConvertEnum16(t *testing.T) {
  function TestConvertNullableEnum16WithNull (line 1067) | func TestConvertNullableEnum16WithNull(t *testing.T) {
  function TestConvertUUID (line 1078) | func TestConvertUUID(t *testing.T) {
  function TestConvertNullableUUID (line 1090) | func TestConvertNullableUUID(t *testing.T) {
  function TestConvertIPv4 (line 1130) | func TestConvertIPv4(t *testing.T) {
  function TestConvertIPv6 (line 1143) | func TestConvertIPv6(t *testing.T) {
  function TestConvertNullableIPv4 (line 1156) | func TestConvertNullableIPv4(t *testing.T) {
  function TestConvertNullableIPv6 (line 1169) | func TestConvertNullableIPv6(t *testing.T) {
  function TestHTTPConnectWithHeaders (line 1248) | func TestHTTPConnectWithHeaders(t *testing.T) {

FILE: pkg/plugin/driver_test.go
  function TestMergeOpenTelemetryLabels (line 16) | func TestMergeOpenTelemetryLabels(t *testing.T) {
  function TestAssignFlattenedPath (line 96) | func TestAssignFlattenedPath(t *testing.T) {
  function TestContainsClickHouseException (line 266) | func TestContainsClickHouseException(t *testing.T) {
  function TestMutateQueryData (line 323) | func TestMutateQueryData(t *testing.T) {
  function TestMutateQuery_GrafanaMetadata (line 387) | func TestMutateQuery_GrafanaMetadata(t *testing.T) {
  function TestMutateQueryData_XGrafanaUserForwarding (line 429) | func TestMutateQueryData_XGrafanaUserForwarding(t *testing.T) {

FILE: pkg/plugin/schema.go
  type dbConnector (line 19) | type dbConnector interface
  type SchemaProvider (line 54) | type SchemaProvider struct
    method getDB (line 75) | func (p *SchemaProvider) getDB(ctx context.Context) (*sql.DB, error) {
    method Close (line 90) | func (p *SchemaProvider) Close() error {
    method Schema (line 102) | func (p *SchemaProvider) Schema(ctx context.Context, req *schemas.Sche...
    method Tables (line 139) | func (p *SchemaProvider) Tables(ctx context.Context, req *schemas.Tabl...
    method fetchTables (line 161) | func (p *SchemaProvider) fetchTables(ctx context.Context) ([]string, e...
    method Columns (line 192) | func (p *SchemaProvider) Columns(ctx context.Context, req *schemas.Col...
    method cachedFetchColumns (line 258) | func (p *SchemaProvider) cachedFetchColumns(ctx context.Context, table...
    method fetchColumnsForAllTables (line 272) | func (p *SchemaProvider) fetchColumnsForAllTables(ctx context.Context,...
    method fetchColumnsForTable (line 363) | func (p *SchemaProvider) fetchColumnsForTable(ctx context.Context, tab...
    method ColumnValues (line 479) | func (p *SchemaProvider) ColumnValues(ctx context.Context, req *schema...
    method fetchColumnValues (line 504) | func (p *SchemaProvider) fetchColumnValues(ctx context.Context, table ...
  function splitTable (line 229) | func splitTable(table string) (string, string) {
  function escapeSQLString (line 238) | func escapeSQLString(s string) string {
  function quoteIdentifier (line 243) | func quoteIdentifier(s string) string {
  function mapClickHouseTypeToSchema (line 404) | func mapClickHouseTypeToSchema(chType string) (schemas.ColumnType, []sch...
  function NewSchemaProvider (line 564) | func NewSchemaProvider(ctx context.Context, clickhousePlugin *Clickhouse...

FILE: pkg/plugin/schema_test.go
  type trackingConnector (line 19) | type trackingConnector struct
    method Connect (line 27) | func (t *trackingConnector) Connect(_ context.Context, _ backend.DataS...
    method allClosed (line 40) | func (t *trackingConnector) allClosed() bool {
    method openedCount (line 51) | func (t *trackingConnector) openedCount() int {
  type fakeDriverConnector (line 59) | type fakeDriverConnector struct
    method Connect (line 63) | func (c *fakeDriverConnector) Connect(context.Context) (driver.Conn, e...
    method Driver (line 66) | func (c *fakeDriverConnector) Driver() driver.Driver { return fakeDriv...
  type fakeDriver (line 68) | type fakeDriver struct
    method Open (line 70) | func (fakeDriver) Open(string) (driver.Conn, error) { return nil, erro...
  type fakeConn (line 72) | type fakeConn struct
    method Prepare (line 76) | func (c *fakeConn) Prepare(string) (driver.Stmt, error) { return nil, ...
    method Close (line 77) | func (c *fakeConn) Close() error                        { return nil }
    method Begin (line 78) | func (c *fakeConn) Begin() (driver.Tx, error)           { return nil, ...
    method QueryContext (line 81) | func (c *fakeConn) QueryContext(_ context.Context, query string, _ []d...
  type fakeRows (line 85) | type fakeRows struct
    method Columns (line 91) | func (r *fakeRows) Columns() []string { return r.cols }
    method Close (line 92) | func (r *fakeRows) Close() error      { return nil }
    method Next (line 93) | func (r *fakeRows) Next(dest []driver.Value) error {
  function newProvider (line 105) | func newProvider(t *testing.T, conn *trackingConnector) *SchemaProvider {
  function tablesRows (line 113) | func tablesRows() (driver.Rows, error) {
  function columnsRows (line 124) | func columnsRows() (driver.Rows, error) {
  function describeRows (line 134) | func describeRows() (driver.Rows, error) {
  function TestFetchTables_Success (line 146) | func TestFetchTables_Success(t *testing.T) {
  function TestFetchColumnsForAllTables_Success (line 159) | func TestFetchColumnsForAllTables_Success(t *testing.T) {
  function TestFetchColumnsForTable_Success (line 172) | func TestFetchColumnsForTable_Success(t *testing.T) {
  function TestFetchTables_QueryErrorIsReturned (line 187) | func TestFetchTables_QueryErrorIsReturned(t *testing.T) {
  function TestFetchColumnsForAllTables_QueryErrorIsReturned (line 198) | func TestFetchColumnsForAllTables_QueryErrorIsReturned(t *testing.T) {
  function TestFetchColumnsForTable_QueryErrorIsReturned (line 209) | func TestFetchColumnsForTable_QueryErrorIsReturned(t *testing.T) {
  function TestGetDB_ReusedAcrossCalls (line 222) | func TestGetDB_ReusedAcrossCalls(t *testing.T) {
  function TestGetDB_ConnectErrorNotCached (line 254) | func TestGetDB_ConnectErrorNotCached(t *testing.T) {
  function TestClose_ClosesHeldDBAndIsIdempotent (line 278) | func TestClose_ClosesHeldDBAndIsIdempotent(t *testing.T) {
  function TestClose_WithoutAnyFetchIsNoOp (line 302) | func TestClose_WithoutAnyFetchIsNoOp(t *testing.T) {
  function TestGetDB_ConcurrentFirstUse (line 316) | func TestGetDB_ConcurrentFirstUse(t *testing.T) {
  function TestSchema_Concurrent_NoRace (line 347) | func TestSchema_Concurrent_NoRace(t *testing.T) {
  function leakedCount (line 398) | func leakedCount(c *trackingConnector) int {
  function containsAny (line 410) | func containsAny(s string, sub string) bool {
  function indexOf (line 414) | func indexOf(s, sub string) int {
  function equalStrings (line 423) | func equalStrings(a, b []string) bool {

FILE: pkg/plugin/schemacache/cache.go
  constant DefaultMaxItems (line 18) | DefaultMaxItems = 256
  type Cache (line 22) | type Cache struct
  type entry (line 34) | type entry struct
  function New (line 42) | func New[V any](ttl, jitter time.Duration, maxItems int) *Cache[V] {
  method Get (line 57) | func (c *Cache[V]) Get(key string) (V, bool) {
  method getLocked (line 63) | func (c *Cache[V]) getLocked(key string) (V, bool) {
  method Set (line 77) | func (c *Cache[V]) Set(key string, value V) {
  method Delete (line 88) | func (c *Cache[V]) Delete(key string) {
  method Clear (line 95) | func (c *Cache[V]) Clear() {
  method Len (line 102) | func (c *Cache[V]) Len() int {
  method Do (line 111) | func (c *Cache[V]) Do(ctx context.Context, key string, fn func(context.C...
  method ttlWithJitter (line 136) | func (c *Cache[V]) ttlWithJitter() time.Duration {
  method evictIfNeededLocked (line 146) | func (c *Cache[V]) evictIfNeededLocked() {

FILE: pkg/plugin/schemacache/cache_bench_test.go
  constant simulatedRoundTrip (line 17) | simulatedRoundTrip = 2 * time.Millisecond
  function fetchSimulated (line 21) | func fetchSimulated(ctx context.Context) ([]string, error) {
  function BenchmarkTablesFetch_Uncached (line 30) | func BenchmarkTablesFetch_Uncached(b *testing.B) {
  function BenchmarkTablesFetch_Cached (line 46) | func BenchmarkTablesFetch_Cached(b *testing.B) {
  function BenchmarkTablesFetch_CachedConcurrent (line 64) | func BenchmarkTablesFetch_CachedConcurrent(b *testing.B) {

FILE: pkg/plugin/schemacache/cache_test.go
  function TestCache_GetSet (line 13) | func TestCache_GetSet(t *testing.T) {
  function TestCache_TTLExpiry (line 27) | func TestCache_TTLExpiry(t *testing.T) {
  function TestCache_Delete (line 51) | func TestCache_Delete(t *testing.T) {
  function TestCache_Clear (line 60) | func TestCache_Clear(t *testing.T) {
  function TestCache_MaxItemsEviction (line 70) | func TestCache_MaxItemsEviction(t *testing.T) {
  function TestCache_DoReturnsCachedValue (line 93) | func TestCache_DoReturnsCachedValue(t *testing.T) {
  function TestCache_DoCachesResult (line 113) | func TestCache_DoCachesResult(t *testing.T) {
  function TestCache_DoErrorNotCached (line 136) | func TestCache_DoErrorNotCached(t *testing.T) {
  function TestCache_DoSingleflight (line 151) | func TestCache_DoSingleflight(t *testing.T) {
  function TestCache_DoLeaderCancelDoesNotPoisonWaiters (line 199) | func TestCache_DoLeaderCancelDoesNotPoisonWaiters(t *testing.T) {
  function TestCache_KeyIsolation (line 250) | func TestCache_KeyIsolation(t *testing.T) {
  function TestCache_JitterStaysWithinBand (line 265) | func TestCache_JitterStaysWithinBand(t *testing.T) {

FILE: pkg/plugin/settings.go
  type Settings (line 19) | type Settings struct
    method isValid (line 69) | func (settings *Settings) isValid() (err error) {
  type CustomSetting (line 62) | type CustomSetting struct
  constant secureHeaderKeyPrefix (line 67) | secureHeaderKeyPrefix = "secureHttpHeaders."
  function LoadSettings (line 80) | func LoadSettings(ctx context.Context, config backend.DataSourceInstance...
  function loadHttpHeaders (line 320) | func loadHttpHeaders(jsonData map[string]interface{}, secureJsonData map...

FILE: pkg/plugin/settings_test.go
  function TestLoadSettings (line 19) | func TestLoadSettings(t *testing.T) {

FILE: src/ch-parser/helpers.ts
  function isWhitespaceASCII (line 8) | function isWhitespaceASCII(c: string): boolean {
  function isNumericASCII (line 15) | function isNumericASCII(c: string): boolean {
  function isWordCharASCII (line 22) | function isWordCharASCII(c: string): boolean {
  function isHexDigit (line 29) | function isHexDigit(c: string): boolean {
  function isNumberSeparator (line 36) | function isNumberSeparator(startOfBlock: boolean, hex: boolean, pos: num...
  function findFirstSymbols (line 63) | function findFirstSymbols(text: string, pos: number, end: number, ...sym...
  function findFirstNotSymbols (line 76) | function findFirstNotSymbols(text: string, pos: number, end: number, ......
  function skipWhitespacesUTF8 (line 89) | function skipWhitespacesUTF8(text: string, pos: number, end: number): nu...
  function isContinuationOctet (line 131) | function isContinuationOctet(c: string): boolean {

FILE: src/ch-parser/lexer.ts
  class Lexer (line 16) | class Lexer {
    method constructor (line 28) | public constructor(text: string, maxQuerySize = 0) {
    method nextToken (line 38) | public nextToken(): Token {
    method parseQuotedString (line 57) | private parseQuotedString(quote: string, successToken: TokenType, erro...
    method parseQuotedHexOrBinString (line 100) | private parseQuotedHexOrBinString(): Token {
    method commentUntilEndOfLine (line 135) | private commentUntilEndOfLine(): Token {
    method parseUnicodeQuotedString (line 155) | private parseUnicodeQuotedString(closeChar: string, successToken: Toke...
    method nextTokenImpl (line 174) | private nextTokenImpl(): Token {

FILE: src/ch-parser/parser.ts
  class QueryNodeParser (line 3) | class QueryNodeParser {
    method constructor (line 7) | constructor(tokens: Token[]) {
    method advance (line 12) | public advance() {
    method hasNext (line 16) | public hasNext(): boolean {
    method next (line 20) | public next(): Token {
    method peek (line 27) | public peek(): Token {
    method nextIs (line 31) | public nextIs(type: TokenType): boolean {
    method peekIs (line 41) | public peekIs(type: TokenType): boolean {
  type ClauseType (line 46) | enum ClauseType {
  type QueryNodeType (line 60) | enum QueryNodeType {
  type QueryNode (line 67) | interface QueryNode {
  type FromQueryNode (line 74) | interface FromQueryNode extends QueryNode {
  type IdentifierQueryNode (line 81) | interface IdentifierQueryNode extends QueryNode {
  type SelectQueryNode (line 85) | interface SelectQueryNode extends QueryNode {
  function parseSelectQueryNode (line 89) | function parseSelectQueryNode(parser: QueryNodeParser): SelectQueryNode ...

FILE: src/ch-parser/pluginMacros.ts
  type PluginMacro (line 1) | interface PluginMacro {

FILE: src/ch-parser/types.ts
  type TokenType (line 4) | enum TokenType {
  class Token (line 182) | class Token {
    method constructor (line 189) | constructor(type: TokenType, begin: number, end: number, text: string) {
    method upperText (line 201) | private upperText(): string {
    method size (line 205) | size(): number {
    method isSignificant (line 209) | isSignificant(): boolean {
    method matchKeyword (line 218) | matchKeyword(keyword: string): boolean {
    method isKeyword (line 222) | isKeyword(): boolean {
    method isError (line 226) | isError(): boolean {
    method isEnd (line 230) | isEnd(): boolean {
  function getTokenName (line 238) | function getTokenName(type: TokenType): string {
  function getErrorTokenDescription (line 245) | function getErrorTokenDescription(type: TokenType): string {

FILE: src/components/Divider.tsx
  function Divider (line 6) | function Divider() {

FILE: src/components/LogsContextPanel.tsx
  type LogContextPanelProps (line 14) | interface LogContextPanelProps {
  type LogContextKeyProps (line 104) | interface LogContextKeyProps {

FILE: src/components/QueryToolbox.tsx
  type QueryToolboxProps (line 6) | interface QueryToolboxProps {
  function QueryToolbox (line 11) | function QueryToolbox({ showTools, onFormatCode }: QueryToolboxProps) {

FILE: src/components/SqlEditor.tsx
  type SqlEditorProps (line 18) | type SqlEditorProps = QueryEditorProps<Datasource, CHQuery, CHConfig>;
  function setupAutoSize (line 20) | function setupAutoSize(editor: monacoTypes.editor.IStandaloneCodeEditor) {

FILE: src/components/configEditor/AliasTableConfig.tsx
  type AliasTablesConfigProps (line 10) | interface AliasTablesConfigProps {
  type AliasTableEditorProps (line 106) | interface AliasTableEditorProps {

FILE: src/components/configEditor/DefaultDatabaseTableConfig.tsx
  type DefaultDatabaseTableConfigProps (line 6) | interface DefaultDatabaseTableConfigProps {

FILE: src/components/configEditor/HttpHeadersConfig.tsx
  type HttpHeadersConfigProps (line 10) | interface HttpHeadersConfigProps {
  type HttpHeaderEditorProps (line 84) | interface HttpHeaderEditorProps {

FILE: src/components/configEditor/LabeledInput.tsx
  type LabeledInputProps (line 4) | interface LabeledInputProps {
  function LabeledInput (line 13) | function LabeledInput(props: LabeledInputProps) {

FILE: src/components/configEditor/LogsConfig.tsx
  type LogsConfigProps (line 13) | interface LogsConfigProps {

FILE: src/components/configEditor/QuerySettingsConfig.tsx
  type QuerySettingsConfigProps (line 6) | interface QuerySettingsConfigProps {

FILE: src/components/configEditor/TracesConfig.test.tsx
  function defaultTraceConfigProps (line 8) | function defaultTraceConfigProps(): TraceConfigProps {

FILE: src/components/configEditor/TracesConfig.tsx
  type TraceConfigProps (line 14) | interface TraceConfigProps {

FILE: src/components/experimental/ConfigSection/ConfigSection.tsx
  type Props (line 4) | type Props = Omit<GenericConfigSectionProps, 'kind'>;

FILE: src/components/experimental/ConfigSection/ConfigSubSection.tsx
  type Props (line 4) | type Props = Omit<GenericConfigSectionProps, 'kind'>;

FILE: src/components/experimental/ConfigSection/DataSourceDescription.tsx
  type Props (line 5) | type Props = {

FILE: src/components/experimental/ConfigSection/GenericConfigSection.tsx
  type Props (line 5) | type Props = {

FILE: src/components/queryBuilder/AggregateEditor.tsx
  type AggregateProps (line 9) | interface AggregateProps {
  type AggregateEditorProps (line 91) | interface AggregateEditorProps {

FILE: src/components/queryBuilder/ColumnRolesHelp.tsx
  type ColumnRolesHelpProps (line 4) | interface ColumnRolesHelpProps {

FILE: src/components/queryBuilder/ColumnSelect.tsx
  type ColumnSelectProps (line 7) | interface ColumnSelectProps {

FILE: src/components/queryBuilder/ColumnsEditor.tsx
  type ColumnsEditorProps (line 9) | interface ColumnsEditorProps {
  function getCustomColumns (line 17) | function getCustomColumns(columnNames: string[], allColumns: readonly Ta...

FILE: src/components/queryBuilder/DatabaseTableSelect.tsx
  type DatabaseSelectProps (line 9) | type DatabaseSelectProps = {
  type TableSelectProps (line 53) | type TableSelectProps = {
  type DatabaseTableSelectProps (line 97) | type DatabaseTableSelectProps = {

FILE: src/components/queryBuilder/DurationUnitSelect.tsx
  type DurationUnitSelectProps (line 8) | interface DurationUnitSelectProps {

FILE: src/components/queryBuilder/EditorTypeSwitcher.tsx
  type CHEditorTypeSwitcherProps (line 12) | interface CHEditorTypeSwitcherProps {

FILE: src/components/queryBuilder/FilterEditor.tsx
  type PredefinedFilter (line 54) | interface PredefinedFilter {

FILE: src/components/queryBuilder/GroupByEditor.tsx
  type GroupByEditorProps (line 9) | interface GroupByEditorProps {

FILE: src/components/queryBuilder/LimitEditor.tsx
  type LimitEditorProps (line 6) | interface LimitEditorProps {

FILE: src/components/queryBuilder/ModeSwitch.tsx
  type ModeSwitchProps (line 4) | interface ModeSwitchProps {

FILE: src/components/queryBuilder/OrderByEditor.tsx
  type OrderByItemProps (line 9) | interface OrderByItemProps {
  type OrderByEditorProps (line 59) | interface OrderByEditorProps {

FILE: src/components/queryBuilder/OtelVersionSelect.tsx
  type OtelVersionSelectProps (line 7) | interface OtelVersionSelectProps {

FILE: src/components/queryBuilder/QueryBuilder.tsx
  type QueryBuilderProps (line 25) | interface QueryBuilderProps {
  type MinimizedQueryBuilder (line 99) | interface MinimizedQueryBuilder {

FILE: src/components/queryBuilder/QueryTypeSwitcher.tsx
  type QueryTypeSwitcherProps (line 6) | interface QueryTypeSwitcherProps {

FILE: src/components/queryBuilder/SqlPreview.tsx
  type SqlPreviewProps (line 5) | interface SqlPreviewProps {

FILE: src/components/queryBuilder/Switch.tsx
  type SwitchProps (line 5) | interface SwitchProps {

FILE: src/components/queryBuilder/TraceIdInput.tsx
  type TraceIdInputProps (line 6) | interface TraceIdInputProps {

FILE: src/components/queryBuilder/utils.test.ts
  function testCondition (line 639) | function testCondition(name: string, sql: string, builder: QueryBuilderO...

FILE: src/components/queryBuilder/utils.ts
  function getQueryOptionsFromSql (line 83) | function getQueryOptionsFromSql(
  function getFiltersFromAst (line 173) | function getFiltersFromAst(expr: Expr, timeField: string): Filter[] {
  function getRefFilter (line 213) | function getRefFilter(e: ExprRef, filters: Filter[], i: number, notFlag:...
  function getListFilter (line 241) | function getListFilter(filters: Filter[], i: number, e: ExprList): number {
  function getCallFilter (line 254) | function getCallFilter(e: ExprCall, timeField: string, filters: Filter[]...
  function getUnaryFilter (line 278) | function getUnaryFilter(e: ExprUnary, notFlag: boolean, i: number, filte...
  function getStringFilter (line 289) | function getStringFilter(filters: Filter[], i: number, e: ExprString): n...
  function getIntFilter (line 299) | function getIntFilter(filters: Filter[], i: number, e: ExprInteger): num...
  function getBinaryFilter (line 309) | function getBinaryFilter(e: ExprBinary, filters: Filter[], i: number, no...
  function selectCallFunc (line 330) | function selectCallFunc(s: SelectedColumn): [AggregateColumn | string, s...
  function getAggregatesFromAst (line 356) | function getAggregatesFromAst(selectClauses: SelectedColumn[] | null): {
  function getOper (line 395) | function getOper(v: string): FilterOperator {

FILE: src/components/queryBuilder/views/LogsQueryBuilder.tsx
  type LogsQueryBuilderProps (line 28) | interface LogsQueryBuilderProps {
  type LogsQueryBuilderState (line 34) | interface LogsQueryBuilderState {
  type LogMessageLikeInputProps (line 211) | interface LogMessageLikeInputProps {

FILE: src/components/queryBuilder/views/TableQueryBuilder.tsx
  type TableQueryBuilderProps (line 16) | interface TableQueryBuilderProps {
  type TableQueryBuilderState (line 22) | interface TableQueryBuilderState {

FILE: src/components/queryBuilder/views/TimeSeriesQueryBuilder.tsx
  type TimeSeriesQueryBuilderProps (line 31) | interface TimeSeriesQueryBuilderProps {
  type TimeSeriesQueryBuilderState (line 37) | interface TimeSeriesQueryBuilderState {

FILE: src/components/queryBuilder/views/TraceQueryBuilder.tsx
  type TraceQueryBuilderProps (line 25) | interface TraceQueryBuilderProps {
  type TraceQueryBuilderState (line 31) | interface TraceQueryBuilderState {

FILE: src/components/sqlProvider.ts
  type Model (line 6) | interface Model {
  type Position (line 13) | interface Position {
  type Range (line 18) | interface Range {
  type SuggestionResponse (line 25) | interface SuggestionResponse {
  type Suggestion (line 29) | interface Suggestion {
  type Fetcher (line 39) | type Fetcher = {
  function formatSql (line 43) | function formatSql(rawSql: string, tabWidth = 4): string {
  type SqlRegistration (line 57) | interface SqlRegistration {
  function registerSQL (line 62) | function registerSQL(lang: string, editor: MonacoEditor, fetchSuggestion...

FILE: src/components/suggestions.ts
  type Schema (line 19) | interface Schema {
  type CursorData (line 27) | interface CursorData {
  function getCursorInSelectQueryNode (line 38) | function getCursorInSelectQueryNode(root: SelectQueryNode, cursorPositio...
  function getSuggestions (line 112) | async function getSuggestions(
  function dedupeSuggestions (line 146) | function dedupeSuggestions(
  function getSuggestionsFromCursorData (line 161) | async function getSuggestionsFromCursorData(
  function fetchDatabaseSuggestions (line 258) | async function fetchDatabaseSuggestions(schema: Schema, range: Range, pr...
  function fetchTableSuggestions (line 281) | async function fetchTableSuggestions(schema: Schema, range: Range, datab...
  function fetchFieldSuggestions (line 304) | async function fetchFieldSuggestions(schema: Schema, range: Range, db: s...
  function fetchFunctionSuggestions (line 319) | async function fetchFunctionSuggestions(schema: Schema, range: Range) {
  function getVariableSuggestions (line 343) | function getVariableSuggestions(range: Range) {
  function getMacroSuggestions (line 363) | function getMacroSuggestions(range: Range, prefix?: string) {

FILE: src/components/ui/CertificationKey.tsx
  type Props (line 4) | interface Props {

FILE: src/data/CHDatasource.test.ts
  type InstanceConfig (line 30) | interface InstanceConfig {

FILE: src/data/CHDatasource.ts
  class Datasource (line 61) | class Datasource
    method constructor (line 76) | constructor(instanceSettings: DataSourceInstanceSettings<CHConfig>) {
    method getSupplementaryRequest (line 85) | getSupplementaryRequest(
    method getSupportedSupplementaryQueryTypes (line 145) | getSupportedSupplementaryQueryTypes(dsRequest: DataQueryRequest<CHQuer...
    method getSupplementaryLogsVolumeQuery (line 152) | getSupplementaryLogsVolumeQuery(logsVolumeRequest: DataQueryRequest<CH...
    method getSupplementaryLogsSampleQuery (line 231) | getSupplementaryLogsSampleQuery(query: CHQuery): CHQuery | undefined {
    method getSupplementaryQuery (line 285) | getSupplementaryQuery(_options: SupplementaryQueryOptions, _originalQu...
    method metricFindQuery (line 289) | async metricFindQuery(query: CHQuery | string, options: any) {
    method applyTemplateVariables (line 314) | applyTemplateVariables(query: CHQuery, scoped: ScopedVars, filters: Ad...
    method applyConditionalAll (line 351) | applyConditionalAll(rawQuery: string, templateVars: TypedVariableModel...
    method applyAdHocFiltersMacro (line 380) | applyAdHocFiltersMacro(rawQuery: string, filters: AdHocVariableFilter[...
    method getSupportedQueryModifications (line 413) | getSupportedQueryModifications() {
    method modifyQuery (line 418) | modifyQuery(query: CHQuery, action: QueryFixAction): CHQuery {
    method getMacroArgs (line 555) | private getMacroArgs(query: string, argsIndex: number): string[] {
    method replace (line 581) | private replace(value?: string, scopedVars?: ScopedVars) {
    method format (line 588) | private format(value: any) {
    method getDefaultDatabase (line 595) | getDefaultDatabase(): string {
    method getDefaultTable (line 599) | getDefaultTable(): string | undefined {
    method getDefaultLogsDatabase (line 603) | getDefaultLogsDatabase(): string | undefined {
    method getDefaultLogsTable (line 607) | getDefaultLogsTable(): string | undefined {
    method getDefaultLogsColumns (line 611) | getDefaultLogsColumns(): Map<ColumnHint, string> {
    method shouldSelectLogContextColumns (line 634) | shouldSelectLogContextColumns(): boolean {
    method getLogContextColumnNames (line 638) | getLogContextColumnNames(): string[] {
    method getLogsOtelVersion (line 645) | getLogsOtelVersion(): string | undefined {
    method getDefaultTraceDatabase (line 650) | getDefaultTraceDatabase(): string | undefined {
    method getDefaultTraceTable (line 654) | getDefaultTraceTable(): string | undefined {
    method getDefaultTraceColumns (line 658) | getDefaultTraceColumns(): Map<ColumnHint, string> {
    method getTraceOtelVersion (line 697) | getTraceOtelVersion(): string | undefined {
    method getDefaultTraceDurationUnit (line 702) | getDefaultTraceDurationUnit(): TimeUnit {
    method getDefaultTraceFlattenNested (line 706) | getDefaultTraceFlattenNested(): boolean {
    method getDefaultTraceEventsColumnPrefix (line 710) | getDefaultTraceEventsColumnPrefix(): string {
    method getDefaultTraceLinksColumnPrefix (line 714) | getDefaultTraceLinksColumnPrefix(): string {
    method getTraceTimestampTableSuffix (line 724) | getTraceTimestampTableSuffix(): string {
    method getTracesTraceIdColumn (line 732) | getTracesTraceIdColumn(): string | undefined {
    method fetchDatabases (line 749) | async fetchDatabases(): Promise<string[]> {
    method fetchTables (line 753) | async fetchTables(db?: string): Promise<string[]> {
    method fetchUniqueMapKeys (line 766) | async fetchUniqueMapKeys(mapColumn: string, db: string, table: string)...
    method fetchEntities (line 771) | async fetchEntities() {
    method fetchFields (line 775) | async fetchFields(database: string, table: string): Promise<string[]> {
    method fetchPathsForJSONColumns (line 782) | async fetchPathsForJSONColumns(
    method fetchColumnsFromTable (line 831) | async fetchColumnsFromTable(database: string | undefined, table: strin...
    method fetchSqlFunctions (line 860) | async fetchSqlFunctions(): Promise<SqlFunction[]> {
    method fetchColumnsFromAliasTable (line 893) | async fetchColumnsFromAliasTable(fullTableName: string): Promise<Table...
    method getAliasTable (line 908) | getAliasTable(targetDatabase: string | undefined, targetTable: string)...
    method fetchColumns (line 927) | async fetchColumns(database: string | undefined, table: string): Promi...
    method fetchData (line 936) | private async fetchData(rawSql: string) {
    method getTimezone (line 941) | private getTimezone(request: DataQueryRequest<CHQuery>): string | unde...
    method filterQuery (line 951) | filterQuery(query: CHQuery): boolean {
    method query (line 955) | query(request: DataQueryRequest<CHQuery>): Observable<DataQueryRespons...
    method runQuery (line 986) | private runQuery(request: Partial<CHQuery>, options?: any): Promise<Da...
    method values (line 998) | private values(frame: DataFrame) {
    method getTagKeys (line 1005) | async getTagKeys(): Promise<MetricFindValue[]> {
    method getTagValues (line 1023) | async getTagValues({ key }: any): Promise<MetricFindValue[]> {
    method fieldValuesToMetricFindValues (line 1032) | private fieldValuesToMetricFindValues(field: Field): MetricFindValue[] {
    method fetchTagValuesFromSchema (line 1041) | private async fetchTagValuesFromSchema(key: string): Promise<MetricFin...
    method fetchTagValuesFromQuery (line 1068) | private async fetchTagValuesFromQuery(key: string): Promise<MetricFind...
    method fetchTags (line 1095) | private async fetchTags(): Promise<Tags> {
    method extractTableNameFromQuery (line 1134) | private extractTableNameFromQuery(query: string): string | null {
    method getTagSource (line 1146) | private getTagSource() {
    method canUseAdhocFilters (line 1169) | private async canUseAdhocFilters(): Promise<AdHocFilterStatus> {
    method getLogContextColumnsFromLogRow (line 1186) | getLogContextColumnsFromLogRow(row: LogRowModel): LogContextColumn[] {
    method getLogRowContext (line 1253) | async getLogRowContext(
    method extractQueryErrorMessage (line 1357) | private extractQueryErrorMessage(err: unknown): string | undefined {
    method showContextToggle (line 1375) | showContextToggle(row?: LogRowModel): boolean {
    method getLogRowContextUi (line 1382) | getLogRowContextUi(
    method testDatasource (line 1391) | async testDatasource(): Promise<{ status: string; message: string }> {
  function parseConnectionErrorCategory (line 1413) | function parseConnectionErrorCategory(message: string): string {
  constant CONNECTION_ERROR_HINTS (line 1418) | const CONNECTION_ERROR_HINTS: Record<string, string> = {
  function getConnectionErrorHint (line 1428) | function getConnectionErrorHint(category: string, detail: string): strin...
  type TagType (line 1435) | enum TagType {
  type AdHocFilterStatus (line 1440) | enum AdHocFilterStatus {
  type Tags (line 1446) | interface Tags {
  type LogContextColumn (line 1451) | interface LogContextColumn {

FILE: src/data/adHocFilter.ts
  class AdHocFilter (line 4) | class AdHocFilter {
    method setTargetTableFromQuery (line 7) | setTargetTableFromQuery(query: string) {
    method buildFilterString (line 14) | buildFilterString(adHocFilters: AdHocVariableFilter[], useJSON = false...
    method apply (line 40) | apply(sql: string, adHocFilters: AdHocVariableFilter[], useJSON = fals...
  function isValid (line 69) | function isValid(filter: AdHocVariableFilter): boolean {
  function escapeKey (line 73) | function escapeKey(s: string, isJSON = false): string {
  function escapeValueBasedOnOperator (line 97) | function escapeValueBasedOnOperator(s: string, operator: string): string {
  function convertOperatorToClickHouseOperator (line 109) | function convertOperatorToClickHouseOperator(operator: string): string {

FILE: src/data/ast.ts
  type ReplacePart (line 3) | interface ReplacePart {
  type ReplaceParts (line 8) | type ReplaceParts = ReplacePart[];
  function getReplacementKey (line 10) | function getReplacementKey(isVariable: boolean) {
  function replaceMacroFunctions (line 18) | function replaceMacroFunctions(sql: string): [ReplaceParts, string] {
  function replaceMacroVariables (line 47) | function replaceMacroVariables(sql: string): [ReplaceParts, string] {
  function sqlToStatement (line 69) | function sqlToStatement(rawSql: string): Statement {
  function getTable (line 126) | function getTable(sql: string): string {
  function getFields (line 148) | function getFields(sql: string): string[] {

FILE: src/data/logs.ts
  constant MILLISECOND (line 4) | const MILLISECOND = 1;
  constant SECOND (line 5) | const SECOND = 1000 * MILLISECOND;
  constant MINUTE (line 6) | const MINUTE = 60 * SECOND;
  constant HOUR (line 7) | const HOUR = 60 * MINUTE;
  constant DAY (line 8) | const DAY = 24 * HOUR;
  function getIntervalInfo (line 10) | function getIntervalInfo(scopedVars: ScopedVars): { interval: string; in...
  function getTimeFieldRoundingClause (line 34) | function getTimeFieldRoundingClause(scopedVars: ScopedVars, timeField: s...
  constant TIME_FIELD_ALIAS (line 54) | const TIME_FIELD_ALIAS = 'time';
  constant DEFAULT_LOGS_ALIAS (line 55) | const DEFAULT_LOGS_ALIAS = 'logs';
  type LogLevelToInClause (line 65) | type LogLevelToInClause = Record<'critical' | 'error' | 'warn' | 'info' ...
  constant LOG_LEVEL_TO_IN_CLAUSE (line 66) | const LOG_LEVEL_TO_IN_CLAUSE: LogLevelToInClause = (() => {
  function splitLogsVolumeFrames (line 86) | function splitLogsVolumeFrames(data: DataFrame[], logVolumePrefix: strin...

FILE: src/data/migration.ts
  type AnyCHQuery (line 6) | type AnyCHQuery = Partial<CHQuery> & { [k: string]: any };
  type AnyQueryBuilderOptions (line 7) | type AnyQueryBuilderOptions = Partial<QueryBuilderOptions> & { [k: strin...

FILE: src/data/validate.ts
  type Error (line 4) | interface Error {
  type Validation (line 13) | interface Validation {
  function offsetToLineCol (line 18) | function offsetToLineCol(sql: string, offset: number): { line: number; c...
  function validate (line 26) | function validate(sql: string): Validation {

FILE: src/hooks/useBuilderOptionChanges.test.ts
  type TestData (line 4) | interface TestData {

FILE: src/hooks/useBuilderOptionChanges.ts
  type onOptionChangeFn (line 3) | type onOptionChangeFn<T> = (key: keyof T) => (nextValue: React.SetStateA...
  function useBuilderOptionChanges (line 15) | function useBuilderOptionChanges<T>(onChange: (nextState: T) => void, pr...

FILE: src/hooks/useBuilderOptionsState.ts
  type BuilderOptionsActionType (line 5) | enum BuilderOptionsActionType {
  type QueryBuilderOptionsReducerAction (line 17) | type QueryBuilderOptionsReducerAction = {
  type GenericReducerAction (line 22) | type GenericReducerAction = {
  type BuilderOptionsReducerAction (line 27) | type BuilderOptionsReducerAction = QueryBuilderOptionsReducerAction | Ge...

FILE: src/hooks/useSchemaSuggestionsProvider.ts
  type SchemaCache (line 6) | interface SchemaCache {
  function defaultSchemaCache (line 13) | function defaultSchemaCache(): SchemaCache {
  function useSchemaSuggestionsProvider (line 29) | function useSchemaSuggestionsProvider(datasource: Datasource): Schema {

FILE: src/otel.ts
  type OtelVersion (line 8) | interface OtelVersion {

FILE: src/tracking.test.ts
  type AnalyzeQueriesTestCase (line 5) | interface AnalyzeQueriesTestCase {

FILE: src/tracking.ts
  type ClickhouseCounters (line 16) | type ClickhouseCounters = {
  type ClickhouseDashboardLoadedProps (line 38) | interface ClickhouseDashboardLoadedProps extends ClickhouseCounters {

FILE: src/types/config.ts
  type CHConfig (line 5) | interface CHConfig extends DataSourceJsonData {
  type CHSecureConfigProperties (line 50) | interface CHSecureConfigProperties {
  type CHSecureConfig (line 57) | type CHSecureConfig = CHSecureConfigProperties | KeyValue<string>;
  type CHHttpHeader (line 59) | interface CHHttpHeader {
  type CHCustomSetting (line 65) | interface CHCustomSetting {
  type CHLogsConfig (line 70) | interface CHLogsConfig {
  type CHTracesConfig (line 87) | interface CHTracesConfig {
  type AliasTableEntry (line 125) | interface AliasTableEntry {
  type Protocol (line 132) | enum Protocol {

FILE: src/types/queryBuilder.ts
  type FieldLabel (line 1) | interface FieldLabel {
  type BuilderMode (line 6) | enum BuilderMode {
  type QueryType (line 15) | enum QueryType {
  type QueryBuilderOptions (line 22) | interface QueryBuilderOptions {
  type AggregateType (line 83) | enum AggregateType {
  type AggregateColumn (line 93) | type AggregateColumn = {
  type Field (line 99) | interface Field {
  type FullEntity (line 107) | interface FullEntity {
  type TableColumnPickListItem (line 114) | interface TableColumnPickListItem {
  type TableColumn (line 122) | interface TableColumn {
  type SqlFunction (line 133) | interface SqlFunction {
  type ColumnHint (line 152) | enum ColumnHint {
  type TimeUnit (line 185) | enum TimeUnit {
  type SelectedColumn (line 195) | interface SelectedColumn {
  type OrderByDirection (line 203) | enum OrderByDirection {
  type OrderBy (line 208) | interface OrderBy {
  type FilterOperator (line 223) | enum FilterOperator {
  type CommonFilterProps (line 253) | interface CommonFilterProps {
  type NullFilter (line 286) | interface NullFilter extends CommonFilterProps {
  type BooleanFilter (line 290) | interface BooleanFilter extends CommonFilterProps {
  type StringFilter (line 296) | interface StringFilter extends CommonFilterProps {
  type NumberFilter (line 310) | interface NumberFilter extends CommonFilterProps {
  type DateFilterWithValue (line 322) | interface DateFilterWithValue extends CommonFilterProps {
  type DateFilterWithoutValue (line 335) | interface DateFilterWithoutValue extends CommonFilterProps {
  type DateFilter (line 340) | type DateFilter = DateFilterWithValue | DateFilterWithoutValue;
  type MultiFilter (line 342) | interface MultiFilter extends CommonFilterProps {
  type Filter (line 347) | type Filter = NullFilter | BooleanFilter | NumberFilter | DateFilter | S...

FILE: src/types/sql.ts
  type EditorType (line 7) | enum EditorType {
  type CHQueryBase (line 12) | interface CHQueryBase extends DataQuery {
  type CHSqlQuery (line 25) | interface CHSqlQuery extends CHQueryBase {
  type CHBuilderQuery (line 36) | interface CHBuilderQuery extends CHQueryBase {
  type CHQuery (line 44) | type CHQuery = CHSqlQuery | CHBuilderQuery;

FILE: src/utils/version.ts
  class SemVersion (line 8) | class SemVersion {
    method constructor (line 14) | constructor(version: string) {
    method isGtOrEq (line 29) | isGtOrEq(version: string): boolean {
    method isValid (line 43) | isValid(): boolean {
    method comparable (line 47) | get comparable() {
  function isVersionGtOrEq (line 52) | function isVersionGtOrEq(a: string, b: string): boolean {

FILE: src/views/CHConfigEditor.tsx
  type ConfigEditorProps (line 33) | interface ConfigEditorProps extends DataSourcePluginOptionsEditorProps<C...

FILE: src/views/CHConfigEditorHooks.ts
  type ValidationAPI (line 11) | interface ValidationAPI {
  method registerValidation (line 158) | registerValidation(validator: () => Promise<boolean> | boolean): () => v...
  method validate (line 163) | async validate(): Promise<boolean> {
  method isValid (line 168) | isValid(): boolean {
  method getErrors (line 172) | getErrors(): Record<string, string> {
  method setError (line 176) | setError(field: string, message: string): void {
  method clearError (line 180) | clearError(field: string): void {

FILE: src/views/CHQueryEditor.tsx
  type CHQueryEditorProps (line 18) | type CHQueryEditorProps = QueryEditorProps<Datasource, CHQuery, CHConfig>;

FILE: src/views/config-v2/AdditionalSettingsSection.tsx
  type Props (line 53) | interface Props extends DataSourcePluginOptionsEditorProps<CHConfig, CHS...

FILE: src/views/config-v2/AliasTableConfigV2.tsx
  type AliasTablesConfigProps (line 10) | interface AliasTablesConfigProps {
  type AliasTableEditorProps (line 106) | interface AliasTableEditorProps {

FILE: src/views/config-v2/CHConfigEditor.tsx
  type ConfigEditorProps (line 16) | interface ConfigEditorProps extends DataSourcePluginOptionsEditorProps<C...

FILE: src/views/config-v2/DatabaseCredentialsSection.tsx
  type Props (line 18) | interface Props extends DataSourcePluginOptionsEditorProps<CHConfig, CHS...

FILE: src/views/config-v2/HttpHeadersConfigV2.tsx
  type HttpHeadersConfigProps (line 9) | interface HttpHeadersConfigProps extends DataSourcePluginOptionsEditorPr...
  type HttpHeaderEditorProps (line 84) | interface HttpHeaderEditorProps {

FILE: src/views/config-v2/HttpProtocolSettingsSection.tsx
  type HttpProtocolSettingsSectionProps (line 10) | interface HttpProtocolSettingsSectionProps

FILE: src/views/config-v2/LeftSidebar.tsx
  type LeftSidebarProps (line 5) | interface LeftSidebarProps {

FILE: src/views/config-v2/ServerAndEncryptionSection.tsx
  type Props (line 34) | interface Props extends DataSourcePluginOptionsEditorProps<CHConfig, CHS...

FILE: src/views/config-v2/TLSSSLSettingsSection.tsx
  type Props (line 14) | interface Props extends DataSourcePluginOptionsEditorProps<CHConfig, CHS...

FILE: src/views/config-v2/constants.ts
  constant CONTAINER_MIN_WIDTH (line 3) | const CONTAINER_MIN_WIDTH = '450px';
  constant CONFIG_SECTION_HEADERS (line 5) | const CONFIG_SECTION_HEADERS = [
  constant CONFIG_SECTION_HEADERS_WITH_PDC (line 13) | const CONFIG_SECTION_HEADERS_WITH_PDC = [

FILE: tests/e2e/adhocRegexFilter.spec.ts
  constant PLUGIN_TYPE (line 4) | const PLUGIN_TYPE = 'grafana-clickhouse-datasource';
  constant CLOUD_DEFAULT_UID (line 8) | const CLOUD_DEFAULT_UID = 'clickhouse-native-ds-m';
  constant LOCAL_DEFAULT_UID (line 9) | const LOCAL_DEFAULT_UID = 'clickhouse-e2e';
  constant DATASOURCE_UID (line 10) | const DATASOURCE_UID = process.env.DS_E2E_UID || (isCloudRun ? CLOUD_DEF...
  constant FIXTURE_FROM_ISO (line 13) | const FIXTURE_FROM_ISO = '2024-03-15T09:45:00.000Z';
  constant FIXTURE_TO_ISO (line 14) | const FIXTURE_TO_ISO = '2024-03-15T10:15:00.000Z';
  function exploreUrl (line 16) | function exploreUrl(from = FIXTURE_FROM_ISO, to = FIXTURE_TO_ISO): string {
  function enterSql (line 34) | async function enterSql(page: Page, sql: string) {
  function waitForQueryDataResponseWithBody (line 46) | async function waitForQueryDataResponseWithBody(explorePage: ExplorePage) {

FILE: tests/e2e/columnRoles.spec.ts
  constant PLUGIN_TYPE (line 6) | const PLUGIN_TYPE = 'grafana-clickhouse-datasource';
  constant CLOUD_DEFAULT_UID (line 10) | const CLOUD_DEFAULT_UID = 'clickhouse-native-ds-m';
  constant LOCAL_DEFAULT_UID (line 11) | const LOCAL_DEFAULT_UID = 'clickhouse-e2e';
  constant DATASOURCE_UID (line 12) | const DATASOURCE_UID = process.env.DS_E2E_UID || (isCloudRun ? CLOUD_DEF...
  constant COLUMN_ROLES_DOCS_PATH (line 15) | const COLUMN_ROLES_DOCS_PATH = 'https://grafana.com/docs/plugins/grafana...
  type ExploreUrlOpts (line 17) | interface ExploreUrlOpts {
  function exploreUrl (line 27) | function exploreUrl(opts: ExploreUrlOpts = {}): string {
  function switchToBuilderMode (line 58) | async function switchToBuilderMode(page: Page, queryType?: QueryType) {
  function queryTypeRadioLabel (line 78) | function queryTypeRadioLabel(queryType: QueryType): string {
  function labelLocator (line 96) | function labelLocator(page: Page, labelText: string): Locator {
  function readTooltip (line 105) | async function readTooltip(page: Page, label: Locator): Promise<string> {

FILE: tests/e2e/configEditor.spec.ts
  constant PLUGIN_UID (line 5) | const PLUGIN_UID = 'grafana-clickhouse-datasource';
  constant PROVISIONING_FILE (line 6) | const PROVISIONING_FILE = 'clickhouse.yml';
  function resolveClickhouseUrl (line 13) | function resolveClickhouseUrl(env = process.env) {
  function configurePDC (line 18) | async function configurePDC(page: Page, networkName: string) {
  function isV2Editor (line 29) | async function isV2Editor(page: Page): Promise<boolean> {

FILE: tests/e2e/fixtures/seed.sql
  type e2e_test (line 10) | CREATE TABLE IF NOT EXISTS e2e_test.events

FILE: tests/e2e/fixtures/trace_spans.sql
  type e2e_test (line 15) | CREATE TABLE IF NOT EXISTS e2e_test.trace_spans

FILE: tests/e2e/queryEditor.spec.ts
  constant PLUGIN_TYPE (line 6) | const PLUGIN_TYPE = 'grafana-clickhouse-datasource';
  constant CLOUD_DEFAULT_UID (line 18) | const CLOUD_DEFAULT_UID = 'clickhouse-native-ds-m';
  constant LOCAL_DEFAULT_UID (line 19) | const LOCAL_DEFAULT_UID = 'clickhouse-e2e';
  constant DATASOURCE_UID (line 20) | const DATASOURCE_UID = process.env.DS_E2E_UID || (isCloudRun ? CLOUD_DEF...
  constant FIXTURE_FROM_ISO (line 23) | const FIXTURE_FROM_ISO = '2024-03-15T09:45:00.000Z';
  constant FIXTURE_TO_ISO (line 24) | const FIXTURE_TO_ISO = '2024-03-15T10:15:00.000Z';
  type ExploreUrlOpts (line 26) | interface ExploreUrlOpts {
  function exploreUrl (line 39) | function exploreUrl(opts: ExploreUrlOpts = {}): string {
  function switchToBuilderMode (line 66) | async function switchToBuilderMode(page: Page) {
  function enterSql (line 82) | async function enterSql(page: Page, sql: string) {
  function waitForQueryDataResponseWithBody (line 96) | async function waitForQueryDataResponseWithBody(explorePage: ExplorePage) {

FILE: tests/e2e/sqlAutocomplete.spec.ts
  constant PLUGIN_TYPE (line 4) | const PLUGIN_TYPE = 'grafana-clickhouse-datasource';
  constant CLOUD_DEFAULT_UID (line 9) | const CLOUD_DEFAULT_UID = 'clickhouse-native-ds-m';
  constant LOCAL_DEFAULT_UID (line 10) | const LOCAL_DEFAULT_UID = 'clickhouse-e2e';
  constant DATASOURCE_UID (line 11) | const DATASOURCE_UID = process.env.DS_E2E_UID || (isCloudRun ? CLOUD_DEF...
  function exploreUrl (line 13) | function exploreUrl(): string {
  function focusEditorAndType (line 33) | async function focusEditorAndType(page: Page, text: string) {
  function captureMacroLabels (line 43) | async function captureMacroLabels(page: Page): Promise<string[]> {
  function findDuplicates (line 52) | function findDuplicates(labels: string[]): string[] {

FILE: tests/e2e/sqlValidation.spec.ts
  constant PLUGIN_TYPE (line 4) | const PLUGIN_TYPE = 'grafana-clickhouse-datasource';
  constant CLOUD_DEFAULT_UID (line 15) | const CLOUD_DEFAULT_UID = 'clickhouse-native-ds-m';
  constant LOCAL_DEFAULT_UID (line 16) | const LOCAL_DEFAULT_UID = 'clickhouse-e2e';
  constant DATASOURCE_UID (line 17) | const DATASOURCE_UID = process.env.DS_E2E_UID || (isCloudRun ? CLOUD_DEF...
  function exploreUrl (line 23) | function exploreUrl(): string {
  function enterSql (line 48) | async function enterSql(page: Page, sql: string) {
  function expectNoErrorMarkers (line 64) | async function expectNoErrorMarkers(page: Page) {
  function expectHasErrorMarker (line 70) | async function expectHasErrorMarker(page: Page) {

FILE: tests/e2e/traceLimit.spec.ts
  constant PLUGIN_TYPE (line 21) | const PLUGIN_TYPE = 'grafana-clickhouse-datasource';
  constant CLOUD_DEFAULT_UID (line 25) | const CLOUD_DEFAULT_UID = 'clickhouse-native-ds-m';
  constant LOCAL_DEFAULT_UID (line 26) | const LOCAL_DEFAULT_UID = 'clickhouse-e2e';
  constant DATASOURCE_UID (line 27) | const DATASOURCE_UID = process.env.DS_E2E_UID || (isCloudRun ? CLOUD_DEF...
  constant FIXTURE_FROM_ISO (line 31) | const FIXTURE_FROM_ISO = '2024-03-15T09:45:00.000Z';
  constant FIXTURE_TO_ISO (line 32) | const FIXTURE_TO_ISO = '2024-03-15T10:15:00.000Z';
  constant TRACE_ID (line 33) | const TRACE_ID = 'e2e-trace-a';
  constant EXPECTED_SPAN_COUNT (line 34) | const EXPECTED_SPAN_COUNT = 5;
  function exploreUrl (line 36) | function exploreUrl(from: string, to: string): string {
  function enterSql (line 50) | async function enterSql(page: Page, sql: string) {
  function waitForQueryDataResponseWithBody (line 57) | async function waitForQueryDataResponseWithBody(explorePage: ExplorePage) {

FILE: tests/fixtures/property-prices.sql
  type uk_price_paid (line 5) | CREATE TABLE uk_price_paid
Condensed preview — 293 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,156K chars).
[
  {
    "path": ".config/.cprc.json",
    "chars": 43,
    "preview": "{\n  \"version\": \"6.4.4\",\n  \"features\": {}\n}\n"
  },
  {
    "path": ".config/.prettierrc.js",
    "chars": 371,
    "preview": "/*\n * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️\n *\n * In order"
  },
  {
    "path": ".config/Dockerfile",
    "chars": 2467,
    "preview": "ARG grafana_version=latest\nARG grafana_image=grafana-enterprise\n\nFROM grafana/${grafana_image}:${grafana_version}\n\nARG a"
  },
  {
    "path": ".config/README.md",
    "chars": 5105,
    "preview": "# Default build configuration by Grafana\n\n**This is an auto-generated directory and is not intended to be changed! ⚠️**\n"
  },
  {
    "path": ".config/bundler/externals.ts",
    "chars": 1111,
    "preview": "import type { Configuration, ExternalItemFunctionData } from 'webpack';\n\ntype ExternalsType = Configuration['externals']"
  },
  {
    "path": ".config/docker-compose-base.yaml",
    "chars": 947,
    "preview": "services:\n  grafana:\n    user: root\n    container_name: 'grafana-clickhouse-datasource'\n\n    build:\n      context: .\n   "
  },
  {
    "path": ".config/entrypoint.sh",
    "chars": 388,
    "preview": "#!/bin/sh\n\nif [ \"${DEV}\" = \"false\" ]; then\n    echo \"Starting test mode\"\n    exec /run.sh\nfi\n\necho \"Starting development"
  },
  {
    "path": ".config/eslint.config.mjs",
    "chars": 538,
    "preview": "import { defineConfig } from 'eslint/config';\nimport grafanaConfig from '@grafana/eslint-config/flat.js';\n\nexport defaul"
  },
  {
    "path": ".config/jest/mocks/react-inlinesvg.tsx",
    "chars": 857,
    "preview": "// Due to the grafana/ui Icon component making fetch requests to\n// `/public/img/icon/<icon_name>.svg` we need to mock r"
  },
  {
    "path": ".config/jest/utils.js",
    "chars": 980,
    "preview": "/*\n * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️\n *\n * In order"
  },
  {
    "path": ".config/jest-setup.js",
    "chars": 903,
    "preview": "/*\n * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️\n *\n * In order"
  },
  {
    "path": ".config/jest.config.js",
    "chars": 1520,
    "preview": "/*\n * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️\n *\n * In order"
  },
  {
    "path": ".config/supervisord/supervisord.conf",
    "chars": 1437,
    "preview": "[supervisord]\nnodaemon=true\nuser=root\n\n[program:grafana]\nuser=root\ndirectory=/var/lib/grafana\ncommand=bash -c 'while [ !"
  },
  {
    "path": ".config/tsconfig.json",
    "chars": 722,
    "preview": "/*\n * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️\n *\n * In order"
  },
  {
    "path": ".config/types/bundler-rules.d.ts",
    "chars": 594,
    "preview": "// Image declarations\ndeclare module '*.gif' {\n  const src: string;\n  export default src;\n}\n\ndeclare module '*.jpg' {\n  "
  },
  {
    "path": ".config/types/custom.d.ts",
    "chars": 602,
    "preview": "// Image declarations\ndeclare module '*.gif' {\n  const src: string;\n  export default src;\n}\n\ndeclare module '*.jpg' {\n  "
  },
  {
    "path": ".config/types/setupTests.d.ts",
    "chars": 36,
    "preview": "import '@testing-library/jest-dom';\n"
  },
  {
    "path": ".config/types/webpack-plugins.d.ts",
    "chars": 2429,
    "preview": "declare module 'replace-in-file-webpack-plugin' {\n  import { Compiler, Plugin } from 'webpack';\n\n  interface ReplaceRule"
  },
  {
    "path": ".config/webpack/BuildModeWebpackPlugin.ts",
    "chars": 1064,
    "preview": "import webpack, { type Compiler } from 'webpack';\n\nconst PLUGIN_NAME = 'BuildModeWebpack';\n\nexport class BuildModeWebpac"
  },
  {
    "path": ".config/webpack/constants.ts",
    "chars": 65,
    "preview": "export const SOURCE_DIR = 'src';\nexport const DIST_DIR = 'dist';\n"
  },
  {
    "path": ".config/webpack/utils.ts",
    "chars": 2020,
    "preview": "import fs from 'fs';\nimport process from 'process';\nimport os from 'os';\nimport path from 'path';\nimport { glob } from '"
  },
  {
    "path": ".config/webpack/webpack.config.ts",
    "chars": 7818,
    "preview": "/*\n * ⚠️⚠️⚠️ THIS FILE WAS SCAFFOLDED BY `@grafana/create-plugin`. DO NOT EDIT THIS FILE DIRECTLY. ⚠️⚠️⚠️\n *\n * In order"
  },
  {
    "path": ".cprc.json",
    "chars": 120,
    "preview": "{\n  \"features\": {\n    \"bundleGrafanaUI\": false,\n    \"useReactRouterV6\": false,\n    \"useExperimentalRspack\": false\n  }\n}\n"
  },
  {
    "path": ".cursor/rules/word-list.mdc",
    "chars": 237,
    "preview": "---\ndescription: Project word list and preferred spelling\nalwaysApply: true\n---\n\n# Word list\n\nUse these spellings in thi"
  },
  {
    "path": ".github/CODEOWNERS",
    "chars": 516,
    "preview": "# Lines starting with '#' are comments.\n# Each line is a file pattern followed by one or more owners.\n\n# More details ar"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1-bug_report.md",
    "chars": 1047,
    "preview": "---\nname: Bug report\nabout: Report a bug you found when using this plugin\nlabels: ['datasource/ClickHouse', 'type/bug']\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 310,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: Feature Request\n    url: https://github.com/grafana/clickhouse-data"
  },
  {
    "path": ".github/issue_commands.json",
    "chars": 727,
    "preview": "[\n  {\n    \"type\": \"label\",\n    \"name\": \"datasource/ClickHouse\",\n    \"action\": \"addToProject\",\n    \"addToProject\": {\n    "
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 2480,
    "preview": "<!-- Please take time to fill out the below template appropriately, deleting sections where necessary. -->\n<!-- Doing so"
  },
  {
    "path": ".github/release.yml",
    "chars": 182,
    "preview": "changelog:\n  categories:\n    - title: Copy the following lines for the CHANGELOG\n      labels:\n        - changelog\n    -"
  },
  {
    "path": ".github/renovate.json",
    "chars": 2622,
    "preview": "{\n    \"$schema\": \"https://docs.renovatebot.com/renovate-schema.json\",\n    \"extends\": [\n        \"github>grafana/grafana-r"
  },
  {
    "path": ".github/workflows/cron.yml",
    "chars": 655,
    "preview": "name: Scheduled Cloud E2E tests\n\non:\n  # Run nightly against the shared Cloud instance\n  schedule:\n    - cron: '0 9 * * "
  },
  {
    "path": ".github/workflows/detect-breaking-changes.yml",
    "chars": 778,
    "preview": "name: Compatibility check\non: [push, pull_request]\n\njobs:\n  compatibilitycheck:\n    runs-on: ubuntu-latest\n    steps:\n  "
  },
  {
    "path": ".github/workflows/integration.yml",
    "chars": 886,
    "preview": "name: Integration tests\n\non:\n  push:\n    branches:\n      - v1\n      - main\n  pull_request:\n    branches:\n      - v1\n    "
  },
  {
    "path": ".github/workflows/issue_commands.yml",
    "chars": 596,
    "preview": "name: Run commands when issues are labeled\non:\n  issues:\n    types: [labeled]\njobs:\n  main:\n    runs-on: ubuntu-latest\n "
  },
  {
    "path": ".github/workflows/publish.yml",
    "chars": 1616,
    "preview": "name: Plugins - CD\nrun-name: Deploy ${{ inputs.branch }} to ${{ inputs.environment }} by @${{ github.actor }}\n\non:\n  wor"
  },
  {
    "path": ".github/workflows/push.yml",
    "chars": 1793,
    "preview": "name: Plugins - CI\n\non:\n  # Run CI on all PRs\n  pull_request:\n\n  # Also run on pushes to main (used for publish + downst"
  },
  {
    "path": ".github/workflows/stale.yml",
    "chars": 1981,
    "preview": "name: 'Close stale issues and PRs'\n\non:\n  schedule:\n    - cron: '30 1 * * *'\n  workflow_dispatch:\n\npermissions:\n  conten"
  },
  {
    "path": ".github/zizmor.yml",
    "chars": 214,
    "preview": "# This is also used as the default configuration for the Zizmor reusable\n# workflow.\n\nrules:\n  unpinned-uses:\n    config"
  },
  {
    "path": ".gitignore",
    "chars": 528,
    "preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\nnode_modules/\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid."
  },
  {
    "path": ".nvmrc",
    "chars": 3,
    "preview": "22\n"
  },
  {
    "path": ".prettierrc.js",
    "chars": 124,
    "preview": "module.exports = {\n  // Prettier configuration provided by Grafana scaffolding\n  ...require('./.config/.prettierrc.js'),"
  },
  {
    "path": ".vscode/launch.json",
    "chars": 844,
    "preview": "{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n    {\n      \"name\": \"Run standalone plugin\",\n      \"type\": \"go\",\n      \"re"
  },
  {
    "path": ".vscode/settings.json",
    "chars": 103,
    "preview": "{\n  \"gopls\": {\n    \"buildFlags\": [\"-tags=integration\"]\n  },\n  \"specstory.cloudSync.enabled\": \"never\"\n}\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 24005,
    "preview": "# Changelog\n\n## 4.17.1\n\n### Fixes\n\n- Dependency updates\n\n## 4.17.0\n\n### Features\n\n- Allow `$__adhocFilters` macro to wor"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2972,
    "preview": "# Contributing to ClickHouse Datasource\n\nThank you for your interest in contributing to this repository. We are glad you"
  },
  {
    "path": "DEV_GUIDE.md",
    "chars": 4315,
    "preview": "# Guide to get Clickhouse running\n\n## Add a directory where the database files will mount to from your docker container\n"
  },
  {
    "path": "LICENSE",
    "chars": 11347,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Magefile.go",
    "chars": 324,
    "preview": "//+build mage\n\npackage main\n\nimport (\n\t\"fmt\"\n\t// mage:import\n\tbuild \"github.com/grafana/grafana-plugin-sdk-go/build\"\n)\n\n"
  },
  {
    "path": "README.md",
    "chars": 390,
    "preview": "### ClickHouse Support\n\nGrafana supports ClickHouse through a plugin. You can perform a variety of simple or complex Cli"
  },
  {
    "path": "config/admin.xml",
    "chars": 438,
    "preview": "<clickhouse>\n    <!-- Profiles of settings. -->\n    <profiles>\n        <!-- Default settings. -->\n        <default>\n    "
  },
  {
    "path": "config/config-preprocessed.xml",
    "chars": 1117,
    "preview": "<!-- This file was generated automatically.\n     Do not edit it: it is likely to be discarded and generated again before"
  },
  {
    "path": "config/config.xml",
    "chars": 61295,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n  NOTE: User and query level settings are set up in \"users.xml\" file.\n  If you have accidenta"
  },
  {
    "path": "config/custom.xml",
    "chars": 240,
    "preview": "<?xml version=\"1.0\" ?>\n<clickhouse>\n    <listen_host>::</listen_host>\n    <listen_host>0.0.0.0</listen_host>\n    <listen"
  },
  {
    "path": "config/server.crt",
    "chars": 985,
    "preview": "-----BEGIN CERTIFICATE-----\nMIICqjCCAZICCQCmreUKLiQrrzANBgkqhkiG9w0BAQsFADAXMRUwEwYDVQQDDAxt\neS5ob3N0Lm5hbWUwHhcNMjExMjE"
  },
  {
    "path": "config/server.key",
    "chars": 1704,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBt3kbY3SwS89o\nNQhllMyK+AumX9d01bbU1ZFcLJc"
  },
  {
    "path": "config/users.xml",
    "chars": 6236,
    "preview": "<?xml version=\"1.0\"?>\n<clickhouse>\n    <!-- See also the files in users.d directory where the settings can be overridden"
  },
  {
    "path": "config-secure/config.xml",
    "chars": 61295,
    "preview": "<?xml version=\"1.0\"?>\n<!--\n  NOTE: User and query level settings are set up in \"users.xml\" file.\n  If you have accidenta"
  },
  {
    "path": "config-secure/my-own-ca.crt",
    "chars": 1123,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDEDCCAfigAwIBAgIUeyhiP/kbQCZacNPgv+BdoUBN6PcwDQYJKoZIhvcNAQEL\nBQAwDzENMAsGA1UEAwwEcm9vdDA"
  },
  {
    "path": "config-secure/my-own-ca.key",
    "chars": 1704,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDNU3zvxLjeTDnR\ni2Vlqd3UaO8ViV/jjQwj6Gtx7Qc"
  },
  {
    "path": "config-secure/my-own-ca.srl",
    "chars": 17,
    "preview": "F1882B6FB9749F92\n"
  },
  {
    "path": "config-secure/server.crt",
    "chars": 1131,
    "preview": "-----BEGIN CERTIFICATE-----\nMIIDFTCCAf2gAwIBAgIUT3+4BMdujNm5CYsgrvGHHq+1CtIwDQYJKoZIhvcNAQEL\nBQAwDzENMAsGA1UEAwwEcm9vdDA"
  },
  {
    "path": "config-secure/server.csr",
    "chars": 883,
    "preview": "-----BEGIN CERTIFICATE REQUEST-----\nMIICUzCCATsCAQAwDjEMMAoGA1UEAwwDZm9vMIIBIjANBgkqhkiG9w0BAQEFAAOC\nAQ8AMIIBCgKCAQEA5W3"
  },
  {
    "path": "config-secure/server.ext",
    "chars": 193,
    "preview": "authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage = digitalSignature, nonRepudiation, keyEncipherme"
  },
  {
    "path": "config-secure/server.key",
    "chars": 1704,
    "preview": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDlbfAPxHTBkTwC\nAfoxKgHi5VyRYA4Bq+XMnwzF9hJ"
  },
  {
    "path": "config-secure/users.xml",
    "chars": 6236,
    "preview": "<?xml version=\"1.0\"?>\n<clickhouse>\n    <!-- See also the files in users.d directory where the settings can be overridden"
  },
  {
    "path": "cspell.config.json",
    "chars": 1961,
    "preview": "{\n  \"ignorePaths\": [\n    \"node_modules/**\",\n    \"coverage/**\",\n    \"provisioning/**\",\n    \"src/dashboards/**\",\n    \"dist"
  },
  {
    "path": "docker-compose.yml",
    "chars": 2154,
    "preview": "services:\n  grafana:\n    extends:\n      file: .config/docker-compose-base.yaml\n      service: grafana\n    depends_on:\n  "
  },
  {
    "path": "docs/Makefile",
    "chars": 175,
    "preview": ".ONESHELL:\n.DELETE_ON_ERROR:\nexport SHELL := bash\nexport SHELLOPTS := pipefail:errexit\nMAKEFLAGS += --warn-undefined-var"
  },
  {
    "path": "docs/docs.mk",
    "chars": 4241,
    "preview": "# The source of this file is https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/docs.mk.\n# A changelog "
  },
  {
    "path": "docs/make-docs",
    "chars": 28191,
    "preview": "#!/bin/sh\n# shellcheck disable=SC2034\n#\n# The source of this file is https://raw.githubusercontent.com/grafana/writers-t"
  },
  {
    "path": "docs/sources/_index.md",
    "chars": 4481,
    "preview": "---\ndescription: This document introduces the ClickHouse data source\nlabels:\nproducts:\n  - Grafana Cloud\n  - Grafana OSS"
  },
  {
    "path": "docs/sources/alerting.md",
    "chars": 11265,
    "preview": "---\ndescription: Create alert rules from ClickHouse queries\nlabels:\nproducts:\n  - Grafana Cloud\n  - Grafana OSS\n  - Graf"
  },
  {
    "path": "docs/sources/annotations.md",
    "chars": 7130,
    "preview": "---\ndescription: Use ClickHouse queries to create annotations on dashboards\nlabels:\nproducts:\n  - Grafana Cloud\n  - Graf"
  },
  {
    "path": "docs/sources/configure.md",
    "chars": 18895,
    "preview": "---\ndescription: Configure the ClickHouse data source for Grafana, including connection, TLS, logs, traces, and provisio"
  },
  {
    "path": "docs/sources/query-editor.md",
    "chars": 18068,
    "preview": "---\ndescription: This document describes the ClickHouse query editor\nlabels:\nproducts:\n  - Grafana Cloud\n  - Grafana OSS"
  },
  {
    "path": "docs/sources/template-variables.md",
    "chars": 14820,
    "preview": "---\ndescription: Use template variables with the ClickHouse data source to build dynamic dashboards\nlabels:\nproducts:\n  "
  },
  {
    "path": "docs/sources/troubleshooting.md",
    "chars": 28910,
    "preview": "---\ndescription: Solutions for common errors when using the ClickHouse data source\nlabels:\nproducts:\n  - Grafana Cloud\n "
  },
  {
    "path": "docs/variables.mk",
    "chars": 694,
    "preview": "# List of projects to provide to the make-docs script.\n# Format is PROJECT[:[VERSION][:[REPOSITORY][:[DIRECTORY]]]]\n# Th"
  },
  {
    "path": "eslint.config.mjs",
    "chars": 793,
    "preview": "import { defineConfig } from 'eslint/config';\nimport baseConfig from './.config/eslint.config.mjs';\n\nexport default defi"
  },
  {
    "path": "gen-db-dashboards.js",
    "chars": 6906,
    "preview": "/**\n * This script will code-gen a Grafana dashboard using the \"system.dashboards\" table in a locally running ClickHouse"
  },
  {
    "path": "go.mod",
    "chars": 8647,
    "preview": "module github.com/grafana/clickhouse-datasource\n\ngo 1.26.0\n\nrequire (\n\tgithub.com/ClickHouse/clickhouse-go/v2 v2.45.0\n\tg"
  },
  {
    "path": "go.sum",
    "chars": 44675,
    "preview": "dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=\ndario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMI"
  },
  {
    "path": "jest-runner-serial.js",
    "chars": 232,
    "preview": "const JestRunner = require('jest-runner');\n\nclass SerialJestRunner extends JestRunner {\n  constructor(...args) {\n    sup"
  },
  {
    "path": "jest-setup.js",
    "chars": 490,
    "preview": "// Jest setup provided by Grafana scaffolding\nimport './.config/jest-setup';\nimport { TextEncoder, TextDecoder } from 'u"
  },
  {
    "path": "jest.config.js",
    "chars": 281,
    "preview": "// force timezone to UTC to allow tests to work regardless of local timezone\n// generally used by snapshots, but can aff"
  },
  {
    "path": "otel-semconv.yaml",
    "chars": 6161,
    "preview": "# otel-semconv.yaml — generated by otel-scout on 2026-03-19\n\nplugin_id: grafana-clickhouse-datasource\nrepo: grafana/clic"
  },
  {
    "path": "package.json",
    "chars": 4224,
    "preview": "{\n  \"name\": \"clickhouse-datasource\",\n  \"version\": \"4.17.1\",\n  \"description\": \"Clickhouse Datasource\",\n  \"engines\": {\n   "
  },
  {
    "path": "pkg/converters/converters.go",
    "chars": 16581,
    "preview": "package converters\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"math/big\"\n\t\"net\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time"
  },
  {
    "path": "pkg/converters/converters_test.go",
    "chars": 19309,
    "preview": "package converters\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"math/big\"\n\t\"net\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/ClickHouse/c"
  },
  {
    "path": "pkg/macros/macros.go",
    "chars": 5673,
    "preview": "package macros\n\nimport (\n\t\"fmt\"\n\t\"math\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/grafana/sqlds/v5\"\n\n\t\"github.com/grafana/grafana"
  },
  {
    "path": "pkg/macros/macros_test.go",
    "chars": 9533,
    "preview": "package macros\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/grafana/grafana-plugin-sdk-go/backend\"\n\t\"github.com/gra"
  },
  {
    "path": "pkg/main.go",
    "chars": 401,
    "preview": "package main\n\nimport (\n\t\"os\"\n\n\t\"github.com/grafana/clickhouse-datasource/pkg/plugin\"\n\t\"github.com/grafana/grafana-plugin"
  },
  {
    "path": "pkg/plugin/connection_error.go",
    "chars": 4997,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"net\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/ClickHouse/c"
  },
  {
    "path": "pkg/plugin/connection_error_test.go",
    "chars": 8219,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"fmt\"\n\t\"net\"\n\t\"testing\"\n\n\t\"github.com/ClickHouse/click"
  },
  {
    "path": "pkg/plugin/datasource.go",
    "chars": 1931,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\n\t\"github.com/grafana/grafana-plugin-sdk-go/backend\"\n\t\"github.com/grafana/grafana-pl"
  },
  {
    "path": "pkg/plugin/driver.go",
    "chars": 20518,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"crypto/x509\"\n\t\"database/sql\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net\"\n\t\"regexp"
  },
  {
    "path": "pkg/plugin/driver_integration_test.go",
    "chars": 43476,
    "preview": "//go:build integration\n// +build integration\n\npackage plugin\n\nimport (\n\t\"context\"\n\t\"crypto/tls\"\n\t\"database/sql\"\n\t\"encodi"
  },
  {
    "path": "pkg/plugin/driver_test.go",
    "chars": 13670,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/ClickHouse/clickhouse-go/"
  },
  {
    "path": "pkg/plugin/errors.go",
    "chars": 716,
    "preview": "package plugin\n\nimport \"github.com/pkg/errors\"\n\nvar (\n\tErrorMessageInvalidJSON       = errors.New(\"could not parse json\""
  },
  {
    "path": "pkg/plugin/schema.go",
    "chars": 19278,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github"
  },
  {
    "path": "pkg/plugin/schema_test.go",
    "chars": 12036,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"sync\"\n\t\"sy"
  },
  {
    "path": "pkg/plugin/schemacache/cache.go",
    "chars": 4195,
    "preview": "// Package schemacache is a TTL + singleflight cache for ClickHouse schema\n// introspection queries (system.tables, syst"
  },
  {
    "path": "pkg/plugin/schemacache/cache_bench_test.go",
    "chars": 2880,
    "preview": "package schemacache\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n)\n\n// simulatedRoundTrip mimics the latency p"
  },
  {
    "path": "pkg/plugin/schemacache/cache_test.go",
    "chars": 6969,
    "preview": "package schemacache\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"sync\"\n\t\"sync/atomic\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestCache_Ge"
  },
  {
    "path": "pkg/plugin/settings.go",
    "chars": 11130,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/ClickHouse/click"
  },
  {
    "path": "pkg/plugin/settings_test.go",
    "chars": 11027,
    "preview": "package plugin\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/ClickHouse/clickhouse-g"
  },
  {
    "path": "playwright.config.ts",
    "chars": 1862,
    "preview": "import { dirname } from 'path';\n\nimport { defineConfig, devices } from '@playwright/test';\nimport type { PluginOptions }"
  },
  {
    "path": "provisioning/datasources/clickhouse.yml",
    "chars": 725,
    "preview": "# Configuration file version\napiVersion: 1\n\n# List of data sources to delete from the database.\ndeleteDatasources:\n  - n"
  },
  {
    "path": "scripts/ca-cert.sh",
    "chars": 636,
    "preview": "# Generate server.key and server.crt signed by our local CA. \nopenssl genrsa -out $PWD/config-secure/server.key 2048\n# T"
  },
  {
    "path": "scripts/ca.ext",
    "chars": 194,
    "preview": "authorityKeyIdentifier=keyid,issuer\nbasicConstraints=CA:FALSE\nkeyUsage = digitalSignature, nonRepudiation, keyEncipherme"
  },
  {
    "path": "scripts/ca.sh",
    "chars": 529,
    "preview": "# create a ca certificate\n\nopenssl genrsa -out $PWD/config-secure/my-own-ca.key 2048\nopenssl req -new -x509 -days 3650 -"
  },
  {
    "path": "scripts/certs.sh",
    "chars": 140,
    "preview": "openssl req -subj \"/CN=foo\" -new \\\n-newkey rsa:2048 -days 365 -nodes -x509 \\\n-keyout $PWD/config/server.key \\\n-out $PWD/"
  },
  {
    "path": "src/__mocks__/ConfigEditor.ts",
    "chars": 519,
    "preview": "import * as fs from 'fs';\nimport { ConfigEditorProps } from 'views/CHConfigEditor';\nimport { CHConfig } from 'types/conf"
  },
  {
    "path": "src/__mocks__/datasource.ts",
    "chars": 1601,
    "preview": "import { PluginType } from '@grafana/data';\nimport { Protocol } from 'types/config';\nimport { CHQuery, EditorType } from"
  },
  {
    "path": "src/ch-parser/helpers.ts",
    "chars": 3192,
    "preview": "/**\n * Helper functions for character classification and string handling\n */\n\n/**\n * Check if a character is a whitespac"
  },
  {
    "path": "src/ch-parser/lexer.ts",
    "chars": 22171,
    "preview": "import { Token, TokenType } from './types';\nimport {\n  isWhitespaceASCII,\n  isNumericASCII,\n  isWordCharASCII,\n  isHexDi"
  },
  {
    "path": "src/ch-parser/parser.ts",
    "chars": 5753,
    "preview": "import { Token, TokenType } from './types';\n\nexport class QueryNodeParser {\n  private tokens: Token[];\n  private offset:"
  },
  {
    "path": "src/ch-parser/pluginMacros.ts",
    "chars": 3699,
    "preview": "export interface PluginMacro {\n  name: string;\n  isFunction: boolean;\n  columnType?: string;\n  documentation: string;\n  "
  },
  {
    "path": "src/ch-parser/types.ts",
    "chars": 5644,
    "preview": "/**\n * Enum for all token types supported by the lexer\n */\nexport enum TokenType {\n  Whitespace,\n  Comment,\n\n  BareWord,"
  },
  {
    "path": "src/components/Divider.tsx",
    "chars": 482,
    "preview": "import React from 'react';\nimport { Divider as GrafanaDivider, useTheme2 } from '@grafana/ui';\nimport { config } from '@"
  },
  {
    "path": "src/components/LogContextPanel.test.tsx",
    "chars": 1982,
    "preview": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport LogsContextPanel, { _testExports } fr"
  },
  {
    "path": "src/components/LogsContextPanel.tsx",
    "chars": 4881,
    "preview": "import React from 'react';\nimport { Alert, Icon, IconName, Stack, useTheme2 } from '@grafana/ui';\nimport { css } from '@"
  },
  {
    "path": "src/components/QueryToolbox.tsx",
    "chars": 1892,
    "preview": "import React, { useMemo } from 'react';\nimport { css } from '@emotion/css';\n\nimport { Icon, IconButton, Stack, Tooltip, "
  },
  {
    "path": "src/components/SqlEditor.test.tsx",
    "chars": 5163,
    "preview": "import React from 'react';\nimport { render, screen } from '@testing-library/react';\nimport '@testing-library/jest-dom';\n"
  },
  {
    "path": "src/components/SqlEditor.tsx",
    "chars": 4825,
    "preview": "import React, { useRef } from 'react';\nimport { QueryEditorProps } from '@grafana/data';\nimport { CodeEditor, monacoType"
  },
  {
    "path": "src/components/configEditor/AliasTableConfig.test.tsx",
    "chars": 4685,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { AliasTableConfig } from "
  },
  {
    "path": "src/components/configEditor/AliasTableConfig.tsx",
    "chars": 6349,
    "preview": "import React, { ChangeEvent, useState } from 'react';\nimport { ConfigSection } from 'components/experimental/ConfigSecti"
  },
  {
    "path": "src/components/configEditor/DefaultDatabaseTableConfig.test.tsx",
    "chars": 2180,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { DefaultDatabaseTableConf"
  },
  {
    "path": "src/components/configEditor/DefaultDatabaseTableConfig.tsx",
    "chars": 1671,
    "preview": "import React, { SyntheticEvent } from 'react';\nimport { ConfigSection } from 'components/experimental/ConfigSection';\nim"
  },
  {
    "path": "src/components/configEditor/HttpHeadersConfig.test.tsx",
    "chars": 5912,
    "preview": "import React from 'react';\nimport { render, fireEvent, renderHook } from '@testing-library/react';\nimport { HttpHeadersC"
  },
  {
    "path": "src/components/configEditor/HttpHeadersConfig.tsx",
    "chars": 6719,
    "preview": "import React, { ChangeEvent, useMemo, useState } from 'react';\nimport { ConfigSection } from 'components/experimental/Co"
  },
  {
    "path": "src/components/configEditor/LabeledInput.test.tsx",
    "chars": 911,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { LabeledInput } from './L"
  },
  {
    "path": "src/components/configEditor/LabeledInput.tsx",
    "chars": 757,
    "preview": "import React from 'react';\nimport { Input, InlineFormLabel } from '@grafana/ui';\n\ninterface LabeledInputProps {\n  label:"
  },
  {
    "path": "src/components/configEditor/LogsConfig.test.tsx",
    "chars": 10860,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { LogsConfig } from './Log"
  },
  {
    "path": "src/components/configEditor/LogsConfig.tsx",
    "chars": 6419,
    "preview": "import React from 'react';\nimport { ConfigSection, ConfigSubSection } from 'components/experimental/ConfigSection';\nimpo"
  },
  {
    "path": "src/components/configEditor/QuerySettingsConfig.test.tsx",
    "chars": 5949,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { QuerySettingsConfig } fr"
  },
  {
    "path": "src/components/configEditor/QuerySettingsConfig.tsx",
    "chars": 3788,
    "preview": "import React, { FormEvent } from 'react';\nimport { Switch, Input, Field } from '@grafana/ui';\nimport { ConfigSection } f"
  },
  {
    "path": "src/components/configEditor/TracesConfig.test.tsx",
    "chars": 19550,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { TracesConfig, TraceConfi"
  },
  {
    "path": "src/components/configEditor/TracesConfig.tsx",
    "chars": 13743,
    "preview": "import React from 'react';\nimport { ConfigSection, ConfigSubSection } from 'components/experimental/ConfigSection';\nimpo"
  },
  {
    "path": "src/components/experimental/ConfigSection/ConfigSection.test.tsx",
    "chars": 400,
    "preview": "import React from 'react';\nimport { screen, render } from '@testing-library/react';\nimport { ConfigSection } from './Con"
  },
  {
    "path": "src/components/experimental/ConfigSection/ConfigSection.tsx",
    "chars": 365,
    "preview": "import React from 'react';\nimport { GenericConfigSection, Props as GenericConfigSectionProps } from './GenericConfigSect"
  },
  {
    "path": "src/components/experimental/ConfigSection/ConfigSubSection.test.tsx",
    "chars": 415,
    "preview": "import React from 'react';\nimport { screen, render } from '@testing-library/react';\nimport { ConfigSubSection } from './"
  },
  {
    "path": "src/components/experimental/ConfigSection/ConfigSubSection.tsx",
    "chars": 372,
    "preview": "import React from 'react';\nimport { GenericConfigSection, Props as GenericConfigSectionProps } from './GenericConfigSect"
  },
  {
    "path": "src/components/experimental/ConfigSection/DataSourceDescription.test.tsx",
    "chars": 2011,
    "preview": "import React from 'react';\nimport { DataSourceDescription } from './DataSourceDescription';\nimport { render } from '@tes"
  },
  {
    "path": "src/components/experimental/ConfigSection/DataSourceDescription.tsx",
    "chars": 1332,
    "preview": "import React from 'react';\nimport { cx, css } from '@emotion/css';\nimport { useTheme2 } from '@grafana/ui';\n\ntype Props "
  },
  {
    "path": "src/components/experimental/ConfigSection/GenericConfigSection.test.tsx",
    "chars": 3865,
    "preview": "import React from 'react';\nimport { screen, render } from '@testing-library/react';\nimport userEvent from '@testing-libr"
  },
  {
    "path": "src/components/experimental/ConfigSection/GenericConfigSection.tsx",
    "chars": 2010,
    "preview": "import React, { useState, ReactNode } from 'react';\nimport { css } from '@emotion/css';\nimport { useTheme2, IconButton, "
  },
  {
    "path": "src/components/experimental/ConfigSection/index.ts",
    "chars": 169,
    "preview": "export { ConfigSection } from './ConfigSection';\nexport { ConfigSubSection } from './ConfigSubSection';\nexport { DataSou"
  },
  {
    "path": "src/components/queryBuilder/AggregateEditor.test.tsx",
    "chars": 3317,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport userEvent from '@testing-l"
  },
  {
    "path": "src/components/queryBuilder/AggregateEditor.tsx",
    "chars": 6058,
    "preview": "import React, { useState } from 'react';\nimport { SelectableValue } from '@grafana/data';\nimport { InlineFormLabel, Sele"
  },
  {
    "path": "src/components/queryBuilder/ColumnRolesHelp.tsx",
    "chars": 1097,
    "preview": "import React from 'react';\nimport { Box, Icon, Text, TextLink } from '@grafana/ui';\n\ninterface ColumnRolesHelpProps {\n  "
  },
  {
    "path": "src/components/queryBuilder/ColumnSelect.test.tsx",
    "chars": 2094,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { ColumnSelect } from './C"
  },
  {
    "path": "src/components/queryBuilder/ColumnSelect.tsx",
    "chars": 2676,
    "preview": "import React from 'react';\nimport { SelectableValue } from '@grafana/data';\nimport { InlineFormLabel, Select } from '@gr"
  },
  {
    "path": "src/components/queryBuilder/ColumnsEditor.test.tsx",
    "chars": 4073,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport { ColumnsEditor } from './"
  },
  {
    "path": "src/components/queryBuilder/ColumnsEditor.tsx",
    "chars": 3847,
    "preview": "import React, { useState, useEffect } from 'react';\nimport { InlineFormLabel, MultiSelect } from '@grafana/ui';\nimport {"
  },
  {
    "path": "src/components/queryBuilder/DatabaseTableSelect.test.tsx",
    "chars": 5789,
    "preview": "import React from 'react';\nimport { fireEvent, render, waitFor } from '@testing-library/react';\nimport { DatabaseSelect,"
  },
  {
    "path": "src/components/queryBuilder/DatabaseTableSelect.tsx",
    "chars": 3594,
    "preview": "import React, { useEffect } from 'react';\nimport { InlineFormLabel, Select } from '@grafana/ui';\nimport { Datasource } f"
  },
  {
    "path": "src/components/queryBuilder/DurationUnitSelect.tsx",
    "chars": 1451,
    "preview": "import React from 'react';\nimport { TimeUnit } from 'types/queryBuilder';\nimport allLabels from 'labels';\nimport { Inlin"
  },
  {
    "path": "src/components/queryBuilder/EditorTypeSwitcher.test.tsx",
    "chars": 4875,
    "preview": "import React from 'react';\nimport { render, waitFor } from '@testing-library/react';\nimport { EditorTypeSwitcher } from "
  },
  {
    "path": "src/components/queryBuilder/EditorTypeSwitcher.tsx",
    "chars": 4315,
    "preview": "import React, { useState } from 'react';\nimport { SelectableValue } from '@grafana/data';\nimport { RadioButtonGroup, Con"
  },
  {
    "path": "src/components/queryBuilder/FilterEditor.test.tsx",
    "chars": 17150,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport userEvent from '@testing-l"
  },
  {
    "path": "src/components/queryBuilder/FilterEditor.tsx",
    "chars": 17572,
    "preview": "import React, { useState } from 'react';\nimport { SelectableValue } from '@grafana/data';\nimport { Button, HorizontalGro"
  },
  {
    "path": "src/components/queryBuilder/GroupByEditor.test.tsx",
    "chars": 1805,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport { GroupByEditor } from './"
  },
  {
    "path": "src/components/queryBuilder/GroupByEditor.tsx",
    "chars": 1582,
    "preview": "import React, { useState } from 'react';\nimport { InlineFormLabel, MultiSelect } from '@grafana/ui';\nimport { Selectable"
  },
  {
    "path": "src/components/queryBuilder/LimitEditor.test.tsx",
    "chars": 992,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { LimitEditor } from './Li"
  },
  {
    "path": "src/components/queryBuilder/LimitEditor.tsx",
    "chars": 908,
    "preview": "import React, { useState } from 'react';\nimport { InlineFormLabel, Input } from '@grafana/ui';\nimport labels from 'label"
  },
  {
    "path": "src/components/queryBuilder/ModeSwitch.test.tsx",
    "chars": 1369,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport { ModeSwitch } from './Mod"
  },
  {
    "path": "src/components/queryBuilder/ModeSwitch.tsx",
    "chars": 886,
    "preview": "import React from 'react';\nimport { RadioButtonGroup, InlineFormLabel } from '@grafana/ui';\n\nexport interface ModeSwitch"
  },
  {
    "path": "src/components/queryBuilder/OrderByEditor.test.tsx",
    "chars": 9607,
    "preview": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport userEvent from '@testing-library/user"
  },
  {
    "path": "src/components/queryBuilder/OrderByEditor.tsx",
    "chars": 5437,
    "preview": "import React from 'react';\nimport { SelectableValue } from '@grafana/data';\nimport { Button, InlineFormLabel, Select } f"
  },
  {
    "path": "src/components/queryBuilder/OtelVersionSelect.test.tsx",
    "chars": 3312,
    "preview": "import React from 'react';\nimport { render, fireEvent } from '@testing-library/react';\nimport { OtelVersionSelect } from"
  },
  {
    "path": "src/components/queryBuilder/OtelVersionSelect.tsx",
    "chars": 1928,
    "preview": "import React, { useEffect } from 'react';\nimport { SelectableValue } from '@grafana/data';\nimport { InlineFormLabel, Sel"
  },
  {
    "path": "src/components/queryBuilder/QueryBuilder.test.tsx",
    "chars": 5052,
    "preview": "import React from 'react';\nimport { render, screen, waitFor } from '@testing-library/react';\nimport { QueryBuilder } fro"
  },
  {
    "path": "src/components/queryBuilder/QueryBuilder.tsx",
    "chars": 6381,
    "preview": "import React, { useMemo } from 'react';\nimport { Datasource } from 'data/CHDatasource';\nimport { QueryType, QueryBuilder"
  },
  {
    "path": "src/components/queryBuilder/QueryTypeSwitcher.test.tsx",
    "chars": 1461,
    "preview": "import React from 'react';\nimport { fireEvent, render } from '@testing-library/react';\nimport { QueryTypeSwitcher } from"
  },
  {
    "path": "src/components/queryBuilder/QueryTypeSwitcher.tsx",
    "chars": 1202,
    "preview": "import React from 'react';\nimport { RadioButtonGroup, InlineFormLabel } from '@grafana/ui';\nimport labels from 'labels';"
  },
  {
    "path": "src/components/queryBuilder/SqlPreview.test.tsx",
    "chars": 301,
    "preview": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport { SqlPreview } from './SqlPreview';\n\n"
  },
  {
    "path": "src/components/queryBuilder/SqlPreview.tsx",
    "chars": 493,
    "preview": "import React from 'react';\nimport { InlineFormLabel } from '@grafana/ui';\nimport labels from 'labels';\n\ninterface SqlPre"
  },
  {
    "path": "src/components/queryBuilder/Switch.test.tsx",
    "chars": 1194,
    "preview": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport { Switch } from './Switch';\n\ndescribe"
  },
  {
    "path": "src/components/queryBuilder/Switch.tsx",
    "chars": 1182,
    "preview": "import React from 'react';\nimport { InlineFormLabel, Switch as GrafanaSwitch, useTheme } from '@grafana/ui';\nimport { st"
  },
  {
    "path": "src/components/queryBuilder/TraceIdInput.test.tsx",
    "chars": 988,
    "preview": "import React from 'react';\nimport { render } from '@testing-library/react';\nimport { selectors } from 'selectors';\nimpor"
  },
  {
    "path": "src/components/queryBuilder/TraceIdInput.tsx",
    "chars": 1102,
    "preview": "import React, { useEffect, useState } from 'react';\nimport allLabels from 'labels';\nimport { InlineFormLabel, Input } fr"
  },
  {
    "path": "src/components/queryBuilder/utils.test.ts",
    "chars": 20145,
    "preview": "import { generateSql } from 'data/sqlGenerator';\nimport { getQueryOptionsFromSql, isDateTimeType, isDateType, isNumberTy"
  },
  {
    "path": "src/components/queryBuilder/utils.ts",
    "chars": 11714,
    "preview": "import {\n  astVisitor,\n  Expr,\n  ExprBinary,\n  ExprCall,\n  ExprInteger,\n  ExprList,\n  ExprRef,\n  ExprString,\n  ExprUnary"
  },
  {
    "path": "src/components/queryBuilder/views/LogsQueryBuilder.tsx",
    "chars": 9251,
    "preview": "import React, { useEffect, useMemo, useState } from 'react';\nimport { ColumnsEditor } from '../ColumnsEditor';\nimport { "
  },
  {
    "path": "src/components/queryBuilder/views/TableQueryBuilder.tsx",
    "chars": 3918,
    "preview": "import React, { useMemo } from 'react';\nimport { ColumnsEditor } from '../ColumnsEditor';\nimport { AggregateColumn, Buil"
  },
  {
    "path": "src/components/queryBuilder/views/TimeSeriesQueryBuilder.tsx",
    "chars": 5779,
    "preview": "import React, { useMemo } from 'react';\nimport { ColumnsEditor } from '../ColumnsEditor';\nimport {\n  AggregateColumn,\n  "
  },
  {
    "path": "src/components/queryBuilder/views/TraceQueryBuilder.tsx",
    "chars": 18445,
    "preview": "import React, { useMemo, useState } from 'react';\nimport { Filter, QueryBuilderOptions, SelectedColumn, ColumnHint, Time"
  },
  {
    "path": "src/components/queryBuilder/views/logsQueryBuilderHooks.test.ts",
    "chars": 13567,
    "preview": "import { renderHook } from '@testing-library/react';\nimport {\n  useDefaultFilters,\n  useDefaultTimeColumn,\n  useLogDefau"
  },
  {
    "path": "src/components/queryBuilder/views/logsQueryBuilderHooks.ts",
    "chars": 7059,
    "preview": "import { Datasource } from 'data/CHDatasource';\nimport { columnFilterDateTime } from 'data/columnFilters';\nimport { Buil"
  },
  {
    "path": "src/components/queryBuilder/views/timeSeriesQueryBuilderHooks.test.ts",
    "chars": 4067,
    "preview": "import { renderHook } from '@testing-library/react';\nimport { useDefaultFilters, useDefaultTimeColumn } from './timeSeri"
  },
  {
    "path": "src/components/queryBuilder/views/timeSeriesQueryBuilderHooks.ts",
    "chars": 2505,
    "preview": "import { columnFilterDateTime } from 'data/columnFilters';\nimport { BuilderOptionsReducerAction, setColumnByHint, setOpt"
  },
  {
    "path": "src/components/queryBuilder/views/traceQueryBuilderHooks.test.ts",
    "chars": 6929,
    "preview": "import { renderHook } from '@testing-library/react';\nimport { useTraceDefaultsOnMount, useOtelColumns, useDefaultFilters"
  },
  {
    "path": "src/components/queryBuilder/views/traceQueryBuilderHooks.ts",
    "chars": 5833,
    "preview": "import React, { useEffect, useRef } from 'react';\nimport { Datasource } from 'data/CHDatasource';\nimport otel from 'otel"
  },
  {
    "path": "src/components/sqlProvider.test.ts",
    "chars": 1959,
    "preview": "import { formatSql, registerSQL } from './sqlProvider';\n\ndescribe('SQL Formatter', () => {\n  it('formats SQL', () => {\n "
  },
  {
    "path": "src/components/sqlProvider.ts",
    "chars": 2946,
    "preview": "import { Monaco, MonacoEditor, monacoTypes } from '@grafana/ui';\nimport { format } from 'sql-formatter';\n\ndeclare const "
  },
  {
    "path": "src/components/suggestions.test.ts",
    "chars": 5582,
    "preview": "import { SqlFunction, TableColumn } from 'types/queryBuilder';\nimport { getSuggestions, Schema } from './suggestions';\ni"
  },
  {
    "path": "src/components/suggestions.ts",
    "chars": 12035,
    "preview": "import { getTemplateSrv } from '@grafana/runtime';\nimport { Monaco, monacoTypes } from '@grafana/ui';\nimport { Range } f"
  },
  {
    "path": "src/components/ui/CertificationKey.tsx",
    "chars": 825,
    "preview": "import React, { ChangeEvent, MouseEvent, FC } from 'react';\nimport { Input, Button, TextArea, Field } from '@grafana/ui'"
  }
]

// ... and 93 more files (download for full content)

About this extraction

This page contains the full source code of the grafana/clickhouse-datasource GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 293 files (1.9 MB), approximately 514.6k tokens, and a symbol index with 766 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!