clintropolis commented on code in PR #18524:
URL: https://github.com/apache/druid/pull/18524#discussion_r2353783592


##########
server/src/main/java/org/apache/druid/segment/indexing/DataSchema.java:
##########
@@ -415,9 +415,73 @@ private static Set<String> 
computeAndValidateOutputFieldNames(
       }
     }
 
+    return getFieldsOrThrowIfErrors(fields);
+  }
+
+  public static void validateProjections(
+      @Nullable List<AggregateProjectionSpec> projections,
+      @Nullable Granularity segmentGranularity
+  )
+  {
+    if (projections != null) {
+      final Set<String> names = 
Sets.newHashSetWithExpectedSize(projections.size());
+      for (AggregateProjectionSpec projection : projections) {
+        if (names.contains(projection.getName())) {
+          throw InvalidInput.exception("projection[%s] is already defined, 
projection names must be unique", projection.getName());
+        }
+        names.add(projection.getName());
+        final AggregateProjectionMetadata.Schema schema = 
projection.toMetadataSchema();
+
+        if (schema.getTimeColumnName() != null) {
+          final Granularity projectionGranularity = 
schema.getEffectiveGranularity();
+          if (segmentGranularity != null) {
+            if (segmentGranularity.isFinerThan(projectionGranularity)) {
+              throw InvalidInput.exception(
+                  "projection[%s] has granularity[%s] which must be finer than 
or equal to segment granularity[%s]",
+                  projection.getName(),
+                  projectionGranularity,
+                  segmentGranularity
+              );
+            }
+          }
+        }
+
+        final Map<String, Multiset<String>> fields = new TreeMap<>();
+        int position = 0;
+        for (DimensionSchema grouping : projection.getGroupingColumns()) {
+          final String field = grouping.getName();
+          if (Strings.isNullOrEmpty(field)) {
+            throw DruidException
+                .forPersona(DruidException.Persona.USER)
+                .ofCategory(DruidException.Category.INVALID_INPUT)
+                .build("Encountered grouping column with null or empty name at 
position[%d]", position);
+          }
+          fields.computeIfAbsent(field, k -> 
TreeMultiset.create()).add("projection[" + projection.getName() + "] grouping 
column list");
+          position++;
+        }
+        for (AggregatorFactory aggregator : projection.getAggregators()) {
+          final String field = aggregator.getName();
+          if (Strings.isNullOrEmpty(field)) {
+            throw DruidException
+                .forPersona(DruidException.Persona.USER)
+                .ofCategory(DruidException.Category.INVALID_INPUT)
+                .build("Encountered aggregator with null or empty name at 
position[%d]", position);
+          }
+
+          fields.computeIfAbsent(field, k -> 
TreeMultiset.create()).add("projection[" + projection.getName() + "] 
aggregators list");
+          position++;
+        }
+
+        getFieldsOrThrowIfErrors(fields);

Review Comment:
   it is used by `computeAndValidateOutputFieldNames`, which shares this method 
with projection validation



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