{"record":{"id":"9e22ed402d3fedc1","repo":"pathwaycom/pathway","slug":"pivots-not-supported","errorCode":null,"errorMessage":"PIVOTS not supported","messagePattern":"PIVOTS not supported","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/sql/processing.py","lineNumber":313,"sourceCode":"    tabs = []\n    for expression in node.expressions:\n        tab, context = _run(expression, context)\n        tabs.append(tab)\n    ret = tabs[0]\n    for tab in tabs[1:]:\n        ret = ret.join(tab)\n    return ret, context\n\n\n@register(nodetype=sql_expr.Subquery)\ndef _subquery(\n    node: sql_expr.Subquery, context: ContextType\n) -> tuple[table.Table, ContextType]:\n    context = _with_block(node, context)\n    tab, _ = _run(node.args.pop(\"this\"), context)\n    tab, context = _alias_block(node, tab, context)\n    if node.args.pop(\"pivots\", []) != []:\n        raise NotImplementedError(\"PIVOTS not supported\")\n    _check_work_done(node)\n    return tab, context\n\n\n@register(nodetype=sql_expr.Table)\ndef _table(\n    node: sql_expr.Table, context: ContextType\n) -> tuple[table.Joinable, ContextType]:\n    name = _identifier(node.args.pop(\"this\"), context)\n    tab = context[name]\n    tab, context = _alias_block(node, tab, context)\n    joined_tab, context = _joins_block(node, tab, context)\n\n    if node.args.pop(\"pivots\", []) != []:\n        raise NotImplementedError(\"PIVOTS not supported\")\n    _check_work_done(node)\n    return joined_tab, context\n","sourceCodeStart":295,"sourceCodeEnd":331,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/sql/processing.py#L295-L331","documentation":"After translating a subquery node (sql_expr.Subquery) in pw.sql, Pathway checks for leftover PIVOT/UNPIVOT clauses in node.args. A non-empty 'pivots' list raises NotImplementedError('PIVOTS not supported'): Pathway's SQL layer simply has no implementation of PIVOT attached to a subquery.","triggerScenarios":"Calling pw.sql() with a query whose FROM clause contains (subquery) PIVOT(...) or (subquery) UNPIVOT(...); dialect-specific pivot syntax that sqlglot normalizes into the subquery's pivots arg.","commonSituations":"Porting analytics/warehouse SQL that uses PIVOT for reshaping; queries written for SQL Server/BigQuery/Snowflake style PIVOT.","solutions":["Rewrite PIVOT/UNPIVOT using explicit conditional aggregation (FILTER / CASE WHEN with the pathway-reducible form) inside the SELECT","Or perform the reshape with Pathway's native API (table.with_columns, groupby/reduce) after reading the base table via pw.sql","Remove the pivot and pivot manually in a downstream table operation"],"exampleFix":"-- before\nSELECT * FROM (SELECT k, v FROM t) PIVOT (MAX(v) FOR k IN ('a','b'));\n\n-- after\nSELECT\n  MAX(CASE WHEN k = 'a' THEN v END) AS a,\n  MAX(CASE WHEN k = 'b' THEN v END) AS b\nFROM t;","handlingStrategy":"fallback","validationCode":"def has_pivot(query: str) -> bool:\n    q = query.upper()\n    return \"PIVOT\" in q or \"UNPIVOT\" in q","typeGuard":null,"tryCatchPattern":"try:\n    tab = pw.sql(query)\nexcept NotImplementedError as e:\n    if \"PIVOT\" in str(e):\n        tab = pw.sql(to_conditional_aggregation(query))\n    else:\n        raise","preventionTips":["Replace PIVOT/UNPIVOT with conditional aggregation before passing SQL to Pathway","Add a lint check rejecting PIVOT in query templates"],"tags":["sql","pivot","pathway","not-implemented"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}