diff --git a/dbms/programs/server/TCPHandler.cpp b/dbms/programs/server/TCPHandler.cpp index 837812f84af..8debfd7d235 100644 --- a/dbms/programs/server/TCPHandler.cpp +++ b/dbms/programs/server/TCPHandler.cpp @@ -384,7 +384,10 @@ void TCPHandler::processInsertQuery(const Settings & global_settings) { const auto & db_and_table = query_context->getInsertionTable(); if (query_context->getSettingsRef().input_format_defaults_for_omitted_fields) - sendTableColumns(query_context->getTable(db_and_table.first, db_and_table.second)->getColumns()); + { + if (!db_and_table.second.empty()) + sendTableColumns(query_context->getTable(db_and_table.first, db_and_table.second)->getColumns()); + } } /// Send block to the client - table structure. diff --git a/dbms/src/Core/Settings.h b/dbms/src/Core/Settings.h index b1182cae9bf..4df07df60f6 100644 --- a/dbms/src/Core/Settings.h +++ b/dbms/src/Core/Settings.h @@ -170,7 +170,7 @@ struct Settings : public SettingsCollection M(SettingBool, input_format_skip_unknown_fields, false, "Skip columns with unknown names from input data (it works for JSONEachRow, CSVWithNames, TSVWithNames and TSKV formats).") \ M(SettingBool, input_format_with_names_use_header, false, "For TSVWithNames and CSVWithNames input formats this controls whether format parser is to assume that column data appear in the input exactly as they are specified in the header.") \ M(SettingBool, input_format_import_nested_json, false, "Map nested JSON data to nested tables (it works for JSONEachRow format).") \ - M(SettingBool, input_format_defaults_for_omitted_fields, false, "For input data calculate default expressions for omitted fields (it works for JSONEachRow format).") \ + M(SettingBool, input_format_defaults_for_omitted_fields, true, "For input data calculate default expressions for omitted fields (it works for JSONEachRow format).") \ \ M(SettingBool, input_format_values_interpret_expressions, true, "For Values format: if field could not be parsed by streaming parser, run SQL parser and try to interpret it as SQL expression.") \ \ diff --git a/dbms/src/DataStreams/InputStreamFromASTInsertQuery.cpp b/dbms/src/DataStreams/InputStreamFromASTInsertQuery.cpp index aa3faaede28..d8f536c6ace 100644 --- a/dbms/src/DataStreams/InputStreamFromASTInsertQuery.cpp +++ b/dbms/src/DataStreams/InputStreamFromASTInsertQuery.cpp @@ -51,7 +51,7 @@ InputStreamFromASTInsertQuery::InputStreamFromASTInsertQuery( res_stream = context.getInputFormat(format, *input_buffer_contacenated, header, context.getSettings().max_insert_block_size); - if (context.getSettingsRef().input_format_defaults_for_omitted_fields) + if (context.getSettingsRef().input_format_defaults_for_omitted_fields && !ast_insert_query->table.empty()) { StoragePtr storage = context.getTable(ast_insert_query->database, ast_insert_query->table); auto column_defaults = storage->getColumns().getDefaults(); diff --git a/dbms/src/DataStreams/RemoteBlockOutputStream.cpp b/dbms/src/DataStreams/RemoteBlockOutputStream.cpp index 2f93d88ac7c..a95ea174541 100644 --- a/dbms/src/DataStreams/RemoteBlockOutputStream.cpp +++ b/dbms/src/DataStreams/RemoteBlockOutputStream.cpp @@ -50,6 +50,11 @@ RemoteBlockOutputStream::RemoteBlockOutputStream(Connection & connection_, if (auto log_queue = CurrentThread::getInternalTextLogsQueue()) log_queue->pushBlock(std::move(packet.block)); } + else if (Protocol::Server::TableColumns == packet.type) + { + /// Server could attach ColumnsDescription in front of stream for column defaults. There's no need to pass it through cause + /// client's already got this information for remote table. Ignore. + } else throw NetException("Unexpected packet from server (expected Data or Exception, got " + String(Protocol::Server::toString(packet.type)) + ")", ErrorCodes::UNEXPECTED_PACKET_FROM_SERVER); diff --git a/dbms/src/DataStreams/TTLBlockInputStream.cpp b/dbms/src/DataStreams/TTLBlockInputStream.cpp index 1e765f8bb3c..11999b894aa 100644 --- a/dbms/src/DataStreams/TTLBlockInputStream.cpp +++ b/dbms/src/DataStreams/TTLBlockInputStream.cpp @@ -40,8 +40,10 @@ TTLBlockInputStream::TTLBlockInputStream( auto it = column_defaults.find(name); if (it != column_defaults.end()) - default_expr_list->children.emplace_back( - setAlias(it->second.expression, it->first)); + { + auto expression = it->second.expression->clone(); + default_expr_list->children.emplace_back(setAlias(expression, it->first)); + } } else new_ttl_infos.columns_ttl.emplace(name, ttl_info); diff --git a/dbms/src/Interpreters/executeQuery.cpp b/dbms/src/Interpreters/executeQuery.cpp index b001c9bcb0a..5c7617aa8a1 100644 --- a/dbms/src/Interpreters/executeQuery.cpp +++ b/dbms/src/Interpreters/executeQuery.cpp @@ -247,7 +247,12 @@ static std::tuple executeQueryImpl( res = interpreter->execute(); if (auto * insert_interpreter = typeid_cast(&*interpreter)) - context.setInsertionTable(insert_interpreter->getDatabaseTable()); + { + /// Save insertion table (not table function). TODO: support remote() table function. + auto db_table = insert_interpreter->getDatabaseTable(); + if (!db_table.second.empty()) + context.setInsertionTable(std::move(db_table)); + } if (process_list_entry) {