HyukjinKwon commented on code in PR #59313:
URL: https://github.com/apache/spark/pull/59313#discussion_r4235928047


##########
sql/core/src/main/scala/org/apache/spark/sql/execution/datasources/v2/ffi/NativeDataSourceRegistry.scala:
##########
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.spark.sql.execution.datasources.v2.ffi
+
+import java.io.File
+import java.nio.file.Paths
+import java.util.Locale
+
+import org.apache.spark.{SparkEnv, SparkFiles}
+import org.apache.spark.internal.Logging
+import org.apache.spark.internal.LogKeys.PATH
+import org.apache.spark.sql.Artifact
+import org.apache.spark.sql.classic.SparkSession
+import org.apache.spark.sql.datasource.NativeBridge
+import org.apache.spark.sql.errors.{QueryCompilationErrors, 
QueryExecutionErrors}
+import org.apache.spark.sql.internal.{SQLConf, StaticSQLConf}
+import org.apache.spark.util.Utils
+
+/**
+ * Finds the native data sources on the driver. Like the Python data sources 
installed in the
+ * Python path, the native data source libraries installed in the native 
library path are found
+ * automatically, by their file name: the library `spark_datasource_<name>`, 
such as
+ * `libspark_datasource_my_source.so` on Linux, implements the data source 
`<name>`. The active
+ * session can also add packages with `spark.addArtifact`, or with
+ * `spark.sql.dataSource.native.paths`, which take precedence over the 
installed libraries.
+ */
+object NativeDataSourceRegistry extends Logging {
+
+  /** The prefix of the names of the installed native data source libraries. */
+  val LIBRARY_NAME_PREFIX = "spark_datasource_"
+
+  /** Returns whether the native data source with the given name exists. */
+  def exists(name: String, conf: SQLConf): Boolean = lookup(name, 
conf).isDefined
+
+  /**
+   * Finds the package or the installed library that provides the native data 
source with the
+   * given name, which is case-insensitive. Returns the name of the data 
source, as listed in the
+   * manifest of the package or in lower case for an installed library, and 
where its library is.
+   */
+  def lookup(name: String, conf: SQLConf): Option[(String, 
NativeLibraryLocation)] = {
+    if (!conf.getConf(StaticSQLConf.NATIVE_DATA_SOURCE_ENABLED)) {
+      return None
+    }
+    lookupPackage(name, configuredPackageFiles(conf) ++ artifactPackageFiles())
+      .orElse(lookupInstalledLibrary(name))
+  }
+
+  private def lookupPackage(
+      name: String,
+      files: Seq[File]): Option[(String, NativeDataSourcePackage)] = {
+    val found = 
files.map(_.getCanonicalFile).distinct.map(NativeDataSourcePackage.read)

Review Comment:
   Fixed in 9dd4f88. The lookup now reads each package with 
`NativeDataSourcePackage.tryRead` and skips the invalid ones; each invalid file 
is logged once (the result is cached until the file changes). An invalid 
package is reported only when its manifest can be read and lists the requested 
name, e.g. a manifest that names a library missing from the zip. A package 
whose manifest cannot be read at all can't be matched to a name, so it's 
skipped. The new test `ignore invalid packages that do not provide the data 
source` puts a package without a manifest, a non-zip file, and a package for 
another source next to a valid one. It checks that `native_range` still reads, 
`com.typo.Missing` gives `DATA_SOURCE_NOT_FOUND`, `SELECT * FROM 
missing_db.missing_table` gives `TABLE_OR_VIEW_NOT_FOUND`, and only 
`other_source` reports its `INVALID_MANIFEST`. The executor-side lookup also 
skips invalid copies now.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to