Repository: duckdb/duckdb
File: src/main/relation/read_csv_relation.cpp (C++)

Code before:
		D_ASSERT(list[0].type().id() == LogicalTypeId::VARCHAR);
		auto csv_file = StringValue::Get(list[0]);
		alias = StringUtil::Split(csv_file, ".")[0];
	} else {
		throw InternalException("Unsupported type for ReadCSVRelation input Value");
	}
}

ReadCSVRelation::ReadCSVRelation(const shared_ptr<ClientContext> &context, const string &csv_file,
                                 vector<ColumnDefinition> columns_p, string alias_p)
    : TableFunctionRelation(context, "read_csv", {Value(csv_file)}, nullptr, false), alias(std::move(alias_p)),
      auto_detect(false) {

	auto input = Value(csv_file);
	InitializeAlias(input);
	columns = std::move(columns_p);

	child_list_t<Value> column_names;
	for (idx_t i = 0; i < columns.size(); i++) {
		column_names.push_back(make_pair(columns[i].Name(), Value(columns[i].Type().ToString())));
	}

	AddNamedParameter("columns", Value::STRUCT(std::move(column_names)));
}

ReadCSVRelation::ReadCSVRelation(const std::shared_ptr<ClientContext> &context, const Value &input,
                                 named_parameter_map_t &&options, string alias_p)
    : TableFunctionRelation(context, "read_csv_auto", {input}, nullptr, false), alias(std::move(alias_p)),
      auto_detect(true) {

	InitializeAlias(input);
	auto files = MultiFileReader::GetFileList(*context, input, "CSV");
	D_ASSERT(!files.empty());

	auto &file_name = files[0];
	options["auto_detect"] = Value::BOOLEAN(true);
	CSVReaderOptions csv_options;
	csv_options.file_path = file_name;
	vector<string> empty;

	vector<LogicalType> unused_types;
	vector<string> unused_names;
	csv_options.FromNamedParameters(options, *context, unused_types, unused_names);
	// Run the auto-detect, populating the options with the detected settings

	auto bm_file_handle = BaseCSVReader::OpenCSV(*context, csv_options);
	auto buffer_manager = make_shared<CSVBufferManager>(*context, std::move(bm_file_handle), csv_options);
	CSVStateMachineCache state_machine_cache;
	CSVSniffer sniffer(csv_options, buffer_manager, state_machine_cache);
	auto sniffer_result = sniffer.SniffCSV();
	auto &types = sniffer_result.return_types;

Review comment (suggestion):
Maybe have two separate constructors - one with a `string` and one with `vector<string>`? The single string can just call the `vector<string>` with a list.

Code after:
                                 vector<ColumnDefinition> columns_p, string alias_p)
    : TableFunctionRelation(context, "read_csv", {Value(csv_file)}, nullptr, false), alias(std::move(alias_p)),
      auto_detect(false) {

	InitializeAlias({csv_file});
	columns = std::move(columns_p);

	child_list_t<Value> column_names;
	for (idx_t i = 0; i < columns.size(); i++) {
		column_names.push_back(make_pair(columns[i].Name(), Value(columns[i].Type().ToString())));
	}

	AddNamedParameter("columns", Value::STRUCT(std::move(column_names)));
}

static Value CreateValueFromFileList(const vector<string> &file_list) {
	vector<Value> files;
	for (auto &file : file_list) {
		files.push_back(file);
	}
	return Value::LIST(std::move(files));
}

ReadCSVRelation::ReadCSVRelation(const std::shared_ptr<ClientContext> &context, const vector<string> &input,
                                 named_parameter_map_t &&options, string alias_p)
    : TableFunctionRelation(context, "read_csv_auto", {CreateValueFromFileList(input)}, nullptr, false),
      alias(std::move(alias_p)), auto_detect(true) {

	InitializeAlias(input);

	auto file_list = CreateValueFromFileList(input);
	auto files = MultiFileReader::GetFileList(*context, file_list, "CSV");
	D_ASSERT(!files.empty());

	auto &file_name = files[0];
	options["auto_detect"] = Value::BOOLEAN(true);
	CSVReaderOptions csv_options;
	csv_options.file_path = file_name;
	vector<string> empty;

	vector<LogicalType> unused_types;
	vector<string> unused_names;
	csv_options.FromNamedParameters(options, *context, unused_types, unused_names);
	// Run the auto-detect, populating the options with the detected settings

	auto bm_file_handle = BaseCSVReader::OpenCSV(*context, csv_options);
	auto buffer_manager = make_shared<CSVBufferManager>(*context, std::move(bm_file_handle), csv_options);
	CSVStateMachineCache state_machine_cache;
	CSVSniffer sniffer(csv_options, buffer_manager, state_machine_cache);
	auto sniffer_result = sniffer.SniffCSV();
	auto &types = sniffer_result.return_types;