{"record":{"id":"538c281b62a88d9a","repo":"apache/cassandra","slug":"natural-log-of-number-zero-or-less","errorCode":null,"errorMessage":"Natural log of number zero or less","messagePattern":"Natural log of number zero or less","errorType":"validation","errorClass":"ArithmeticException","httpStatus":null,"severity":"error","filePath":"src/java/org/apache/cassandra/db/marshal/DecimalType.java","lineNumber":438,"sourceCode":"    }\n\n    protected BigDecimal exp(BigDecimal input)\n    {\n        int precision = input.precision();\n        precision = Math.max(MIN_SIGNIFICANT_DIGITS, precision);\n        precision = Math.min(MAX_PRECISION.getPrecision(), precision);\n        return BigDecimalMath.exp(input, new MathContext(precision, RoundingMode.HALF_EVEN));\n    }\n\n    @Override\n    public ByteBuffer log(Number input)\n    {\n        return decompose(log(toBigDecimal(input)));\n    }\n\n    protected BigDecimal log(BigDecimal input)\n    {\n        if (input.compareTo(BigDecimal.ZERO) <= 0) throw new ArithmeticException(\"Natural log of number zero or less\");\n        int precision = input.precision();\n        precision = Math.max(MIN_SIGNIFICANT_DIGITS, precision);\n        precision = Math.min(MAX_PRECISION.getPrecision(), precision);\n        return BigDecimalMath.log(input, new MathContext(precision, RoundingMode.HALF_EVEN));\n    }\n\n    @Override\n    public ByteBuffer log10(Number input)\n    {\n        return decompose(log10(toBigDecimal(input)));\n    }\n\n    protected BigDecimal log10(BigDecimal input)\n    {\n        if (input.compareTo(BigDecimal.ZERO) <= 0) throw new ArithmeticException(\"Log10 of number zero or less\");\n        int precision = input.precision();\n        precision = Math.max(MIN_SIGNIFICANT_DIGITS, precision);\n        precision = Math.min(MAX_PRECISION.getPrecision(), precision);","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/apache/cassandra/blob/88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1/src/java/org/apache/cassandra/db/marshal/DecimalType.java#L420-L456","documentation":"DecimalType.log computes the natural logarithm of a decimal operand; since ln is undefined for zero and negative numbers, it raises ArithmeticException('Natural log of number zero or less') when the input compares <= 0.","triggerScenarios":"Executing a CQL expression like ln(col) or the function-call path that reaches log(Number) with a value of 0 or a negative decimal.","commonSituations":"Queries over columns that legitimately hold zeros/negatives (deltas, balances) without filtering; bad data ingested into measured quantities expected positive.","solutions":["Filter rows in the query: WHERE col > 0 before applying ln()","Use a CASE/UDF to map non-positive values to null instead of ln(col)","Clean the data (remove/fix non-positive values) if they are invalid"],"exampleFix":"// before\nSELECT ln(delta) FROM t;\n// after\nSELECT ln(delta) FROM t WHERE delta > 0;","handlingStrategy":"validation","validationCode":"if (input == null || input.signum() <= 0) throw new IllegalArgumentException(\"ln requires a strictly positive value\");","typeGuard":"boolean isPositive(BigDecimal v) { return v != null && v.signum() > 0; }","tryCatchPattern":"try { result = DecimalType.instance.log(value); } catch (ArithmeticException e) { /* map non-positive input to null/default */ }","preventionTips":["Filter col > 0 in queries using ln()","Coerce non-positive values to null at ingestion if domain requires positivity","Add unit tests covering zero/negative inputs"],"tags":["decimal","math","logarithm"],"backgroundTag":"value-out-of-range","analyzedSha":"88fd0f6a0eaed8943f05ac9e8f947882b8ddc8f1","analyzedAt":"2026-09-10T07:29:22.284Z","contentChangedAt":"2026-09-10T07:29:22.284Z","schemaVersion":2},"datasetVersion":"2026-09-17T20:17:13.540Z"}