You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@druid.apache.org by yq...@apache.org on 2026/06/24 18:43:59 UTC

(druid) branch master updated: minor: add debug logs for diagnosing projection match failures (#19613)

This is an automated email from the ASF dual-hosted git repository.

cecemei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 6687229e0e4 minor:  add debug logs for diagnosing projection match failures (#19613)
6687229e0e4 is described below

commit 6687229e0e4a90f20cf7827c2c0c2edcff0b2562
Author: Cece Mei <yi...@gmail.com>
AuthorDate: Wed Jun 24 11:43:53 2026 -0700

    minor:  add debug logs for diagnosing projection match failures (#19613)
    
    * proj
    
    * comment
    
    * debug
    
    * debug
---
 .../druid/segment/projections/Projections.java     | 46 ++++++++++++++++++++--
 1 file changed, 43 insertions(+), 3 deletions(-)

diff --git a/processing/src/main/java/org/apache/druid/segment/projections/Projections.java b/processing/src/main/java/org/apache/druid/segment/projections/Projections.java
index 40980d000bb..54c214f4b37 100644
--- a/processing/src/main/java/org/apache/druid/segment/projections/Projections.java
+++ b/processing/src/main/java/org/apache/druid/segment/projections/Projections.java
@@ -26,6 +26,8 @@ import org.apache.druid.error.InvalidInput;
 import org.apache.druid.java.util.common.granularity.Granularities;
 import org.apache.druid.java.util.common.granularity.Granularity;
 import org.apache.druid.java.util.common.granularity.PeriodGranularity;
+import org.apache.druid.java.util.common.logger.Logger;
+import org.apache.druid.query.QueryContext;
 import org.apache.druid.query.QueryContexts;
 import org.apache.druid.query.aggregation.AggregatorFactory;
 import org.apache.druid.query.aggregation.FilteredAggregatorFactory;
@@ -67,6 +69,17 @@ import java.util.function.Function;
 
 public class Projections
 {
+  private static final Logger log = new Logger(Projections.class);
+
+  private static void logTrace(QueryContext context, String format, Object... args)
+  {
+    if (context.isDebug()) {
+      log.info(format, args);
+    } else {
+      log.debug(format, args);
+    }
+  }
+
   public static final String BASE_TABLE_PROJECTION_NAME = "__base";
 
   private static final String CLUSTER_GROUP_PREFIX = BASE_TABLE_PROJECTION_NAME + "$";
@@ -161,13 +174,22 @@ public class Projections
   )
   {
     if (!queryCursorBuildSpec.isCompatibleOrdering(projection.getOrderingWithTimeColumnSubstitution())) {
+      logTrace(
+          queryCursorBuildSpec.getQueryContext(),
+          "matchAggregateProjection: projection [%s] rejected — incompatible ordering, query wants %s but projection provides %s",
+          projection.getName(),
+          queryCursorBuildSpec.getPreferredOrdering(),
+          projection.getOrderingWithTimeColumnSubstitution()
+      );
       return null;
     }
     if (CollectionUtils.isNullOrEmpty(queryCursorBuildSpec.getPhysicalColumns())) {
+      logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregateProjection: projection [%s] rejected — no physical columns in query", projection.getName());
       return null;
     }
 
     if (isUnalignedInterval(projection, queryCursorBuildSpec, dataInterval)) {
+      logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregateProjection: projection [%s] rejected — unaligned interval", projection.getName());
       return null;
     }
     ProjectionMatchBuilder matchBuilder = new ProjectionMatchBuilder();
@@ -175,21 +197,25 @@ public class Projections
     // match virtual columns first, which will populate the 'remapColumns' of the match builder
     matchBuilder = matchQueryVirtualColumns(projection, queryCursorBuildSpec, physicalColumnChecker, matchBuilder);
     if (matchBuilder == null) {
+      logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregateProjection: projection [%s] rejected — virtual column mismatch", projection.getName());
       return null;
     }
 
     matchBuilder = matchFilter(projection, queryCursorBuildSpec, physicalColumnChecker, matchBuilder);
     if (matchBuilder == null) {
+      logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregateProjection: projection [%s] rejected — filter mismatch", projection.getName());
       return null;
     }
 
     matchBuilder = matchGrouping(projection, queryCursorBuildSpec, physicalColumnChecker, matchBuilder);
     if (matchBuilder == null) {
+      logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregateProjection: projection [%s] rejected — grouping mismatch", projection.getName());
       return null;
     }
 
     matchBuilder = matchAggregators(projection, queryCursorBuildSpec, physicalColumnChecker, matchBuilder);
     if (matchBuilder == null) {
+      logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregateProjection: projection [%s] rejected — aggregator mismatch", projection.getName());
       return null;
     }
 
@@ -213,6 +239,7 @@ public class Projections
           matchBuilder
       );
       if (matchBuilder == null) {
+        logTrace(queryCursorBuildSpec.getQueryContext(), "matchQueryVirtualColumns: projection [%s] rejected — virtual column [%s] could not be matched", projection.getName(), vc.getOutputName());
         return null;
       }
     }
@@ -231,7 +258,6 @@ public class Projections
     if (projection.getFilter() != null) {
       final Filter queryFilter = queryCursorBuildSpec.getFilter();
       if (queryFilter != null) {
-        final Set<String> originalRequired = queryFilter.getRequiredColumns();
         // try to rewrite the query filter into a projection filter, if the rewrite is valid, we can proceed
         final Filter projectionFilter = projection.getFilter().toOptimizedFilter(false);
         final Filter remappedQueryFilter = remapFilterToProjection(matchBuilder, queryFilter);
@@ -239,6 +265,7 @@ public class Projections
         final Filter rewritten = ProjectionFilterMatch.rewriteFilter(projectionFilter, remappedQueryFilter);
         // if the filter does not contain the projection filter, we cannot match this projection
         if (rewritten == null) {
+          logTrace(queryCursorBuildSpec.getQueryContext(), "matchFilter: projection [%s] rejected — query filter does not contain the projection filter", projection.getName());
           return null;
         }
         //noinspection ObjectEquality
@@ -251,6 +278,7 @@ public class Projections
         }
       } else {
         // projection has a filter, but the query doesn't, no good
+        logTrace(queryCursorBuildSpec.getQueryContext(), "matchFilter: projection [%s] rejected — projection has a filter but query does not", projection.getName());
         return null;
       }
     } else {
@@ -269,6 +297,7 @@ public class Projections
             matchBuilder
         );
         if (matchBuilder == null) {
+          logTrace(queryCursorBuildSpec.getQueryContext(), "matchFilter: projection [%s] rejected — required filter column [%s] not available on projection", projection.getName(), queryColumn);
           return null;
         }
       }
@@ -296,14 +325,17 @@ public class Projections
             matchBuilder
         );
         if (matchBuilder == null) {
+          logTrace(queryCursorBuildSpec.getQueryContext(), "matchGrouping: projection [%s] rejected — grouping column [%s] not available on projection", projection.getName(), queryColumn);
           return null;
         }
         // a query grouping column must also be defined as a projection grouping column
         if (projection.isInvalidGrouping(queryColumn)) {
+          logTrace(queryCursorBuildSpec.getQueryContext(), "matchGrouping: projection [%s] rejected — column [%s] is not a grouping column on the projection", projection.getName(), queryColumn);
           return null;
         }
         // even if remapped
         if (projection.isInvalidGrouping(matchBuilder.getRemapValue(queryColumn))) {
+          logTrace(queryCursorBuildSpec.getQueryContext(), "matchGrouping: projection [%s] rejected — remapped column [%s] is not a grouping column on the projection", projection.getName(), matchBuilder.getRemapValue(queryColumn));
           return null;
         }
       }
@@ -354,6 +386,7 @@ public class Projections
                   matchBuilder
               );
               if (matchBuilder == null) {
+                logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregators: projection [%s] rejected — filtered aggregator [%s] requires column [%s] not available on projection", projection.getName(), queryAgg.getName(), column);
                 return null;
               }
             }
@@ -375,6 +408,7 @@ public class Projections
     if (allMatch) {
       return matchBuilder;
     }
+    logTrace(queryCursorBuildSpec.getQueryContext(), "matchAggregators: projection [%s] rejected — one or more query aggregators could not be matched to a projection aggregator", projection.getName());
     return null;
   }
 
@@ -422,7 +456,7 @@ public class Projections
       );
     }
 
-    return matchQueryPhysicalColumn(column, projection, physicalColumnChecker, matchBuilder);
+    return matchQueryPhysicalColumn(column, projection, physicalColumnChecker, matchBuilder, queryCursorBuildSpec.getQueryContext());
   }
 
   @Nullable
@@ -482,12 +516,14 @@ public class Projections
         // 1. virtual gran is NONE, and projection gran is not
         // 2. projection gran is ALL, and virtual gran is not
         // 3. both are period granularities, but projection gran can't be mapped to virtual gran, e.x. PT2H can't be mapped to PT1H
+        logTrace(queryCursorBuildSpec.getQueryContext(), "matchQueryVirtualColumn: projection [%s] rejected — virtual column [%s] granularity [%s] is incompatible with projection granularity [%s]", projection.getName(), queryVirtualColumn.getOutputName(), virtualGranularity, projection.getEffectiveGranularity());
         return null;
       } else {
         // we can't decide query granularity for the virtual column with __time, requires none granularity to be safe
         if (Granularities.NONE.equals(projection.getEffectiveGranularity())) {
           return matchBuilder.addReferencedPhysicalColumn(ColumnHolder.TIME_COLUMN_NAME);
         }
+        logTrace(queryCursorBuildSpec.getQueryContext(), "matchQueryVirtualColumn: projection [%s] rejected — virtual column [%s] uses __time but projection granularity [%s] is not NONE", projection.getName(), queryVirtualColumn.getOutputName(), projection.getEffectiveGranularity());
         return null;
       }
     } else {
@@ -500,6 +536,7 @@ public class Projections
             matchBuilder
         );
         if (matchBuilder == null) {
+          logTrace(queryCursorBuildSpec.getQueryContext(), "matchQueryVirtualColumn: projection [%s] rejected — virtual column [%s] requires input [%s] not available on projection", projection.getName(), queryVirtualColumn.getOutputName(), required);
           return null;
         }
       }
@@ -512,7 +549,8 @@ public class Projections
       String column,
       AggregateProjectionSchema projection,
       PhysicalColumnChecker physicalColumnChecker,
-      ProjectionMatchBuilder matchBuilder
+      ProjectionMatchBuilder matchBuilder,
+      QueryContext context
   )
   {
     // if we need __time as a physical column, the projection must be grouping on __time directly
@@ -520,11 +558,13 @@ public class Projections
       if (ColumnHolder.TIME_COLUMN_NAME.equals(projection.getTimeColumnName())) {
         return matchBuilder.addReferencedPhysicalColumn(ColumnHolder.TIME_COLUMN_NAME);
       }
+      logTrace(context, "matchQueryPhysicalColumn: projection [%s] rejected — query requires __time as a physical column but projection does not group on __time", projection.getName());
       return null;
     }
     if (physicalColumnChecker.check(projection.getName(), column)) {
       return matchBuilder.addReferencedPhysicalColumn(column);
     }
+    logTrace(context, "matchQueryPhysicalColumn: projection [%s] rejected — column [%s] is not available on projection", projection.getName(), column);
     return null;
   }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@druid.apache.org
For additional commands, e-mail: commits-help@druid.apache.org