{"record":{"id":"86f096f6bdae0e53","repo":"apache/druid","slug":"needs-an-integer-as-the-second-argument","errorCode":null,"errorMessage":"needs an integer as the second argument","messagePattern":"needs an integer as the second argument","errorType":"validation","errorClass":"ExpressionValidationException","httpStatus":400,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/math/expr/Function.java","lineNumber":3109,"sourceCode":"    @Override\n    public String name()\n    {\n      return \"repeat\";\n    }\n\n    @Nullable\n    @Override\n    public ExpressionType getOutputType(Expr.InputBindingInspector inspector, List<Expr> args)\n    {\n      return ExpressionType.STRING;\n    }\n\n    @Override\n    protected ExprEval eval(String x, long y)\n    {\n      int yInt = (int) y;\n      if (yInt != y) {\n        throw validationFailed(\"needs an integer as the second argument\");\n      }\n      return ExprEval.ofString(y < 1 ? null : StringUtils.repeat(x, yInt));\n    }\n  }\n\n  class LpadFunc implements Function\n  {\n    @Override\n    public String name()\n    {\n      return \"lpad\";\n    }\n\n    @Override\n    public ExprEval apply(List<Expr> args, Expr.ObjectBinding bindings)\n    {\n      String base = args.get(0).eval(bindings).asString();\n      int len = args.get(1).eval(bindings).asInt();","sourceCodeStart":3091,"sourceCodeEnd":3127,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/math/expr/Function.java#L3091-L3127","documentation":"The REPEAT(string, n) expression function requires its second argument to be an exact integer (no fractional value after narrowing: yInt != y). A non-integral value is rejected; additionally n < 1 yields NULL rather than repeating.","triggerScenarios":"REPEAT('x', 2.5) where the argument evaluates to a non-integral value, or any count not exactly representable as an int.","commonSituations":"DOUBLE-typed columns passed as the repeat count; counts derived from division producing fractions; user parameters with decimals.","solutions":["Cast the second argument to an integral value: CAST(col AS BIGINT)","Use FLOOR/CEIL or integer arithmetic when deriving the count from division","Range-check the count to [1, 2147483647] before calling","Treat n < 1 as NULL in your query logic (REPEAT returns NULL for those)"],"exampleFix":"// before: REPEAT(x, total/4) where total/4 = 2.5 -> throws\n// after: REPEAT(x, CAST(FLOOR(total/4) AS BIGINT))","handlingStrategy":"validation","validationCode":"if (!(count >= 1 && count <= Integer.MAX_VALUE && count == Math.floor((double) count))) {\n  throw new IllegalArgumentException(\"REPEAT count must be a positive integer: \" + count);\n}","typeGuard":"static boolean validRepeatCount(long count) {\n  return count >= 1 && count <= Integer.MAX_VALUE;\n}","tryCatchPattern":null,"preventionTips":["CAST double counts to BIGINT with FLOOR/CEIL","Avoid division-derived counts without rounding","Note REPEAT returns NULL for counts < 1 — handle explicitly"],"tags":["druid","expressions","string-functions","argument-validation"],"backgroundTag":"invalid-argument-value","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"}