# Простые задачи ## Пустой параметр --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, max_memory_usage_for_user, max_memory_usage_for_all_queries ## Битовые операции для 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 для размножения значений столбца. ## Функция flatten для превращения массивов массивов в массив элементов. `flatten([[1, 2, 3], [4, 5]]) = [1, 2, 3, 4, 5]` ColumnArray - внимательно изучаем, как устроены массивы в ClickHouse. ## Добавить 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/yandex/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))` - то же самое для агрегатных функций, принимающих несколько аргументов. ## Корректное сравнение Date и DateTime. https://github.com/yandex/ClickHouse/issues/2011 Нужно сравнивать Date и DateTime так, как будто Date расширено до DateTime на начало суток в том же часовом поясе. ## 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.