OIiveirra commented on code in PR #69528:
URL: https://github.com/apache/doris/pull/69528#discussion_r4369659737


##########
fe/fe-core/src/main/java/org/apache/doris/tablefunction/LocalTableValuedFunction.java:
##########
@@ -135,6 +150,332 @@ private void getFileListFromBackend() throws 
AnalysisException {
         }
     }
 
+    /** Apply LOCAL admission to the effective sink before planning or 
filesystem side effects. */
+    public static void checkSinkEnabled(String tvfName, Map<String, String> 
properties) {
+        if ("local".equalsIgnoreCase(tvfName) || 
isLocalWriter(properties.getOrDefault("writer_class", ""))) {
+            checkEnabled();
+        }
+        if ("hdfs".equalsIgnoreCase(tvfName)) {
+            if (!properties.containsKey("writer_class")) {
+                checkHdfsSinkEnabled(properties);
+            }
+            if 
(Boolean.parseBoolean(properties.getOrDefault("delete_existing_files", 
"false"))) {
+                checkHadoopFileSystemEnabled(
+                        
BrokerUtil.extractParentDirectory(properties.getOrDefault("file_path", "")), 
properties);
+            }
+        }
+    }
+
+    private static boolean isLocalWriter(String writer) {
+        // ScannerLoader accepts slashes, and JNI passes the class name as a C 
string.
+        return 
"org.apache.doris.writer.LocalFileJniWriter".equals(nativeStringPrefix(writer).replace('/',
 '.'));
+    }
+
+    /** Check the NameNode and provider used by the native FILE_HDFS writer. */
+    public static void checkHdfsSinkEnabled(Map<String, String> properties) {
+        checkHdfsSinkEnabled(properties.getOrDefault("file_path", ""), 
properties);
+    }
+
+    public static void checkHdfsSinkEnabled(String outputPrefix, Map<String, 
String> properties) {
+        String nameNode = 
nativeStringPrefix(properties.getOrDefault("fs.defaultFS", "")).trim();
+        if ("default".equals(nameNode)) {
+            // libhdfs delegates this selector to the BE's defaults, which may 
select local storage.
+            checkEnabled();
+        }
+        // libhdfs prefixes bare NameNodes with hdfs:// rather than using the 
output path's scheme.
+        checkHadoopSchemeEnabled(nameNode.contains("://") ? 
uriScheme(nameNode) : "hdfs", properties);
+        if (!Config.enable_local_tvf) {
+            try {
+                URI filesystem = new URI(nameNode.contains("://") ? nameNode : 
"hdfs://" + nameNode);
+                // BE appends a generated filename directly to this prefix, 
then convert_path
+                // removes the NameNode. Resolve its parent, not an exact 
mount-point filename.
+                String generated = outputPrefix + "doris-tvf-file";
+                String rawNameNode = properties.getOrDefault("fs.defaultFS", 
"");
+                if (!rawNameNode.isEmpty() && generated.contains(rawNameNode)) 
{
+                    generated = generated.substring(rawNameNode.length());
+                }
+                if (!generated.startsWith("/")) {
+                    generated = "/" + generated;
+                }
+                String path = 
hadoopPathUri(nativeStringPrefix(generated)).getPath();
+                path = path.substring(0, path.lastIndexOf('/') + 1);
+                if (path.length() > 1) {
+                    path = path.substring(0, path.length() - 1);
+                }
+                checkViewFsEnabled(filesystem, path, properties, new 
HashSet<>());
+            } catch (URISyntaxException e) {
+                // Invalid NameNodes remain subject to the existing storage 
validation.
+            }
+        }
+    }
+
+    /** Check Hadoop's path/default-filesystem selection before FE-side 
cleanup. */
+    public static void checkHadoopFileSystemEnabled(String path, Map<String, 
String> properties) {

Review Comment:
   Fixed in fb92e7d8c337c86e6e90fe135bbd4a5d995115b0. The retained nested 
ViewFS read variant is confirmed and fixed with the same guarded-only 
inner-cache override. Exact authority/profile caching keeps A and a separate 
after warming the outer handler. In an isolated old/new dispatch control the 
old Context allowed /evil while the actual child selected the local leaf; the 
fixed code selected the lowercase table's remote fallback. The successful 
control uses simulated leaf endpoints, without storage content IO. Runtime 
tests execute warm-up followed by repeated lower-table dispatch, alongside 
existing native and Avro per-path checks.
   
   Validation: Final standard JDK17 FE: 107 selected tests passed with fresh 
XML, zero failures/errors/skips and frozen source. Final standard Clang21/ASAN 
BE: 28 selected tests passed. Each release also passed 16 Lance and 19 Paimon 
build-control tests; the new SDK unit/C API tests, matching Rust std/ABI checks 
and private standard build passed. Independent Standards/Spec rechecks found no 
remaining confirmed issue in this follow-up.



-- 
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