Skip to content

Commit 0e4651c

Browse files
authored
fix(c/driver_manager): do not parse driver/URI if both are set (#3790)
This fixes a regression in behavior. We only want to activate the new behavior if only one of driver or URI is set.
1 parent 6073da3 commit 0e4651c

File tree

3 files changed

+93
-71
lines changed

3 files changed

+93
-71
lines changed

c/driver_manager/adbc_driver_manager.cc

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ struct ParseDriverUriResult {
6868
};
6969

7070
ADBC_EXPORT
71-
std::optional<ParseDriverUriResult> InternalAdbcParseDriverUri(std::string_view& str);
71+
std::optional<ParseDriverUriResult> InternalAdbcParseDriverUri(std::string_view str);
7272

7373
namespace {
7474

@@ -1549,7 +1549,7 @@ std::string InternalAdbcDriverManagerDefaultEntrypoint(const std::string& driver
15491549
}
15501550

15511551
ADBC_EXPORT
1552-
std::optional<ParseDriverUriResult> InternalAdbcParseDriverUri(std::string_view& str) {
1552+
std::optional<ParseDriverUriResult> InternalAdbcParseDriverUri(std::string_view str) {
15531553
std::string::size_type pos = str.find(":");
15541554
if (pos == std::string::npos) {
15551555
return std::nullopt;
@@ -1725,36 +1725,9 @@ AdbcStatusCode AdbcDatabaseSetOption(struct AdbcDatabase* database, const char*
17251725

17261726
TempDatabase* args = reinterpret_cast<TempDatabase*>(database->private_data);
17271727
if (std::strcmp(key, "driver") == 0) {
1728-
std::string_view v{value};
1729-
auto result = InternalAdbcParseDriverUri(v);
1730-
if (!result) {
1731-
args->driver = std::string{v};
1732-
} else {
1733-
args->driver = std::string{result->driver};
1734-
if (result->uri) {
1735-
args->options["uri"] = std::string{*result->uri};
1736-
}
1737-
}
1728+
args->driver = value;
17381729
} else if (std::strcmp(key, "entrypoint") == 0) {
17391730
args->entrypoint = value;
1740-
} else if (std::strcmp(key, "uri") == 0) {
1741-
if (!args->driver.empty()) { // if driver is already set, just set uri
1742-
args->options[key] = value;
1743-
} else {
1744-
std::string_view v{value};
1745-
auto result = InternalAdbcParseDriverUri(v);
1746-
if (!result) {
1747-
SetError(error, "Invalid URI: missing scheme");
1748-
return ADBC_STATUS_INVALID_ARGUMENT;
1749-
}
1750-
1751-
args->driver = std::string{result->driver};
1752-
if (!result->uri) {
1753-
SetError(error, "Invalid URI: " + std::string{value});
1754-
return ADBC_STATUS_INVALID_ARGUMENT;
1755-
}
1756-
args->options["uri"] = std::string{*result->uri};
1757-
}
17581731
} else {
17591732
args->options[key] = value;
17601733
}
@@ -1847,11 +1820,31 @@ AdbcStatusCode AdbcDatabaseInit(struct AdbcDatabase* database, struct AdbcError*
18471820
return ADBC_STATUS_INVALID_STATE;
18481821
}
18491822
TempDatabase* args = reinterpret_cast<TempDatabase*>(database->private_data);
1850-
if (args->init_func) {
1851-
// Do nothing
1852-
} else if (args->driver.empty()) {
1853-
SetError(error, "Must provide 'driver' parameter");
1854-
return ADBC_STATUS_INVALID_ARGUMENT;
1823+
if (!args->init_func) {
1824+
const auto uri = args->options.find("uri");
1825+
if (args->driver.empty() && uri != args->options.end()) {
1826+
std::string owned_uri = uri->second;
1827+
auto result = InternalAdbcParseDriverUri(owned_uri);
1828+
if (result && result->uri) {
1829+
args->driver = std::string{result->driver};
1830+
args->options["uri"] = std::string{*result->uri};
1831+
}
1832+
} else if (!args->driver.empty() && uri == args->options.end()) {
1833+
std::string owned_driver = args->driver;
1834+
auto result = InternalAdbcParseDriverUri(owned_driver);
1835+
if (result) {
1836+
args->driver = std::string{result->driver};
1837+
if (result->uri) {
1838+
args->options["uri"] = std::string{*result->uri};
1839+
}
1840+
}
1841+
}
1842+
1843+
if (args->driver.empty()) {
1844+
SetError(error,
1845+
"Must provide 'driver' parameter (or encode driver in 'uri' parameter)");
1846+
return ADBC_STATUS_INVALID_ARGUMENT;
1847+
}
18551848
}
18561849

18571850
database->private_driver = new AdbcDriver;

c/driver_manager/adbc_driver_manager_test.cc

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ struct ParseDriverUriResult {
4545
std::optional<std::string_view> uri;
4646
};
4747

48-
std::optional<ParseDriverUriResult> InternalAdbcParseDriverUri(std::string_view& str);
48+
std::optional<ParseDriverUriResult> InternalAdbcParseDriverUri(std::string_view str);
4949

5050
// Tests of the SQLite example driver, except using the driver manager
5151

@@ -1190,4 +1190,40 @@ shared = "adbc_driver_sqlite")";
11901190
ASSERT_TRUE(std::filesystem::remove(filepath));
11911191
}
11921192

1193+
TEST_F(DriverManifest, DriverFromDriverAndUri) {
1194+
// Regression test: if we set both driver and URI, then we shouldn't try to
1195+
// extract driver from URI or vice versa.
1196+
1197+
auto filepath = temp_dir / "sqlite.toml";
1198+
std::ofstream test_manifest_file(filepath);
1199+
ASSERT_TRUE(test_manifest_file.is_open());
1200+
test_manifest_file << R"([Driver]
1201+
shared = "adbc_driver_sqlite")";
1202+
test_manifest_file.close();
1203+
1204+
const std::string uri = "foo.db";
1205+
std::vector<std::vector<std::pair<std::string, std::string>>> options_cases = {
1206+
{{"driver", "sqlite"}, {"uri", uri}},
1207+
{{"uri", uri}, {"driver", "sqlite"}},
1208+
};
1209+
for (const auto& options : options_cases) {
1210+
adbc_validation::Handle<struct AdbcDatabase> database;
1211+
ASSERT_THAT(AdbcDatabaseNew(&database.value, &error), IsOkStatus(&error));
1212+
for (const auto& option : options) {
1213+
ASSERT_THAT(AdbcDatabaseSetOption(&database.value, option.first.c_str(),
1214+
option.second.c_str(), &error),
1215+
IsOkStatus(&error));
1216+
}
1217+
1218+
std::string search_path = temp_dir.string();
1219+
ASSERT_THAT(AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
1220+
&database.value, search_path.data(), &error),
1221+
IsOkStatus(&error));
1222+
ASSERT_THAT(AdbcDatabaseInit(&database.value, &error),
1223+
IsStatus(ADBC_STATUS_OK, &error));
1224+
}
1225+
1226+
ASSERT_TRUE(std::filesystem::remove(filepath));
1227+
}
1228+
11931229
} // namespace adbc

go/adbc/drivermgr/adbc_driver_manager.cc

Lines changed: 28 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)