#include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace DB { namespace ErrorCodes { extern const int UNKNOWN_QUERY_PARAMETER; extern const int BAD_QUERY_PARAMETER; } void ReplaceQueryParameterVisitor::visit(ASTPtr & ast) { for (auto & child : ast->children) { if (child->as()) visitQueryParameter(child); else visit(child); } } const String & ReplaceQueryParameterVisitor::getParamValue(const String & name) { auto search = query_parameters.find(name); if (search != query_parameters.end()) return search->second; else throw Exception("Substitution " + backQuote(name) + " is not set", ErrorCodes::UNKNOWN_QUERY_PARAMETER); } void ReplaceQueryParameterVisitor::visitQueryParameter(ASTPtr & ast) { const auto & ast_param = ast->as(); const String & value = getParamValue(ast_param.name); const String & type_name = ast_param.type; const auto data_type = DataTypeFactory::instance().get(type_name); auto temp_column_ptr = data_type->createColumn(); IColumn & temp_column = *temp_column_ptr; ReadBufferFromString read_buffer{value}; FormatSettings format_settings; data_type->deserializeAsTextEscaped(temp_column, read_buffer, format_settings); if (!read_buffer.eof()) throw Exception("Value " + value + " cannot be parsed as " + type_name + " for query parameter '" + ast_param.name + "'" " because it isn't parsed completely: only " + toString(read_buffer.count()) + " of " + toString(value.size()) + " bytes was parsed: " + value.substr(0, read_buffer.count()), ErrorCodes::BAD_QUERY_PARAMETER); ast = addTypeConversionToAST(std::make_shared(temp_column[0]), type_name); } }