| 697 | } |
| 698 | |
| 699 | ASTPtr DatabaseOnDisk::parseQueryFromMetadata( |
| 700 | Poco::Logger * logger, |
| 701 | ContextPtr local_context, |
| 702 | const String & metadata_file_path, |
| 703 | bool throw_on_error /*= true*/, |
| 704 | bool remove_empty /*= false*/) |
| 705 | { |
| 706 | String query; |
| 707 | |
| 708 | int metadata_file_fd = ::open(metadata_file_path.c_str(), O_RDONLY | O_CLOEXEC); |
| 709 | |
| 710 | if (metadata_file_fd == -1) |
| 711 | { |
| 712 | if (errno == ENOENT && !throw_on_error) |
| 713 | return nullptr; |
| 714 | |
| 715 | throwFromErrnoWithPath("Cannot open file " + metadata_file_path, metadata_file_path, |
| 716 | errno == ENOENT ? ErrorCodes::FILE_DOESNT_EXIST : ErrorCodes::CANNOT_OPEN_FILE); |
| 717 | } |
| 718 | |
| 719 | |
| 720 | ReadBufferFromFile in(metadata_file_fd, metadata_file_path, METADATA_FILE_BUFFER_SIZE); |
| 721 | readStringUntilEOF(query, in); |
| 722 | |
| 723 | /** Empty files with metadata are generated after a rough restart of the server. |
| 724 | * Remove these files to slightly reduce the work of the admins on startup. |
| 725 | */ |
| 726 | if (remove_empty && query.empty()) |
| 727 | { |
| 728 | if (logger) |
| 729 | LOG_ERROR(logger, "File {} is empty. Removing.", metadata_file_path); |
| 730 | fs::remove(metadata_file_path); |
| 731 | return nullptr; |
| 732 | } |
| 733 | |
| 734 | auto settings = local_context->getSettingsRef(); |
| 735 | ParserCreateQuery parser(ParserSettings::valueOf(settings)); |
| 736 | const char * pos = query.data(); |
| 737 | std::string error_message; |
| 738 | auto ast = tryParseQuery(parser, pos, pos + query.size(), error_message, /* hilite = */ false, |
| 739 | "in file " + metadata_file_path, /* allow_multi_statements = */ false, 0, settings.max_parser_depth); |
| 740 | |
| 741 | if (!ast && throw_on_error) |
| 742 | throw Exception(error_message, ErrorCodes::SYNTAX_ERROR); |
| 743 | else if (!ast) |
| 744 | return nullptr; |
| 745 | |
| 746 | auto & create = ast->as<ASTCreateQuery &>(); |
| 747 | if (!create.table.empty() && create.uuid != UUIDHelpers::Nil) |
| 748 | { |
| 749 | String table_name = unescapeForFileName(fs::path(metadata_file_path).stem()); |
| 750 | |
| 751 | if (create.table != TABLE_WITH_UUID_NAME_PLACEHOLDER && logger) |
| 752 | LOG_WARNING( |
| 753 | logger, |
| 754 | "File {} contains both UUID and table name. Will use name `{}` instead of `{}`", |
| 755 | metadata_file_path, |
| 756 | table_name, |
nothing calls this directly
no test coverage detected