| 1275 | } |
| 1276 | |
| 1277 | void ClientBase::processOrdinaryQuery(String query, ASTPtr parsed_query) |
| 1278 | { |
| 1279 | /// Rewrite query only when we have query parameters. |
| 1280 | /// Note that if query is rewritten, comments in query are lost. |
| 1281 | /// But the user often wants to see comments in server logs, query log, processlist, etc. |
| 1282 | /// For recent versions of the server query parameters will be transferred by network and applied on the server side. |
| 1283 | if (!query_parameters.empty() |
| 1284 | && connection->getServerRevision(connection_parameters.timeouts) < DBMS_MIN_PROTOCOL_VERSION_WITH_PARAMETERS) |
| 1285 | { |
| 1286 | /// Replace ASTQueryParameter with ASTLiteral for prepared statements. |
| 1287 | ReplaceQueryParameterVisitor visitor(query_parameters); |
| 1288 | visitor.visit(parsed_query); |
| 1289 | |
| 1290 | /// Get new query after substitutions. |
| 1291 | if (visitor.getNumberOfReplacedParameters()) |
| 1292 | query = parsed_query->formatWithSecretsOneLine(); |
| 1293 | chassert(!query.empty()); |
| 1294 | } |
| 1295 | |
| 1296 | if (allow_merge_tree_settings && parsed_query->as<ASTCreateQuery>()) |
| 1297 | { |
| 1298 | /// Rewrite query if new settings were added. |
| 1299 | if (addMergeTreeSettings(*parsed_query->as<ASTCreateQuery>())) |
| 1300 | { |
| 1301 | /// Replace query parameters because AST cannot be serialized otherwise. |
| 1302 | if (!query_parameters.empty()) |
| 1303 | { |
| 1304 | ReplaceQueryParameterVisitor visitor(query_parameters); |
| 1305 | visitor.visit(parsed_query); |
| 1306 | } |
| 1307 | |
| 1308 | query = parsed_query->formatWithSecretsOneLine(); |
| 1309 | } |
| 1310 | } |
| 1311 | |
| 1312 | String out_file; |
| 1313 | String out_file_if_truncated; |
| 1314 | |
| 1315 | // Run some local checks to make sure queries into output file will work before sending to server. |
| 1316 | if (const auto * query_with_output = dynamic_cast<const ASTQueryWithOutput *>(parsed_query.get())) |
| 1317 | { |
| 1318 | if (query_with_output->out_file) |
| 1319 | { |
| 1320 | if (isEmbeeddedClient()) |
| 1321 | throw Exception(ErrorCodes::SUPPORT_IS_DISABLED, "Out files are disabled when you are running client embedded into server."); |
| 1322 | |
| 1323 | const auto & out_file_node = query_with_output->out_file->as<ASTLiteral &>(); |
| 1324 | out_file = out_file_node.value.safeGet<std::string>(); |
| 1325 | |
| 1326 | if (query_with_output->isOutfileTruncate() && fs::is_regular_file(out_file)) |
| 1327 | { |
| 1328 | out_file_if_truncated = out_file; |
| 1329 | fs::path out_file_path(out_file); |
| 1330 | out_file = (out_file_path.parent_path() / fmt::format("tmp_{}.{}", UUIDHelpers::generateV4(), out_file_path.filename().string())).string(); |
| 1331 | |
| 1332 | /// Update the AST literal so that initOutputFormat writes to the temp file |
| 1333 | /// and performAtomicRename reads the temp path from the AST. |
| 1334 | auto & out_file_node_mutable = query_with_output->out_file->as<ASTLiteral &>(); |
nothing calls this directly
no test coverage detected