From 17cb9dea6952470c66da7d1e4fe68dba2e38a1f6 Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Mon, 13 Jan 2025 20:43:21 +0000 Subject: [PATCH 1/7] First proposal for new HTML UI --- yb-voyager/cmd/assessMigrationCommand.go | 4 +- yb-voyager/cmd/common.go | 15 +- .../migration_assessment_report_new.template | 291 ++++++++++++++++++ 3 files changed, 307 insertions(+), 3 deletions(-) create mode 100644 yb-voyager/cmd/templates/migration_assessment_report_new.template diff --git a/yb-voyager/cmd/assessMigrationCommand.go b/yb-voyager/cmd/assessMigrationCommand.go index 586610676..cedb97cac 100644 --- a/yb-voyager/cmd/assessMigrationCommand.go +++ b/yb-voyager/cmd/assessMigrationCommand.go @@ -857,7 +857,7 @@ func populateMetadataCSVIntoAssessmentDB() error { return nil } -//go:embed templates/migration_assessment_report.template +//go:embed templates/migration_assessment_report_new.template var bytesTemplate []byte func generateAssessmentReport() (err error) { @@ -908,6 +908,7 @@ func generateAssessmentReport() (err error) { addNotesToAssessmentReport() postProcessingOfAssessmentReport() + assessmentReport.SortIssuesByCategory() assessmentReportDir := filepath.Join(exportDir, "assessment", "reports") err = generateAssessmentReportJson(assessmentReportDir) if err != nil { @@ -1013,7 +1014,6 @@ func getUnsupportedFeaturesFromSchemaAnalysisReport(featureName string, issueRea return UnsupportedFeature{featureName, objects, displayDDLInHTML, link, description, minVersionsFixedIn} } -// Q: do we no need of displayDDLInHTML in this approach? DDL can always be there for issues in the table if present. func convertAnalyzeSchemaIssueToAssessmentIssue(analyzeSchemaIssue utils.AnalyzeSchemaIssue, issueDescription string, minVersionsFixedIn map[string]*ybversion.YBVersion) AssessmentIssue { return AssessmentIssue{ Category: analyzeSchemaIssue.IssueType, diff --git a/yb-voyager/cmd/common.go b/yb-voyager/cmd/common.go index 4c9f34138..1fce14e43 100644 --- a/yb-voyager/cmd/common.go +++ b/yb-voyager/cmd/common.go @@ -1073,7 +1073,7 @@ type AssessmentReport struct { // Fields apart from Category, CategoryDescription, TypeName and Impact will be populated only if/when available type AssessmentIssue struct { - Category string // expected values: feature, query_constrcuts, migration_caveats, plpgsql_objects, datatytpe + Category string // expected values: feature, query_constructs, migration_caveats, plpgsql_objects, datatype CategoryDescription string Type string // Ex: GIN_INDEXES, SECURITY_INVOKER_VIEWS, STORED_GENERATED_COLUMNS Name string // Ex: "Stored generated columns are not supported." @@ -1195,6 +1195,19 @@ func (ar *AssessmentReport) AppendIssues(issues ...AssessmentIssue) { ar.Issues = append(ar.Issues, issues...) } +// Sort AssessmentIssue by Category and Impact +func (ar *AssessmentReport) SortIssuesByCategory() { + sort.Slice(ar.Issues, func(i, j int) bool { + if ar.Issues[i].Category < ar.Issues[j].Category { + return true + } else if ar.Issues[i].Category > ar.Issues[j].Category { + return false + } + // If categories are same, sort by Impact (higher first) + return ar.Issues[i].Impact > ar.Issues[j].Impact + }) +} + func (ar *AssessmentReport) GetShardedTablesRecommendation() ([]string, error) { if ar.Sizing == nil { return nil, fmt.Errorf("sizing report is null, can't fetch sharded tables") diff --git a/yb-voyager/cmd/templates/migration_assessment_report_new.template b/yb-voyager/cmd/templates/migration_assessment_report_new.template new file mode 100644 index 000000000..1176b2198 --- /dev/null +++ b/yb-voyager/cmd/templates/migration_assessment_report_new.template @@ -0,0 +1,291 @@ + + + + Migration Assessment Report + + + +
+

Migration Assessment Report

+

Voyager Version: {{ .VoyagerVersion }}

+

Database Name: {{.SchemaSummary.DBName}}

+ {{ if .SchemaSummary.SchemaNames}} +

Schema Name: + {{range $i, $a := .SchemaSummary.SchemaNames}} + {{$a}}  + {{end}} +

+ {{end}} + {{with .SchemaSummary.DBVersion}} +

Database Version: {{.}}

+ {{end}} + +

Target YB Version: {{.TargetDBVersion}}

+ + {{if eq .MigrationComplexity "NOT AVAILABLE"}} + + {{else}} +

Migration Complexity: {{ .MigrationComplexity }}

+ {{end}} + +

Database Objects

+

{{.SchemaSummary.Description}}

+ + + + + + + {{range .SchemaSummary.DBObjects}} + + + + + + {{end}} +
Object TypeTotal ObjectsObject Names
{{.ObjectType}}{{.TotalCount}} +
+ {{range split .ObjectNames ","}} + {{.}}
+ {{end}} +
+
+ + {{with .Sizing}} +

Sharding Recommendations

+ {{ if eq .FailureReasoning "" }} + {{ with .SizingRecommendation }} + + + + + + + + + +
Colocated TablesSharded Tables
+
+ {{range .ColocatedTables}} + {{.}}
+ {{end}} +
+
+
+ {{range .ShardedTables}} + {{.}}
+ {{end}} +
+
+

Sizing Recommendations

+ + + + + + + + + + + + +
ParameterRecommendation
Num of Nodes{{ .NumNodes }}
vCPU per instance{{ .VCPUsPerInstance }}
Memory per instance(GiB){{ .MemoryPerInstance }}
Optimal select connections per node{{ if eq .OptimalSelectConnectionsPerNode 0 }}--{{else}}{{.OptimalSelectConnectionsPerNode }}{{end}}
Optimal insert connections per node{{ if eq .OptimalInsertConnectionsPerNode 0 }}--{{else}}{{.OptimalInsertConnectionsPerNode}}{{end}}
Parallel Voyager Jobs{{ .ParallelVoyagerJobs }}
Estimated time taken for data import {{ .EstimatedTimeInMinForImport }} min
+

Reasoning:

+

{{ .ColocatedReasoning }}

+ {{ end }} + {{else}} +

Could not perform sizing assessment: {{ .FailureReasoning }}

+ {{ end }} + {{end}} + + {{if ne .MigrationComplexity "NOT AVAILABLE"}} +

Migration Complexity Explanation

+

{{ .MigrationComplexityExplanation }}

+ {{end}} + +

Assessment Issues

+ {{ if .Issues }} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {{ $lastCategory := "" }} + {{ range .Issues }} + {{ if ne .Category $lastCategory }} + + + + {{- $lastCategory = .Category }} + {{ end }} + + + + + + + + + + + + + + + + + {{ end }} + +
ImpactTypeNameObjectTypeObjectNameSQL StatementDocs LinkSupported In (versions)Description
+ {{.Category}} + {{ if .CategoryDescription }} +
+ {{ .CategoryDescription }} +
+ {{ end }} +
{{ .Impact }}{{ .Type }}{{ .Name }}{{ .ObjectType }}{{ .ObjectName }} + {{ if .SqlStatement }} + +
+
{{ .SqlStatement }}
+
+ {{ else }} + N/A + {{ end }} +
+ {{ if .DocsLink }} + Docs + {{ else }} + N/A + {{ end }} + + {{ $verStr := getSupportedVersionString .MinimumVersionFixedIn }} + {{ if $verStr }} + {{ $verStr }} + {{ else }} + N/A + {{ end }} + + {{ if .Description }} +
+
{{ .Description }}
+
+ {{ else }} + N/A + {{ end }} +
+ {{ else }} +

No issues were found in the assessment.

+ {{ end }} + + {{if .Notes}} +
+
+
+

Notes

+
    + {{range .Notes}} +
  • {{.}}
  • + {{end}} +
+
+ {{end}} + +
+ + From 6fc877e0cdf4f0ff50f23dba98f67a5378fe6dbd Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Tue, 14 Jan 2025 09:05:38 +0000 Subject: [PATCH 2/7] Final Design for html report: For each issue there is summary which is expandable to show more info --- yb-voyager/cmd/assessMigrationCommand.go | 3 +- yb-voyager/cmd/migration_complexity.go | 18 +- .../migration_assessment_report.template | 442 ++++++++---------- .../migration_assessment_report_new.template | 291 ------------ 4 files changed, 218 insertions(+), 536 deletions(-) delete mode 100644 yb-voyager/cmd/templates/migration_assessment_report_new.template diff --git a/yb-voyager/cmd/assessMigrationCommand.go b/yb-voyager/cmd/assessMigrationCommand.go index cedb97cac..9cf0be749 100644 --- a/yb-voyager/cmd/assessMigrationCommand.go +++ b/yb-voyager/cmd/assessMigrationCommand.go @@ -857,7 +857,7 @@ func populateMetadataCSVIntoAssessmentDB() error { return nil } -//go:embed templates/migration_assessment_report_new.template +//go:embed templates/migration_assessment_report.template var bytesTemplate []byte func generateAssessmentReport() (err error) { @@ -1655,6 +1655,7 @@ func generateAssessmentReportHtml(reportDir string) error { "groupByObjectName": groupByObjectName, "totalUniqueObjectNamesOfAllTypes": totalUniqueObjectNamesOfAllTypes, "getSupportedVersionString": getSupportedVersionString, + "snakeCaseToTitleCase": utils.SnakeCaseToTitleCase, } tmpl := template.Must(template.New("report").Funcs(funcMap).Parse(string(bytesTemplate))) diff --git a/yb-voyager/cmd/migration_complexity.go b/yb-voyager/cmd/migration_complexity.go index 69b71d1d3..ca263f7f6 100644 --- a/yb-voyager/cmd/migration_complexity.go +++ b/yb-voyager/cmd/migration_complexity.go @@ -221,9 +221,9 @@ const explainTemplateHTML = ` Category - Level-1 - Level-2 - Level-3 + Level 1 + Level 2 + Level 3 Total @@ -248,9 +248,9 @@ const explainTemplateHTML = `

Impact Levels:
- Level-1: Resolutions are available with minimal effort.
- Level-2: Resolutions are available requiring moderate effort.
- Level-3: Resolutions may not be available or are complex. + Level 1: Resolutions are available with minimal effort.
+ Level 2: Resolutions are available requiring moderate effort.
+ Level 3: Resolutions may not be available or are complex.

` @@ -301,11 +301,11 @@ func buildMigrationComplexityExplanation(sourceDBType string, assessmentReport A func buildRationale(finalComplexity string, l1Count int, l2Count int, l3Count int) string { switch finalComplexity { case constants.MIGRATION_COMPLEXITY_HIGH: - return fmt.Sprintf("Found %d Level-2 issue(s) and %d Level-3 issue(s), resulting in HIGH migration complexity", l2Count, l3Count) + return fmt.Sprintf("Found %d Level 2 issue(s) and %d Level 3 issue(s), resulting in HIGH migration complexity", l2Count, l3Count) case constants.MIGRATION_COMPLEXITY_MEDIUM: - return fmt.Sprintf("Found %d Level-1 issue(s), %d Level-2 issue(s) and %d Level-3 issue(s), resulting in MEDIUM migration complexity", l1Count, l2Count, l3Count) + return fmt.Sprintf("Found %d Level 1 issue(s), %d Level 2 issue(s) and %d Level 3 issue(s), resulting in MEDIUM migration complexity", l1Count, l2Count, l3Count) case constants.MIGRATION_COMPLEXITY_LOW: - return fmt.Sprintf("Found %d Level-1 issue(s) and %d Level-2 issue(s), resulting in LOW migration complexity", l1Count, l2Count) + return fmt.Sprintf("Found %d Level 1 issue(s) and %d Level 2 issue(s), resulting in LOW migration complexity", l1Count, l2Count) } return "" } diff --git a/yb-voyager/cmd/templates/migration_assessment_report.template b/yb-voyager/cmd/templates/migration_assessment_report.template index eeef96253..175498d73 100644 --- a/yb-voyager/cmd/templates/migration_assessment_report.template +++ b/yb-voyager/cmd/templates/migration_assessment_report.template @@ -25,12 +25,15 @@ border-collapse: collapse; width: 100%; margin-top: 20px; + table-layout: fixed; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; vertical-align: top; /* Vertically center content in table cells */ + word-wrap: break-word; + white-space: normal; } th { background-color: #f2f2f2; @@ -65,12 +68,79 @@ overflow-wrap: break-word; /* Same as word-wrap but for newer browsers */ white-space: pre-wrap; /* Preserve whitespace and allow wrapping */ word-break: break-all; /* Prevents long words from overflowing */ - margin: 0; /* Remove default margins */ - padding: 0; /* Remove default padding */ + margin: 5px; /* Remove default margins */ + padding: 5px; /* Remove default padding */ font-family: monospace; /* Optional: ensure a monospaced font */ } - + .table-highlight thead tr { + background-color: #f2f2f2; + font-weight: bold; + border-bottom: 2px solid #ccc; /* a visual separator from the body */ + } + .summary-row { + cursor: pointer; + border-bottom:2px solid #000; + } + .details-row { + background-color: #fafafa; + border-bottom:2px solid #ccc; + } + /* Container for the top summary + buttons */ + .assessment-issues-header { + display: flex; /* enable flex layout */ + justify-content: space-between; /* pushes left content to one side, buttons to the other */ + align-items: center; /* vertically center items */ + margin-bottom: 1rem; /* space before the table */ + } + .assessment-issues-header p { + margin: 0; /* remove default paragraph margins or adjust to your liking */ + margin-bottom: 4px; + } + /* Container for the buttons on the right */ + .assessment-issues-header .buttons { + display: flex; /* let buttons sit side by side */ + gap: 5px; /* small space between them */ + } + .rounded-button { + padding: 6px 12px; + border-radius: 9999px; /* pill shape */ + border: 1px solid #ccc; + background-color: #f9f9f9; + cursor: pointer; + font-size: 0.9rem; + } + .rounded-button:hover { + background-color: #eee; + } +
@@ -90,10 +160,8 @@

Target YB Version: {{.TargetDBVersion}}

- {{if eq .MigrationComplexity "NOT AVAILABLE"}} - - {{else}} -

Migration Complexity: {{ .MigrationComplexity }}

+ {{if ne .MigrationComplexity "NOT AVAILABLE"}} +

Migration Complexity: {{ .MigrationComplexity }}

{{end}}

Database Objects

@@ -172,246 +240,150 @@

{{ .MigrationComplexityExplanation }}

{{end}} -

Unsupported Data Types

-

{{.UnsupportedDataTypesDesc}}

- {{ if .UnsupportedDataTypes }} -
- - - - - - - - {{range .UnsupportedDataTypes}} - - - - - - - {{end}} -
SchemaTableColumnData Type
{{.SchemaName}}{{.TableName}}{{.ColumnName}}{{.DataType}}
+

Assessment Issues

+ {{ if .Issues }} +
+ +
+

Total Issues: {{ len .Issues }}

+

Below is a detailed breakdown of each issue.

- {{ else }} -

No unsupported data types present in the assessed schemas.

- {{ end }} - -

Unsupported Features

-

{{.UnsupportedFeaturesDesc}}

- {{ $hasUnsupportedFeatures := false }} - {{range .UnsupportedFeatures}} - {{if .Objects}} - {{ $hasUnsupportedFeatures = true }} - {{if .DisplayDDL }} -

{{.FeatureName}}

- {{ $supporterVerStr := getSupportedVersionString .MinimumVersionsFixedIn }} - {{ if $supporterVerStr }} -

Supported in Versions: {{ $supporterVerStr }}

- {{ end }} -
-
    - {{range .Objects}} -
  • {{.SqlStatement}}
  • - {{end}} -
-
- {{else}} -

{{.FeatureName}}

- {{ $supporterVerStr := getSupportedVersionString .MinimumVersionsFixedIn }} - {{ if $supporterVerStr }} -

Supported in Versions: {{ $supporterVerStr }}

- {{ end }} -
-
    - {{range .Objects}} -
  • {{.ObjectName}}
  • - {{end}} -
-
- {{end}} - {{if .DocsLink}} -

Details

- {{end}} - {{end}} - {{end}} - {{if not $hasUnsupportedFeatures}} -

No unsupported features were present among the ones assessed.

- {{end}} + +
+ + +
+
+ + + + + + + + -

Unsupported Query Constructs

- {{ if .UnsupportedQueryConstructs}} -

Source database queries not supported in YugabyteDB, identified by scanning system tables:

-
- - - - + + + + + + - {{ $currentType := "" }} - {{ $docsLink := "" }} - {{ $supporterVerStr := "" }} - {{ range $i, $construct := .UnsupportedQueryConstructs }} - {{ if ne $construct.ConstructTypeName $currentType }} - {{ if ne $currentType "" }} - - - - + + + {{ range $idx, $issue := .Issues }} + + + - - {{ end }} - {{ $docsLink = $construct.DocsLink }} - {{ $supporterVerStr = getSupportedVersionString $construct.MinimumVersionsFixedIn }} - - - - - - {{ end }} -
Construct TypeQueriesDetails
CategoryTypeNameImpact
{{ if $supporterVerStr }} - Supported in Versions: {{ $supporterVerStr }} - {{ end }} - {{ if $docsLink }} - Docs Link - {{ else }} - N/A - {{ end }} +
+ +    + {{ snakeCaseToTitleCase $issue.Category }}
{{ $construct.ConstructTypeName }} -
-
    - {{ $currentType = $construct.ConstructTypeName }} - {{ end }} -
  • {{ $construct.Query }}
  • - {{ end }} - - {{ if ne $currentType "" }} -
-
-
- {{ if $supporterVerStr }} - Supported in Versions: {{ $supporterVerStr }}
- {{ end }} - {{ if $docsLink }} - Docs Link - {{ else }} - N/A - {{ end }} -
- {{ else }} -

No unsupported query constructs found in the source database for target YugabyteDB.

- {{ end }} + {{ snakeCaseToTitleCase $issue.Type }} + {{ $issue.Name }} + {{ snakeCaseToTitleCase $issue.Impact }} + -

Unsupported PL/pgSQL objects

- {{ if .UnsupportedPlPgSqlObjects}} -

Source schema objects having unsupported statements in PL/pgSQL code block:

- - - - - - - - - {{ range .UnsupportedPlPgSqlObjects }} - - - {{ $objectsGroupByObjectType := groupByObjectType .Objects }} - {{ $numUniqueObjectNamesOfAllTypes := totalUniqueObjectNamesOfAllTypes $objectsGroupByObjectType }} - {{ $docsLink := .DocsLink }} - {{ $supportedVerStr := getSupportedVersionString .MinimumVersionsFixedIn }} - - {{ $isNextRowRequiredForObjectType := false }} - {{ range $type, $objectsByType := $objectsGroupByObjectType }} - {{ $objectGroupByObjectName := groupByObjectName $objectsByType }} - {{ $numUniqueObjectNames := numKeysInMapStringObjectInfo $objectGroupByObjectName }} - {{ if $isNextRowRequiredForObjectType }} - - {{ end }} - - {{ $isNextRowRequiredForObjectName := false }} - {{ range $name, $objectsByName := $objectGroupByObjectName }} - {{ if $isNextRowRequiredForObjectName }} - - {{ end }} - - + + {{ end }} -
Feature NameObject typeObject nameStatementDetails
{{ .FeatureName }}
{{ $type }}
{{ $name }} -
-
    - {{ range $objectsByName }} -
  • {{ .SqlStatement }}
  • + +
+ + {{ else }} -

No unsupported PL/pgSQL objects found in the source database for target YugabyteDB.

+

No issues were found in the assessment.

{{ end }} - {{ if .MigrationCaveats}} - {{ $hasMigrationCaveats := false }} -

Migration caveats

- {{range .MigrationCaveats}} - {{if .Objects}} - {{ $hasMigrationCaveats = true }} - {{if .DisplayDDL }} -

{{.FeatureName}}

- {{ $supporterVerStr := getSupportedVersionString .MinimumVersionsFixedIn }} - {{ if $supporterVerStr }} -

Supported in Versions: {{ $supporterVerStr }}

- {{ end }} -

{{.FeatureDescription}}

-
-
    - {{range .Objects}} -
  • {{.SqlStatement}}
  • - {{end}} -
-
- {{else}} -

{{.FeatureName}}

- {{ $supporterVerStr := getSupportedVersionString .MinimumVersionsFixedIn }} - {{ if $supporterVerStr }} -

Supported in Versions: {{ $supporterVerStr }}

- {{ end }} -

{{.FeatureDescription}}

-
-
    - {{range .Objects}} -
  • {{.ObjectName}}
  • - {{end}} -
-
- {{end}} - {{if .DocsLink}} -

Details

- {{end}} - {{end}} - {{end}} - {{if not $hasMigrationCaveats}} -

No migration caveats were found in the schema.

- {{end}} - {{end}} - - {{if .Notes}}

diff --git a/yb-voyager/cmd/templates/migration_assessment_report_new.template b/yb-voyager/cmd/templates/migration_assessment_report_new.template deleted file mode 100644 index 1176b2198..000000000 --- a/yb-voyager/cmd/templates/migration_assessment_report_new.template +++ /dev/null @@ -1,291 +0,0 @@ - - - - Migration Assessment Report - - - -
-

Migration Assessment Report

-

Voyager Version: {{ .VoyagerVersion }}

-

Database Name: {{.SchemaSummary.DBName}}

- {{ if .SchemaSummary.SchemaNames}} -

Schema Name: - {{range $i, $a := .SchemaSummary.SchemaNames}} - {{$a}}  - {{end}} -

- {{end}} - {{with .SchemaSummary.DBVersion}} -

Database Version: {{.}}

- {{end}} - -

Target YB Version: {{.TargetDBVersion}}

- - {{if eq .MigrationComplexity "NOT AVAILABLE"}} - - {{else}} -

Migration Complexity: {{ .MigrationComplexity }}

- {{end}} - -

Database Objects

-

{{.SchemaSummary.Description}}

- - - - - - - {{range .SchemaSummary.DBObjects}} - - - - - - {{end}} -
Object TypeTotal ObjectsObject Names
{{.ObjectType}}{{.TotalCount}} -
- {{range split .ObjectNames ","}} - {{.}}
- {{end}} -
-
- - {{with .Sizing}} -

Sharding Recommendations

- {{ if eq .FailureReasoning "" }} - {{ with .SizingRecommendation }} - - - - - - - - - -
Colocated TablesSharded Tables
-
- {{range .ColocatedTables}} - {{.}}
- {{end}} -
-
-
- {{range .ShardedTables}} - {{.}}
- {{end}} -
-
-

Sizing Recommendations

- - - - - - - - - - - - -
ParameterRecommendation
Num of Nodes{{ .NumNodes }}
vCPU per instance{{ .VCPUsPerInstance }}
Memory per instance(GiB){{ .MemoryPerInstance }}
Optimal select connections per node{{ if eq .OptimalSelectConnectionsPerNode 0 }}--{{else}}{{.OptimalSelectConnectionsPerNode }}{{end}}
Optimal insert connections per node{{ if eq .OptimalInsertConnectionsPerNode 0 }}--{{else}}{{.OptimalInsertConnectionsPerNode}}{{end}}
Parallel Voyager Jobs{{ .ParallelVoyagerJobs }}
Estimated time taken for data import {{ .EstimatedTimeInMinForImport }} min
-

Reasoning:

-

{{ .ColocatedReasoning }}

- {{ end }} - {{else}} -

Could not perform sizing assessment: {{ .FailureReasoning }}

- {{ end }} - {{end}} - - {{if ne .MigrationComplexity "NOT AVAILABLE"}} -

Migration Complexity Explanation

-

{{ .MigrationComplexityExplanation }}

- {{end}} - -

Assessment Issues

- {{ if .Issues }} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {{ $lastCategory := "" }} - {{ range .Issues }} - {{ if ne .Category $lastCategory }} - - - - {{- $lastCategory = .Category }} - {{ end }} - - - - - - - - - - - - - - - - - {{ end }} - -
ImpactTypeNameObjectTypeObjectNameSQL StatementDocs LinkSupported In (versions)Description
- {{.Category}} - {{ if .CategoryDescription }} -
- {{ .CategoryDescription }} -
- {{ end }} -
{{ .Impact }}{{ .Type }}{{ .Name }}{{ .ObjectType }}{{ .ObjectName }} - {{ if .SqlStatement }} - -
-
{{ .SqlStatement }}
-
- {{ else }} - N/A - {{ end }} -
- {{ if .DocsLink }} - Docs - {{ else }} - N/A - {{ end }} - - {{ $verStr := getSupportedVersionString .MinimumVersionFixedIn }} - {{ if $verStr }} - {{ $verStr }} - {{ else }} - N/A - {{ end }} - - {{ if .Description }} -
-
{{ .Description }}
-
- {{ else }} - N/A - {{ end }} -
- {{ else }} -

No issues were found in the assessment.

- {{ end }} - - {{if .Notes}} -
-
-
-

Notes

-
    - {{range .Notes}} -
  • {{.}}
  • - {{end}} -
-
- {{end}} - -
- - From 14ca8064c64f49b9220f28df1bd6be14a8aeb208 Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Tue, 14 Jan 2025 19:37:12 +0000 Subject: [PATCH 3/7] Misc changes: variable names, spacing, comments --- yb-voyager/cmd/analyzeSchema.go | 8 +++----- yb-voyager/cmd/assessMigrationCommand.go | 2 +- yb-voyager/cmd/common.go | 4 ++-- .../migration_assessment_report.template | 4 ++-- yb-voyager/src/query/queryissue/issues_ddl.go | 18 +++++++++--------- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/yb-voyager/cmd/analyzeSchema.go b/yb-voyager/cmd/analyzeSchema.go index 8ff11381a..e473ee12c 100644 --- a/yb-voyager/cmd/analyzeSchema.go +++ b/yb-voyager/cmd/analyzeSchema.go @@ -663,10 +663,8 @@ func convertIssueInstanceToAnalyzeIssue(issueInstance queryissue.QueryIssue, fil // 2. Keep it in issue.Details and write logic in UI layer to construct display name. */ displayObjectName := issueInstance.ObjectName - - constraintName, ok := issueInstance.Details[queryissue.CONSTRAINT_NAME] - if slices.Contains(constraintIssues, issueInstance.Type) && ok { - //In case of constraint issues we add constraint name to the object name as well + if constraintName, ok := issueInstance.Details[queryissue.CONSTRAINT_NAME]; slices.Contains(constraintIssues, issueInstance.Type) && ok { + //In case of constraint issues we add constraint name to the object name to achieve the uniqueness displayObjectName = fmt.Sprintf("%s, constraint: (%s)", issueInstance.ObjectName, constraintName) } @@ -676,8 +674,8 @@ func convertIssueInstanceToAnalyzeIssue(issueInstance queryissue.QueryIssue, fil IssueType: issueType, ObjectType: issueInstance.ObjectType, ObjectName: displayObjectName, - Reason: issueInstance.Name, Type: issueInstance.Type, + Reason: issueInstance.Name, Impact: issueInstance.Impact, SqlStatement: issueInstance.SqlStatement, DocsLink: issueInstance.DocsLink, diff --git a/yb-voyager/cmd/assessMigrationCommand.go b/yb-voyager/cmd/assessMigrationCommand.go index 9cf0be749..c602ec8c2 100644 --- a/yb-voyager/cmd/assessMigrationCommand.go +++ b/yb-voyager/cmd/assessMigrationCommand.go @@ -1019,7 +1019,7 @@ func convertAnalyzeSchemaIssueToAssessmentIssue(analyzeSchemaIssue utils.Analyze Category: analyzeSchemaIssue.IssueType, CategoryDescription: GetCategoryDescription(analyzeSchemaIssue.IssueType), Type: analyzeSchemaIssue.Type, - Name: analyzeSchemaIssue.Reason, // in convertIssueInstanceToAnalyzeIssue() we assign IssueType to Reason field + Name: analyzeSchemaIssue.Reason, // in convertIssueInstanceToAnalyzeIssue() we assign Issue.Name to AnalyzeSchemaIssue.Reason field Description: issueDescription, // TODO: verify Impact: analyzeSchemaIssue.Impact, ObjectType: analyzeSchemaIssue.ObjectType, diff --git a/yb-voyager/cmd/common.go b/yb-voyager/cmd/common.go index 1fce14e43..67d3665bf 100644 --- a/yb-voyager/cmd/common.go +++ b/yb-voyager/cmd/common.go @@ -1073,12 +1073,12 @@ type AssessmentReport struct { // Fields apart from Category, CategoryDescription, TypeName and Impact will be populated only if/when available type AssessmentIssue struct { - Category string // expected values: feature, query_constructs, migration_caveats, plpgsql_objects, datatype + Category string // expected values: unsupported_features, unsupported_query_constructs, migration_caveats, unsupported_plpgsql_objects, unsupported_datatype CategoryDescription string Type string // Ex: GIN_INDEXES, SECURITY_INVOKER_VIEWS, STORED_GENERATED_COLUMNS Name string // Ex: "Stored generated columns are not supported." Description string - Impact string // Level-1, Level-2, Level-3 (default: Level-1 ??) + Impact string // Level-1, Level-2, Level-3 (no default: need to be assigned for each issue) ObjectType string // For datatype category, ObjectType will be datatype (for eg "geometry") ObjectName string SqlStatement string diff --git a/yb-voyager/cmd/templates/migration_assessment_report.template b/yb-voyager/cmd/templates/migration_assessment_report.template index 175498d73..a79e106e2 100644 --- a/yb-voyager/cmd/templates/migration_assessment_report.template +++ b/yb-voyager/cmd/templates/migration_assessment_report.template @@ -250,8 +250,8 @@
- - + +
diff --git a/yb-voyager/src/query/queryissue/issues_ddl.go b/yb-voyager/src/query/queryissue/issues_ddl.go index 6f3da748c..30808d6cb 100644 --- a/yb-voyager/src/query/queryissue/issues_ddl.go +++ b/yb-voyager/src/query/queryissue/issues_ddl.go @@ -30,7 +30,7 @@ var generatedColumnsIssue = issue.Issue{ Name: "Stored generated columns are not supported.", Impact: constants.IMPACT_LEVEL_1, GH: "https://github.com/yugabyte/yugabyte-db/issues/10695", - Suggestion: "Using Triggers to update the generated columns is one way to work around this issue, refer docs link for more details.", + Suggestion: "Use Triggers to update the generated columns is one way to work around this issue, refer docs link for more details.", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#generated-always-as-stored-type-column-is-not-supported", } @@ -477,8 +477,8 @@ var multiRangeDatatypeIssue = issue.Issue{ Name: "Unsupported datatype", Impact: constants.IMPACT_LEVEL_1, Suggestion: "Multirange data type is not yet supported in YugabyteDB, no workaround available currently", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewMultiRangeDatatypeIssue(objectType string, objectName string, sqlStatement string, typeName string, colName string) QueryIssue { @@ -492,8 +492,8 @@ var securityInvokerViewIssue = issue.Issue{ Name: "Security Invoker Views not supported yet", Impact: constants.IMPACT_LEVEL_1, Suggestion: "Security Invoker Views are not yet supported in YugabyteDB, no workaround available currently", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewSecurityInvokerViewIssue(objectType string, objectName string, SqlStatement string) QueryIssue { @@ -505,8 +505,8 @@ var deterministicOptionCollationIssue = issue.Issue{ Name: DETERMINISTIC_OPTION_WITH_COLLATION_NAME, Impact: constants.IMPACT_LEVEL_1, Suggestion: "This feature is not supported in YugabyteDB yet", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewDeterministicOptionCollationIssue(objectType string, objectName string, SqlStatement string) QueryIssue { @@ -518,8 +518,8 @@ var foreignKeyReferencesPartitionedTableIssue = issue.Issue{ Name: FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE_NAME, Impact: constants.IMPACT_LEVEL_1, Suggestion: "No workaround available ", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewForeignKeyReferencesPartitionedTableIssue(objectType string, objectName string, SqlStatement string, constraintName string) QueryIssue { From 517ef84c645931b8880e1be82aa130026812d0a5 Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Tue, 14 Jan 2025 20:52:18 +0000 Subject: [PATCH 4/7] minor refactoring to analyze schema issue struct --- yb-voyager/cmd/analyzeSchema.go | 23 +++++++++---------- yb-voyager/src/query/queryissue/issues_ddl.go | 2 +- yb-voyager/src/utils/commonVariables.go | 8 +++---- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/yb-voyager/cmd/analyzeSchema.go b/yb-voyager/cmd/analyzeSchema.go index e473ee12c..eacf247c5 100644 --- a/yb-voyager/cmd/analyzeSchema.go +++ b/yb-voyager/cmd/analyzeSchema.go @@ -222,18 +222,17 @@ const ( // Reports one case in JSON func reportCase(filePath string, reason string, ghIssue string, suggestion string, objType string, objName string, sqlStmt string, category string, docsLink string, impact string) { - var issue utils.AnalyzeSchemaIssue - issue.FilePath = filePath - issue.Reason = reason - issue.GH = ghIssue - issue.Suggestion = suggestion - issue.ObjectType = objType - issue.ObjectName = objName - issue.SqlStatement = sqlStmt - issue.IssueType = category // IssueType field of analyze schema should be renamed to Category - issue.Impact = lo.Ternary(impact != "", impact, constants.IMPACT_LEVEL_1) - if sourceDBType == POSTGRESQL { - issue.DocsLink = docsLink + issue := utils.AnalyzeSchemaIssue{ + IssueType: category, // TODO: to be replaced with Category as a field + Reason: reason, + Impact: lo.Ternary(impact != "", impact, constants.IMPACT_LEVEL_1), + ObjectType: objType, + ObjectName: objName, + SqlStatement: sqlStmt, + FilePath: filePath, + Suggestion: suggestion, + GH: ghIssue, + DocsLink: docsLink, } schemaAnalysisReport.Issues = append(schemaAnalysisReport.Issues, issue) diff --git a/yb-voyager/src/query/queryissue/issues_ddl.go b/yb-voyager/src/query/queryissue/issues_ddl.go index 30808d6cb..24e0aa511 100644 --- a/yb-voyager/src/query/queryissue/issues_ddl.go +++ b/yb-voyager/src/query/queryissue/issues_ddl.go @@ -30,7 +30,7 @@ var generatedColumnsIssue = issue.Issue{ Name: "Stored generated columns are not supported.", Impact: constants.IMPACT_LEVEL_1, GH: "https://github.com/yugabyte/yugabyte-db/issues/10695", - Suggestion: "Use Triggers to update the generated columns is one way to work around this issue, refer docs link for more details.", + Suggestion: "Using Triggers to update the generated columns is one way to work around this issue, refer docs link for more details.", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#generated-always-as-stored-type-column-is-not-supported", } diff --git a/yb-voyager/src/utils/commonVariables.go b/yb-voyager/src/utils/commonVariables.go index 38a924486..c7612b9a0 100644 --- a/yb-voyager/src/utils/commonVariables.go +++ b/yb-voyager/src/utils/commonVariables.go @@ -100,13 +100,13 @@ type DBObject struct { // TODO: support MinimumVersionsFixedIn in xml type AnalyzeSchemaIssue struct { - // TODO: rename IssueType to Category + // TODO: deprecate this and rename to Category IssueType string `json:"IssueType"` //category: unsupported_features, unsupported_plpgsql_objects, etc - ObjectType string `json:"ObjectType"` - ObjectName string `json:"ObjectName"` - Reason string `json:"Reason"` Type string `json:"-" xml:"-"` // identifier for issue type ADVISORY_LOCKS, SYSTEM_COLUMNS, etc + Reason string `json:"Reason"` Impact string `json:"-" xml:"-"` // temporary field; since currently we generate assessment issue from analyze issue + ObjectType string `json:"ObjectType"` + ObjectName string `json:"ObjectName"` SqlStatement string `json:"SqlStatement,omitempty"` FilePath string `json:"FilePath"` Suggestion string `json:"Suggestion"` From c3603ffaa3512afc832b9e554e5d263d38095f65 Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Wed, 15 Jan 2025 05:13:52 +0000 Subject: [PATCH 5/7] Added description to each of the defined issues(ddl and dml) --- yb-voyager/src/query/queryissue/issues_ddl.go | 438 ++++++++++-------- yb-voyager/src/query/queryissue/issues_dml.go | 41 +- 2 files changed, 258 insertions(+), 221 deletions(-) diff --git a/yb-voyager/src/query/queryissue/issues_ddl.go b/yb-voyager/src/query/queryissue/issues_ddl.go index 24e0aa511..d85c18ee3 100644 --- a/yb-voyager/src/query/queryissue/issues_ddl.go +++ b/yb-voyager/src/query/queryissue/issues_ddl.go @@ -26,12 +26,13 @@ import ( ) var generatedColumnsIssue = issue.Issue{ - Type: STORED_GENERATED_COLUMNS, - Name: "Stored generated columns are not supported.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/10695", - Suggestion: "Using Triggers to update the generated columns is one way to work around this issue, refer docs link for more details.", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#generated-always-as-stored-type-column-is-not-supported", + Type: STORED_GENERATED_COLUMNS, + Name: "Stored generated columns are not supported.", + Impact: constants.IMPACT_LEVEL_1, + Description: "Stored generated columns are not supported in YugabyteDB.\nGenerated columns can be either VIRTUAL or STORED. YugabyteDB supports VIRTUAL generated columns but does not support STORED generated columns.", + GH: "https://github.com/yugabyte/yugabyte-db/issues/10695", + Suggestion: "Using Triggers to update the generated columns is one way to work around this issue, refer docs link for more details.", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#generated-always-as-stored-type-column-is-not-supported", } func NewGeneratedColumnsIssue(objectType string, objectName string, sqlStatement string, generatedColumns []string) QueryIssue { @@ -41,12 +42,13 @@ func NewGeneratedColumnsIssue(objectType string, objectName string, sqlStatement } var unloggedTableIssue = issue.Issue{ - Type: UNLOGGED_TABLE, - Name: "UNLOGGED tables are not supported yet.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/1129/", - Suggestion: "Remove UNLOGGED keyword to make it work", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unlogged-table-is-not-supported", + Type: UNLOGGED_TABLE, + Name: "UNLOGGED tables are not supported yet.", + Impact: constants.IMPACT_LEVEL_1, + Description: "UNLOGGED tables are not supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/1129/", + Suggestion: "Remove UNLOGGED keyword to make it work", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unlogged-table-is-not-supported", MinimumVersionsFixedIn: map[string]*ybversion.YBVersion{ ybversion.SERIES_2024_2: ybversion.V2024_2_0_0, }, @@ -58,11 +60,12 @@ func NewUnloggedTableIssue(objectType string, objectName string, sqlStatement st } var unsupportedIndexMethodIssue = issue.Issue{ - Type: UNSUPPORTED_INDEX_METHOD, - Name: "Schema contains %s index which is not supported.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/YugaByte/yugabyte-db/issues/1337", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#gist-brin-and-spgist-index-types-are-not-supported", + Type: UNSUPPORTED_INDEX_METHOD, + Name: "Schema contains %s index which is not supported.", + Impact: constants.IMPACT_LEVEL_1, + Description: "The schema contains an index with an access method(gist, spgist, brin) which is not supported in YugabyteDB.", + GH: "https://github.com/YugaByte/yugabyte-db/issues/1337", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#gist-brin-and-spgist-index-types-are-not-supported", } func NewUnsupportedIndexMethodIssue(objectType string, objectName string, sqlStatement string, indexAccessMethod string) QueryIssue { @@ -72,12 +75,13 @@ func NewUnsupportedIndexMethodIssue(objectType string, objectName string, sqlSta } var storageParameterIssue = issue.Issue{ - Type: STORAGE_PARAMETER, - Name: "Storage parameters are not supported yet.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/23467", - Suggestion: "Remove the storage parameters from the DDL", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#storage-parameters-on-indexes-or-constraints-in-the-source-postgresql", + Type: STORAGE_PARAMETER, + Name: "Storage parameters are not supported yet.", + Impact: constants.IMPACT_LEVEL_1, + Description: "Storage parameters in tables, indexes, and constraints are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/23467", + Suggestion: "Remove the storage parameters from the DDL", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#storage-parameters-on-indexes-or-constraints-in-the-source-postgresql", } func NewStorageParameterIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -86,12 +90,13 @@ func NewStorageParameterIssue(objectType string, objectName string, sqlStatement } var setColumnAttributeIssue = issue.Issue{ - Type: ALTER_TABLE_SET_COLUMN_ATTRIBUTE, - Name: "ALTER TABLE .. ALTER COLUMN .. SET ( attribute = value ) not supported yet", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/1124", - Suggestion: "Remove it from the exported schema", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-alter-table-ddl-variants-in-source-schema", + Type: ALTER_TABLE_SET_COLUMN_ATTRIBUTE, + Name: "ALTER TABLE .. ALTER COLUMN .. SET ( attribute = value ) not supported yet", + Impact: constants.IMPACT_LEVEL_1, + Description: "ALTER TABLE .. ALTER COLUMN .. SET ( attribute = value ) is not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/1124", + Suggestion: "Remove it from the exported schema", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-alter-table-ddl-variants-in-source-schema", } func NewSetColumnAttributeIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -100,12 +105,13 @@ func NewSetColumnAttributeIssue(objectType string, objectName string, sqlStateme } var alterTableClusterOnIssue = issue.Issue{ - Type: ALTER_TABLE_CLUSTER_ON, - Name: "ALTER TABLE CLUSTER not supported yet.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/YugaByte/yugabyte-db/issues/1124", - Suggestion: "Remove it from the exported schema.", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-alter-table-ddl-variants-in-source-schema", + Type: ALTER_TABLE_CLUSTER_ON, + Name: "ALTER TABLE CLUSTER not supported yet.", + Impact: constants.IMPACT_LEVEL_1, + Description: "ALTER TABLE CLUSTER is not yet supported in YugabyteDB", + GH: "https://github.com/YugaByte/yugabyte-db/issues/1124", + Suggestion: "Remove it from the exported schema.", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-alter-table-ddl-variants-in-source-schema", } func NewClusterONIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -114,12 +120,13 @@ func NewClusterONIssue(objectType string, objectName string, sqlStatement string } var alterTableDisableRuleIssue = issue.Issue{ - Type: ALTER_TABLE_DISABLE_RULE, - Name: "ALTER TABLE name DISABLE RULE not supported yet", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/1124", - Suggestion: "Remove this and the rule '%s' from the exported schema to be not enabled on the table.", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-alter-table-ddl-variants-in-source-schema", + Type: ALTER_TABLE_DISABLE_RULE, + Name: "ALTER TABLE name DISABLE RULE not supported yet", + Impact: constants.IMPACT_LEVEL_1, + Description: "ALTER TABLE name DISABLE RULE is not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/1124", + Suggestion: "Remove this and the rule '%s' from the exported schema to be not enabled on the table.", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-alter-table-ddl-variants-in-source-schema", } func NewAlterTableDisableRuleIssue(objectType string, objectName string, sqlStatement string, ruleName string) QueryIssue { @@ -130,12 +137,13 @@ func NewAlterTableDisableRuleIssue(objectType string, objectName string, sqlStat } var exclusionConstraintIssue = issue.Issue{ - Type: EXCLUSION_CONSTRAINTS, - Name: "Exclusion constraint is not supported yet", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/3944", - Suggestion: "Refer docs link for details on possible workaround", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#exclusion-constraints-is-not-supported", + Type: EXCLUSION_CONSTRAINTS, + Name: "Exclusion constraint is not supported yet", + Impact: constants.IMPACT_LEVEL_1, + Description: "Exclusion constraints are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/3944", + Suggestion: "Refer docs link for details on possible workaround", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#exclusion-constraints-is-not-supported", } func NewExclusionConstraintIssue(objectType string, objectName string, sqlStatement string, constraintName string) QueryIssue { @@ -146,12 +154,13 @@ func NewExclusionConstraintIssue(objectType string, objectName string, sqlStatem } var deferrableConstraintIssue = issue.Issue{ - Type: DEFERRABLE_CONSTRAINTS, - Name: "DEFERRABLE constraints not supported yet", - Impact: constants.IMPACT_LEVEL_3, - GH: "https://github.com/yugabyte/yugabyte-db/issues/1709", - Suggestion: "Remove these constraints from the exported schema and make the neccessary changes to the application to work on target seamlessly", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#deferrable-constraint-on-constraints-other-than-foreign-keys-is-not-supported", + Type: DEFERRABLE_CONSTRAINTS, + Name: "DEFERRABLE constraints not supported yet", + Impact: constants.IMPACT_LEVEL_3, + Description: "Deferrable constraints are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/1709", + Suggestion: "Remove these constraints from the exported schema and make the neccessary changes to the application to work on target seamlessly", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#deferrable-constraint-on-constraints-other-than-foreign-keys-is-not-supported", } func NewDeferrableConstraintIssue(objectType string, objectName string, sqlStatement string, constraintName string) QueryIssue { @@ -162,11 +171,12 @@ func NewDeferrableConstraintIssue(objectType string, objectName string, sqlState } var multiColumnGinIndexIssue = issue.Issue{ - Type: MULTI_COLUMN_GIN_INDEX, - Name: "Schema contains gin index on multi column which is not supported.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/10652", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#gin-indexes-on-multiple-columns-are-not-supported", + Type: MULTI_COLUMN_GIN_INDEX, + Name: "Schema contains gin index on multi column which is not supported.", + Impact: constants.IMPACT_LEVEL_1, + Description: "GIN indexes on multiple columns are not supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/10652", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#gin-indexes-on-multiple-columns-are-not-supported", } func NewMultiColumnGinIndexIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -174,11 +184,12 @@ func NewMultiColumnGinIndexIssue(objectType string, objectName string, sqlStatem } var orderedGinIndexIssue = issue.Issue{ - Type: ORDERED_GIN_INDEX, - Name: "Schema contains gin index on column with ASC/DESC/HASH Clause which is not supported.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/10653", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#issue-in-some-unsupported-cases-of-gin-indexes", + Type: ORDERED_GIN_INDEX, + Name: "Schema contains gin index on column with ASC/DESC/HASH Clause which is not supported.", + Impact: constants.IMPACT_LEVEL_1, + Description: "GIN indexes on columns with ASC/DESC/HASH clause are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/10653", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#issue-in-some-unsupported-cases-of-gin-indexes", // TODO: link is not working } func NewOrderedGinIndexIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -186,12 +197,13 @@ func NewOrderedGinIndexIssue(objectType string, objectName string, sqlStatement } var policyRoleIssue = issue.Issue{ - Type: POLICY_WITH_ROLES, - Name: "Policy require roles to be created.", - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Users/Grants are not migrated during the schema migration. Create the Users manually to make the policies work", - GH: "https://github.com/yugabyte/yb-voyager/issues/1655", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#policies-on-users-in-source-require-manual-user-creation", + Type: POLICY_WITH_ROLES, + Name: "Policy require roles to be created.", + Impact: constants.IMPACT_LEVEL_1, + Description: "Policies require roles to be created in the target database but the roles are not migrated during schema migration.", + Suggestion: "Users/Grants are not migrated during the schema migration. Create the Users manually to make the policies work", + GH: "https://github.com/yugabyte/yb-voyager/issues/1655", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#policies-on-users-in-source-require-manual-user-creation", } func NewPolicyRoleIssue(objectType string, objectName string, sqlStatement string, roles []string) QueryIssue { @@ -201,11 +213,12 @@ func NewPolicyRoleIssue(objectType string, objectName string, sqlStatement strin } var constraintTriggerIssue = issue.Issue{ - Type: CONSTRAINT_TRIGGER, - Name: "CONSTRAINT TRIGGER not supported yet.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/YugaByte/yugabyte-db/issues/1709", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#constraint-trigger-is-not-supported", + Type: CONSTRAINT_TRIGGER, + Name: "CONSTRAINT TRIGGER not supported yet.", + Impact: constants.IMPACT_LEVEL_1, + Description: "CONSTRAINT TRIGGER is not yet supported in YugabyteDB", + GH: "https://github.com/YugaByte/yugabyte-db/issues/1709", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#constraint-trigger-is-not-supported", } func NewConstraintTriggerIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -214,11 +227,12 @@ func NewConstraintTriggerIssue(objectType string, objectName string, sqlStatemen } var referencingClauseInTriggerIssue = issue.Issue{ - Type: REFERENCING_CLAUSE_IN_TRIGGER, - Name: "REFERENCING clause (transition tables) not supported yet.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/YugaByte/yugabyte-db/issues/1668", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#referencing-clause-for-triggers", + Type: REFERENCING_CLAUSE_IN_TRIGGER, + Name: "REFERENCING clause (transition tables) not supported yet.", + Impact: constants.IMPACT_LEVEL_1, + Description: "REFERENCING clause (transition tables) is not yet supported in YugabyteDB", + GH: "https://github.com/YugaByte/yugabyte-db/issues/1668", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#referencing-clause-for-triggers", } func NewReferencingClauseTrigIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -226,12 +240,13 @@ func NewReferencingClauseTrigIssue(objectType string, objectName string, sqlStat } var beforeRowTriggerOnPartitionTableIssue = issue.Issue{ - Type: BEFORE_ROW_TRIGGER_ON_PARTITIONED_TABLE, - Name: "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers.", - Impact: constants.IMPACT_LEVEL_1, - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#before-row-triggers-on-partitioned-tables", - GH: "https://github.com/yugabyte/yugabyte-db/issues/24830", - Suggestion: "Create the triggers on individual partitions.", + Type: BEFORE_ROW_TRIGGER_ON_PARTITIONED_TABLE, + Name: "Partitioned tables cannot have BEFORE / FOR EACH ROW triggers.", + Impact: constants.IMPACT_LEVEL_1, + Description: "BEFORE ROW triggers on partitioned tables are not yet supported in YugabyteDB", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#before-row-triggers-on-partitioned-tables", + GH: "https://github.com/yugabyte/yugabyte-db/issues/24830", + Suggestion: "Create the triggers on individual partitions.", } func NewBeforeRowOnPartitionTableIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -239,11 +254,12 @@ func NewBeforeRowOnPartitionTableIssue(objectType string, objectName string, sql } var alterTableAddPKOnPartitionIssue = issue.Issue{ - Type: ALTER_TABLE_ADD_PK_ON_PARTITIONED_TABLE, - Name: "Adding primary key to a partitioned table is not supported yet.", - Impact: constants.IMPACT_LEVEL_1, - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#adding-primary-key-to-a-partitioned-table-results-in-an-error", - GH: "https://github.com/yugabyte/yugabyte-db/issues/10074", + Type: ALTER_TABLE_ADD_PK_ON_PARTITIONED_TABLE, + Name: "Adding primary key to a partitioned table is not supported yet.", + Impact: constants.IMPACT_LEVEL_1, + Description: "Adding primary key using ALTER TABLE to a partitioned table is not yet supported in YugabyteDB", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#adding-primary-key-to-a-partitioned-table-results-in-an-error", + GH: "https://github.com/yugabyte/yugabyte-db/issues/10074", MinimumVersionsFixedIn: map[string]*ybversion.YBVersion{ ybversion.SERIES_2024_1: ybversion.V2024_1_0_0, ybversion.SERIES_2024_2: ybversion.V2024_2_0_0, @@ -257,12 +273,13 @@ func NewAlterTableAddPKOnPartiionIssue(objectType string, objectName string, sql } var expressionPartitionIssue = issue.Issue{ - Type: EXPRESSION_PARTITION_WITH_PK_UK, - Name: "Issue with Partition using Expression on a table which cannot contain Primary Key / Unique Key on any column", - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Remove the Constriant from the table definition", - GH: "https://github.com/yugabyte/yb-voyager/issues/698", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/mysql/#tables-partitioned-with-expressions-cannot-contain-primary-unique-keys", + Type: EXPRESSION_PARTITION_WITH_PK_UK, + Name: "Issue with Partition using Expression on a table which cannot contain Primary Key / Unique Key on any column", + Impact: constants.IMPACT_LEVEL_1, + Description: "Tables partitioned using expressions cannot contain primary or unique keys in YugabyteDB", + Suggestion: "Remove the Constriant from the table definition", + GH: "https://github.com/yugabyte/yb-voyager/issues/698", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/mysql/#tables-partitioned-with-expressions-cannot-contain-primary-unique-keys", } func NewExpressionPartitionIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -270,12 +287,13 @@ func NewExpressionPartitionIssue(objectType string, objectName string, sqlStatem } var multiColumnListPartition = issue.Issue{ - Type: MULTI_COLUMN_LIST_PARTITION, - Name: `cannot use "list" partition strategy with more than one column`, - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Make it a single column partition by list or choose other supported Partitioning methods", - GH: "https://github.com/yugabyte/yb-voyager/issues/699", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/mysql/#multi-column-partition-by-list-is-not-supported", + Type: MULTI_COLUMN_LIST_PARTITION, + Name: `cannot use "list" partition strategy with more than one column`, + Impact: constants.IMPACT_LEVEL_1, + Description: "Multi-column partition by list is not supported in YugabyteDB", + Suggestion: "Make it a single column partition by list or choose other supported Partitioning methods", + GH: "https://github.com/yugabyte/yb-voyager/issues/699", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/mysql/#multi-column-partition-by-list-is-not-supported", } func NewMultiColumnListPartition(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -283,12 +301,13 @@ func NewMultiColumnListPartition(objectType string, objectName string, sqlStatem } var insufficientColumnsInPKForPartition = issue.Issue{ - Type: INSUFFICIENT_COLUMNS_IN_PK_FOR_PARTITION, - Name: "insufficient columns in the PRIMARY KEY constraint definition in CREATE TABLE", - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Add all Partition columns to Primary Key", - GH: "https://github.com/yugabyte/yb-voyager/issues/578", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/oracle/#partition-key-column-not-part-of-primary-key-columns", + Type: INSUFFICIENT_COLUMNS_IN_PK_FOR_PARTITION, + Name: "insufficient columns in the PRIMARY KEY constraint definition in CREATE TABLE", + Impact: constants.IMPACT_LEVEL_1, + Description: "Partition key column not part of Primary Key columns", + Suggestion: "Add all Partition columns to Primary Key", + GH: "https://github.com/yugabyte/yb-voyager/issues/578", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/oracle/#partition-key-column-not-part-of-primary-key-columns", } func NewInsufficientColumnInPKForPartition(objectType string, objectName string, sqlStatement string, partitionColumnsNotInPK []string) QueryIssue { @@ -298,12 +317,13 @@ func NewInsufficientColumnInPKForPartition(objectType string, objectName string, } var xmlDatatypeIssue = issue.Issue{ - Type: XML_DATATYPE, - Name: "Unsupported datatype - xml", - Impact: constants.IMPACT_LEVEL_3, - Suggestion: "Data ingestion is not supported for this type in YugabyteDB so handle this type in different way. Refer link for more details.", - GH: "https://github.com/yugabyte/yugabyte-db/issues/1043", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#data-ingestion-on-xml-data-type-is-not-supported", + Type: XML_DATATYPE, + Name: "Unsupported datatype - xml", + Impact: constants.IMPACT_LEVEL_3, + Description: "XML datatype is not yet supported in YugabyteDB", + Suggestion: "Data ingestion is not supported for this type in YugabyteDB so handle this type in different way. Refer link for more details.", + GH: "https://github.com/yugabyte/yugabyte-db/issues/1043", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#data-ingestion-on-xml-data-type-is-not-supported", } func NewXMLDatatypeIssue(objectType string, objectName string, sqlStatement string, colName string) QueryIssue { @@ -313,12 +333,13 @@ func NewXMLDatatypeIssue(objectType string, objectName string, sqlStatement stri } var xidDatatypeIssue = issue.Issue{ - Type: XID_DATATYPE, - Name: "Unsupported datatype - xid", - Impact: constants.IMPACT_LEVEL_3, - Suggestion: "Functions for this type e.g. txid_current are not supported in YugabyteDB yet", - GH: "https://github.com/yugabyte/yugabyte-db/issues/15638", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#xid-functions-is-not-supported", + Type: XID_DATATYPE, + Name: "Unsupported datatype - xid", + Impact: constants.IMPACT_LEVEL_3, + Description: "XID datatype is not yet supported in YugabyteDB", + Suggestion: "Functions for this type e.g. txid_current are not supported in YugabyteDB yet", + GH: "https://github.com/yugabyte/yugabyte-db/issues/15638", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#xid-functions-is-not-supported", } func NewXIDDatatypeIssue(objectType string, objectName string, sqlStatement string, colName string) QueryIssue { @@ -328,11 +349,12 @@ func NewXIDDatatypeIssue(objectType string, objectName string, sqlStatement stri } var postgisDatatypeIssue = issue.Issue{ - Type: POSTGIS_DATATYPES, - Name: "Unsupported datatype", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/11323", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-yugabytedb", + Type: POSTGIS_DATATYPES, + Name: "Unsupported datatype", + Impact: constants.IMPACT_LEVEL_1, + Description: "PostGIS datatypes are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/11323", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-yugabytedb", } func NewPostGisDatatypeIssue(objectType string, objectName string, sqlStatement string, typeName string, colName string) QueryIssue { @@ -342,54 +364,61 @@ func NewPostGisDatatypeIssue(objectType string, objectName string, sqlStatement } var unsupportedDatatypesIssue = issue.Issue{ - Type: UNSUPPORTED_DATATYPES, - Name: "Unsupported datatype", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yb-voyager/issues/1731", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-yugabytedb", + Type: UNSUPPORTED_DATATYPES, + Name: "Unsupported datatype", + Impact: constants.IMPACT_LEVEL_1, + Description: "%s datatype is not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yb-voyager/issues/1731", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-yugabytedb", } func NewUnsupportedDatatypesIssue(objectType string, objectName string, sqlStatement string, typeName string, colName string) QueryIssue { issue := unsupportedDatatypesIssue issue.Name = fmt.Sprintf("%s - %s on column - %s", issue.Name, typeName, colName) + issue.Description = fmt.Sprintf(issue.Description, typeName) return newQueryIssue(issue, objectType, objectName, sqlStatement, map[string]interface{}{}) } var unsupportedDatatypesForLiveMigrationIssue = issue.Issue{ - Type: UNSUPPORTED_DATATYPES_LIVE_MIGRATION, - Name: "Unsupported datatype for Live migration", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yb-voyager/issues/1731", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-voyager-during-live-migration", + Type: UNSUPPORTED_DATATYPES_LIVE_MIGRATION, + Name: "Unsupported datatype for Live migration", + Impact: constants.IMPACT_LEVEL_1, + Description: "%s datatype is not yet supported by voyager for Live Migration", + GH: "https://github.com/yugabyte/yb-voyager/issues/1731", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-voyager-during-live-migration", } func NewUnsupportedDatatypesForLMIssue(objectType string, objectName string, sqlStatement string, typeName string, colName string) QueryIssue { issue := unsupportedDatatypesForLiveMigrationIssue issue.Name = fmt.Sprintf("%s - %s on column - %s", issue.Name, typeName, colName) + issue.Description = fmt.Sprintf(issue.Description, typeName) return newQueryIssue(issue, objectType, objectName, sqlStatement, map[string]interface{}{}) } var unsupportedDatatypesForLiveMigrationWithFFOrFBIssue = issue.Issue{ - Type: UNSUPPORTED_DATATYPES_LIVE_MIGRATION_WITH_FF_FB, - Name: "Unsupported datatype for Live migration with fall-forward/fallback", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yb-voyager/issues/1731", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-voyager-during-live-migration", + Type: UNSUPPORTED_DATATYPES_LIVE_MIGRATION_WITH_FF_FB, + Name: "Unsupported datatype for Live migration with fall-forward/fallback", + Impact: constants.IMPACT_LEVEL_1, + Description: "%s datatype is not yet supported by voyager for Live Migration with fall-forward/fallback", + GH: "https://github.com/yugabyte/yb-voyager/issues/1731", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#unsupported-datatypes-by-voyager-during-live-migration", } func NewUnsupportedDatatypesForLMWithFFOrFBIssue(objectType string, objectName string, sqlStatement string, typeName string, colName string) QueryIssue { issue := unsupportedDatatypesForLiveMigrationWithFFOrFBIssue issue.Name = fmt.Sprintf("%s - %s on column - %s", issue.Name, typeName, colName) + issue.Description = fmt.Sprintf(issue.Description, typeName) return newQueryIssue(issue, objectType, objectName, sqlStatement, map[string]interface{}{}) } var primaryOrUniqueOnUnsupportedIndexTypesIssue = issue.Issue{ - Type: PK_UK_ON_COMPLEX_DATATYPE, - Name: "Primary key and Unique constraint on column '%s' not yet supported", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/25003", - Suggestion: "Refer to the docs link for the workaround", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#indexes-on-some-complex-data-types-are-not-supported", //Keeping it similar for now, will see if we need to a separate issue on docs, + Type: PK_UK_ON_COMPLEX_DATATYPE, + Name: "Primary key and Unique constraint on column '%s' not yet supported", + Impact: constants.IMPACT_LEVEL_1, + Description: "Primary key and Unique constraints on columns with complex data types are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25003", + Suggestion: "Refer to the docs link for the workaround", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#indexes-on-some-complex-data-types-are-not-supported", //Keeping it similar for now, will see if we need to a separate issue on docs, } func NewPrimaryOrUniqueConsOnUnsupportedIndexTypesIssue(objectType string, objectName string, sqlStatement string, typeName string, constraintName string) QueryIssue { @@ -402,12 +431,13 @@ func NewPrimaryOrUniqueConsOnUnsupportedIndexTypesIssue(objectType string, objec } var indexOnComplexDatatypesIssue = issue.Issue{ - Type: INDEX_ON_COMPLEX_DATATYPE, - Name: "INDEX on column '%s' not yet supported", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yugabyte-db/issues/25003", - Suggestion: "Refer to the docs link for the workaround", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#indexes-on-some-complex-data-types-are-not-supported", + Type: INDEX_ON_COMPLEX_DATATYPE, + Name: "INDEX on column '%s' not yet supported", + Impact: constants.IMPACT_LEVEL_1, + Description: "Indexes on columns with complex data types are not yet supported in YugabyteDB", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25003", + Suggestion: "Refer to the docs link for the workaround", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#indexes-on-some-complex-data-types-are-not-supported", } func NewIndexOnComplexDatatypesIssue(objectType string, objectName string, sqlStatement string, typeName string) QueryIssue { @@ -417,12 +447,13 @@ func NewIndexOnComplexDatatypesIssue(objectType string, objectName string, sqlSt } var foreignTableIssue = issue.Issue{ - Type: FOREIGN_TABLE, - Name: "Foreign tables require manual intervention.", - Impact: constants.IMPACT_LEVEL_1, - GH: "https://github.com/yugabyte/yb-voyager/issues/1627", - Suggestion: "SERVER '%s', and USER MAPPING should be created manually on the target to create and use the foreign table", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#foreign-table-in-the-source-database-requires-server-and-user-mapping", + Type: FOREIGN_TABLE, + Name: "Foreign tables require manual intervention.", + Impact: constants.IMPACT_LEVEL_1, + Description: "Foreign table creation fails as SERVER and USER MAPPING objects are not exported by Voyager", + GH: "https://github.com/yugabyte/yb-voyager/issues/1627", + Suggestion: "SERVER '%s', and USER MAPPING should be created manually on the target to create and use the foreign table", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#foreign-table-in-the-source-database-requires-server-and-user-mapping", } func NewForeignTableIssue(objectType string, objectName string, sqlStatement string, serverName string) QueryIssue { @@ -432,11 +463,12 @@ func NewForeignTableIssue(objectType string, objectName string, sqlStatement str } var inheritanceIssue = issue.Issue{ - Type: INHERITANCE, - Name: "TABLE INHERITANCE not supported in YugabyteDB", - Impact: constants.IMPACT_LEVEL_3, - GH: "https://github.com/YugaByte/yugabyte-db/issues/1129", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#table-inheritance-is-not-supported", + Type: INHERITANCE, + Name: "TABLE INHERITANCE not supported in YugabyteDB", + Impact: constants.IMPACT_LEVEL_3, + Description: "Table inheritance is not yet supported in YugabyteDB", + GH: "https://github.com/YugaByte/yugabyte-db/issues/1129", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#table-inheritance-is-not-supported", } func NewInheritanceIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -447,7 +479,7 @@ var percentTypeSyntax = issue.Issue{ Type: REFERENCED_TYPE_DECLARATION, Name: "Referenced type declaration of variables", Impact: constants.IMPACT_LEVEL_1, - Description: "", + Description: "Referencing the type of a column instead of the actual type name is not supported in YugabyteDB", Suggestion: "Fix the syntax to include the actual type name instead of referencing the type of a column", GH: "https://github.com/yugabyte/yugabyte-db/issues/23619", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#type-syntax-is-not-supported", @@ -458,12 +490,13 @@ func NewPercentTypeSyntaxIssue(objectType string, objectName string, sqlStatemen } var loDatatypeIssue = issue.Issue{ - Type: LARGE_OBJECT_DATATYPE, - Name: "Unsupported datatype - lo", - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Large objects are not yet supported in YugabyteDB, no workaround available currently", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25318", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#large-objects-and-its-functions-are-currently-not-supported", // TODO + Type: LARGE_OBJECT_DATATYPE, + Name: "Unsupported datatype - lo", + Impact: constants.IMPACT_LEVEL_1, + Description: "Large objects are not yet supported in YugabyteDB", + Suggestion: "Large objects are not yet supported in YugabyteDB, no workaround available currently", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25318", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#large-objects-and-its-functions-are-currently-not-supported", // TODO } func NewLODatatypeIssue(objectType string, objectName string, SqlStatement string, colName string) QueryIssue { @@ -473,12 +506,13 @@ func NewLODatatypeIssue(objectType string, objectName string, SqlStatement strin } var multiRangeDatatypeIssue = issue.Issue{ - Type: MULTI_RANGE_DATATYPE, - Name: "Unsupported datatype", - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Multirange data type is not yet supported in YugabyteDB, no workaround available currently", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + Type: MULTI_RANGE_DATATYPE, + Name: "Unsupported datatype", + Impact: constants.IMPACT_LEVEL_1, + Description: "Multirange data type is not yet supported in YugabyteDB", + Suggestion: "Multirange data type is not yet supported in YugabyteDB, no workaround available currently", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewMultiRangeDatatypeIssue(objectType string, objectName string, sqlStatement string, typeName string, colName string) QueryIssue { @@ -488,12 +522,13 @@ func NewMultiRangeDatatypeIssue(objectType string, objectName string, sqlStateme } var securityInvokerViewIssue = issue.Issue{ - Type: SECURITY_INVOKER_VIEWS, - Name: "Security Invoker Views not supported yet", - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "Security Invoker Views are not yet supported in YugabyteDB, no workaround available currently", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + Type: SECURITY_INVOKER_VIEWS, + Name: "Security Invoker Views not supported yet", + Impact: constants.IMPACT_LEVEL_1, + Description: "Security Invoker Views are not yet supported in YugabyteDB", + Suggestion: "Security Invoker Views are not yet supported in YugabyteDB, no workaround available currently", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewSecurityInvokerViewIssue(objectType string, objectName string, SqlStatement string) QueryIssue { @@ -501,12 +536,13 @@ func NewSecurityInvokerViewIssue(objectType string, objectName string, SqlStatem } var deterministicOptionCollationIssue = issue.Issue{ - Type: DETERMINISTIC_OPTION_WITH_COLLATION, - Name: DETERMINISTIC_OPTION_WITH_COLLATION_NAME, - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "This feature is not supported in YugabyteDB yet", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + Type: DETERMINISTIC_OPTION_WITH_COLLATION, + Name: DETERMINISTIC_OPTION_WITH_COLLATION_NAME, + Impact: constants.IMPACT_LEVEL_1, + Description: "Deterministic option with collation is not supported in YugabyteDB", + Suggestion: "This feature is not supported in YugabyteDB yet", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewDeterministicOptionCollationIssue(objectType string, objectName string, SqlStatement string) QueryIssue { @@ -514,12 +550,13 @@ func NewDeterministicOptionCollationIssue(objectType string, objectName string, } var foreignKeyReferencesPartitionedTableIssue = issue.Issue{ - Type: FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE, - Name: FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE_NAME, - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "No workaround available ", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + Type: FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE, + Name: FOREIGN_KEY_REFERENCES_PARTITIONED_TABLE_NAME, + Impact: constants.IMPACT_LEVEL_1, + Description: "Foreign key references to partitioned tables are not yet supported in YugabyteDB", + Suggestion: "No workaround available ", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewForeignKeyReferencesPartitionedTableIssue(objectType string, objectName string, SqlStatement string, constraintName string) QueryIssue { @@ -530,12 +567,13 @@ func NewForeignKeyReferencesPartitionedTableIssue(objectType string, objectName } var uniqueNullsNotDistinctIssue = issue.Issue{ - Type: UNIQUE_NULLS_NOT_DISTINCT, - Name: UNIQUE_NULLS_NOT_DISTINCT_NAME, - Impact: constants.IMPACT_LEVEL_1, - Suggestion: "", - GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + Type: UNIQUE_NULLS_NOT_DISTINCT, + Name: UNIQUE_NULLS_NOT_DISTINCT_NAME, + Impact: constants.IMPACT_LEVEL_1, + Description: "Unique constraint on columns with NULL values is not yet supported in YugabyteDB", + Suggestion: "", + GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewUniqueNullsNotDistinctIssue(objectType string, objectName string, sqlStatement string) QueryIssue { diff --git a/yb-voyager/src/query/queryissue/issues_dml.go b/yb-voyager/src/query/queryissue/issues_dml.go index 8bc2c356c..eca78e7df 100644 --- a/yb-voyager/src/query/queryissue/issues_dml.go +++ b/yb-voyager/src/query/queryissue/issues_dml.go @@ -27,7 +27,7 @@ var advisoryLocksIssue = issue.Issue{ Type: ADVISORY_LOCKS, Name: "Advisory Locks", Impact: constants.IMPACT_LEVEL_2, - Description: "", + Description: "Advisory locks are not yet implemented in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/3642", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#advisory-locks-is-not-yet-implemented", @@ -41,7 +41,7 @@ var systemColumnsIssue = issue.Issue{ Type: SYSTEM_COLUMNS, Name: "System Columns", Impact: constants.IMPACT_LEVEL_2, - Description: "", + Description: "System columns are not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/24843", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#system-columns-is-not-yet-supported", @@ -55,7 +55,7 @@ var xmlFunctionsIssue = issue.Issue{ Type: XML_FUNCTIONS, Name: "XML Functions", Impact: constants.IMPACT_LEVEL_2, - Description: "", + Description: "XML functions are not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/1043", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#xml-functions-is-not-yet-supported", @@ -69,7 +69,7 @@ var regexFunctionsIssue = issue.Issue{ Type: REGEX_FUNCTIONS, Name: "Regex Functions", Impact: constants.IMPACT_LEVEL_2, - Description: "", + Description: "Regex functions are not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", @@ -83,10 +83,10 @@ var aggregateFunctionIssue = issue.Issue{ Type: AGGREGATE_FUNCTION, Name: AGGREGATION_FUNCTIONS_NAME, Impact: constants.IMPACT_LEVEL_2, - Description: "any_value, range_agg and range_intersect_agg functions not supported yet in YugabyteDB", + Description: "any_value, range_agg and range_intersect_agg functions are not supported yet in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewAggregationFunctionIssue(objectType string, objectName string, sqlStatement string, funcNames []string) QueryIssue { @@ -101,7 +101,7 @@ var jsonConstructorFunctionsIssue = issue.Issue{ Type: JSON_CONSTRUCTOR_FUNCTION, Name: JSON_CONSTRUCTOR_FUNCTION_NAME, Impact: constants.IMPACT_LEVEL_2, - Description: "Postgresql 17 features not supported yet in YugabyteDB", + Description: "JSON constructor functions from PostgreSQL 17 are not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", @@ -119,10 +119,10 @@ var jsonQueryFunctionIssue = issue.Issue{ Type: JSON_QUERY_FUNCTION, Name: JSON_QUERY_FUNCTIONS_NAME, Impact: constants.IMPACT_LEVEL_2, - Description: "Postgresql 17 features not supported yet in YugabyteDB", + Description: "JSON query functions from PostgreSQL 17 are not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewJsonQueryFunctionIssue(objectType string, objectName string, sqlStatement string, funcNames []string) QueryIssue { @@ -138,9 +138,8 @@ var loFunctionsIssue = issue.Issue{ Name: LARGE_OBJECT_FUNCTIONS_NAME, Impact: constants.IMPACT_LEVEL_2, Description: "Large Objects functions are not supported in YugabyteDB", - Suggestion: "Large objects functions are not yet supported in YugabyteDB, no workaround available right now", GH: "https://github.com/yugabyte/yugabyte-db/issues/25318", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#large-objects-and-its-functions-are-currently-not-supported", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#large-objects-and-its-functions-are-currently-not-supported", } func NewLOFuntionsIssue(objectType string, objectName string, sqlStatement string, funcNames []string) QueryIssue { @@ -155,10 +154,10 @@ var jsonbSubscriptingIssue = issue.Issue{ Type: JSONB_SUBSCRIPTING, Name: JSONB_SUBSCRIPTING_NAME, Impact: constants.IMPACT_LEVEL_2, - Description: "Jsonb subscripting is not supported in YugabyteDB yet", + Description: "Jsonb subscripting is not yet supported in YugabyteDB", Suggestion: "Use Arrow operators (-> / ->>) to access the jsonb fields.", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#jsonb-subscripting", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#jsonb-subscripting", } func NewJsonbSubscriptingIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -169,10 +168,10 @@ var jsonPredicateIssue = issue.Issue{ Type: JSON_TYPE_PREDICATE, Name: JSON_TYPE_PREDICATE_NAME, Impact: constants.IMPACT_LEVEL_2, - Description: "IS JSON predicate expressions not supported yet in YugabyteDB", + Description: "IS JSON predicate expressions are not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewJsonPredicateIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -183,7 +182,7 @@ var copyFromWhereIssue = issue.Issue{ Type: COPY_FROM_WHERE, Name: "COPY FROM ... WHERE", Impact: constants.IMPACT_LEVEL_2, - Description: "", + Description: "COPY FROM ... WHERE is not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", @@ -197,7 +196,7 @@ var copyOnErrorIssue = issue.Issue{ Type: COPY_ON_ERROR, Name: "COPY ... ON_ERROR", Impact: constants.IMPACT_LEVEL_2, - Description: "", + Description: "COPY ... ON_ERROR is not yet supported in YugabyteDB", Suggestion: "", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", @@ -211,10 +210,10 @@ var fetchWithTiesIssue = issue.Issue{ Type: FETCH_WITH_TIES, Name: "FETCH .. WITH TIES", Impact: constants.IMPACT_LEVEL_2, - Description: "FETCH .. WITH TIES is not supported in YugabyteDB", + Description: "FETCH .. WITH TIES is not yet supported in YugabyteDB", Suggestion: "No workaround available right now", GH: "https://github.com/yugabyte/yugabyte-db/issues/25575", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#postgresql-12-and-later-features", } func NewFetchWithTiesIssue(objectType string, objectName string, sqlStatement string) QueryIssue { @@ -225,10 +224,10 @@ var mergeStatementIssue = issue.Issue{ Type: MERGE_STATEMENT, Name: "Merge Statement", Impact: constants.IMPACT_LEVEL_2, - Description: "This statement is not supported in YugabyteDB yet", + Description: "MERGE statement is not yet supported in YugabyteDB", Suggestion: "Use PL/pgSQL to write the logic to get this functionality", GH: "https://github.com/yugabyte/yugabyte-db/issues/25574", - DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#merge-command", + DocsLink: "https://docs.yugabyte.com/preview/yugabyte-voyager/known-issues/postgresql/#merge-command", } func NewMergeStatementIssue(objectType string, objectName string, sqlStatement string) QueryIssue { From 72f301fcfa4df0cae13b46ba1391f5d8703972f6 Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Wed, 15 Jan 2025 05:40:31 +0000 Subject: [PATCH 6/7] reverting reordering of fields in analyze schema issue - due to test validation phase limitation that it needs the same order right now --- yb-voyager/src/utils/commonVariables.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yb-voyager/src/utils/commonVariables.go b/yb-voyager/src/utils/commonVariables.go index c7612b9a0..6ea9815f5 100644 --- a/yb-voyager/src/utils/commonVariables.go +++ b/yb-voyager/src/utils/commonVariables.go @@ -102,11 +102,11 @@ type DBObject struct { type AnalyzeSchemaIssue struct { // TODO: deprecate this and rename to Category IssueType string `json:"IssueType"` //category: unsupported_features, unsupported_plpgsql_objects, etc - Type string `json:"-" xml:"-"` // identifier for issue type ADVISORY_LOCKS, SYSTEM_COLUMNS, etc - Reason string `json:"Reason"` - Impact string `json:"-" xml:"-"` // temporary field; since currently we generate assessment issue from analyze issue ObjectType string `json:"ObjectType"` ObjectName string `json:"ObjectName"` + Reason string `json:"Reason"` + Type string `json:"-" xml:"-"` // identifier for issue type ADVISORY_LOCKS, SYSTEM_COLUMNS, etc + Impact string `json:"-" xml:"-"` // temporary field; since currently we generate assessment issue from analyze issue SqlStatement string `json:"SqlStatement,omitempty"` FilePath string `json:"FilePath"` Suggestion string `json:"Suggestion"` From 72e0a2fc2f33d538916105680e2d28131676469a Mon Sep 17 00:00:00 2001 From: Sanyam Singhal Date: Wed, 15 Jan 2025 08:39:07 +0000 Subject: [PATCH 7/7] Added Object/Preview Sql Field in the html table and also allow sorting based on the table headers --- yb-voyager/cmd/assessMigrationCommand.go | 2 +- yb-voyager/cmd/common.go | 13 - .../migration_assessment_report.template | 259 +++++++++++------- 3 files changed, 158 insertions(+), 116 deletions(-) diff --git a/yb-voyager/cmd/assessMigrationCommand.go b/yb-voyager/cmd/assessMigrationCommand.go index c602ec8c2..e508040be 100644 --- a/yb-voyager/cmd/assessMigrationCommand.go +++ b/yb-voyager/cmd/assessMigrationCommand.go @@ -908,7 +908,6 @@ func generateAssessmentReport() (err error) { addNotesToAssessmentReport() postProcessingOfAssessmentReport() - assessmentReport.SortIssuesByCategory() assessmentReportDir := filepath.Join(exportDir, "assessment", "reports") err = generateAssessmentReportJson(assessmentReportDir) if err != nil { @@ -1656,6 +1655,7 @@ func generateAssessmentReportHtml(reportDir string) error { "totalUniqueObjectNamesOfAllTypes": totalUniqueObjectNamesOfAllTypes, "getSupportedVersionString": getSupportedVersionString, "snakeCaseToTitleCase": utils.SnakeCaseToTitleCase, + "getSqlPreview": utils.GetSqlStmtToPrint, } tmpl := template.Must(template.New("report").Funcs(funcMap).Parse(string(bytesTemplate))) diff --git a/yb-voyager/cmd/common.go b/yb-voyager/cmd/common.go index 67d3665bf..ff2f6ffd1 100644 --- a/yb-voyager/cmd/common.go +++ b/yb-voyager/cmd/common.go @@ -1195,19 +1195,6 @@ func (ar *AssessmentReport) AppendIssues(issues ...AssessmentIssue) { ar.Issues = append(ar.Issues, issues...) } -// Sort AssessmentIssue by Category and Impact -func (ar *AssessmentReport) SortIssuesByCategory() { - sort.Slice(ar.Issues, func(i, j int) bool { - if ar.Issues[i].Category < ar.Issues[j].Category { - return true - } else if ar.Issues[i].Category > ar.Issues[j].Category { - return false - } - // If categories are same, sort by Impact (higher first) - return ar.Issues[i].Impact > ar.Issues[j].Impact - }) -} - func (ar *AssessmentReport) GetShardedTablesRecommendation() ([]string, error) { if ar.Sizing == nil { return nil, fmt.Errorf("sizing report is null, can't fetch sharded tables") diff --git a/yb-voyager/cmd/templates/migration_assessment_report.template b/yb-voyager/cmd/templates/migration_assessment_report.template index a79e106e2..9f4f4a97a 100644 --- a/yb-voyager/cmd/templates/migration_assessment_report.template +++ b/yb-voyager/cmd/templates/migration_assessment_report.template @@ -140,6 +140,43 @@ document.getElementById('arrow-' + i).innerHTML = '▶'; } } + + // Keep track of the current sort direction per field, so we can toggle it + let sortState = { + category: 'asc', + type: 'asc', + impact: 'asc' + }; + function sortTableBy(field) { + // Grab the table element + const table = document.querySelector(".table-highlight"); + + // Collect all the .issue-pair elements + const issuePairs = Array.from(table.querySelectorAll("tbody.issue-summary-detail-pair")); + + // Determine the current sort direction and flip it + let currentDirection = sortState[field] || 'asc'; + let newDirection = (currentDirection === 'asc') ? 'desc' : 'asc'; + sortState[field] = newDirection; + + issuePairs.sort((a, b) => { + let aValue = a.dataset[field] || ""; + let bValue = b.dataset[field] || ""; + + if (aValue < bValue) return newDirection === 'asc' ? -1 : 1; + if (aValue > bValue) return newDirection === 'asc' ? 1 : -1; + return 0; + }); + + // Re-append the sorted elements to the table + issuePairs.forEach(pair => table.appendChild(pair)); + + // Update the sort indicator in the table header + const sortIndicator = table.querySelector(`th[onclick="sortTableBy('${field}')"] .sort-indicator`); + if (sortIndicator) { + sortIndicator.innerHTML = newDirection === 'asc' ? '↑' : '↓'; // ↑ is up arrow, ↓ is down arrow + } + } @@ -255,128 +292,146 @@
- + - - + + - - - - + + + + {{ range $idx, $issue := .Issues }} - - - - - - - - - - - + + {{ end }}
CategoryTypeNameImpact + Category + + Type + Object/SQL Preview + Impact +
- -    - {{ snakeCaseToTitleCase $issue.Category }} - {{ snakeCaseToTitleCase $issue.Type }}{{ $issue.Name }}{{ snakeCaseToTitleCase $issue.Impact }}