| 1042 | } |
| 1043 | |
| 1044 | bool processMultiQuery(const String & all_queries_text) |
| 1045 | { |
| 1046 | // It makes sense not to base any control flow on this, so that it is |
| 1047 | // the same in tests and in normal usage. The only difference is that in |
| 1048 | // normal mode we ignore the test hints. |
| 1049 | const bool test_mode = config().has("testmode"); |
| 1050 | |
| 1051 | { |
| 1052 | /// disable logs if expects errors |
| 1053 | TestHint test_hint(test_mode, all_queries_text); |
| 1054 | if (test_hint.clientError() || test_hint.serverError()) |
| 1055 | processTextAsSingleQuery("SET send_logs_level = 'fatal'"); |
| 1056 | } |
| 1057 | |
| 1058 | bool echo_query = echo_queries; |
| 1059 | |
| 1060 | /// Several queries separated by ';'. |
| 1061 | /// INSERT data is ended by the end of line, not ';'. |
| 1062 | /// An exception is VALUES format where we also support semicolon in |
| 1063 | /// addition to end of line. |
| 1064 | |
| 1065 | const char * this_query_begin = all_queries_text.data(); |
| 1066 | const char * all_queries_end = all_queries_text.data() + all_queries_text.size(); |
| 1067 | |
| 1068 | while (this_query_begin < all_queries_end) |
| 1069 | { |
| 1070 | // Remove leading empty newlines and other whitespace, because they |
| 1071 | // are annoying to filter in query log. This is mostly relevant for |
| 1072 | // the tests. |
| 1073 | while (this_query_begin < all_queries_end && isWhitespaceASCII(*this_query_begin)) |
| 1074 | { |
| 1075 | ++this_query_begin; |
| 1076 | } |
| 1077 | if (this_query_begin >= all_queries_end) |
| 1078 | { |
| 1079 | break; |
| 1080 | } |
| 1081 | |
| 1082 | // If there are only comments left until the end of file, we just |
| 1083 | // stop. The parser can't handle this situation because it always |
| 1084 | // expects that there is some query that it can parse. |
| 1085 | // We can get into this situation because the parser also doesn't |
| 1086 | // skip the trailing comments after parsing a query. This is because |
| 1087 | // they may as well be the leading comments for the next query, |
| 1088 | // and it makes more sense to treat them as such. |
| 1089 | { |
| 1090 | Tokens tokens(this_query_begin, all_queries_end); |
| 1091 | IParser::Pos token_iterator(tokens, context->getSettingsRef().max_parser_depth); |
| 1092 | if (!token_iterator.isValid()) |
| 1093 | { |
| 1094 | break; |
| 1095 | } |
| 1096 | } |
| 1097 | |
| 1098 | // Try to parse the query. |
| 1099 | const char * this_query_end = this_query_begin; |
| 1100 | try |
| 1101 | { |
nothing calls this directly
no test coverage detected