Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/ci-trino-adapter.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: YDB Trino Adapter CI with Maven

on:
push:
paths:
- 'ydb-trino-adapter/**'
- '.github/workflows/ci-trino-adapter.yaml'
branches:
- main
pull_request:
paths:
- 'ydb-trino-adapter/**'
- '.github/workflows/ci-trino-adapter.yaml'

env:
MAVEN_ARGS: --batch-mode --update-snapshots -Dstyle.color=always

jobs:
build:
name: YDB Trino Adapter
runs-on: ubuntu-latest

strategy:
matrix:
java: [ '25' ]

steps:
- uses: actions/checkout@v5

- name: Set up JDK ${{matrix.java}}
uses: actions/setup-java@v5
with:
java-version: ${{matrix.java}}
distribution: 'temurin'
cache: maven

- name: Download Trino Adapter dependencies
working-directory: ./ydb-trino-adapter
run: mvn $MAVEN_ARGS dependency:go-offline

- name: Build and test Trino Adapter
working-directory: ./ydb-trino-adapter
run: mvn $MAVEN_ARGS clean test
56 changes: 13 additions & 43 deletions ydb-trino-adapter/README.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,27 @@
# YDB Trino Adapter

Minimal Trino JDBC connector for YDB. Built on `trino-base-jdbc` and uses the official YDB JDBC driver.
План развития и покрытие Trino connector tests: [ROADMAP.md](ROADMAP.md).

## Build
# Инструкция по сборке

```bash
mvn -f ydb-trino-adapter/pom.xml -DskipTests package
```

## Local example with YDB and Trino

`examples/` contains a minimal Docker Compose setup that runs both Trino (479) and YDB locally.
mvn -f pom.xml -DskipTests package
mvn -f pom.xml -DskipTests dependency:copy-dependencies -DincludeScope=runtime

1) Build the plugin and assemble the plugin directory:
mkdir -p docker/trino/plugin
cp target/ydb-trino-0.1.0.jar docker/trino/plugin
cp target/dependency/*.jar docker/trino/plugin

```bash
mvn -f ydb-trino-adapter/pom.xml -DskipTests package
mvn -f ydb-trino-adapter/pom.xml -DskipTests dependency:copy-dependencies -DincludeScope=runtime

mkdir -p ydb-trino-adapter/examples/trino/plugin
cp ydb-trino-adapter/target/ydb-trino-adapter-0.1.0.jar ydb-trino-adapter/examples/trino/plugin/
cp ydb-trino-adapter/target/dependency/*.jar ydb-trino-adapter/examples/trino/plugin/
cd docker
docker-compose down
docker-compose up -d
```

2) Start Trino + YDB:
## Запуск Trino CLI

```bash
cd ydb-trino-adapter/examples
docker compose up -d
```

3) Open Trino UI: `http://localhost:8080`

4) Connect to Trino:

```bash
docker exec -it ydb-trino-trino trino
```

Check schemas and tables:

```sql
SHOW SCHEMAS FROM ydb;
SHOW TABLES FROM ydb.default;
```

## Connector configuration

Catalog file: `examples/trino/etc/catalog/ydb.properties`:

```
connector.name=ydb
connection-url=jdbc:ydb:grpc://ydb-local:2136/local
```

If you need a token or service account, add parameters to the JDBC URL as supported by the YDB JDBC driver.
docker exec -it ydb-trino trino
```
134 changes: 134 additions & 0 deletions ydb-trino-adapter/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# YDB Trino Adapter — roadmap

Статус относительно Trino `BaseConnectorTest` / `BaseConnectorSmokeTest`
(ветка `ydb-trino-17-07`, ~314 тестов: ~187 green, ~127 skipped).

Skipped почти всегда означают `hasBehavior(...)=false` или явный `NOT_SUPPORTED`
в `YdbClient`, а не случайный флаaky. Пустые `@Override` (тест «проходит», но ничего
не проверяет) отмечены отдельно — это тоже долг.

## Уже есть

- CREATE / DROP TABLE, INSERT (non-transactional), SELECT
- Predicate pushdown, в том числе по `varchar` (`FULL_PUSHDOWN`, bind через JDBC → `Text`/`Utf8`)
- LIMIT / TopN pushdown (включая TopN по varchar)
- Базовый набор скалярных типов: bool, int*, float/double, decimal, date, timestamp, varchar/Text
- Агрегации и часть expression rewrite (arithmetic, `IN`, string ops, …)

## Phase 0 — честный тест-долг (быстро)

Сейчас часть тестов green из‑за пустого override. Либо починить, либо явно
документировать/оставить skip с причиной.

| Тест / тема | Проблема |
|---|---|
| Long table / column names | Лимиты имён YDB |
| Negative dates / year-of-era | Нет отрицательных дат в YQL |
| `testCharVarcharComparison` | CHAR без pad → не семантика Trino CHAR |
| `testVarcharCastToDateInPredicate` | Cast/pushdown не поддержан |
| Row-level UPDATE declaration / `testRowLevelUpdate` | Planner падает до `NOT_SUPPORTED` |
| `testInsertForDefaultColumn` | Нет default columns |

**Критерий готовности:** нет «пустых» overrides без комментария «unsupported by design».

## Phase 1 — DDL, которое уже есть в YQL (высокий ROI)

YDB умеет `ALTER TABLE ... ADD/DROP COLUMN`, `SET/DROP NOT NULL`. В адаптере это
сейчас выключено.

1. **DROP COLUMN** — снять `SUPPORTS_DROP_COLUMN=false`, реализовать в `YdbClient`
2. **ADD COLUMN** (без comment / position) — базовая добавка nullable-колонок
3. **DROP / SET NOT NULL** — если поведение совпадёт с ожиданиями Trino-тестов

Ожидаемый эффект: разблокировка пачки `testDrop*Column`, `testAddAndDropColumnName`,
части not-null тестов (~10–20 кейсов).

**Вне scope phase 1:** rename column, `SET DATA TYPE`, column/table comments,
`ADD COLUMN ... NOT NULL` с backfill-семантикой Trino, `WITH POSITION`.

## Phase 2 — UPDATE / DELETE (без MERGE)

В YQL есть `UPDATE` / `DELETE`. Коннектор сейчас бросает `MODIFYING_ROWS_MESSAGE`.

1. Простой `DELETE` / `UPDATE` с pushdown предикатов (в т.ч. varchar через `?`)
2. Сложные предикаты из BaseConnectorTest (LIKE, subquery, semi-join) — по мере готовности
3. **MERGE не целиться** — в YDB нет Trino-MERGE; оставляем `SUPPORTS_MERGE=false`
(или позже эмулировать через UPSERT, отдельным решением)

Ожидаемый эффект: до ~30–40 тестов из группы delete/update (без merge-сюиты).

**Риски:** семантика транзакций, `testRollback` / `testInsertInTransaction`,
row-level update planner quirks, written stats.

## Phase 3 — schema as path (дизайн)

Trino `CREATE SCHEMA` ≠ SQL schema в YDB. Схемы естественно мапятся на директории
в path БД.

Варианты:

- оставить один schema `ydb` (как сейчас) — просто и предсказуемо;
- мапить `schema` → subdirectory + реализовать create/drop/rename directory.

Без явного дизайн-решения флаги `SUPPORTS_CREATE_SCHEMA` / rename / cascade
не включать. Cascade + views/MV — отдельно.

## Phase 4 — типы контейнеров

| Trino | YDB | Статус |
|---|---|---|
| `ARRAY` | `List` | не замаплено → skip insert/array/field-in-array |
| `MAP` | `Dict` | не замаплено |
| `ROW` | `Struct` | не замаплено → skip row-field + projection pushdown по nested |

Нужны read/write mappings, predicate/projection pushdown, тесты data-mapping.
Крупный объём, лучше отдельными PR по типу.

## Phase 5 — Views / comments / прочее

- **Views:** в YDB есть ограниченная поддержка; Trino VIEW + metadata-тесты —
отдельный трек. Materialized / federated MV — низкий приоритет.
- **COMMENT ON TABLE/COLUMN:** семантика Trino не совпадает 1:1 с YDB table/column
properties — не блокирует core DML/DDL.
- **RENAME COLUMN / SET COLUMN TYPE:** проверить актуальные возможности YQL;
сейчас считаем unsupported.
- **RENAME TABLE across schemas:** зависит от phase 3 (path move).

## Порядок PR (предложение)

```text
0. ROADMAP + подчистить пустые overrides (docs/honesty)
1. DROP COLUMN (+ минимальные ADD COLUMN)
2. UPDATE / DELETE (простые предикаты) → расширять предикаты
3. Design note: schema-as-path (да/нет) → реализация или явный отказ
4. List / Dict / Struct mappings по одному типу
5. Views / comments по необходимости продукта
```

## Как мерить прогресс

После каждого PR:

```bash
cd ydb-trino-adapter
mvn test
# смотреть surefire: Tests run / Skipped / Failures
```

Целевые ориентиры (грубо):

| Milestone | Skipped (ориентир) |
|---|---|
| Сейчас | ~127 |
| После phase 1 | ~110 |
| После phase 2 | ~70–80 |
| После phase 4 | заметно ниже за счёт array/map/row |

Точные числа зависят от того, сколько тестов завязано на комбинации флагов
(например MERGE останется большим блоком skip).

## Не делать

- Включать `hasBehavior=true` без реализации в `YdbClient` / QueryBuilder
- Ослаблять CI workflow, чтобы «позеленеть»
- Эмулировать MERGE «лишь бы тесты» без явной семантики и документации
5 changes: 4 additions & 1 deletion ydb-trino-adapter/examples/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ services:
container_name: ydb-trino-trino
ports:
- "8080:8080"
- "5005:5005"
environment:
- JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
volumes:
- ./trino/etc:/etc/trino
- ./trino/plugin:/usr/lib/trino/plugin/ydb
Expand All @@ -26,4 +29,4 @@ services:
ports:
- "2135:2135"
- "2136:2136"
- "8765:8765"
- "8765:8765"
75 changes: 46 additions & 29 deletions ydb-trino-adapter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,14 @@
<modelVersion>4.0.0</modelVersion>

<groupId>tech.ydb.dialects</groupId>
<artifactId>ydb-trino-adapter</artifactId>
<artifactId>ydb-trino</artifactId>
<version>0.1.0</version>

<name>YDB Trino Adapter</name>
<description>Trino JDBC connector for YDB</description>
<url>https://github.com/ydb-platform/ydb-java-dialects</url>

<packaging>jar</packaging>

<developers>
<developer>
<name>Kirill Kurdyukov</name>
<email>kurdyukov-kir@ydb.tech</email>
<organization>YDB</organization>
<organizationUrl>https://ydb.tech/</organizationUrl>
</developer>
</developers>

<scm>
<url>https://github.com/ydb-platform/ydb-java-dialects</url>
<connection>scm:git:https://github.com/ydb-platform/ydb-java-dialects.git</connection>
<developerConnection>scm:git:https://github.com/ydb-platform/ydb-java-dialects.git</developerConnection>
</scm>

<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
</license>
</licenses>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.release>25</maven.compiler.release>
Expand Down Expand Up @@ -92,12 +69,42 @@
<artifactId>ydb-junit5-support</artifactId>
<version>${ydb.sdk.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.20.0</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.25.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.trino</groupId>
<artifactId>trino-testing</artifactId>
<version>${trino.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.trino</groupId>
Expand All @@ -110,6 +117,12 @@
<artifactId>trino-main</artifactId>
<version>${trino.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.trino</groupId>
Expand All @@ -127,16 +140,20 @@

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.13.0</version>
<configuration>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<environmentVariables>
<TESTCONTAINERS_REUSE_ENABLE>true</TESTCONTAINERS_REUSE_ENABLE>
<YDB_ENDPOINT>localhost:2136</YDB_ENDPOINT>
<YDB_DATABASE>/local</YDB_DATABASE>
</environmentVariables>
<argLine>--add-modules jdk.incubator.vector</argLine>
</configuration>
</plugin>
Expand Down
Loading