| 131 | |
| 132 | |
| 133 | void writeCommonErrorMessage( |
| 134 | WriteBuffer & out, |
| 135 | const char * begin, |
| 136 | const char * end, |
| 137 | Token last_token, |
| 138 | const std::string & query_description) |
| 139 | { |
| 140 | out << "Syntax error"; |
| 141 | |
| 142 | if (!query_description.empty()) |
| 143 | out << " (" << query_description << ")"; |
| 144 | |
| 145 | out << ": failed at position " << (last_token.begin - begin + 1); |
| 146 | |
| 147 | if (last_token.type == TokenType::EndOfStream || last_token.type == TokenType::Semicolon) |
| 148 | { |
| 149 | out << " (end of query)"; |
| 150 | } |
| 151 | else |
| 152 | { |
| 153 | /// Do not print too long tokens. |
| 154 | size_t token_size_bytes = last_token.end - last_token.begin; |
| 155 | size_t token_preview_size_bytes = UTF8::computeBytesBeforeWidth( |
| 156 | reinterpret_cast<const UInt8 *>(last_token.begin), token_size_bytes, 0, SHOW_CHARS_ON_SYNTAX_ERROR); |
| 157 | |
| 158 | out << " (" << std::string(last_token.begin, token_preview_size_bytes) |
| 159 | << (token_preview_size_bytes < token_size_bytes ? "..." : "") << ")"; |
| 160 | } |
| 161 | |
| 162 | /// If query is multiline. |
| 163 | const char * nl = find_first_symbols<'\n'>(begin, end); |
| 164 | if (nl + 1 < end) |
| 165 | { |
| 166 | size_t line = 0; |
| 167 | size_t col = 0; |
| 168 | std::tie(line, col) = getLineAndCol(begin, last_token.begin); |
| 169 | |
| 170 | out << " (line " << line << ", col " << col << ")"; |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | |
| 175 | std::string getSyntaxErrorMessage( |
no test coverage detected