{"record":{"id":"464242a9096d35f0","repo":"apache/druid","slug":"cartesian-product-too-large-must-have-size-at-mos","errorCode":null,"errorMessage":"Cartesian product too large; must have size at most Integer.MAX_VALUE","messagePattern":"Cartesian product too large; must have size at most Integer\\.MAX_VALUE","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/CartesianList.java","lineNumber":68,"sourceCode":"        return Collections.emptyList();\n      }\n      axesBuilder.add(new ArrayList<>(list));\n    }\n    return new CartesianList<>(axesBuilder);\n  }\n\n  CartesianList(List<List<? extends E>> axes)\n  {\n    this.axes = axes;\n    int[] axesSizeProduct = new int[axes.size() + 1];\n    axesSizeProduct[axes.size()] = 1;\n    try {\n      for (int i = axes.size() - 1; i >= 0; i--) {\n        axesSizeProduct[i] = IntMath.checkedMultiply(axesSizeProduct[i + 1], axes.get(i).size());\n      }\n    }\n    catch (ArithmeticException e) {\n      throw new IllegalArgumentException(\n          \"Cartesian product too large; must have size at most Integer.MAX_VALUE\");\n    }\n    this.axesSizeProduct = axesSizeProduct;\n  }\n\n  private int getAxisIndexForProductIndex(int index, int axis)\n  {\n    return (index / axesSizeProduct[axis + 1]) % axes.get(axis).size();\n  }\n\n  @Override\n  public int indexOf(Object o)\n  {\n    if (!(o instanceof List)) {\n      return -1;\n    }\n    List<?> list = (List<?>) o;\n    if (list.size() != axes.size()) {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/CartesianList.java#L50-L86","documentation":"Druid's CartesianList builds a cartesian product of several lists and precomputes axis size products with IntMath.checkedMultiply. If the total product size would exceed Integer.MAX_VALUE, it throws IllegalArgumentException instead of overflowing silently.","triggerScenarios":"Calling CartesianList.create(...) with axes whose sizes multiply to more than 2^31-1, e.g. many moderately sized lists combined.","commonSituations":"Expression/array expansion code producing join-like combinations of large arrays; generated test data or cross-join-style computations over many columns; accidental use of a giant nested-array input.","solutions":["Reduce the number of elements in the input lists so the product fits under Integer.MAX_VALUE","Restructure the computation to iterate lazily/streaming instead of materializing the full cartesian product","Split the operation into batched smaller cartesian products"],"exampleFix":"// before\nCartesianList.create(List.of(largeListA, largeListB, hugeListC));\n// after\n// limit or chunk axes first\nif ((long)a.size()*b.size()*c.size() > Integer.MAX_VALUE) { /* batch */ }","handlingStrategy":"validation","validationCode":"long total = 1;\nfor (List<?> axis : axes) { total *= axis.size(); }\nif (total > Integer.MAX_VALUE) throw new IllegalArgumentException(\"cartesian product too large\");","typeGuard":null,"tryCatchPattern":"try {\n  list = CartesianList.create(axes);\n} catch (IllegalArgumentException e) {\n  if (e.getMessage() != null && e.getMessage().contains(\"Cartesian product too large\")) {\n    // batch the computation\n  } else { throw e; }\n}","preventionTips":["Estimate product size with long math before creating the list","Batch or stream large cross-product computations","Keep input axis sizes small and bounded"],"tags":["expressions","memory","integer-overflow"],"backgroundTag":"value-out-of-range","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}