{"record":{"id":"b1debd12f6b6c320","repo":"bytebase/bytebase","slug":"unsupported-oracle-table-source-t","errorCode":null,"errorMessage":"unsupported oracle table source: %T","messagePattern":"unsupported oracle table source: %T","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/plugin/parser/plsql/query_span_extractor_omni.go","lineNumber":568,"sourceCode":"\t\t\tdatabase = q.defaultDatabase\n\t\t}\n\t\ttableSource, err := q.plsqlFindTableSchema(nil, database, expr.Name.Name)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn aliasOmniTableSource(tableSource, expr.Alias), nil\n\tcase *oracleast.InlineExternalTable:\n\t\treturn extractOmniInlineExternalTable(expr), nil\n\tcase *oracleast.TableCollectionExpr:\n\t\treturn q.extractOmniTableCollection(expr)\n\tcase *oracleast.PivotClause:\n\t\treturn q.extractOmniPivot(expr)\n\tcase *oracleast.UnpivotClause:\n\t\treturn q.extractOmniUnpivot(expr)\n\tcase *oracleast.MatchRecognizeClause:\n\t\treturn q.extractOmniMatchRecognize(expr)\n\tdefault:\n\t\treturn nil, errors.Errorf(\"unsupported oracle table source: %T\", expr)\n\t}\n}\n\nfunc (q *omniQuerySpanExtractor) extractOmniPivot(pivot *oracleast.PivotClause) (base.TableSource, error) {\n\tif pivot == nil {\n\t\treturn nil, nil\n\t}\n\t// Capture the FROM scope before extracting the source: a join source\n\t// appends its operands to tableSourcesFrom, and they must not leak past\n\t// this transform — the clause replaces them with its own output.\n\toldFrom := q.tableSourcesFrom\n\tdefer func() {\n\t\tq.tableSourcesFrom = oldFrom\n\t}()\n\tsource, err := q.extractOmniTableExpr(pivot.Source)\n\tif err != nil {\n\t\treturn nil, err\n\t}","sourceCodeStart":550,"sourceCodeEnd":586,"githubUrl":"https://github.com/bytebase/bytebase/blob/1870550677fe08f0d2a78c07acd27541464eb945/backend/plugin/parser/plsql/query_span_extractor_omni.go#L550-L586","documentation":"extractOmniTableExpr dispatches on the FROM-clause element type and throws for node types it does not implement — the default case. The message includes the Go type of the unsupported table expression so the missing case is easy to identify.","triggerScenarios":"A FROM clause containing a table expression type outside the supported set (e.g. an exotic join form, JSON table, flashback clause, or newly added AST node) reaching extractOmniTableExpr via extractOmniSelect, pivot/unpivot, model, or match_recognize handling.","commonSituations":"Using advanced Oracle FROM-clause features (lateral, JSON_TABLE, SAMPLE, AS OF TIMESTAMP) not yet supported by the lineage extractor; grammar upgrades introducing new node types the extractor switch lags behind on.","solutions":["Identify the unsupported type from %T in the message and add a case for it in extractOmniTableExpr","Rewrite the SQL to use a supported FROM-clause form for lineage analysis","If the feature must be supported (e.g. JSON_TABLE), implement extraction for that node type in the omni extractor"],"exampleFix":"// before\ncase *oracleast.JsonTableClause:\n    // not handled -> default: error\n// after\ncase *oracleast.JsonTableClause:\n    return q.extractOmniJsonTable(expr)","handlingStrategy":"validation","validationCode":"if !supportedFromClauseKinds[stmtKind(sql)] { return errors.New(\"FROM clause contains unsupported expression\") }","typeGuard":null,"tryCatchPattern":"src, err := extractor.GetQuerySpan(ctx, sql)\nif err != nil && strings.Contains(err.Error(), \"unsupported oracle table source\") {\n    return nil, errUnsupportedFromClause\n}","preventionTips":["Restrict lineage analysis to supported FROM-clause constructs","Extend extractOmniTableExpr whenever the grammar adds node types","Log the %T type from the error to identify the missing case quickly"],"tags":["plsql","from-clause","unsupported-feature"],"backgroundTag":"unsupported-operation","analyzedSha":"1870550677fe08f0d2a78c07acd27541464eb945","analyzedAt":"2026-09-06T21:16:13.665Z","contentChangedAt":"2026-09-06T21:16:13.665Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}