{"record":{"id":"e391cc4211ff7354","repo":"cube-js/cube","slug":"unterminated-string-sql","errorCode":null,"errorMessage":"Unterminated string: ${sql}","messagePattern":"Unterminated string: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cubejs-schema-compiler/src/parser/SqlParser.ts","lineNumber":106,"sourceCode":"        // Check for start of single-line comment\n        commentType = '--';\n        result += sql[i];\n      } else if (sql[i] === '/' && sql[i + 1] === '*') {\n        // Check for start of multi-line comment\n        commentType = '/*';\n        result += sql[i];\n      } else if (sql[i] === '\\'' || sql[i] === '\"' || sql[i] === '`') {\n        // Check for string literals\n        openChar = sql[i];\n        result += sql[i];\n      } else {\n        // Regular character - convert to uppercase\n        result += sql[i].toUpperCase();\n      }\n    }\n\n    if (openChar) {\n      throw new Error(`Unterminated string: ${sql}`);\n    }\n\n    return result;\n  }\n\n  protected parse() {\n    const { sql } = this;\n\n    const chars = new CharStream(SqlParser.sqlUpperCase(sql));\n    chars.getText = (start, stop) => {\n      if (stop >= chars.size) {\n        stop = chars.size - 1;\n      }\n\n      if (start >= chars.size) {\n        return '';\n      } else {\n        return sql.slice(start, stop + 1);","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-schema-compiler/src/parser/SqlParser.ts#L88-L124","documentation":"Thrown by SqlParser.sqlUpperCase(), a pre-parse pass that uppercases SQL outside string literals while tracking quote state ('', \"\", ``) and comments. If the scan ends with a quote character still open, the string was never closed and the parser throws a plain Error 'Unterminated string: <sql>' with the whole SQL text.","triggerScenarios":"Constructing a SqlParser (parse() -> sqlUpperCase) with SQL containing a quote ('...\", \"... or `...) that is never closed, including quotes inside comments the tracker mishandles or escaped-quote edge cases.","commonSituations":"Dynamically built SQL passed to scaffolding/query introspection APIs with a missing closing quote, copy-pasted SQL truncated mid-literal, or SQL where a quote appears in a -- comment causing mis-tracking.","solutions":["Inspect the SQL in the error message and add the missing closing quote","Validate the SQL in your database client first; only pass executable statements to the parser","Remove quotes from comments or move them before the comment to avoid tracker confusion","Escape embedded quotes properly (double them: 'it''s') instead of unescaped apostrophes"],"exampleFix":"// before\nconst p = new SqlParser(\"SELECT * FROM t WHERE name = 'foo\");\n// after\nconst p = new SqlParser(\"SELECT * FROM t WHERE name = 'foo'\");","handlingStrategy":"try-catch","validationCode":"function hasBalancedQuotes(sql) {\n  let open = null;\n  for (let i = 0; i < sql.length; i++) {\n    if (open) { if (sql[i] === open) open = null; }\n    else if (sql[i] === \"'\" || sql[i] === '\"' || sql[i] === '`') open = sql[i];\n  }\n  return open === null;\n}\nif (!hasBalancedQuotes(sql)) throw new Error('SQL has an unterminated string literal');","typeGuard":null,"tryCatchPattern":"try {\n  new SqlParser(sql); // or extractTableFrom(sql)\n} catch (e) {\n  if (/Unterminated string/.test(e.message)) {\n    throw new Error('Check quotes in: ' + sql.slice(0, 120));\n  }\n  throw e;\n}","preventionTips":["Balance every ', \" and ` before passing SQL to the parser","Escape embedded apostrophes by doubling them ('it''s')","Avoid quote characters inside -- comments","Preview the SQL in a database client before feeding it to scaffolding/introspection"],"tags":["sql","parsing","string-literal","schema-compiler"],"backgroundTag":"unterminated-string-literal","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}