ClickHouse/dbms/tests/instructions/easy_tasks_sorted_ru.md
2020-01-14 18:33:09 +03:00

20 KiB
Raw Blame History

Простые задачи

Пустой параметр --password в клиенте должен быть эквивалентен --ask-password.

То есть означать предложение ввести пароль в интерактивном режиме.

dbms/programs/client/ConnectionParameters.h

* кстати, сейчас функциональность реализована плохо: ввод пароля не поддерживает корректную обработку backspace.

Недостатки юзабилити: у clickhouse-client отсутствует сокращённая опция -C, как вариант --config-file; Недостатки юзабилити, если пользователь не может прочитать конфиг клиента.

dbms/programs/client/Client.cpp

Также делаем chmod 000 /etc/clickhouse-client/config.xml и смотрим, что получится.

Оператор NOT BETWEEN.

SELECT * FROM system.numbers WHERE number NOT BETWEEN 5 AND 10 LIMIT 10

ExpressionListParsers.cpp: ParserBetweenExpression::parseImpl

HTTP заголовок query_id.

programs/server/HTTPHandler.cpp - смотрим метод executeQuery

src/Interpreters/executeQuery.h

src/Interpreters/executeQuery.cpp - смотрим колбэк на выставление Content-Type

Уменьшать max_memory_usage и размеры кэшей при старте, если на сервере мало оперативки.

Смотрим, сколько на сервере оперативки. Если max_memory_usage, max_memory_usage_for_all_queries ограничены, но больше 90% (настройка) от имеющейся оперативки, то уменьшать их и выводить предупреждение в лог. Аналогично для кэшей: mark_cache, uncompressed_cache.

programs/server/Server.cpp - инициализация сервера, установка размера кэшей

getMemoryAmount.h - информация о доступной оперативке

context.setSetting - для выставления max_memory_usage и других.

Битовые операции для FixedString.

bitAnd, bitOr, bitNot, bitXor для значения типа FixedString, интерпретируемого как набор бит.

Сделайте сначала в C++ побитовые функции для работы с куском памяти:

void memoryBitAnd(const char * a, const char * b, char * result, size_t size);

Потом используйте их в вашей функции.

Функция arrayWithConstant.

arrayWithConstant(3, 'hello') = ['hello', 'hello', 'hello']

Смотрите метод IColumn::replicate для размножения значений столбца.

Добавить generic вариант функций least, greatest.

SELECT least(123, 456) - работает.

SELECT least('123', '456') - не работает. Надо сделать.

Делаем с помощью IColumn::compareAt для одинаковых типов и с помощью castColumn, getLeastSuperType для разных.

При ATTACH кусков, проверять владельца файлов.

Смотрим, что все файлы в прикрепляемых кусках от правильного пользователя.

COLLATE должно работать для Nullable(String).

В ClickHouse есть возможность указать collation для сортировки строк. Это не работает для Nullable(String).

Проверить возможность использования pdqsort вместо std::sort для полной comparison-based сортировки.

В случае, когда есть ORDER BY без LIMIT, это может позволить слегка увеличить производительность.

Запретить чтение значений типа AggregateFunction по-умолчанию и добавить настройку.

Состояния агрегатных функций могут быть записаны в дамп и считаны из него. Но десериализация состояний агрегатных функций небезопасна. Аккуратно выбранные пользовательские данные могут привести к segfault или порче памяти. Поэтому нужно просто сделать настройку, которая запрещает читать AggregateFunction из пользовательских данных.

Опции progress и time для clickhouse-local (по аналогии с clickhouse-client).

Возможность выводить время выполнения запроса, а также красивый прогресс-бар для каждого запроса.

Usability: clickhouse-server должен поддерживать --help.

В статистику jemalloc добавить информацию по arenas.

В system.asynchronous_metrics - суммарный размер арен.

Добавить агрегатную функцию topKWeighted.

SELECT topKWeighted(value, weight) - учитывать каждое значение с весом.

Функция isValidUTF8, toValidUTF8.

isValidUTF8 возвращает 1, если строка содержит набор байт в кодировке UTF-8.

toValidUTF8 - заменяет последовательности байт, не соответствующие кодировке UTF-8, на replacement character.

Более сложные задачи

CREATE TABLE AS table_function()

Возможность создать таблицу с таким же типом и структурой, как табличная функция.

ParserCreateQuery.cpp, InterpreterCreateQuery, Context::executeTableFunction

Layout внешних словарей "direct".

Как cache, но без кэша — всегда прямой запрос в источник.

Подсказки в фабриках на основе edit distance.

Всевозможные объекты: функции, агрегатные функции, типы данных, движки таблиц, и т. п. достаются по имени из фабрик. Часто пользователь допускает опечатку. Например, вместо SELECT count(*) может быть написано SELECT cunt(*). В случае опечатки, необходимо в текст сообщения добавлять указание на ближайшие варианты. Для реализации можно использовать расстояние Левенштейна и полный перебор, или (лучше) - триграмный индекс. Подсказки выдаём, если указанное имя отличается от существующего на 1..2 буквы. Сортируем возможные варианты в порядке похожести. Для того, чтобы это работало во всех фабриках, может быть, потребуется обобщить их.

Учитывать порядок столбцов в заголовке в форматах CSV и TSV.

В заголовке CSV, TSV могут быть указаны имена столбцов. Сейчас они полностью игнорируются. Надо учитывать, под настройкой.

Функции randomFixedString, randomBinaryString, fuzzBits, fuzzBytes.

Функции для geoHash.

Geohash - способ преобразования географических координат в строку, так что отображение обладает свойством локальности. https://en.wikipedia.org/wiki/Geohash В качестве библиотеки следует использовать эту: https://github.com/yinqiwen/geohash-int Необходимо добавить функции для перевода в обе стороны, а также для числового и текстового вариантов.

Агрегатные функции для статистических тестов (e.g. тест нормальности распределения) и статистик (e.g. энтропия).

Энтропию следует считать по гистограмме. Пример расчёта гистограммы смотрите в реализации функции quantileExact.

https://github.com/ClickHouse/ClickHouse/issues/3266

Функции создания и обновления состояния агрегатной функции по одному кортежу аргументов.

В ClickHouse есть понятие - состояние вычисления агрегатной функции. Состояния агрегатных функций можно записывать в таблицы, складывать, финализировать и т. п. https://clickhouse.yandex/docs/ru/data_types/nested_data_structures/aggregatefunction/

Получить состояние агрегатной функции можно с помощью комбинатора State: https://clickhouse.yandex/docs/ru/query_language/agg_functions/combinators/#-state Но хотелось бы добавить ещё более простой способ получения состояния агрегатной функции.

Например:

createAggregationState('groupArray') - создать пустое (начальное) состояние агрегатной функции.

createAggregationState('groupArray', 1) - создать состояние агрегатной функции, в котором агрегировано одно значение 1.

createAggregationState('argMax', ('hello', 123)) - то же самое для агрегатных функций, принимающих несколько аргументов.

LEFT ONLY JOIN

Функции makeDate, makeDateTime.

makeDate(year, month, day) makeDateTime(year, month, day, hour, minute, second, [timezone])

Функции changeYear, changeMonth, ...

changeYear(datetime, 2019)

Исправить мерцание прогресс-бара в clickhouse-client.

Это заметно при работе с серверами с большим пингом. Прогресс бар не должен мерцать. Наверное, надо просто вместо очистки строки, перемещать курсор в начало, не очищая её.

Функция format для вставки значений в строку-шаблон.

format('Hello {2} World {1}', x, y)

Добавить поддержку hyperscan.

https://github.com/intel/hyperscan

Реализовать на основе этой библиотеки функцию для матчинга сразу большого количества регулярных выражений.

Функция rowNumberForKey.

Возвращает инкрементальное число для повторно встречающихся значений key.

Агрегатная функция groupConcat.

groupConcat(x, ',') - собрать из переданных значений x строку, разделённую запятыми.

Функции DATE_ADD, DATE_SUB как синонимы для совместимости с SQL.

https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-add

Функции positionReverse, positionUTF8Reverse, positionCaseInsensitiveReverse, positionCaseInsensitiveUTF8Reverse.

position с конца строки.

Функция indexOf должна поддерживать Enum-ы без cast-а.

indexOf(arr, 'hello'), indexOf(arr, 1) должны работать, если arr имеет тип Array(Enum8('hello' = 1, 'world' = 2))

Комбинатор агрегатных функций Distinct.

Пример: avgDistinct(x) - вычислить среднее по всем различным переданным значениям.

Проверка набора инструкций при старте сервера.

Если сервер собран с поддержкой SSE 4.2, 4.1, 4, SSSE 3, SSE 3, то как можно ближе к началу работы, запускаем функцию, которая выполняет нужную инструкцию в качестве теста (asm volatile вставка), а до этого ставим обработчик сигнала SIGILL, который в случае невозможности выполнить инструкцию, сделает siglongjmp, позволит нам вывести понятное сообщение в лог и завершить работу. Замечание: /proc/cpuinfo зачастую не содержит актуальную информацию.

Добавить сжатие Brotli для HTTP интерфейса.

Content-Encoding: br

Метрики количества ошибок.

Добавляем счётчики всех ошибок (ErrorCodes) по аналогии с ProfileEvents. Кроме количества запоминаем также время последней ошибки, стек трейс, сообщение. Добавляем системную таблицу system.errors. Отправка в Graphite.

Добавить Lizard, LZSSE и density в качестве вариантов алгоритмов сжатия.

Экспериментальные алгоритмы сжатия. Сейчас ClickHouse поддерживает только lz4 и zstd.

Запрос CREATE OR REPLACE TABLE/VIEW.

Атомарно (под блокировкой) удаляет таблицу перед созданием новой, если такая была.

Приведение типов для IN (subquery).

SELECT 1 IN (SELECT -1 UNION ALL SELECT 1)

  • сейчас не работает.

Возможность задать смещение для LIMIT BY.

https://clickhouse.yandex/docs/ru/query_language/select/#limit-n-by

LIMIT 100, 10 BY RegionID - выдать не более 10 строк для каждого RegionID, но пропустив первые 100 строк.

Возможность вставки значений типа AggregateFunction в виде кортежа значений аргументов, а не бинарного дампа состояния, под настройкой.

Во входных данных в запросе INSERT должна быть возможность передать значение типа AggregateFunction не в виде сериализованного состояния, а в виде аргументов, которые будут агрегированы, для формирования этого состояния.

Возможность использовать ALIAS столбцы при INSERT.

https://clickhouse.yandex/docs/en/query_language/create/#create-table

INSERT INTO table (column1, column2, ...)

  • если column - это ALIAS столбец, и если выражение для ALIAS тривиально (просто ссылается на другой столбец), то разрешить использовать его вместо другого столбца в запросе INSERT.

Запрос ALTER TABLE LOCK/UNLOCK PARTITION.

Запретить модификацию данных в партиции. На партицию ставится флаг, что она заблокирована. В неё нельзя делать INSERT и ALTER. С файлов снимается доступ на запись.

Поддержка произвольных константных выражений в LIMIT.

Возможность писать LIMIT 1 + 2. То же самое для LIMIT BY.

Добавить информацию об exp-smoothed количестве ошибок соединений с репликами в таблицу system.clusters.

У нас есть счётчик ошибок соединения с серверами для failover. Надо сделать его видимым для пользователя.

Настройка join_use_nulls: поддержка для LEFT ARRAY JOIN.

Внешние словари из Redis/Aerospike/Couchbase/Cassandra (на выбор).

Подключить одну из key-value БД как источник.

Движок таблиц Mongo, табличная функция mongo.

Возможность легко импортировать данные из MongoDB.

Возможность использования нескольких потоков для INSERT при INSERT SELECT.

При INSERT SELECT, запрос SELECT может выполняться параллельно, но все данные будут передаваться на вставку в INSERT в один поток. Хотя некоторые таблицы (семейства MergeTree) поддерживают параллельную вставку. Необходимо сделать настройку для максимального количества потоков для INSERT.

Корректная обработка multiline значений в Pretty форматах.

SELECT 'hello\nworld' AS x, 123 AS y

┌─x──────────┬───y─┐
│ hello
world │ 123 │
└────────────┴─────┘

А надо так:

┌─x─────┬───y─┐
│ hello…│ 123 │
│…world │     │
└───────┴─────┘

Писать логи ClickHouse в ClickHouse.

Пишем текстовые логи ClickHouse в системную таблицу в структурированном виде.

См. SystemLog.h, cpp.

Работоспособность внешних данных на время сессии.

https://clickhouse.yandex/docs/en/operations/table_engines/external_data/

Не работает, если открыть clickhouse-client в интерактивном режиме и делать несколько запросов.

Настройка для возможности получить частичный результат при cancel-е.

Хотим по Ctrl+C получить те данные, которые успели обработаться.

Раскрытие кортежей в функциях высшего порядка.

Табличная функция loop.

SELECT * FROM loop(database, table)

Читает данные из таблицы в бесконечном цикле.

Настройка, позволяющая обратиться ко всем репликам кластера, как к разным шардам.

Возможность ATTACH партиции с меньшим или большим количеством столбцов.

Поддержка неконстантного аргумента с тайм-зоной у некоторых функций для работы с датой и временем.

Возможность задавать параметры соединений для табличных функций, движков таблиц и для реплик из отдельных разделов конфигурации.

Настройка rollup_use_nulls.

Настройка cast_keep_nullable.

Функция bitEquals для сравнения произвольных типов данных побитово.

Функция serialize для implementation specific non portable non backwards compatible сериализации любого типа данных в набор байт.

Функция arrayEnumerateUniqDeep

Как arrayEnumerateUniq, но смотрит на самые глубокие элементы вложенных массивов.

Функция bitEquals и оператор <=>.

Параллельный ALTER MODIFY COLUMN.