github-advanced-security[bot] commented on code in PR #17726:
URL: https://github.com/apache/druid/pull/17726#discussion_r1954582087


##########
processing/src/main/java/org/apache/druid/query/JoinDataSource.java:
##########
@@ -419,164 +399,148 @@
            '}';
   }
 
-  private DataSourceAnalysis getAnalysisForDataSource()
-  {
-    final Triple<DataSource, DimFilter, List<PreJoinableClause>> flattened = 
flattenJoin(this);
-    return new DataSourceAnalysis(flattened.first, null, flattened.second, 
flattened.third);
-  }
-
   /**
    * Creates a Function that maps base segments to {@link HashJoinSegment} if 
needed (i.e. if the number of join
    * clauses is > 0). If mapping is not needed, this method will return {@link 
Function#identity()}.
-   *
-   * @param baseFilter         Filter to apply before the join takes place
-   * @param clauses            Pre-joinable clauses
-   * @param cpuTimeAccumulator An accumulator that we will add CPU nanos to; 
this is part of the function to encourage
-   *                           callers to remember to track metrics on CPU 
time required for creation of Joinables
-   * @param query              The query that will be run on the mapped 
segments. Usually this should be
-   *                           {@code analysis.getBaseQuery().orElse(query)}, 
where "analysis" is a
-   *                           {@link DataSourceAnalysis} and "query" is the 
original
-   *                           query from the end user.
+   * @param query
    */
-  private Function<SegmentReference, SegmentReference> 
createSegmentMapFunctionInternal(
-      @Nullable final Filter baseFilter,
-      final List<PreJoinableClause> clauses,
-      final Query<?> query
-  )
+  @Override
+  public Function<SegmentReference, SegmentReference> 
createSegmentMapFunction(Query query)
   {
-    // compute column correlations here and RHS correlated values
+    DataSourceAnalysis safeAnalysis = getSafeAnalysisForDataSource();
+    List<PreJoinableClause> clauses = safeAnalysis.getPreJoinableClauses();
+    Filter baseFilter = 
safeAnalysis.getJoinBaseTableFilter().map(Filters::toFilter).orElse(null);
+
     if (clauses.isEmpty()) {
-      return Function.identity();
-    } else {
-      final JoinableClauses joinableClauses = JoinableClauses.createClauses(
-          clauses,
-          joinableFactoryWrapper.getJoinableFactory()
+      throw DruidException.defensive("A JoinDataSource with no join clauses 
should not be mapped.");
+    }
+    final JoinableClauses joinableClauses = JoinableClauses.createClauses(
+        clauses,
+        joinableFactoryWrapper.getJoinableFactory()
+    );
+    final JoinFilterRewriteConfig filterRewriteConfig = 
JoinFilterRewriteConfig.forQuery(query);
+
+    // Pick off any join clauses that can be converted into filters.
+    final Set<String> requiredColumns = query.getRequiredColumns();
+    final Filter baseFilterToUse;
+    final List<JoinableClause> clausesToUse;
+
+    if (requiredColumns != null && 
filterRewriteConfig.isEnableRewriteJoinToFilter()) {
+      final Pair<List<Filter>, List<JoinableClause>> conversionResult = 
JoinableFactoryWrapper.convertJoinsToFilters(
+          joinableClauses.getJoinableClauses(),
+          requiredColumns,
+          
Ints.checkedCast(Math.min(filterRewriteConfig.getFilterRewriteMaxSize(), 
Integer.MAX_VALUE))
       );
-      final JoinFilterRewriteConfig filterRewriteConfig = 
JoinFilterRewriteConfig.forQuery(query);
-
-      // Pick off any join clauses that can be converted into filters.
-      final Set<String> requiredColumns = query.getRequiredColumns();
-      final Filter baseFilterToUse;
-      final List<JoinableClause> clausesToUse;
-
-      if (requiredColumns != null && 
filterRewriteConfig.isEnableRewriteJoinToFilter()) {
-        final Pair<List<Filter>, List<JoinableClause>> conversionResult = 
JoinableFactoryWrapper.convertJoinsToFilters(
-            joinableClauses.getJoinableClauses(),
-            requiredColumns,
-            
Ints.checkedCast(Math.min(filterRewriteConfig.getFilterRewriteMaxSize(), 
Integer.MAX_VALUE))
-        );
-
-        baseFilterToUse =
-            Filters.maybeAnd(
-                Lists.newArrayList(
-                    Iterables.concat(
-                        Collections.singleton(baseFilter),
-                        conversionResult.lhs
-                    )
-                )
-            ).orElse(null);
-        clausesToUse = conversionResult.rhs;
-      } else {
-        baseFilterToUse = baseFilter;
-        clausesToUse = joinableClauses.getJoinableClauses();
-      }
 
-      // Analyze remaining join clauses to see if filters on them can be 
pushed down.
-      final JoinFilterPreAnalysis joinFilterPreAnalysis = 
JoinFilterAnalyzer.computeJoinFilterPreAnalysis(
-          new JoinFilterPreAnalysisKey(
-              filterRewriteConfig,
-              clausesToUse,
-              query.getVirtualColumns(),
-              Filters.maybeAnd(Arrays.asList(baseFilterToUse, 
Filters.toFilter(query.getFilter())))
-                     .orElse(null)
+      baseFilterToUse = Filters.maybeAnd(
+          Lists.newArrayList(
+              Iterables.concat(
+                  Collections.singleton(baseFilter),
+                  conversionResult.lhs
+              )
           )
-      );
-      final Function<SegmentReference, SegmentReference> baseMapFn;
-      // A join data source is not concrete
-      // And isConcrete() of an unnest datasource delegates to its base
-      // Hence, in the case of a Join -> Unnest -> Join
-      // if we just use isConcrete on the left
-      // the segment map function for the unnest would never get called
-      // This calls us to delegate to the segmentMapFunction of the left
-      // only when it is not a JoinDataSource
-      if (left instanceof JoinDataSource) {
-        baseMapFn = Function.identity();
-      } else {
-        baseMapFn = left.createSegmentMapFunction(
-            query
-        );
-      }
-      return baseSegment ->
-          new HashJoinSegment(
-              baseMapFn.apply(baseSegment),
-              baseFilterToUse,
-              GuavaUtils.firstNonNull(clausesToUse, ImmutableList.of()),
-              joinFilterPreAnalysis
-          );
+      ).orElse(null);
+      clausesToUse = conversionResult.rhs;
+
+    } else {
+      baseFilterToUse = baseFilter;
+      clausesToUse = joinableClauses.getJoinableClauses();
     }
+
+    // Analyze remaining join clauses to see if filters on them can be pushed 
down.
+    final JoinFilterPreAnalysis joinFilterPreAnalysis = 
JoinFilterAnalyzer.computeJoinFilterPreAnalysis(
+        new JoinFilterPreAnalysisKey(
+            filterRewriteConfig,
+            clausesToUse,
+            query.getVirtualColumns(),
+            Filters.maybeAnd(Arrays.asList(baseFilterToUse, 
Filters.toFilter(query.getFilter())))
+                .orElse(null)
+        )
+    );
+    final Function<SegmentReference, SegmentReference> baseMapFn = 
safeAnalysis.getBaseDataSource().createSegmentMapFunction(query);
+    return baseSegment -> newHashJoinSegment(
+        baseMapFn.apply(baseSegment),
+        baseFilterToUse,
+        clausesToUse,
+        joinFilterPreAnalysis
+    );
+  }
+
+  private SegmentReference newHashJoinSegment(
+      SegmentReference sourceSegment,
+      Filter baseFilterToUse,
+      List<JoinableClause> clausesToUse,
+      JoinFilterPreAnalysis joinFilterPreAnalysis)
+  {
+    if (clausesToUse.isEmpty() && baseFilterToUse == null) {
+      return sourceSegment;
+    }
+    return new HashJoinSegment(sourceSegment, baseFilterToUse, clausesToUse, 
joinFilterPreAnalysis);
+  }
+
+
+  private DataSourceAnalysis getAnalysisForDataSource()
+  {
+    return flattenJoin(this, true);
+  }
+
+  public DataSourceAnalysis getSafeAnalysisForDataSource()
+  {
+    return flattenJoin(this, false);
   }
 
   /**
    * Flatten a datasource into two parts: the left-hand side datasource (the 
'base' datasource), and a list of join
    * clauses, if any.
+   * @param b

Review Comment:
   ## Spurious Javadoc @param tags
   
   @param tag "b" does not match any actual parameter of method "flattenJoin()".
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/4889)



##########
processing/src/test/java/org/apache/druid/query/planning/DataSourceAnalysisTest.java:
##########
@@ -485,10 +485,11 @@
   @Test
   public void testJoinUnderTopLevelSubqueries()
   {
+    final JoinDataSource joinDataSource;

Review Comment:
   ## Unread local variable
   
   Variable 'JoinDataSource joinDataSource' is never read.
   
   [Show more 
details](https://github.com/apache/druid/security/code-scanning/4890)



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