{"record":{"id":"f3a3af003e152b8a","repo":"prestodb/presto","slug":"name-is-too-large-stack-overflow-while-parsing","errorCode":null,"errorMessage":"${name} is too large (stack overflow while parsing)","messagePattern":"(.+?) is too large \\(stack overflow while parsing\\)","errorType":"exception","errorClass":"ParsingException","httpStatus":null,"severity":"error","filePath":"presto-parser/src/main/java/com/facebook/presto/sql/parser/SqlParser.java","lineNumber":186,"sourceCode":"            ParserRuleContext tree;\n            try {\n                // first, try parsing with potentially faster SLL mode\n                parser.getInterpreter().setPredictionMode(PredictionMode.SLL);\n                tree = parseFunction.apply(parser);\n            }\n            catch (ParseCancellationException ex) {\n                // if we fail, parse with LL mode\n                tokenStream.reset(); // rewind input stream\n                parser.reset();\n\n                parser.getInterpreter().setPredictionMode(PredictionMode.LL);\n                tree = parseFunction.apply(parser);\n            }\n\n            return new AstBuilder(parsingOptions).visit(tree);\n        }\n        catch (StackOverflowError e) {\n            throw new ParsingException(name + \" is too large (stack overflow while parsing)\");\n        }\n    }\n\n    private class PostProcessor\n            extends SqlBaseBaseListener\n    {\n        private final List<String> ruleNames;\n        private final Consumer<ParsingWarning> warningConsumer;\n\n        public PostProcessor(List<String> ruleNames, Consumer<ParsingWarning> warningConsumer)\n        {\n            this.ruleNames = ruleNames;\n            this.warningConsumer = requireNonNull(warningConsumer, \"warningConsumer is null\");\n        }\n\n        @Override\n        public void exitUnquotedIdentifier(SqlBaseParser.UnquotedIdentifierContext context)\n        {","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-parser/src/main/java/com/facebook/presto/sql/parser/SqlParser.java#L168-L204","documentation":"SqlParser catches StackOverflowError during ANTLR parsing and rethrows it as a ParsingException saying the input is too large. Deeply nested expressions exceed the parser's recursive-descent stack depth, so the library converts the JVM-level crash into a controlled error named after the statement kind.","triggerScenarios":"Parsing SQL whose expression nesting is extremely deep — hundreds of nested parentheses, huge OR/AND chains, or deeply nested subqueries — via createStatement, createExpression, or createReturn.","commonSituations":"Machine-generated SQL (ORMs, query builders, OR-chain filters from large id lists), programmatic query generators without depth limits.","solutions":["Reduce expression nesting: break giant OR/AND chains into IN lists or temp tables","Run parsing with a larger thread stack (e.g. new Thread(group, runnable, name, 8MB))","Split very large statements into smaller ones","Pre-process generated SQL to flatten redundant parentheses"],"exampleFix":"// before\nString sql = \"SELECT * FROM t WHERE a=1 OR a=2 OR ... OR a=10000\"; // stack overflow\n// after\nString sql = \"SELECT * FROM t WHERE a IN (1,2,...,10000)\";","handlingStrategy":"validation","validationCode":"// Reject excessively deep nesting before parsing\nint depth = 0, max = 0;\nfor (char c : sql.toCharArray()) {\n    if (c == '(') max = Math.max(max, ++depth);\n    else if (c == ')') depth--;\n}\nif (max > 300) throw new IllegalArgumentException(\"Query nesting too deep (\" + max + \")\");","typeGuard":"boolean nestingWithinLimit(String sql, int limit) {\n    int depth = 0;\n    for (char c : sql.toCharArray()) {\n        if (c == '(' && ++depth > limit) return false;\n        if (c == ')') depth--;\n    }\n    return true;\n}","tryCatchPattern":"try {\n    return sqlParser.createStatement(sql);\n} catch (ParsingException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"stack overflow\")) {\n        throw new QueryTooLargeException(sql.length(), e);\n    }\n    throw e;\n}","preventionTips":["Convert long OR/AND chains to IN lists","Flatten redundant nested parentheses in generated SQL","Cap generated query size/depth at the query builder level","Parse huge inputs on a thread with a larger stack size"],"tags":["sql","parser","stack-overflow","deep-nesting"],"backgroundTag":"stack-overflow-deep-recursion","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}