@@ -16,6 +16,7 @@ public class DuckDBDriver implements java.sql.Driver {
1616 public static final String JDBC_STREAM_RESULTS = "jdbc_stream_results" ;
1717 public static final String JDBC_AUTO_COMMIT = "jdbc_auto_commit" ;
1818 public static final String JDBC_PIN_DB = "jdbc_pin_db" ;
19+ public static final String JDBC_IGNORE_UNSUPPORTED_OPTIONS = "jdbc_ignore_unsupported_options" ;
1920
2021 static final String DUCKDB_URL_PREFIX = "jdbc:duckdb:" ;
2122 static final String MEMORY_DB = ":memory:" ;
@@ -33,6 +34,9 @@ public class DuckDBDriver implements java.sql.Driver {
3334 private static boolean pinnedDbRefsShutdownHookRegistered = false ;
3435 private static boolean pinnedDbRefsShutdownHookRun = false ;
3536
37+ private static final Set <String > supportedOptions = new LinkedHashSet <>();
38+ private static final ReentrantLock supportedOptionsLock = new ReentrantLock ();
39+
3640 static {
3741 try {
3842 DriverManager .registerDriver (new DuckDBDriver ());
@@ -52,13 +56,20 @@ public Connection connect(String url, Properties info) throws SQLException {
5256 props = (Properties ) info .clone ();
5357 }
5458
59+ // URL options
5560 ParsedProps pp = parsePropsFromUrl (url );
5661 for (Map .Entry <String , String > en : pp .props .entrySet ()) {
5762 props .put (en .getKey (), en .getValue ());
5863 }
5964
65+ // Ignore unsupported
66+ removeUnsupportedOptions (props );
67+
68+ // Read-only option
6069 String readOnlyStr = removeOption (props , DUCKDB_READONLY_PROPERTY );
6170 boolean readOnly = isStringTruish (readOnlyStr , false );
71+
72+ // Client name option
6273 props .put ("duckdb_api" , "jdbc" );
6374
6475 // Apache Spark passes this option when SELECT on a JDBC DataSource
@@ -67,6 +78,7 @@ public Connection connect(String url, Properties info) throws SQLException {
6778 // to be established.
6879 props .remove ("path" );
6980
81+ // DuckLake options
7082 String ducklake = removeOption (props , DUCKLAKE_OPTION );
7183 String ducklakeAlias = removeOption (props , DUCKLAKE_ALIAS_OPTION , DUCKLAKE_OPTION );
7284 final String shortUrl ;
@@ -83,13 +95,13 @@ public Connection connect(String url, Properties info) throws SQLException {
8395 shortUrl = pp .shortUrl ;
8496 }
8597
98+ // Pin DB option
8699 String pinDbOptStr = removeOption (props , JDBC_PIN_DB );
87100 boolean pinDBOpt = isStringTruish (pinDbOptStr , false );
88101
102+ // Create connection
89103 DuckDBConnection conn = DuckDBConnection .newConnection (shortUrl , readOnly , props );
90-
91104 pinDB (pinDBOpt , shortUrl , conn );
92-
93105 initDucklake (conn , shortUrl , ducklake , ducklakeAlias );
94106
95107 return conn ;
@@ -116,6 +128,8 @@ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws
116128 list .add (createDriverPropInfo (JDBC_AUTO_COMMIT , "" , "Set default auto-commit mode" ));
117129 list .add (createDriverPropInfo (JDBC_PIN_DB , "" ,
118130 "Do not close the DB instance after all connections to it are closed" ));
131+ list .add (createDriverPropInfo (JDBC_IGNORE_UNSUPPORTED_OPTIONS , "" ,
132+ "Silently discard unsupported connection options" ));
119133 list .sort ((o1 , o2 ) -> o1 .name .compareToIgnoreCase (o2 .name ));
120134 return list .toArray (new DriverPropertyInfo [0 ]);
121135 }
@@ -251,6 +265,38 @@ private static DriverPropertyInfo createDriverPropInfo(String name, String value
251265 return dpi ;
252266 }
253267
268+ private static void removeUnsupportedOptions (Properties props ) throws SQLException {
269+ String ignoreStr = removeOption (props , JDBC_IGNORE_UNSUPPORTED_OPTIONS );
270+ boolean ignore = isStringTruish (ignoreStr , false );
271+ if (!ignore ) {
272+ return ;
273+ }
274+ supportedOptionsLock .lock ();
275+ try {
276+ if (supportedOptions .isEmpty ()) {
277+ Driver driver = DriverManager .getDriver (DUCKDB_URL_PREFIX );
278+ Properties dpiProps = new Properties ();
279+ dpiProps .put ("threads" , 1 );
280+ DriverPropertyInfo [] dpis = driver .getPropertyInfo (DUCKDB_URL_PREFIX , dpiProps );
281+ for (DriverPropertyInfo dpi : dpis ) {
282+ supportedOptions .add (dpi .name );
283+ }
284+ }
285+ List <String > unsupportedNames = new ArrayList <>();
286+ for (Object nameObj : props .keySet ()) {
287+ String name = String .valueOf (nameObj );
288+ if (!supportedOptions .contains (name )) {
289+ unsupportedNames .add (name );
290+ }
291+ }
292+ for (String name : unsupportedNames ) {
293+ props .remove (name );
294+ }
295+ } finally {
296+ supportedOptionsLock .unlock ();
297+ }
298+ }
299+
254300 private static class ParsedProps {
255301 final String shortUrl ;
256302 final LinkedHashMap <String , String > props ;
0 commit comments