| 1774 | } |
| 1775 | |
| 1776 | void textIndexValidator(const IndexDescription & index, bool /*attach*/, const MergeTreeSettings & settings) |
| 1777 | { |
| 1778 | auto options = convertArgumentsToOptionsMap(index.arguments); |
| 1779 | |
| 1780 | auto tokenizer_ast = extractASTOption(options, ARGUMENT_TOKENIZER, true); |
| 1781 | auto preprocessor_ast = extractASTOption(options, ARGUMENT_PREPROCESSOR, false); |
| 1782 | TokenizerFactory::instance().get(tokenizer_ast); |
| 1783 | |
| 1784 | UInt64 dictionary_block_size = extractFieldOption<UInt64>(options, ARGUMENT_DICTIONARY_BLOCK_SIZE) |
| 1785 | .value_or(settings[MergeTreeSetting::text_index_dictionary_block_size]); |
| 1786 | |
| 1787 | if (dictionary_block_size == 0) |
| 1788 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Text index argument '{}' must be greater than 0, but got {}", ARGUMENT_DICTIONARY_BLOCK_SIZE, dictionary_block_size); |
| 1789 | |
| 1790 | UInt64 dictionary_block_use_fc_compression = extractFieldOption<UInt64>(options, ARGUMENT_DICTIONARY_BLOCK_FRONTCODING_COMPRESSION) |
| 1791 | .value_or(settings[MergeTreeSetting::text_index_dictionary_block_frontcoding_compression]); |
| 1792 | |
| 1793 | if (dictionary_block_use_fc_compression > 1) |
| 1794 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Text index argument '{}' must be 0 or 1, but got {}", ARGUMENT_DICTIONARY_BLOCK_FRONTCODING_COMPRESSION, dictionary_block_use_fc_compression); |
| 1795 | |
| 1796 | UInt64 posting_list_block_size = extractFieldOption<UInt64>(options, ARGUMENT_POSTING_LIST_BLOCK_SIZE) |
| 1797 | .value_or(settings[MergeTreeSetting::text_index_posting_list_block_size]); |
| 1798 | |
| 1799 | if (posting_list_block_size == 0) |
| 1800 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Text index argument '{}' must be greater than 0, but got {}", ARGUMENT_POSTING_LIST_BLOCK_SIZE, posting_list_block_size); |
| 1801 | |
| 1802 | String posting_list_codec_name = extractFieldOption<String>(options, ARGUMENT_POSTING_LIST_CODEC) |
| 1803 | .value_or(settings[MergeTreeSetting::text_index_posting_list_codec].toString()); |
| 1804 | |
| 1805 | PostingListCodecFactory::createPostingListCodec(posting_list_codec_name, index.name); |
| 1806 | |
| 1807 | if (!options.empty()) |
| 1808 | throw Exception(ErrorCodes::BAD_ARGUMENTS, "Unexpected text index arguments: {}", fmt::join(std::views::keys(options), ", ")); |
| 1809 | |
| 1810 | /// Check that the index is created on a single column |
| 1811 | if (index.column_names.size() != 1 || index.data_types.size() != 1) |
| 1812 | throw Exception(ErrorCodes::INCORRECT_NUMBER_OF_COLUMNS, "Text index must be created on a single column"); |
| 1813 | |
| 1814 | DataTypePtr index_data_type = index.data_types[0]; |
| 1815 | WhichDataType which_data_type(MergeTreeIndexText::getNestedDataType(index_data_type)); |
| 1816 | |
| 1817 | if (!which_data_type.isString() && !which_data_type.isFixedString()) |
| 1818 | { |
| 1819 | throw Exception( |
| 1820 | ErrorCodes::BAD_ARGUMENTS, |
| 1821 | "Text index must be created on columns of type with base type of String or FixedString, got: {}", |
| 1822 | index_data_type->getName()); |
| 1823 | } |
| 1824 | |
| 1825 | /// Create the preprocessor for validation. |
| 1826 | /// For very strict validation of the expression we fully parse it here. |
| 1827 | /// However it will be parsed again for index construction, generally immediately after this call. |
| 1828 | /// This is a bit redundant but that doesn't impact performance anyhow because the expression is intended to be simple enough. |
| 1829 | MergeTreeIndexTextPreprocessor preprocessor(preprocessor_ast, index); |
| 1830 | } |
| 1831 | |
| 1832 | } |
nothing calls this directly
no test coverage detected