Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/include/postgres_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ class PostgresUtils {
static PostgresQueryMode ExtractQueryMode(Value &value);
static PostgresCatalog &GetCatalogByName(ClientContext &context, const std::string &name);

static void DeduplicateColumns(vector<Identifier> &names);

private:
static mutex libpq_init_lock;
static bool libpq_connect_succeeded_at_least_once;
Expand Down
3 changes: 2 additions & 1 deletion src/postgres_query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,9 +206,10 @@ static unique_ptr<FunctionData> PGQueryBind(ClientContext &context, TableFunctio
result->postgres_types.push_back(postgres_type);
return_types.emplace_back(converted_type);
char *name_ptr = PQfname(describe_prepared, c);
string name = name_ptr ? name_ptr : StringUtil::Format("unnamed_%llu", c);
string name = name_ptr ? name_ptr : "unnamed";
names.emplace_back(name);
}
PostgresUtils::DeduplicateColumns(names);
int nparams = PQnparams(describe_prepared);
if (nparams != param_values.size()) {
throw BinderException("Incorrect number of parameters specified, expected: %d, actual: %zu, query: \"%s\"",
Expand Down
20 changes: 20 additions & 0 deletions src/postgres_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,4 +781,24 @@ PostgresCatalog &PostgresUtils::GetCatalogByName(ClientContext &context, const s
return catalog.Cast<PostgresCatalog>();
}

void PostgresUtils::DeduplicateColumns(vector<Identifier> &names) {
identifier_map_t<idx_t> name_map;
for (auto &column_name : names) {
if (name_map.find(column_name) == name_map.end()) {
// Name does not exist yet
name_map[column_name]++;
} else {
// Name already exists, we add _x where x is the repetition number
Identifier new_column_name(column_name + "_" + std::to_string(name_map[column_name]));
while (name_map.find(new_column_name) != name_map.end()) {
// This name is already here due to a previous definition
name_map[column_name]++;
new_column_name = Identifier(column_name + "_" + std::to_string(name_map[column_name]));
}
column_name = new_column_name;
name_map[new_column_name]++;
}
}
}

} // namespace duckdb
14 changes: 14 additions & 0 deletions test/sql/scanner/postgres_query.test
Original file line number Diff line number Diff line change
Expand Up @@ -342,5 +342,19 @@ WHERE query = 'SELECT "brand" FROM (SELECT * FROM cars WHERE color=''red'') AS _
statement ok
CALL disable_logging()

# duplicate column names

query III
FROM postgres_query('s1', 'SELECT 41, 42, 43')
----
41 42 43

query I
SELECT column_name FROM (DESCRIBE FROM postgres_query('s1', 'SELECT 41, 42, 43'))
----
?column?
?column?_1
?column?_2

statement ok
DETACH s1
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# name: test/sql/storage/limit_parallel_bug.test
# name: test/sql/storage/limit_parallel_bug.test_slow
# description: Test LIMIT bug with parallelism (issues #380, #395)
# group: [storage]

Expand Down
Loading