Repository: cloudspannerecosystem/harbourbridge
Pull request #387 (2022-10-14 10:28:56)

Milestone5 column-edit UI changes

> UI changes for column edit review and update.

- [ ] UI changes for reviewing column edit.
- [ ] UI changes for updating column edit.


Patch:
diff --git a/internal/convert.go b/internal/convert.go
index ea7f388..124b098 100644
--- a/internal/convert.go
+++ b/internal/convert.go
@@ -93,6 +93,7 @@ const (
 	InterleavedOrder
 	InterleavedAddColumn
 	IllegalName
+	InterleavedRenameColumn
 )
 
 // NameAndCols contains the name of a table and its columns.
diff --git a/internal/report.go b/internal/report.go
index 12e1340..5767008 100644
--- a/internal/report.go
+++ b/internal/report.go
@@ -404,6 +404,13 @@ func buildTableReportBody(conv *Conv, srcTable string, issues map[string][]Schem
 				case InterleavedAddColumn:
 					str := fmt.Sprintf(" %s add %s as a primary key in table %s", IssueDB[i].Brief, srcCol, spSchema.Name)
 
+					if !contains(l, str) {
+						l = append(l, str)
+					}
+				case InterleavedRenameColumn:
+					fkName, referCol := getFkAndReferColumn(spSchema, srcCol)
+					str := fmt.Sprintf(" %s rename %s primary key in table %s to match the foreign key %s refer column %s", IssueDB[i].Brief, srcCol, spSchema.Name, fkName, referCol)
+
 					if !contains(l, str) {
 						l = append(l, str)
 					}
@@ -449,6 +456,17 @@ func buildTableReportBody(conv *Conv, srcTable string, issues map[string][]Schem
 	return body
 }
 
+func getFkAndReferColumn(spSchema ddl.CreateTable, col string) (fkName string, referCol string) {
+	for _, fk := range spSchema.Fks {
+		for k, v := range fk.Columns {
+			if col == v {
+				return fk.Name, fk.ReferColumns[k]
+			}
+		}
+	}
+	return fkName, referCol
+}
+
 func fillRowStats(conv *Conv, srcTable string, badWrites map[string]int64, tr *tableReport) {
 	rows := conv.Stats.Rows[srcTable]
 	goodConvRows := conv.Stats.GoodRows[srcTable]
@@ -479,30 +497,31 @@ var IssueDB = map[SchemaIssue]struct {
 	severity severity
 	batch    bool // Whether multiple instances of this issue are combined.
 }{
-	DefaultValue:          {Brief: "Some columns have default values which Spanner does not support", severity: warning, batch: true},
-	ForeignKey:            {Brief: "Spanner does not support foreign keys", severity: warning},
-	MultiDimensionalArray: {Brief: "Spanner doesn't support multi-dimensional arrays", severity: warning},
-	NoGoodType:            {Brief: "No appropriate Spanner type", severity: warning},
-	Numeric:               {Brief: "Spanner does not support numeric. This type mapping could lose precision and is not recommended for production use", severity: warning},
-	NumericThatFits:       {Brief: "Spanner does not support numeric, but this type mapping preserves the numeric's specified precision", severity: suggestion},
-	Decimal:               {Brief: "Spanner does not support decimal. This type mapping could lose precision and is not recommended for production use", severity: warning},
-	DecimalThatFits:       {Brief: "Spanner does not support decimal, but this type mapping preserves the decimal's specified precision", severity: suggestion},
-	Serial:                {Brief: "Spanner does not support autoincrementing types", severity: warning},
-	AutoIncrement:         {Brief: "Spanner does not support auto_increment attribute", severity: warning},
-	Timestamp:             {Brief: "Spanner timestamp is closer to PostgreSQL timestamptz", severity: suggestion, batch: true},
-	Datetime:              {Brief: "Spanner timestamp is closer to MySQL timestamp", severity: suggestion, batch: true},
-	Time:                  {Brief: "Spanner does not support time/year types", severity: warning, batch: true},
-	Widened:               {Brief: "Some columns will consume more storage in Spanner", severity: warning, batch: true},
-	StringOverflow:        {Brief: "String overflow issue might occur as maximum supported length in Spanner is 2621440", severity: warning},
-	HotspotTimestamp:      {Brief: "Timestamp Hotspot Occured", severity: warning},
-	HotspotAutoIncrement:  {Brief: "Autoincrement Hotspot Occured", severity: warning},
-	InterleavedOrder:      {Brief: "can be converted as Interleaved Table", severity: suggestion},
-	RedundantIndex:        {Brief: "Redundant Index", severity: warning},
-	AutoIncrementIndex:    {Brief: "Auto increment column in Index can create a Hotspot", severity: warning},
-	InterleaveIndex:       {Brief: "can be converted to an Interleave Index", severity: suggestion},
-	InterleavedNotInOrder: {Brief: "Can be converted to interleaved table if primary key order parameter is changed for the table", severity: suggestion},
-	InterleavedAddColumn:  {Brief: "Candidate for Interleaved Table", severity: suggestion},
-	IllegalName:           {Brief: "Names must adhere to the spanner regular expression {a-z|A-Z}[{a-z|A-Z|0-9|_}+]", severity: warning},
+	DefaultValue:            {Brief: "Some columns have default values which Spanner does not support", severity: warning, batch: true},
+	ForeignKey:              {Brief: "Spanner does not support foreign keys", severity: warning},
+	MultiDimensionalArray:   {Brief: "Spanner doesn't support multi-dimensional arrays", severity: warning},
+	NoGoodType:              {Brief: "No appropriate Spanner type", severity: warning},
+	Numeric:                 {Brief: "Spanner does not support numeric. This type mapping could lose precision and is not recommended for production use", severity: warning},
+	NumericThatFits:         {Brief: "Spanner does not support numeric, but this type mapping preserves the numeric's specified precision", severity: suggestion},
+	Decimal:                 {Brief: "Spanner does not support decimal. This type mapping could lose precision and is not recommended for production use", severity: warning},
+	DecimalThatFits:         {Brief: "Spanner does not support decimal, but this type mapping preserves the decimal's specified precision", severity: suggestion},
+	Serial:                  {Brief: "Spanner does not support autoincrementing types", severity: warning},
+	AutoIncrement:           {Brief: "Spanner does not support auto_increment attribute", severity: warning},
+	Timestamp:               {Brief: "Spanner timestamp is closer to PostgreSQL timestamptz", severity: suggestion, batch: true},
+	Datetime:                {Brief: "Spanner timestamp is closer to MySQL timestamp", severity: suggestion, batch: true},
+	Time:                    {Brief: "Spanner does not support time/year types", severity: warning, batch: true},
+	Widened:                 {Brief: "Some columns will consume more storage in Spanner", severity: warning, batch: true},
+	StringOverflow:          {Brief: "String overflow issue might occur as maximum supported length in Spanner is 2621440", severity: warning},
+	HotspotTimestamp:        {Brief: "Timestamp Hotspot Occured", severity: warning},
+	HotspotAutoIncrement:    {Brief: "Autoincrement Hotspot Occured", severity: warning},
+	InterleavedOrder:        {Brief: "can be converted as Interleaved Table", severity: suggestion},
+	RedundantIndex:          {Brief: "Redundant Index", severity: warning},
+	AutoIncrementIndex:      {Brief: "Auto increment column in Index can create a Hotspot", severity: warning},
+	InterleaveIndex:         {Brief: "can be converted to an Interleave Index", severity: suggestion},
+	InterleavedNotInOrder:   {Brief: "Can be converted to interleaved table if primary key order parameter is changed for the table", severity: suggestion},
+	InterleavedAddColumn:    {Brief: "Candidate for Interleaved Table", severity: suggestion},
+	IllegalName:             {Brief: "Names must adhere to the spanner regular expression {a-z|A-Z}[{a-z|A-Z|0-9|_}+]", severity: warning},
+	InterleavedRenameColumn: {Brief: "Candidate for Interleaved Table", severity: suggestion},
 }
 
 type severity int
diff --git a/spanner/ddl/ast.go b/spanner/ddl/ast.go
index 2939f52..fe6b911 100644
--- a/spanner/ddl/ast.go
+++ b/spanner/ddl/ast.go
@@ -72,8 +72,9 @@ const (
 )
 
 // Type represents the type of a column.
-//     type:
-//        { BOOL | INT64 | FLOAT64 | STRING( length ) | BYTES( length ) | DATE | TIMESTAMP | NUMERIC }
+//
+//	type:
+//	   { BOOL | INT64 | FLOAT64 | STRING( length ) | BYTES( length ) | DATE | TIMESTAMP | NUMERIC }
 type Type struct {
 	Name string
 	// Len encodes the following Spanner DDL definition:
@@ -140,8 +141,9 @@ func (ty Type) PGPrintColumnDefType() string {
 }
 
 // ColumnDef encodes the following DDL definition:
-//     column_def:
-//       column_name type [NOT NULL] [options_def]
+//
+//	column_def:
+//	  column_name type [NOT NULL] [options_def]
 type ColumnDef struct {
 	Name    string
 	T       Type
@@ -162,7 +164,7 @@ type Config struct {
 func (c Config) quote(s string) string {
 	if c.ProtectIds {
 		if c.TargetDb == constants.TargetExperimentalPostgres {
-			return "\"" + s + "\""
+			return s
 		} else {
 			return "`" + s + "`"
 		}
@@ -187,10 +189,11 @@ func (cd ColumnDef) PrintColumnDef(c Config) (string, string) {
 }
 
 // IndexKey encodes the following DDL definition:
-//     primary_key:
-//       PRIMARY KEY ( [key_part, ...] )
-//     key_part:
-//        column_name [{ ASC | DESC }]
+//
+//	primary_key:
+//	  PRIMARY KEY ( [key_part, ...] )
+//	key_part:
+//	   column_name [{ ASC | DESC }]
 type IndexKey struct {
 	Col   string
 	Desc  bool // Default order is ascending i.e. Desc = false.
@@ -208,8 +211,9 @@ func (pk IndexKey) PrintIndexKey(c Config) string {
 }
 
 // Foreignkey encodes the following DDL definition:
-//    [ CONSTRAINT constraint_name ]
-// 	  FOREIGN KEY ( column_name [, ... ] ) REFERENCES ref_table ( ref_column [, ... ] ) }
+//
+//	   [ CONSTRAINT constraint_name ]
+//		  FOREIGN KEY ( column_name [, ... ] ) REFERENCES ref_table ( ref_column [, ... ] ) }
 type Foreignkey struct {
 	Name         string
 	Columns      []string
@@ -233,7 +237,8 @@ func (k Foreignkey) PrintForeignKey(c Config) string {
 }
 
 // CreateTable encodes the following DDL definition:
-//     create_table: CREATE TABLE table_name ([column_def, ...] ) primary_key [, cluster]
+//
+//	create_table: CREATE TABLE table_name ([column_def, ...] ) primary_key [, cluster]
 type CreateTable struct {
 	Name     string
 	ColNames []string             // Provides names and order of columns
@@ -294,7 +299,8 @@ func (ct CreateTable) PrintCreateTable(config Config) string {
 }
 
 // CreateIndex encodes the following DDL definition:
-//     create index: CREATE [UNIQUE] [NULL_FILTERED] INDEX index_name ON table_name ( key_part [, ...] ) [ storing_clause ] [ , interleave_clause ]
+//
+//	create index: CREATE [UNIQUE] [NULL_FILTERED] INDEX index_name ON table_name ( key_part [, ...] ) [ storing_clause ] [ , interleave_clause ]
 type CreateIndex struct {
 	Name          string
 	Table         string
diff --git a/ui/src/app/app.component.html b/ui/src/app/app.component.html
index 4c28240..186c16f 100644
--- a/ui/src/app/app.component.html
+++ b/ui/src/app/app.component.html
@@ -6,11 +6,15 @@
     [opened]="showSidenav"
     [ngClass]="{
       'width-40pc': sidenavComponent === 'rule' || sidenavComponent === 'saveSession',
+      'width-50pc': sidenavComponent === 'reviewChanges',
       'width-60pc': sidenavComponent === 'assessment' || sidenavComponent === 'instruction'
     }"
   >
     <app-sidenav-rule *ngIf="sidenavComponent === 'rule'"></app-sidenav-rule>
     <app-sidenav-save-session *ngIf="sidenavComponent == 'saveSession'"></app-sidenav-save-session>
+    <app-sidenav-review-changes
+      *ngIf="sidenavComponent == 'reviewChanges'"
+    ></app-sidenav-review-changes>
     <app-sidenav-view-assessment
       *ngIf="sidenavComponent === 'assessment'"
     ></app-sidenav-view-assessment>
diff --git a/ui/src/app/app.component.scss b/ui/src/app/app.component.scss
index cde1798..e4e2ccf 100644
--- a/ui/src/app/app.component.scss
+++ b/ui/src/app/app.component.scss
@@ -28,6 +28,9 @@ mat-sidenav {
 .width-40pc {
   width: 40%;
 }
+.width-50pc {
+  width: 50%;
+}
 .width-60pc {
   width: 60%;
 }
diff --git a/ui/src/app/app.module.ts b/ui/src/app/app.module.ts
index 6a846bb..0912788 100644
--- a/ui/src/app/app.module.ts
+++ b/ui/src/app/app.module.ts
@@ -33,10 +33,12 @@ import { EditGlobalDatatypeFormComponent } from './components/edit-global-dataty
 import { SidenavViewAssessmentComponent } from './components/sidenav-view-assessment/sidenav-view-assessment.component'
 import { SidenavSaveSessionComponent } from './components/sidenav-save-session/sidenav-save-session.component'
 import { DropIndexOrTableDialogComponent } from './components/drop-index-or-table-dialog/drop-index-or-table-dialog.component'
-import { DatabaseLoaderComponent } from './components/database-loader/database-loader.component';
-import { PrepareMigrationComponent } from './components/prepare-migration/prepare-migration.component';
-import { TargetDetailsFormComponent } from './components/target-details-form/target-details-form.component';
+import { DatabaseLoaderComponent } from './components/database-loader/database-loader.component'
+import { PrepareMigrationComponent } from './components/prepare-migration/prepare-migration.component'
+import { TargetDetailsFormComponent } from './components/target-details-form/target-details-form.component'
 import { ConnectionProfileFormComponent } from './components/connection-profile-form/connection-profile-form.component'
+import { SidenavReviewChangesComponent } from './components/sidenav-review-changes/sidenav-review-changes.component'
+import { TableColumnChangesPreviewComponent } from './components/table-column-changes-preview/table-column-changes-preview.component'
 
 @NgModule({
   declarations: [
@@ -68,6 +70,8 @@ import { ConnectionProfileFormComponent } from './components/connection-profile-
     PrepareMigrationComponent,
     TargetDetailsFormComponent,
     ConnectionProfileFormComponent,
+    SidenavReviewChangesComponent,
+    TableColumnChangesPreviewComponent,
   ],
   imports: [
     BrowserModule,
@@ -77,7 +81,7 @@ import { ConnectionProfileFormComponent } from './components/connection-profile-
     HttpClientModule,
     FormsModule,
     MatRadioModule,
-    ClipboardModule
+    ClipboardModule,
   ],
   providers: [
     {
@@ -88,4 +92,4 @@ import { ConnectionProfileFormComponent } from './components/connection-profile-
   ],
   bootstrap: [AppComponent],
 })
-export class AppModule { }
+export class AppModule {}
diff --git a/ui/src/app/components/connection-profile-form/connection-profile-form.component.html b/ui/src/app/components/connection-profile-form/connection-profile-form.component.html
index fdc1ab8..dfe4a4f 100644
--- a/ui/src/app/components/connection-profile-form/connection-profile-form.component.html
+++ b/ui/src/app/components/connection-profile-form/connection-profile-form.component.html
@@ -32,7 +32,7 @@
                         connections
                         from them.</b><a href="https://cloud.google.com/datastream/docs/network-connectivity-options#ipallowlists">Learn More</a></div>
                 <br>
-                <li *ngFor="let ip of ipList" class="container">
+                <li *ngFor="let ip of ipList" class="connection-form-container">
                     <span class="left-text">{{ip}}</span>
                     <span>
                         <mat-icon class="icon copy" [cdkCopyToClipboard]="ip" matTooltip="Copy">file_copy</mat-icon>
diff --git a/ui/src/app/components/connection-profile-form/connection-profile-form.component.scss b/ui/src/app/components/connection-profile-form/connection-profile-form.component.scss
index c1f7e18..910c786 100644
--- a/ui/src/app/components/connection-profile-form/connection-profile-form.component.scss
+++ b/ui/src/app/components/connection-profile-form/connection-profile-form.component.scss
@@ -2,7 +2,7 @@
     font-size: 15px;
 }
 
-.container {
+.connection-form-container {
     display: block;
 }
 
diff --git a/ui/src/app/components/infodialog/infodialog.component.html b/ui/src/app/components/infodialog/infodialog.component.html
index e8764c8..135aa3f 100644
--- a/ui/src/app/components/infodialog/infodialog.component.html
+++ b/ui/src/app/components/infodialog/infodialog.component.html
@@ -1,9 +1,14 @@
-<h1 mat-dialog-title>{{ data.title }}</h1>
-<div mat-dialog-content>
-  <p class="info-text">
-    {{ data.message }}
-  </p>
-</div>
-<div mat-dialog-actions class="action-container">
-  <button mat-button color="primary" mat-dialog-close>CANCEL</button>
+<div class="dialog-container">
+  <h1 mat-dialog-title>{{ data.title }}</h1>
+  <div mat-dialog-content>
+    <p class="dialog-message">
+      {{ data.message }}
+    </p>
+  </div>
+  <div mat-dialog-actions class="dialog-action">
+    <button mat-button color="primary" mat-dialog-close>CANCEL</button>
+    <button *ngIf="data.type != 'error'" mat-raised-button color="primary" (click)="onConfirm()">
+      Continue
+    </button>
+  </div>
 </div>
diff --git a/ui/src/app/components/infodialog/infodialog.component.scss b/ui/src/app/components/infodialog/infodialog.component.scss
index 4b2c336..8b13789 100644
--- a/ui/src/app/components/infodialog/infodialog.component.scss
+++ b/ui/src/app/components/infodialog/infodialog.component.scss
@@ -1,15 +1,1 @@
-.info-text {
-  padding-top: 1rem;
-  padding-bottom: 1rem;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
-.action-container {
-  display: flex;
-  justify-content: flex-end;
-}
 
-.icon {
-  margin-right: 20px;
-}
diff --git a/ui/src/app/components/infodialog/infodialog.component.ts b/ui/src/app/components/infodialog/infodialog.component.ts
index d089085..ac66958 100644
--- a/ui/src/app/components/infodialog/infodialog.component.ts
+++ b/ui/src/app/components/infodialog/infodialog.component.ts
@@ -1,5 +1,5 @@
 import { Component, OnInit, Inject } from '@angular/core'
-import { MAT_DIALOG_DATA } from '@angular/material/dialog'
+import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'
 interface IDialogProps {
   message: string
   type: 'warning' | 'error' | 'success'
@@ -11,14 +11,27 @@ interface IDialogProps {
   styleUrls: ['./infodialog.component.scss'],
 })
 export class InfodialogComponent implements OnInit {
-  constructor(@Inject(MAT_DIALOG_DATA) public data: IDialogProps) {
+  constructor(
+    public dialogRef: MatDialogRef<InfodialogComponent>,
+    @Inject(MAT_DIALOG_DATA) public data: IDialogProps
+  ) {
     if (data.title === undefined) {
-      data.title = "Update can not be saved"
+      data.title = 'Update can not be saved'
     }
   }
 
   ngOnInit(): void {}
 
+  onConfirm(): void {
+    // Close the dialog, return true
+    this.dialogRef.close(true)
+  }
+
+  onDismiss(): void {
+    // Close the dialog, return false
+    this.dialogRef.close(false)
+  }
+
   getIconFromMessageType() {
     switch (this.data.type) {
       case 'warning':
diff --git a/ui/src/app/components/object-detail/object-detail.component.html b/ui/src/app/components/object-detail/object-detail.component.html
index d3f39a5..012ff2e 100644
--- a/ui/src/app/components/object-detail/object-detail.component.html
+++ b/ui/src/app/components/object-detail/object-detail.component.html
@@ -112,203 +112,243 @@
   >
     <mat-tab label="COLUMNS">
       <div class="column-tab-container">
-        <table mat-table [dataSource]="dataSource">
-          <ng-container matColumnDef="srcDatabase">
-            <th mat-header-cell class="db_name" *matHeaderCellDef colspan="5">{{ srcDbName }}</th>
-          </ng-container>
-
-          <ng-container matColumnDef="spDatabase">
-            <th mat-header-cell *matHeaderCellDef class="db_name" colspan="6">
-              <div class="spanner_edit-button">
-                <span>Spanner</span>
-                <div *ngIf="!isEditMode && !currentObject.isDeleted">
-                  <button
-                    mat-stroked-button
-                    color="primary"
-                    (click)="toggleEdit()"
-                    *ngIf="currentObject!.isSpannerNode"
+        <div class="column-table-container">
+          <table mat-table [dataSource]="srcDataSource">
+            <ng-container matColumnDef="srcDatabase">
+              <th mat-header-cell class="db_name" *matHeaderCellDef colspan="5">{{ srcDbName }}</th>
+            </ng-container>
+
+            <ng-container matColumnDef="srcOrder">
+              <th class="table_header" mat-header-cell *matHeaderCellDef>Order</th>
+              <td mat-cell *matCellDef="let element">
+                {{ element.get('srcOrder').value }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="srcColName">
+              <th class="table_header" mat-header-cell *matHeaderCellDef>Name</th>
+              <td mat-cell *matCellDef="let element">
+                {{ element.get('srcColName').value }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="srcDataType">
+              <th mat-header-cell class="table_header" *matHeaderCellDef>Type</th>
+              <td mat-cell *matCellDef="let element">
+                {{ element.get('srcDataType').value }}
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="srcIsPk">
+              <th class="table_header" mat-header-cell *matHeaderCellDef>Pk</th>
+              <td mat-cell *matCellDef="let element">
+                <div *ngIf="element.get('srcIsPk').value">
+                  <svg
+                    width="14"
+                    height="8"
+                    viewBox="0 0 14 8"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
                   >
-                    <mat-icon class="edit-icon">edit</mat-icon>
-                    EDIT
-                  </button>
+                    <path
+                      fill-rule="evenodd"
+                      clip-rule="evenodd"
+                      d="M4 8C5.86384 8 7.42994 6.72523 7.87398 5H10V7H13V5H14V3H7.87398C7.42994 1.27477 5.86384 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM6 4C6 5.10457 5.10457 6 4 6C2.89543 6 2 5.10457 2 4C2 2.89543 2.89543 2 4 2C5.10457 2 6 2.89543 6 4Z"
+                      fill="black"
+                    />
+                  </svg>
                 </div>
-              </div>
-            </th>
-          </ng-container>
-
-          <ng-container matColumnDef="srcOrder">
-            <th class="table_header" mat-header-cell *matHeaderCellDef>Order</th>
-            <td mat-cell *matCellDef="let element">
-              {{ element.get('srcOrder').value }}
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="srcColName">
-            <th class="table_header" mat-header-cell *matHeaderCellDef>Name</th>
-            <td mat-cell *matCellDef="let element">
-              {{ element.get('srcColName').value }}
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="srcDataType">
-            <th mat-header-cell class="table_header" *matHeaderCellDef>Type</th>
-            <td mat-cell *matCellDef="let element">
-              {{ element.get('srcDataType').value }}
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="srcIsPk">
-            <th class="table_header" mat-header-cell *matHeaderCellDef>Pk</th>
-            <td mat-cell *matCellDef="let element">
-              <div *ngIf="element.get('srcIsPk').value">
-                <svg
-                  width="14"
-                  height="8"
-                  viewBox="0 0 14 8"
-                  fill="none"
-                  xmlns="http://www.w3.org/2000/svg"
-                >
-                  <path
-                    fill-rule="evenodd"
-                    clip-rule="evenodd"
-                    d="M4 8C5.86384 8 7.42994 6.72523 7.87398 5H10V7H13V5H14V3H7.87398C7.42994 1.27477 5.86384 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM6 4C6 5.10457 5.10457 6 4 6C2.89543 6 2 5.10457 2 4C2 2.89543 2.89543 2 4 2C5.10457 2 6 2.89543 6 4Z"
-                    fill="black"
-                  />
-                </svg>
-              </div>
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="srcIsNotNull">
-            <th mat-header-cell class="table_header" *matHeaderCellDef>Nullable</th>
-            <td mat-cell *matCellDef="let element">
-              {{ element.get('srcIsNotNull').value ? 'Not Null' : '' }}
-            </td>
-          </ng-container>
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="srcIsNotNull">
+              <th mat-header-cell class="table_header" *matHeaderCellDef>Nullable</th>
+              <td mat-cell *matCellDef="let element">
+                {{ element.get('srcIsNotNull').value ? 'Not Null' : '' }}
+              </td>
+            </ng-container>
+
+            <tr mat-header-row *matHeaderRowDef="['srcDatabase']"></tr>
+            <tr mat-header-row *matHeaderRowDef="srcDisplayedColumns"></tr>
+            <tr
+              mat-row
+              [ngClass]="{ 'scr-column-data-edit-mode': isEditMode }"
+              *matRowDef="let row; columns: srcDisplayedColumns"
+            ></tr>
+          </table>
+
+          <table mat-table [dataSource]="spDataSource">
+            <ng-container matColumnDef="spDatabase">
+              <th mat-header-cell *matHeaderCellDef class="db_name" colspan="6">
+                <div class="spanner_edit-button">
+                  <span>Spanner</span>
+                  <div *ngIf="!isEditMode && !currentObject.isDeleted">
+                    <button
+                      mat-stroked-button
+                      color="primary"
+                      (click)="toggleEdit()"
+                      *ngIf="currentObject!.isSpannerNode"
+                    >
+                      <mat-icon class="edit-icon">edit</mat-icon>
+                      EDIT
+                    </button>
+                  </div>
+                </div>
+              </th>
+            </ng-container>
 
-          <ng-container matColumnDef="spColName">
-            <th mat-header-cell class="table_header" *matHeaderCellDef>Name</th>
-            <td mat-cell *matCellDef="let element">
+            <ng-container matColumnDef="spColName">
+              <th mat-header-cell class="table_header" *matHeaderCellDef>Name</th>
+              <td mat-cell *matCellDef="let element">
                 <div *ngIf="isEditMode && element.get('spOrder').value !== ''">
                   <input
                     matInput
                     class="name_input"
                     type="text"
                     [formControl]="element.get('spColName')"
-                    matTooltip="No special characters allowed except underscore." 
+                    matTooltip="No special characters allowed except underscore."
                     [matTooltipDisabled]="!element.get('spColName')?.hasError('pattern')"
                   />
                 </div>
-              <p *ngIf="!isEditMode">{{ element.get('spColName').value }}</p>
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="spDataType">
-            <th mat-header-cell class="table_header" *matHeaderCellDef>Type</th>
-            <td mat-cell *matCellDef="let element; let i = index">
-              <div class="sp-datatype-data-cells">
-                <span
-                  *ngIf="isSpTableSuggesstionDisplay[i] && element.get('spOrder').value !== ''"
-                  class="material-icons summary-type warning sp-datatype-suggestion-icon"
-                  [matTooltip]="spTableSuggestion[i]"
-                  matTooltipPosition="above"
-                  >warning</span
-                >
+                <p *ngIf="!isEditMode">{{ element.get('spColName').value }}</p>
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="spDataType">
+              <th mat-header-cell class="table_header" *matHeaderCellDef>Type</th>
+              <td mat-cell *matCellDef="let element; let i = index">
+                <div class="sp-datatype-data-cells">
+                  <span
+                    *ngIf="isSpTableSuggesstionDisplay[i] && element.get('spOrder').value !== ''"
+                    class="material-icons summary-type warning sp-datatype-suggestion-icon"
+                    [matTooltip]="spTableSuggestion[i]"
+                    matTooltipPosition="above"
+                    >warning</span
+                  >
 
-                <mat-form-field
-                  appearance="legacy"
-                  class="w-100"
-                  *ngIf="isEditMode && element.get('spOrder').value !== ''"
-                >
-                  <mat-select
-                    #matSelectspDataType
-                    [formControl]="element.get('spDataType')"
-                    selected="element.get('spDataType').value"
-                    (selectionChange)="spTableEditSuggestionHandler(i, matSelectspDataType.value)"
+                  <mat-form-field
+                    appearance="legacy"
+                    class="w-100"
+                    *ngIf="isEditMode && element.get('spOrder').value !== ''"
                   >
-                    <mat-option
-                      *ngFor="let t of typeMap[element.get('srcDataType').value]"
-                      [value]="t.T"
+                    <mat-select
+                      #matSelectspDataType
+                      [formControl]="element.get('spDataType')"
+                      selected="element.get('spDataType').value"
+                      (selectionChange)="spTableEditSuggestionHandler(i, matSelectspDataType.value)"
                     >
-                      {{ t.T }}
-                    </mat-option>
-                  </mat-select>
-                </mat-form-field>
-                <p *ngIf="!isEditMode">{{ element.get('spDataType').value }}</p>
-              </div>
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="spIsPk">
-            <th class="table_header" mat-header-cell *matHeaderCellDef>Pk</th>
-            <td mat-cell *matCellDef="let element">
-              <div *ngIf="element.get('spIsPk').value">
-                <svg
-                  width="14"
-                  height="8"
-                  viewBox="0 0 14 8"
-                  fill="none"
-                  xmlns="http://www.w3.org/2000/svg"
+                      <mat-option
+                        *ngFor="let t of typeMap[element.get('srcDataType').value]"
+                        [value]="t.T"
+                      >
+                        {{ t.T }}
+                      </mat-option>
+                    </mat-select>
+                  </mat-form-field>
+                  <p *ngIf="!isEditMode">{{ element.get('spDataType').value }}</p>
+                </div>
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="spIsPk">
+              <th class="table_header" mat-header-cell *matHeaderCellDef>Pk</th>
+              <td mat-cell *matCellDef="let element">
+                <div *ngIf="element.get('spIsPk').value">
+                  <svg
+                    width="14"
+                    height="8"
+                    viewBox="0 0 14 8"
+                    fill="none"
+                    xmlns="http://www.w3.org/2000/svg"
+                  >
+                    <path
+                      fill-rule="evenodd"
+                      clip-rule="evenodd"
+                      d="M4 8C5.86384 8 7.42994 6.72523 7.87398 5H10V7H13V5H14V3H7.87398C7.42994 1.27477 5.86384 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM6 4C6 5.10457 5.10457 6 4 6C2.89543 6 2 5.10457 2 4C2 2.89543 2.89543 2 4 2C5.10457 2 6 2.89543 6 4Z"
+                      fill="black"
+                    />
+                  </svg>
+                </div>
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="spIsNotNull">
+              <th mat-header-cell class="table_header" *matHeaderCellDef>
+                <span *ngIf="isEditMode">Not Null</span><span *ngIf="!isEditMode">Nullable</span>
+              </th>
+              <td mat-cell *matCellDef="let element">
+                <div class="notNullContent">
+                  <div *ngIf="isEditMode && element.get('spOrder').value !== ''">
+                    <mat-checkbox
+                      color="primary"
+                      [formControl]="element.get('spIsNotNull')"
+                    ></mat-checkbox>
+                  </div>
+                  <p *ngIf="!isEditMode">
+                    {{ element.get('spIsNotNull').value ? 'Not Null' : '' }}
+                  </p>
+                </div>
+              </td>
+            </ng-container>
+
+            <ng-container matColumnDef="dropButton">
+              <th mat-header-cell class="table_header" *matHeaderCellDef></th>
+              <td
+                mat-cell
+                *matCellDef="let element"
+                [ngClass]="{ 'drop-button-left-border': isEditMode }"
+              >
+                <div
+                  class="actions"
+                  *ngIf="
+                    isEditMode &&
+                    currentObject!.isSpannerNode &&
+                    !(element.get('spOrder').value === '')
+                  "
                 >
-                  <path
-                    fill-rule="evenodd"
-                    clip-rule="evenodd"
-                    d="M4 8C5.86384 8 7.42994 6.72523 7.87398 5H10V7H13V5H14V3H7.87398C7.42994 1.27477 5.86384 0 4 0C1.79086 0 0 1.79086 0 4C0 6.20914 1.79086 8 4 8ZM6 4C6 5.10457 5.10457 6 4 6C2.89543 6 2 5.10457 2 4C2 2.89543 2.89543 2 4 2C5.10457 2 6 2.89543 6 4Z"
-                    fill="black"
-                  />
-                </svg>
-              </div>
-            </td>
-          </ng-container>
-
-          <ng-container matColumnDef="spIsNotNull">
-            <th mat-header-cell class="table_header" *matHeaderCellDef>
-              <span *ngIf="isEditMode">Not Null</span><span *ngIf="!isEditMode">Nullable</span>
-            </th>
-            <td mat-cell *matCellDef="let element">
-              <div class="notNullContent">
-                <div *ngIf="isEditMode && element.get('spOrder').value !== ''">
-                  <mat-checkbox
-                    color="primary"
-                    [formControl]="element.get('spIsNotNull')"
-                  ></mat-checkbox>
+                  <mat-icon [matMenuTriggerFor]="menu">more_vert</mat-icon>
+                  <mat-menu #menu="matMenu" xPosition="before">
+                    <button mat-menu-item (click)="dropColumn(element)">
+                      <span>Drop Column</span>
+                    </button>
+                  </mat-menu>
                 </div>
-                <p *ngIf="!isEditMode">
-                  {{ element.get('spIsNotNull').value ? 'Not Null' : '' }}
-                </p>
-              </div>
-            </td>
-          </ng-container>
+              </td>
+            </ng-container>
 
-          <ng-container matColumnDef="dropButton">
-            <th mat-header-cell class="table_header" *matHeaderCellDef></th>
-            <td
-              mat-cell
-              *matCellDef="let element"
-              [ngClass]="{ 'drop-button-left-border': isEditMode }"
+            <tr mat-header-row *matHeaderRowDef="['spDatabase']"></tr>
+            <tr mat-header-row *matHeaderRowDef="spDisplayedColumns"></tr>
+            <tr mat-row *matRowDef="let row; columns: spDisplayedColumns"></tr>
+          </table>
+        </div>
+
+        <div [formGroup]="addColumnForm" *ngIf="isEditMode" class="add-column">
+          <mat-form-field appearance="outline" class="column-list">
+            <mat-label>Column Name</mat-label>
+            <mat-select
+              matSelect
+              class="input-field"
+              (selectionChange)="setColumn($event.value)"
+              formControlName="columnName"
+              required="true"
             >
-              <div
-                class="actions"
-                *ngIf="
-                  isEditMode &&
-                  currentObject!.isSpannerNode &&
-                  !(element.get('spOrder').value === '')
-                "
-              >
-                <mat-icon [matMenuTriggerFor]="menu">more_vert</mat-icon>
-                <mat-menu #menu="matMenu" xPosition="before">
-                  <button mat-menu-item (click)="dropColumn(element)">
-                    <span>Drop Column</span>
-                  </button>
-                </mat-menu>
-              </div>
-            </td>
-          </ng-container>
+              <mat-option *ngFor="let column of droppedColumns" [value]="column.srcColName">{{
+                column.srcColName
+              }}</mat-option>
+            </mat-select>
+          </mat-form-field>
 
-          <tr mat-header-row *matHeaderRowDef="['srcDatabase', 'spDatabase']"></tr>
-          <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
-          <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
-        </table>
+          <button
+            mat-button
+            color="primary"
+            class="add-column-btn"
+            type="button"
+            (click)="addColumn()"
+          >
+            <mat-icon>add</mat-icon>
+            ADD COLUMN
+          </button>
+        </div>
       </div>
     </mat-tab>
 
@@ -399,7 +439,7 @@
                   class="order_input"
                   type="text"
                   [formControl]="element.get('spOrder')"
-                  matTooltip="Must have a value greater than 0." 
+                  matTooltip="Must have a value greater than 0."
                   [matTooltipDisabled]="!element.get('spOrder')?.hasError('pattern')"
                 />
               </div>
@@ -589,7 +629,7 @@
                   class="name_input"
                   type="text"
                   [formControl]="element.get('spName')"
-                  matTooltip="No special characters allowed except underscore." 
+                  matTooltip="No special characters allowed except underscore."
                   [matTooltipDisabled]="!element.get('spName')?.hasError('pattern')"
                 />
               </div>
@@ -728,7 +768,7 @@
   </mat-tab-group>
 
   <div *ngIf="currentObject!.type === 'indexName'" class="index-tab-container">
-    <table mat-table [dataSource]="dataSource">
+    <table mat-table [dataSource]="spDataSource">
       <ng-container matColumnDef="srcDatabase">
         <th mat-header-cell class="db_name" *matHeaderCellDef colspan="3">{{ srcDbName }}</th>
       </ng-container>
@@ -854,7 +894,14 @@
     <mat-divider *ngIf="isEditMode || isPkEditMode || isFkEditMode"></mat-divider>
 
     <div class="save-button" *ngIf="isEditMode && currentTabIndex === 0">
-      <button mat-raised-button color="primary" (click)="saveColumnTable()" [disabled]="!rowArray.valid">SAVE & CONVERT</button>
+      <button
+        mat-raised-button
+        color="primary"
+        (click)="saveColumnTable()"
+        [disabled]="!spRowArray.valid"
+      >
+        SAVE & CONVERT
+      </button>
       <button
         class="cancel-button"
         mat-raised-button
@@ -866,7 +913,9 @@
       </button>
     </div>
     <div class="save-button" *ngIf="isPkEditMode && currentTabIndex === 1">
-      <button mat-raised-button color="primary" (click)="savePk()" [disabled]="!pkArray.valid">SAVE & CONVERT</button>
+      <button mat-raised-button color="primary" (click)="savePk()" [disabled]="!pkArray.valid">
+        SAVE & CONVERT
+      </button>
       <button
         class="cancel-button"
         mat-raised-button
@@ -878,7 +927,9 @@
       </button>
     </div>
     <div class="save-button" *ngIf="isFkEditMode && currentTabIndex === 2">
-      <button mat-raised-button color="primary" (click)="saveFk()" [disabled]="!fkArray.valid">SAVE & CONVERT</button>
+      <button mat-raised-button color="primary" (click)="saveFk()" [disabled]="!fkArray.valid">
+        SAVE & CONVERT
+      </button>
       <button
         class="cancel-button"
         mat-raised-button
diff --git a/ui/src/app/components/object-detail/object-detail.component.scss b/ui/src/app/components/object-detail/object-detail.component.scss
index 0d01365..7d20c32 100644
--- a/ui/src/app/components/object-detail/object-detail.component.scss
+++ b/ui/src/app/components/object-detail/object-detail.component.scss
@@ -66,7 +66,8 @@
     margin-right: 1rem;
   }
 }
-.add-pk-column {
+.add-pk-column,
+.add-column {
   margin-left: 50%;
   padding: 10px;
   .column-list {
@@ -86,6 +87,12 @@
 .pk-tab-container,
 .index-tab-container {
   height: 84%;
+
+  .column-table-container {
+    display: flex;
+    flex-direction: row;
+    align-items: flex-start;
+  }
   table {
     width: 100%;
   }
@@ -103,6 +110,11 @@
     background-color: #f5f5f5;
   }
 
+  .tr {
+    max-height: 48px;
+    line-height: 48px;
+  }
+
   .mat-cell,
   .mat-header-cell {
     padding: 0px 5px;
@@ -255,3 +267,6 @@ p {
 .mr10 {
   margin-right: 10px;
 }
+.scr-column-data-edit-mode {
+  height: 58.3px;
+}
diff --git a/ui/src/app/components/object-detail/object-detail.component.ts b/ui/src/app/components/object-detail/object-detail.component.ts
index 6e53b37..2d431b0 100644
--- a/ui/src/app/components/object-detail/object-detail.component.ts
+++ b/ui/src/app/components/object-detail/object-detail.component.ts
@@ -11,9 +11,11 @@ import { ObjectDetailNodeType, ObjectExplorerNodeType, StorageKeys } from 'src/a
 import FlatNode from 'src/app/model/schema-object-node'
 import { Subscription, take } from 'rxjs'
 import { MatTabChangeEvent } from '@angular/material/tabs/tab-group'
-import IConv, { ICreateIndex, IPrimaryKey } from 'src/app/model/conv'
+import IConv, { ICreateIndex, IIndexKey, IPkColumnDefs, IPrimaryKey } from 'src/app/model/conv'
 import { ConversionService } from 'src/app/services/conversion/conversion.service'
 import { DropIndexOrTableDialogComponent } from '../drop-index-or-table-dialog/drop-index-or-table-dialog.component'
+import { SidenavService } from 'src/app/services/sidenav/sidenav.service'
+import { TableUpdatePubSubService } from 'src/app/services/table-update-pub-sub/table-update-pub-sub.service'
 
 @Component({
   selector: 'app-object-detail',
@@ -27,7 +29,8 @@ export class ObjectDetailComponent implements OnInit {
     private dialog: MatDialog,
     private snackbar: SnackbarService,
     private conversion: ConversionService,
-    private formBuilder: FormBuilder
+    private sidenav: SidenavService,
+    private tableUpdatePubSub: TableUpdatePubSubService
   ) {}
 
   @Input() currentObject: FlatNode | null = null
@@ -53,18 +56,9 @@ export class ObjectDetailComponent implements OnInit {
     })
   }
 
-  displayedColumns = [
-    'srcOrder',
-    'srcColName',
-    'srcDataType',
-    'srcIsPk',
-    'srcIsNotNull',
-    'spColName',
-    'spDataType',
-    'spIsPk',
-    'spIsNotNull',
-    'dropButton',
-  ]
+  srcDisplayedColumns = ['srcOrder', 'srcColName', 'srcDataType', 'srcIsPk', 'srcIsNotNull']
+
+  spDisplayedColumns = ['spColName', 'spDataType', 'spIsPk', 'spIsNotNull', 'dropButton']
   displayedFkColumns = [
     'srcName',
     'srcColumns',
@@ -99,7 +93,8 @@ export class ObjectDetailComponent implements OnInit {
     'spIndexOrder',
     'dropButton',
   ]
-  dataSource: any = []
+  spDataSource: any = []
+  srcDataSource: any = []
   fkDataSource: any = []
   pkDataSource: any = []
   pkData: IColumnTabData[] = []
@@ -108,20 +103,26 @@ export class ObjectDetailComponent implements OnInit {
   isFkEditMode: boolean = false
   isIndexEditMode: boolean = false
   isObjectSelected: boolean = false
-  rowArray: FormArray = new FormArray([])
+  srcRowArray: FormArray = new FormArray([])
+  spRowArray: FormArray = new FormArray([])
   pkArray: FormArray = new FormArray([])
   fkArray: FormArray = new FormArray([])
   srcDbName: string = localStorage.getItem(StorageKeys.SourceDbName) as string
   isSpTableSuggesstionDisplay: boolean[] = []
   spTableSuggestion: string[] = []
   currentTabIndex: number = 0
+  addedColumnName: string = ''
+  droppedColumns: IColumnTabData[] = []
+  pkColumnNames: string[] = []
   indexColumnNames: string[] = []
+  addColumnForm = new FormGroup({
+    columnName: new FormControl('', [Validators.required]),
+  })
   addIndexKeyForm = new FormGroup({
     columnName: new FormControl('', [Validators.required]),
     ascOrDesc: new FormControl('', [Validators.required]),
   })
   addedPkColumnName: string = ''
-  pkColumnNames: string[] = []
   addPkColumnForm = new FormGroup({
     columnName: new FormControl('', [Validators.required]),
   })
@@ -142,81 +143,122 @@ export class ObjectDetailComponent implements OnInit {
     this.isFkEditMode = false
     this.isIndexEditMode = false
     this.isPkEditMode = false
+    this.srcRowArray = new FormArray([])
+    this.spRowArray = new FormArray([])
+    this.droppedColumns = []
+    this.pkColumnNames = []
+    this.interleaveParentName = this.getInterleaveParentFromConv()
 
     this.localTableData = JSON.parse(JSON.stringify(this.tableData))
     this.localIndexData = JSON.parse(JSON.stringify(this.indexData))
 
     if (this.currentObject?.type === ObjectExplorerNodeType.Table) {
       this.checkIsInterleave()
+
       this.interleaveObj = this.data.tableInterleaveStatus.subscribe((res) => {
         this.interleaveStatus = res
       })
-      this.setColumnTable()
-      this.setFkRows()
+
+      this.setSrcTableRows()
+      this.setSpTableRows()
+      this.setColumnsToAdd()
       this.setAddPkColumnList()
       this.setPkOrder()
       this.setPkRows()
-
+      this.setFkRows()
       this.updateSpTableSuggestion()
-    } else if (this.currentObject) {
+    } else if (this.currentObject?.type === ObjectExplorerNodeType.Index) {
       this.checkIsInterleave()
       this.indexOrderValidation()
       this.setIndexRows()
     }
+
     this.data.getSummary()
   }
 
-  setColumnTable() {
-    this.rowArray = new FormArray([])
+  setSpTableRows() {
+    this.spRowArray = new FormArray([])
     this.localTableData.forEach((row) => {
-      this.rowArray.push(
-        new FormGroup({
-          srcOrder: new FormControl(row.srcOrder),
-          srcColName: new FormControl(row.srcColName),
-          srcDataType: new FormControl(row.srcDataType),
-          srcIsPk: new FormControl(row.srcIsPk),
-          srcIsNotNull: new FormControl(row.srcIsNotNull),
-          spOrder: new FormControl(row.spOrder),
-          spColName: new FormControl(row.spColName, [
-            Validators.required,
-            Validators.pattern('^[a-zA-Z]([a-zA-Z0-9/_]*[a-zA-Z0-9])?'),
-          ]),
-          spDataType: new FormControl(row.spDataType),
-          spIsPk: new FormControl(row.spIsPk),
-          spIsNotNull: new FormControl(row.spIsNotNull),
-        })
-      )
+      if (row.spOrder) {
+        this.spRowArray.push(
+          new FormGroup({
+            srcOrder: new FormControl(row.srcOrder),
+            srcColName: new FormControl(row.srcColName),
+            srcDataType: new FormControl(row.srcDataType),
+            srcIsPk: new FormControl(row.srcIsPk),
+            srcIsNotNull: new FormControl(row.srcIsNotNull),
+            spOrder: new FormControl(row.srcOrder),
+            spColName: new FormControl(row.spColName, [
+              Validators.required,
+              Validators.pattern('^[a-zA-Z]([a-zA-Z0-9/_]*[a-zA-Z0-9])?'),
+            ]),
+            spDataType: new FormControl(row.spDataType),
+            spIsPk: new FormControl(row.spIsPk),
+            spIsNotNull: new FormControl(row.spIsNotNull),
+          })
+        )
+      }
     })
-    this.dataSource = this.rowArray.controls
+    this.spDataSource = this.spRowArray.controls
   }
 
-  setFkRows() {
-    this.fkArray = new FormArray([])
-    this.fkData.forEach((fk) => {
-      this.fkArray.push(
-        new FormGroup({
-          spName: new FormControl(fk.spName, [
-            Validators.required,
-            Validators.pattern('^[a-zA-Z]([a-zA-Z0-9/_]*[a-zA-Z0-9])?'),
-          ]),
-          srcName: new FormControl(fk.srcName),
-          spColumns: new FormControl(fk.spColumns),
-          srcColumns: new FormControl(fk.srcColumns),
-          spReferTable: new FormControl(fk.spReferTable),
-          srcReferTable: new FormControl(fk.srcReferTable),
-          spReferColumns: new FormControl(fk.spReferColumns),
-          srcReferColumns: new FormControl(fk.srcReferColumns),
+  setSrcTableRows() {
+    this.srcRowArray = new FormArray([])
+
+    this.localTableData.forEach((col: IColumnTabData) => {
+      if (col.spColName != '') {
+        this.srcRowArray.push(
+          new FormGroup({
+            srcOrder: new FormControl(col.srcOrder),
+            srcColName: new FormControl(col.srcColName),
+            srcDataType: new FormControl(col.srcDataType),
+            srcIsPk: new FormControl(col.srcIsPk),
+            srcIsNotNull: new FormControl(col.srcIsNotNull),
+            spOrder: new FormControl(col.spOrder),
+            spColName: new FormControl(col.spColName),
+            spDataType: new FormControl(col.spDataType),
+            spIsPk: new FormControl(col.spIsPk),
+            spIsNotNull: new FormControl(col.spIsNotNull),
+          })
+        )
+      } else {
+        this.srcRowArray.push(
+          new FormGroup({
+            srcOrder: new FormControl(col.srcOrder),
+            srcColName: new FormControl(col.srcColName),
+            srcDataType: new FormControl(col.srcDataType),
+            srcIsPk: new FormControl(col.srcIsPk),
+            srcIsNotNull: new FormControl(col.srcIsNotNull),
+            spOrder: new FormControl(col.srcOrder),
+            spColName: new FormControl(col.srcColName),
+            spDataType: new FormControl(this.typeMap[col.srcDataType][0].T),
+            spIsPk: new FormControl(col.srcIsPk),
+            spIsNotNull: new FormControl(col.srcIsNotNull),
+          })
+        )
+      }
+    })
+
+    this.srcDataSource = this.srcRowArray.controls
+  }
+
+  setColumnsToAdd() {
+    this.localTableData.forEach((col) => {
+      if (!col.spColName) {
+        this.srcRowArray.value.forEach((element: IColumnTabData) => {
+          if (col.srcColName == element.srcColName) {
+            this.droppedColumns.push(element)
+          }
         })
-      )
+      }
     })
-    this.fkDataSource = this.fkArray.controls
   }
 
   toggleEdit() {
     this.currentTabIndex = 0
     if (this.isEditMode) {
       this.localTableData = JSON.parse(JSON.stringify(this.tableData))
-      this.setColumnTable()
+      this.setSpTableRows()
       this.isEditMode = false
     } else {
       this.isEditMode = true
@@ -225,47 +267,43 @@ export class ObjectDetailComponent implements OnInit {
   saveColumnTable() {
     this.isEditMode = false
     let updateData: IUpdateTable = { UpdateCols: {} }
-    this.rowArray.value.forEach((col: IColumnTabData, i: number) => {
-      let oldRow = this.localTableData[i]
-      updateData.UpdateCols[this.localTableData[i].spColName] = {
-        Rename: oldRow.spColName !== col.spColName ? col.spColName : '',
-        NotNull: col.spIsNotNull ? 'ADDED' : 'REMOVED',
-        PK: '',
-        Removed: false,
-        ToType: oldRow.spDataType !== col.spDataType ? col.spDataType : '',
-      }
-    })
-    this.data.updateTable(this.currentObject!.name, updateData).subscribe({
-      next: (res: string) => {
-        if (res == '') {
-          this.isEditMode = false
-        } else {
-          this.dialog.open(InfodialogComponent, {
-            data: { message: res, type: 'error' },
-            maxWidth: '500px',
-          })
+
+    this.spRowArray.value.forEach((col: IColumnTabData, i: number) => {
+      for (let j = 0; j < this.localTableData.length; j++) {
+        if (col.srcColName == this.localTableData[j].srcColName) {
+          let oldRow = this.localTableData[j]
+          updateData.UpdateCols[this.localTableData[j].spColName] = {
+            Add: this.localTableData[j].spOrder == -1,
+            Rename: oldRow.spColName !== col.spColName ? col.spColName : '',
+            NotNull: col.spIsNotNull ? 'ADDED' : 'REMOVED',
+            Removed: false,
+            ToType: col.spDataType,
+          }
+          break
         }
-      },
+      }
     })
-  }
 
-  dropColumn(element: any) {
-    let colName = element.get('spColName').value
-    let updateData: IUpdateTable = { UpdateCols: {} }
-    this.rowArray.value.forEach((col: IColumnTabData, i: number) => {
-      updateData.UpdateCols[this.localTableData[i].spColName] = {
+    this.droppedColumns.forEach((col: IColumnTabData) => {
+      updateData.UpdateCols[col.spColName] = {
+        Add: false,
         Rename: '',
         NotNull: '',
-        PK: '',
-        Removed: col.spColName === colName ? true : false,
+        Removed: true,
         ToType: '',
       }
     })
-    this.data.updateTable(this.currentObject!.name, updateData).subscribe({
+
+    this.data.reviewTableUpdate(this.currentObject!.name, updateData).subscribe({
       next: (res: string) => {
         if (res == '') {
-          this.data.getDdl()
-          this.snackbar.openSnackBar(`${colName} column dropped successfully`, 'Close', 5)
+          this.sidenav.openSidenav()
+          this.sidenav.setSidenavComponent('reviewChanges')
+          this.tableUpdatePubSub.setTableUpdateDetail({
+            tableName: this.currentObject!.name,
+            updateDetail: updateData,
+          })
+          this.isEditMode = true
         } else {
           this.dialog.open(InfodialogComponent, {
             data: { message: res, type: 'error' },
@@ -276,6 +314,53 @@ export class ObjectDetailComponent implements OnInit {
     })
   }
 
+  setColumn(columnName: string) {
+    this.addedColumnName = columnName
+  }
+
+  addColumn() {
+    let index = this.tableData.map((item) => item.srcColName).indexOf(this.addedColumnName)
+
+    let addedRowIndex = this.droppedColumns
+      .map((item) => item.srcColName)
+      .indexOf(this.addedColumnName)
+    this.tableData[index].spColName = this.droppedColumns[addedRowIndex].spColName
+    this.tableData[index].spDataType = this.droppedColumns[addedRowIndex].spDataType
+    this.tableData[index].spOrder = -1
+    this.tableData[index].spIsPk = this.droppedColumns[addedRowIndex].spIsPk
+    this.tableData[index].spIsNotNull = this.droppedColumns[addedRowIndex].spIsNotNull
+    let ind = this.droppedColumns
+      .map((col: IColumnTabData) => col.spColName)
+      .indexOf(this.addedColumnName)
+    if (ind > -1) {
+      this.droppedColumns.splice(ind, 1)
+    }
+    this.setSpTableRows()
+  }
+
+  dropColumn(element: any) {
+    let colName = element.get('srcColName').value
+    this.spRowArray.value.forEach((col: IColumnTabData, i: number) => {
+      if (col.srcColName === colName) {
+        this.droppedColumns.push(col)
+      }
+    })
+    this.dropColumnFromUI(colName)
+  }
+
+  dropColumnFromUI(colName: string) {
+    this.localTableData.forEach((col: IColumnTabData, i: number) => {
+      if (colName == col.srcColName) {
+        col.spColName = col.spColName
+        col.spDataType = ''
+        col.spIsNotNull = false
+        col.spIsPk = false
+        col.spOrder = ''
+      }
+    })
+    this.setSpTableRows()
+  }
+
   updateSpTableSuggestion() {
     this.isSpTableSuggesstionDisplay = []
     this.spTableSuggestion = []
@@ -439,7 +524,7 @@ export class ObjectDetailComponent implements OnInit {
           let index = this.conv.SpSchema[this.currentObject!.name].Pks.map(
             (item) => item.Col
           ).indexOf(pk.spColName)
-          pk.spOrder = this.conv.SpSchema[this.currentObject!.name].Pks[index].Order
+          pk.spOrder = this.conv.SpSchema[this.currentObject!.name].Pks[index]?.Order
         }
       })
     } else {
@@ -470,6 +555,7 @@ export class ObjectDetailComponent implements OnInit {
         })
       })
     }
+
     if (arr[0] == 0 && arr[arr.length - 1] <= arr.length) {
       let missingOrder: number
       for (let i = 0; i < arr.length; i++) {
@@ -516,6 +602,7 @@ export class ObjectDetailComponent implements OnInit {
       this.localTableData = JSON.parse(JSON.stringify(this.tableData))
       this.pkData = this.conversion.getPkMapping(this.tableData)
       this.setAddPkColumnList()
+      this.setPkOrder()
       this.setPkRows()
       this.isPkEditMode = false
     } else {
@@ -540,8 +627,34 @@ export class ObjectDetailComponent implements OnInit {
         data: { message: 'Add columns to the primary key for saving', type: 'error' },
         maxWidth: '500px',
       })
+    } else {
+      let interleaveTable = this.tableInterleaveWith(this.currentObject?.name!)
+      if (interleaveTable != '' && this.isPKFirstOrderModified(this.currentObject?.name!)) {
+        const dialogRef = this.dialog.open(InfodialogComponent, {
+          data: {
+            message:
+              'Proceeding the update will remove interleaving between ' +
+              this.currentObject?.name +
+              ' and ' +
+              interleaveTable +
+              ' tables.',
+            title: 'Confirm Update',
+            type: 'warning',
+          },
+          maxWidth: '500px',
+        })
+        dialogRef.afterClosed().subscribe((dialogResult) => {
+          if (dialogResult) {
+            this.updatePk()
+          }
+        })
+      } else {
+        this.updatePk()
+      }
     }
+  }
 
+  updatePk() {
     this.isPkEditMode = false
     this.data.updatePk(this.pkObj).subscribe({
       next: (res: string) => {
@@ -583,6 +696,28 @@ export class ObjectDetailComponent implements OnInit {
     this.setPkRows()
   }
 
+  setFkRows() {
+    this.fkArray = new FormArray([])
+    this.fkData.forEach((fk) => {
+      this.fkArray.push(
+        new FormGroup({
+          spName: new FormControl(fk.spName, [
+            Validators.required,
+            Validators.pattern('^[a-zA-Z]([a-zA-Z0-9/_]*[a-zA-Z0-9])?'),
+          ]),
+          srcName: new FormControl(fk.srcName),
+          spColumns: new FormControl(fk.spColumns),
+          srcColumns: new FormControl(fk.srcColumns),
+          spReferTable: new FormControl(fk.spReferTable),
+          srcReferTable: new FormControl(fk.srcReferTable),
+          spReferColumns: new FormControl(fk.spReferColumns),
+          srcReferColumns: new FormControl(fk.srcReferColumns),
+        })
+      )
+    })
+    this.fkDataSource = this.fkArray.controls
+  }
+
   toggleFkEdit() {
     this.currentTabIndex = 2
     if (this.isFkEditMode) {
@@ -672,7 +807,7 @@ export class ObjectDetailComponent implements OnInit {
   }
 
   setIndexRows() {
-    this.rowArray = new FormArray([])
+    this.spRowArray = new FormArray([])
     const addedIndexColumns: string[] = this.localIndexData
       .map((data) => (data.spColName ? data.spColName : ''))
       .filter((name) => name != '')
@@ -685,9 +820,8 @@ export class ObjectDetailComponent implements OnInit {
         }
       }
     )
-
     this.localIndexData.forEach((row: IIndexData) => {
-      this.rowArray.push(
+      this.spRowArray.push(
         new FormGroup({
           srcOrder: new FormControl(row.srcOrder),
           srcColName: new FormControl(row.srcColName),
@@ -701,11 +835,11 @@ export class ObjectDetailComponent implements OnInit {
         })
       )
     })
-    this.dataSource = this.rowArray.controls
+    this.spDataSource = this.spRowArray.controls
   }
 
   setIndexOrder() {
-    this.rowArray.value.forEach((idx: IIndexData) => {
+    this.spRowArray.value.forEach((idx: IIndexData) => {
       for (let i = 0; i < this.localIndexData.length; i++) {
         if (idx.spColName != '' && idx.spColName == this.localIndexData[i].spColName) {
           this.localIndexData[i].spOrder = idx.spOrder
@@ -893,4 +1027,35 @@ export class ObjectDetailComponent implements OnInit {
   tabChanged(tabChangeEvent: MatTabChangeEvent): void {
     this.currentTabIndex = tabChangeEvent.index
   }
+
+  tableInterleaveWith(table: string): string {
+    if (this.conv.SpSchema[table].Parent != '') {
+      return this.conv.SpSchema[table].Parent
+    }
+    let interleaveTable = ''
+    Object.keys(this.conv.SpSchema).forEach((tableName: string) => {
+      if (
+        this.conv.SpSchema[tableName].Parent != '' &&
+        this.conv.SpSchema[tableName].Parent == table
+      ) {
+        interleaveTable = tableName
+      }
+    })
+
+    return interleaveTable
+  }
+
+  isPKFirstOrderModified(table: string): boolean {
+    let firstOrderPk = this.conv.SpSchema[table].Pks.filter((pk: IIndexKey) => {
+      if (pk.Order == 1) return true
+      return false
+    })[0]
+    if (this.pkObj.Columns.length < 1) return true
+    let updatedFirstOrderPk = this.pkObj.Columns.filter((pk: IPkColumnDefs) => {
+      if (pk.Order == 1) return true
+      return false
+    })[0]
+    if (firstOrderPk.Col != updatedFirstOrderPk.ColName) return true
+    return false
+  }
 }
diff --git a/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.html b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.html
new file mode 100644
index 0000000..2567516
--- /dev/null
+++ b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.html
@@ -0,0 +1,29 @@
+<div class="sidenav">
+  <div class="sidenav-header">
+    <span class="header-title">Review changes to your schema</span>
+    <button class="close-button" mat-icon-button color="primary" (click)="closeSidenav()">
+      <mat-icon class="close-icon">close</mat-icon>
+    </button>
+  </div>
+  <mat-divider></mat-divider>
+  <div class="sidenav-content">
+    <p *ngIf="showDdl">Review the DDL changes below.</p>
+    <p *ngIf="!showDdl">
+      Changing an interleaved table will have an impact on the following tables :
+      <b>{{ tableList }}</b>
+    </p>
+    <div *ngIf="showDdl" class="ddl-display">
+      <pre><code>{{ddl}}</code></pre>
+    </div>
+    <div *ngIf="!showDdl" class="table-changes-display">
+      <ng-container *ngFor="let key of tableChanges; let i = index">
+        <h4>{{ tableNames[i] }}</h4>
+        <app-table-column-changes-preview [tableChange]="key"></app-table-column-changes-preview>
+      </ng-container>
+    </div>
+  </div>
+  <mat-divider></mat-divider>
+  <div class="sidenav-footer">
+    <button (click)="updateTable()" mat-raised-button color="primary">Confirm Conversion</button>
+  </div>
+</div>
diff --git a/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.scss b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.scss
new file mode 100644
index 0000000..ad02482
--- /dev/null
+++ b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.scss
@@ -0,0 +1,13 @@
+.sidenav-content {
+  height: 82%;
+  .ddl-display {
+    height: 90%;
+    background-color: rgb(218, 218, 218);
+    padding: 10px;
+    overflow: auto;
+  }
+  .table-changes-display {
+    height: 90%;
+    overflow: auto;
+  }
+}
diff --git a/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.spec.ts b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.spec.ts
new file mode 100644
index 0000000..db094a1
--- /dev/null
+++ b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.spec.ts
@@ -0,0 +1,24 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing'
+
+import { SidenavReviewChangesComponent } from './sidenav-review-changes.component'
+
+describe('SidenavReviewChangesComponent', () => {
+  let component: SidenavReviewChangesComponent
+  let fixture: ComponentFixture<SidenavReviewChangesComponent>
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [SidenavReviewChangesComponent],
+    }).compileComponents()
+  })
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SidenavReviewChangesComponent)
+    component = fixture.componentInstance
+    fixture.detectChanges()
+  })
+
+  it('should create', () => {
+    expect(component).toBeTruthy()
+  })
+})
diff --git a/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.ts b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.ts
new file mode 100644
index 0000000..14406fa
--- /dev/null
+++ b/ui/src/app/components/sidenav-review-changes/sidenav-review-changes.component.ts
@@ -0,0 +1,77 @@
+import { Component, OnInit } from '@angular/core'
+import IUpdateTable, { IReviewInterleaveTableChanges } from 'src/app/model/update-table'
+import { DataService } from 'src/app/services/data/data.service'
+import { SidenavService } from 'src/app/services/sidenav/sidenav.service'
+import { SnackbarService } from 'src/app/services/snackbar/snackbar.service'
+import { TableUpdatePubSubService } from 'src/app/services/table-update-pub-sub/table-update-pub-sub.service'
+
+@Component({
+  selector: 'app-sidenav-review-changes',
+  templateUrl: './sidenav-review-changes.component.html',
+  styleUrls: ['./sidenav-review-changes.component.scss'],
+})
+export class SidenavReviewChangesComponent implements OnInit {
+  ddl: string = ''
+  showDdl: boolean = true
+  tableUpdateData: { tableName: string; updateDetail: IUpdateTable } = {
+    tableName: '',
+    updateDetail: { UpdateCols: {} },
+  }
+  tableChanges: IReviewInterleaveTableChanges[] = []
+  tableNames: string[] = []
+  tableList: string = ''
+
+  constructor(
+    private sidenav: SidenavService,
+    private tableUpdatePubSub: TableUpdatePubSubService,
+    private data: DataService,
+    private snackbar: SnackbarService
+  ) {}
+
+  ngOnInit(): void {
+    this.tableUpdatePubSub.reviewTableChanges.subscribe((data) => {
+      if (data.Changes && data.Changes.length > 0) {
+        this.showDdl = false
+        this.tableChanges = data.Changes
+        const updatedTableNames: string[] = []
+        this.tableList = ''
+        this.tableChanges.forEach((data, index) => {
+          updatedTableNames.push(data.Table)
+          if (index == 0) {
+            this.tableList += data.Table
+          } else {
+            this.tableList += ', ' + data.Table
+          }
+        })
+        this.tableList += '.'
+        this.tableNames = updatedTableNames
+      } else {
+        this.showDdl = true
+        this.ddl = data.DDL
+      }
+    })
+    this.tableUpdatePubSub.tableUpdateDetail.subscribe((data) => {
+      this.tableUpdateData = data
+    })
+  }
+
+  updateTable() {
+    this.data
+      .updateTable(this.tableUpdateData.tableName, this.tableUpdateData.updateDetail)
+      .subscribe({
+        next: (res: string) => {
+          if (res == '') {
+            this.snackbar.openSnackBar('Table updated successfully', 'Close', 5)
+            this.closeSidenav()
+          } else {
+            this.snackbar.openSnackBar(res, 'Close', 5)
+          }
+        },
+      })
+  }
+
+  closeSidenav(): void {
+    this.ddl = ''
+    this.sidenav.closeSidenav()
+  }
+}
diff --git a/ui/src/app/components/sidenav-rule/sidenav-rule.component.html b/ui/src/app/components/sidenav-rule/sidenav-rule.component.html
index f0b3d37..6cc958c 100644
--- a/ui/src/app/components/sidenav-rule/sidenav-rule.component.html
+++ b/ui/src/app/components/sidenav-rule/sidenav-rule.component.html
@@ -1,11 +1,11 @@
-<div class="sidenav-container">
+<div class="sidenav">
   <div class="sidenav-header">
     <span class="header-title">Add rule</span>
     <button class="close-button" mat-icon-button color="primary" (click)="closeSidenav()">
       <mat-icon class="close-icon">close</mat-icon>
     </button>
   </div>
-  <div class="form-container">
+  <div class="sidenav-content">
     <form [formGroup]="ruleForm">
       <h3>Rule info</h3>
       <mat-form-field
diff --git a/ui/src/app/components/sidenav-rule/sidenav-rule.component.scss b/ui/src/app/components/sidenav-rule/sidenav-rule.component.scss
index 89e5e36..fe0d2d4 100644
--- a/ui/src/app/components/sidenav-rule/sidenav-rule.component.scss
+++ b/ui/src/app/components/sidenav-rule/sidenav-rule.component.scss
@@ -1,34 +1,6 @@
-.sidenav-container {
-  width: 100%;
-  .sidenav-header {
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    height: 48px;
-    box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.12);
-    margin-bottom: 1px;
-    .header-title {
-      margin-left: 16px;
-      font-size: 1rem;
-      letter-spacing: 0.05px;
-    }
-    .close-button {
-      margin-right: 10px;
-      background-color: inherit;
-    }
-  }
-  .form-container {
-    padding: 15px 25px;
-    h3 {
-      margin-bottom: 0;
-    }
-    mat-form-field {
-      width: 100%;
-      padding-top: 0;
-      padding-bottom: 0;
-    }
-    ::ng-deep .mat-form-field-wrapper {
-      padding-bottom: 14px;
-    }
-  }
+mat-form-field {
+  padding-bottom: 0;
+}
+::ng-deep .mat-form-field-wrapper {
+  padding-bottom: 14px;
 }
diff --git a/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.html b/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.html
index 8a23a98..cc97a5c 100644
--- a/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.html
+++ b/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.html
@@ -1,11 +1,11 @@
-<div class="container">
-  <div class="header">
-    <span class="mat-h3 header-title">Save Session</span>
+<div class="sidenav">
+  <div class="sidenav-header">
+    <span class="header-title">Save Session</span>
     <button class="close-button" mat-icon-button color="primary" (click)="closeSidenav()">
       <mat-icon class="close-icon">close</mat-icon>
     </button>
   </div>
-  <div class="form-container">
+  <div class="sidenav-content">
     <h3>Session Details</h3>
     <form [formGroup]="saveSessionForm" class="save-session-form">
       <mat-form-field
@@ -52,7 +52,7 @@
     </form>
   </div>
 
-  <div class="save-button-container">
+  <div class="sidenav-footer">
     <button
       mat-raised-button
       (click)="saveSession()"
diff --git a/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.scss b/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.scss
index da41e51..98f094d 100644
--- a/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.scss
+++ b/ui/src/app/components/sidenav-save-session/sidenav-save-session.component.scss
@@ -1,26 +1,3 @@
-.container{
-    .header{
-        padding:5px 20px;
-        display: flex;
-        flex-direction: row;
-        justify-content: space-between;
-        align-items: center;
-        border-bottom: 1px solid rgb(208, 204, 204);
-        .header-title{
-            margin:0;
-        }
-    }
-    .form-container{
-        padding:15px 25px;
-        .mat-form-field {
-            width: 100%;
-            padding-top: 0;
-            padding-bottom: 10px;
-        }
-    }
-    .save-button-container{
-        padding:15px;
-        display: flex;
-        justify-content: flex-end;
-    }
-}
\ No newline at end of file
+.mat-form-field {
+  padding-bottom: 10px;
+}
diff --git a/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.html b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.html
new file mode 100644
index 0000000..7227a4a
--- /dev/null
+++ b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.html
@@ -0,0 +1,24 @@
+<table mat-table [dataSource]="dataSource" class="object-full-width margin-bot-1">
+  <ng-container matColumnDef="ColumnName">
+    <th mat-header-cell *matHeaderCellDef>Column</th>
+    <td mat-cell *matCellDef="let element">{{ element.ColumnName }}</td>
+  </ng-container>
+
+  <ng-container matColumnDef="Type">
+    <th mat-header-cell *matHeaderCellDef>Type</th>
+    <td mat-cell *matCellDef="let element">{{ element.Type }}</td>
+  </ng-container>
+
+  <ng-container matColumnDef="UpdateColumnName">
+    <th mat-header-cell *matHeaderCellDef>Updated Column</th>
+    <td mat-cell *matCellDef="let element">{{ element.UpdateColumnName }}</td>
+  </ng-container>
+
+  <ng-container matColumnDef="UpdateType">
+    <th mat-header-cell *matHeaderCellDef>Updated Type</th>
+    <td mat-cell *matCellDef="let element">{{ element.UpdateType }}</td>
+  </ng-container>
+
+  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
+  <tr mat-row *matRowDef="let row; columns: displayedColumns"></tr>
+</table>
diff --git a/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.scss b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.scss
new file mode 100644
index 0000000..8c8e8ef
--- /dev/null
+++ b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.scss
@@ -0,0 +1,21 @@
+.margin-bot-1{
+  margin-bottom: 1rem;
+}
+
+.mat-header-row {
+  background-color: #f5f5f5;
+}
+.mat-column-ColumnName,
+.mat-column-UpdateColumnName {
+  width: 30%;
+  max-width: 30%;
+}
+.mat-column-Type,
+.mat-column-UpdateType {
+  width: 20%;
+  max-width: 20%;
+}
+.mat-cell {
+  padding-right: 1rem;
+  word-break: break-all;
+}
diff --git a/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.spec.ts b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.spec.ts
new file mode 100644
index 0000000..924347f
--- /dev/null
+++ b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { TableColumnChangesPreviewComponent } from './table-column-changes-preview.component';
+
+describe('TableColumnChangesPreviewComponent', () => {
+  let component: TableColumnChangesPreviewComponent;
+  let fixture: ComponentFixture<TableColumnChangesPreviewComponent>;
+
+  beforeEach(async () => {
+    await TestBed.configureTestingModule({
+      declarations: [ TableColumnChangesPreviewComponent ]
+    })
+    .compileComponents();
+  });
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(TableColumnChangesPreviewComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.ts b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.ts
new file mode 100644
index 0000000..d2fd795
--- /dev/null
+++ b/ui/src/app/components/table-column-changes-preview/table-column-changes-preview.component.ts
@@ -0,0 +1,21 @@
+import { Component, Input, OnInit, SimpleChanges } from '@angular/core'
+import { IReviewInterleaveTableChanges, ITableColumnChanges } from 'src/app/model/update-table'
+
+@Component({
+  selector: 'app-table-column-changes-preview',
+  templateUrl: './table-column-changes-preview.component.html',
+  styleUrls: ['./table-column-changes-preview.component.scss'],
+})
+export class TableColumnChangesPreviewComponent implements OnInit {
+  @Input() tableChange: IReviewInterleaveTableChanges = { InterleaveColumnChanges: [], Table: '' }
+  dataSource: ITableColumnChanges[] = []
+  displayedColumns: string[] = ['ColumnName', 'Type', 'UpdateColumnName', 'UpdateType']
+
+  constructor() {}
+
+  ngOnInit(): void {}
+  ngOnChanges(changes: SimpleChanges): void {
+    this.tableChange = changes['tableChange']?.currentValue || this.tableChange
+    this.dataSource = this.tableChange.InterleaveColumnChanges
+  }
+}
diff --git a/ui/src/app/model/update-table.ts b/ui/src/app/model/update-table.ts
index 2b07a21..8490328 100644
--- a/ui/src/app/model/update-table.ts
+++ b/ui/src/app/model/update-table.ts
@@ -1,10 +1,21 @@
 interface IUpdateCol {
+  Add: boolean
   Removed: boolean
   Rename: string
-  PK: string
   NotNull: string
   ToType: string
 }
+export interface ITableColumnChanges {
+  ColumnId: string
+  ColumnName: string
+  Type: string
+  UpdateColumnName: string
+  UpdateType: string
+}
+export interface IReviewInterleaveTableChanges {
+  InterleaveColumnChanges: ITableColumnChanges[]
+  Table: string
+}
 export interface IUpdateTableArgument {
   text: string
   order: string
@@ -13,3 +24,8 @@ export interface IUpdateTableArgument {
 export default interface IUpdateTable {
   UpdateCols: { [key: string]: IUpdateCol }
 }
+
+export interface IReviewUpdateTable {
+  Changes: IReviewInterleaveTableChanges[]
+  DDL: string
+}
diff --git a/ui/src/app/services/conversion/conversion.service.ts b/ui/src/app/services/conversion/conversion.service.ts
index b267964..88bac7e 100644
--- a/ui/src/app/services/conversion/conversion.service.ts
+++ b/ui/src/app/services/conversion/conversion.service.ts
@@ -1,6 +1,12 @@
 import { Injectable } from '@angular/core'
 import ISchemaObjectNode from 'src/app/model/schema-object-node'
-import IConv, { ICreateIndex, IIndexKey, IIndex, ISpannerForeignKey } from '../../model/conv'
+import IConv, {
+  ICreateIndex,
+  IIndexKey,
+  IIndex,
+  ISpannerForeignKey,
+  IColumnDef,
+} from '../../model/conv'
 import IColumnTabData, { IIndexData } from '../../model/edit-table'
 import IFkTabData from 'src/app/model/fk-tab-data'
 import { ObjectExplorerNodeType } from 'src/app/app.constants'
@@ -210,7 +216,7 @@ export class ConversionService {
         }
         let spannerColDef = spTableName ? data.SpSchema[spTableName]?.ColDefs[spColName] : null
         return {
-          spOrder: spPkOrder ? Number(spPkOrder) : i + 1,
+          spOrder: spannerColDef ? i + 1 : '',
           srcOrder: i + 1,
           spColName: spannerColDef ? spColName : '',
           spDataType: spannerColDef ? spannerColDef.T.Name : '',
@@ -367,6 +373,16 @@ export class ConversionService {
     return res
   }
 
+  getSpannerColDefFromId(tableName: string, id: string, data: IConv): IColumnDef | null {
+    let res: IColumnDef | null = null
+    Object.keys(data.SpSchema[tableName].ColDefs).forEach((colName) => {
+      if (data.SpSchema[tableName].ColDefs[colName].Id == id) {
+        res = data.SpSchema[tableName].ColDefs[colName]
+      }
+    })
+    return res
+  }
+
   getSourceTableNameFromId(id: string, conv: IConv): string {
     let srcName: string = ''
     Object.keys(conv.SrcSchema).forEach((key: string) => {
diff --git a/ui/src/app/services/data/data.service.ts b/ui/src/app/services/data/data.service.ts
index dd31eec..e034ccc 100644
--- a/ui/src/app/services/data/data.service.ts
+++ b/ui/src/app/services/data/data.service.ts
@@ -7,12 +7,12 @@ import { catchError, filter, map, tap } from 'rxjs/operators'
 import IUpdateTable from 'src/app/model/update-table'
 import IDumpConfig from 'src/app/model/dump-config'
 import ISessionConfig from '../../model/session-config'
-import { InputType, StorageKeys } from 'src/app/app.constants'
 import ISession from 'src/app/model/session'
 import ISpannerConfig from '../../model/spanner-config'
 import { SnackbarService } from '../snackbar/snackbar.service'
 import ISummary from 'src/app/model/summary'
 import { ClickEventService } from '../click-event/click-event.service'
+import { TableUpdatePubSubService } from '../table-update-pub-sub/table-update-pub-sub.service'
 
 @Injectable({
   providedIn: 'root',
@@ -50,7 +50,8 @@ export class DataService {
   constructor(
     private fetch: FetchService,
     private snackbar: SnackbarService,
-    private clickEvent: ClickEventService
+    private clickEvent: ClickEventService,
+    private tableUpdatePubSub: TableUpdatePubSubService
   ) {
     this.getLastSessionDetails()
     this.getConfig()
@@ -163,6 +164,23 @@ export class DataService {
     })
   }
 
+  reviewTableUpdate(tableName: string, data: IUpdateTable): Observable<string> {
+    return this.fetch.reviewTableUpdate(tableName, data).pipe(
+      catchError((e: any) => {
+        return of({ error: e.error })
+      }),
+      tap(console.log),
+      map((data: any) => {
+        if (data.error) {
+          return data.error
+        } else {
+          this.tableUpdatePubSub.setTableReviewChanges(data)
+          return ''
+        }
+      })
+    )
+  }
+
   updateTable(tableName: string, data: IUpdateTable): Observable<string> {
     return this.fetch.updateTable(tableName, data).pipe(
       catchError((e: any) => {
diff --git a/ui/src/app/services/fetch/fetch.service.ts b/ui/src/app/services/fetch/fetch.service.ts
index 885f374..520e2fb 100644
--- a/ui/src/app/services/fetch/fetch.service.ts
+++ b/ui/src/app/services/fetch/fetch.service.ts
@@ -2,15 +2,19 @@ import { HttpClient, HttpResponse } from '@angular/common/http'
 import { Injectable } from '@angular/core'
 import IDbConfig from 'src/app/model/db-config'
 import ISession, { ISaveSessionPayload } from '../../model/session'
-import IUpdateTable from '../../model/update-table'
-import IConv, { ICreateIndex, IInterleaveStatus, IPrimaryKey, ISessionSummary } from '../../model/conv'
+import IUpdateTable, { IReviewUpdateTable } from '../../model/update-table'
+import IConv, {
+  ICreateIndex,
+  IInterleaveStatus,
+  IPrimaryKey,
+  ISessionSummary,
+} from '../../model/conv'
 import IDumpConfig from '../../model/dump-config'
 import ISessionConfig from '../../model/session-config'
 import ISpannerConfig from '../../model/spanner-config'
 import IMigrationDetails, { IGeneratedResources, IProgress } from 'src/app/model/migrate'
 import IConnectionProfile, { ICreateConnectionProfile } from 'src/app/model/profile'
 
-
 @Injectable({
   providedIn: 'root',
 })
@@ -54,14 +58,16 @@ export class FetchService {
   }
 
   getConnectionProfiles(region: string, isSource: boolean) {
-    return this.http.get<IConnectionProfile[]>(`${this.url}/GetConnectionProfiles?region=${region}&source=${isSource}`)
+    return this.http.get<IConnectionProfile[]>(
+      `${this.url}/GetConnectionProfiles?region=${region}&source=${isSource}`
+    )
   }
 
   getGeneratedResources() {
     return this.http.get<IGeneratedResources>(`${this.url}/GetGeneratedResources`)
   }
 
-  getStaticIps(region:string) {
+  getStaticIps(region: string) {
     return this.http.get<string[]>(`${this.url}/GetStaticIps?region=${region}`)
   }
 
@@ -81,6 +87,13 @@ export class FetchService {
     return this.http.get(`${this.url}/typemap`)
   }
 
+  reviewTableUpdate(tableName: string, data: IUpdateTable): any {
+    return this.http.post<HttpResponse<IReviewUpdateTable>>(
+      `${this.url}/typemap/reviewTableSchema?table=${tableName}`,
+      data
+    )
+  }
+
   updateTable(tableName: string, data: IUpdateTable): any {
     return this.http.post<HttpResponse<IConv>>(`${this.url}/typemap/table?table=${tableName}`, data)
   }
@@ -171,7 +184,7 @@ export class FetchService {
   }
 
   migrate(payload: IMigrationDetails) {
-    return this.http.post(`${this.url}/Migrate`,payload)
+    return this.http.post(`${this.url}/Migrate`, payload)
   }
   getProgress() {
     return this.http.get<IProgress>(`${this.url}/GetProgress`)
diff --git a/ui/src/app/services/table-update-pub-sub/table-update-pub-sub.service.spec.ts b/ui/src/app/services/table-update-pub-sub/table-update-pub-sub.service.spec.ts
new file mode 100644
index 0000000..1362e8c
--- /dev/null
+++ b/ui/src/app/services/table-update-pub-sub/table-update-pub-sub.service.spec.ts
@@ -0,0 +1,16 @@
+import { TestBed } from '@angular/core/testing';
+
+import { TableUpdatePubSubService } from './table-update-pub-sub.service';
+
+describe('TableUpdatePubSubService', () => {
+  let service: TableUpdatePubSubService;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({});
+    service = TestBed.inject(TableUpdatePubSubService);
+  });
+
+  it('should be created', () => {
+    expect(service).toBeTruthy();
+  });
+});
diff --git a/ui/src/app/services/table-update-pub-sub/table-update-pub-sub.service.ts b/ui/src/app/services/table-update-pub-sub/table-update-pub-sub.service.ts
new file mode 100644
index 0000000..c5e0e5c
--- /dev/null
+++ b/ui/src/app/services/table-update-pub-sub/table-update-pub-sub.service.ts
@@ -0,0 +1,25 @@
+import { Injectable } from '@angular/core'
+import { BehaviorSubject } from 'rxjs'
+import IUpdateTable, { IReviewUpdateTable } from 'src/app/model/update-table'
+
+@Injectable({
+  providedIn: 'root',
+})
+export class TableUpdatePubSubService {
+  private reviewTableChangesSub = new BehaviorSubject<IReviewUpdateTable>({ Changes: [], DDL: '' })
+  private tableUpdateDetailSub = new BehaviorSubject<{
+    tableName: string
+    updateDetail: IUpdateTable
+  }>({ tableName: '', updateDetail: { UpdateCols: {} } })
+
+  constructor() {}
+  reviewTableChanges = this.reviewTableChangesSub.asObservable()
+  tableUpdateDetail = this.tableUpdateDetailSub.asObservable()
+
+  setTableReviewChanges(data: IReviewUpdateTable) {
+    this.reviewTableChangesSub.next(data)
+  }
+  setTableUpdateDetail(data: { tableName: string; updateDetail: IUpdateTable }) {
+    this.tableUpdateDetailSub.next(data)
+  }
+}
diff --git a/ui/src/styles.scss b/ui/src/styles.scss
index a48a077..a1e065f 100644
--- a/ui/src/styles.scss
+++ b/ui/src/styles.scss
@@ -82,7 +82,7 @@ body {
   color: red;
 }
 .copy {
-  color:cornflowerblue;
+  color: cornflowerblue;
   margin-left: 40%;
 }
 
@@ -183,3 +183,63 @@ body {
   text-align: center;
   padding-left: 20vw;
 }
+
+.object-display-flex {
+  display: flex;
+  flex-direction: row;
+}
+
+.object-full-width {
+  width: 100%;
+}
+
+.dialog-container {
+  .dialog-message {
+    padding-top: 1rem;
+    padding-bottom: 1rem;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+  .dialog-action {
+    display: flex;
+    justify-content: flex-end;
+  }
+}
+
+.sidenav {
+  box-sizing: border-box;
+  height: 100%;
+  .sidenav-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    height: 48px;
+    box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.12);
+    margin-bottom: 1px;
+    .header-title {
+      margin-left: 25px;
+      font-size: 1rem;
+      letter-spacing: 0.05px;
+    }
+    .close-button {
+      margin-right: 10px;
+      background-color: inherit;
+    }
+  }
+  .sidenav-content {
+    padding: 15px 25px;
+    h3 {
+      margin-bottom: 0;
+    }
+    mat-form-field {
+      width: 100%;
+      padding-top: 0;
+    }
+  }
+  .sidenav-footer {
+    padding: 1rem;
+    display: flex;
+    justify-content: flex-end;
+  }
+}
diff --git a/webv2/table/rename_column.go b/webv2/table/rename_column.go
index 21e43fe..5161a2c 100644
--- a/webv2/table/rename_column.go
+++ b/webv2/table/rename_column.go
@@ -22,19 +22,12 @@ import (
 // renameColumn renames given column to newname and update in schema.
 func renameColumn(newName, table, colName string, conv *internal.Conv) {
 
-	sp := conv.SpSchema[table]
-
 	renameColumnNameTableSchema(conv, table, colName, newName)
 
-	// update foreignKey relationship Table.
-	for _, fk := range sp.Fks {
-		renameColumnNameTableSchema(conv, fk.ReferTable, colName, newName)
-	}
-
-	for _, sp := range conv.SpSchema {
+	for k, sp := range conv.SpSchema {
 		for j := 0; j < len(sp.Fks); j++ {
 			if sp.Fks[j].ReferTable == table {
-				renameColumnNameTableSchema(conv, sp.Name, colName, newName)
+				renameColumnNameInSpannerForeignkeyReferColumns(conv.SpSchema[k], colName, newName)
 			}
 		}
 	}
@@ -63,8 +56,6 @@ func renameColumnNameTableSchema(conv *internal.Conv, table string, colName stri
 
 	sp = renameColumnNameInSpannerForeignkeyColumns(sp, colName, newName)
 
-	sp = renameColumnNameInSpannerForeignkeyReferColumns(sp, colName, newName)
-
 	sp = renameColumnNameInSpannerColNames(sp, colName, newName)
 
 	renameColumnNameInSpannerSchemaIssue(table, colName, newName, conv)
diff --git a/webv2/table/review_rename_column.go b/webv2/table/review_rename_column.go
index d89fb6b..c77f377 100644
--- a/webv2/table/review_rename_column.go
+++ b/webv2/table/review_rename_column.go
@@ -25,27 +25,13 @@ func reviewRenameColumn(newName, table, colName string, conv *internal.Conv, int
 
 	columnId := sp.ColDefs[colName].Id
 
-	// update column name for refer tables.
-	for _, fk := range sp.Fks {
-		reviewRenameColumnNameTableSchema(conv, fk.ReferTable, colName, newName)
-	}
-
-	// update column name for table which are referring to the current table.
-	for _, sp := range conv.SpSchema {
-		for j := 0; j < len(sp.Fks); j++ {
-			if sp.Fks[j].ReferTable == table {
-				reviewRenameColumnNameTableSchema(conv, sp.Name, colName, newName)
-			}
-		}
-	}
-
 	// review column name update for interleaved child.
 	isParent, childTableName := IsParent(table)
 
 	if isParent {
 		reviewRenameColumnNameTableSchema(conv, childTableName, colName, newName)
-		if _, ok := conv.SpSchema[childTableName].ColDefs[colName]; ok {
-			childColumnId := conv.SpSchema[childTableName].ColDefs[colName].Id
+		if _, ok := conv.SpSchema[childTableName].ColDefs[newName]; ok {
+			childColumnId := conv.SpSchema[childTableName].ColDefs[newName].Id
 			interleaveTableSchema = renameInterleaveTableSchema(interleaveTableSchema, childTableName, childColumnId, colName, newName)
 		}
 	}
@@ -55,8 +41,8 @@ func reviewRenameColumn(newName, table, colName string, conv *internal.Conv, int
 
 	if parentTableName != "" {
 		reviewRenameColumnNameTableSchema(conv, parentTableName, colName, newName)
-		if _, ok := conv.SpSchema[parentTableName].ColDefs[colName]; ok {
-			parentColumnId := conv.SpSchema[parentTableName].ColDefs[colName].Id
+		if _, ok := conv.SpSchema[parentTableName].ColDefs[newName]; ok {
+			parentColumnId := conv.SpSchema[parentTableName].ColDefs[newName].Id
 			interleaveTableSchema = renameInterleaveTableSchema(interleaveTableSchema, parentTableName, parentColumnId, colName, newName)
 		}
 	}
@@ -82,7 +68,6 @@ func reviewRenameColumnNameTableSchema(conv *internal.Conv, tableName, colName,
 			sp = renameColumnNameInSpannerPK(sp, colName, newName)
 			sp = renameColumnNameInSpannerSecondaryIndex(sp, colName, newName)
 			sp = renameColumnNameInSpannerForeignkeyColumns(sp, colName, newName)
-			sp = renameColumnNameInSpannerForeignkeyReferColumns(sp, colName, newName)
 			sp = renameColumnNameInSpannerColNames(sp, colName, newName)
 			renameColumnNameInToSpannerToSource(tableName, colName, newName, conv)
 			renameColumnNameInSpannerSchemaIssue(tableName, colName, newName, conv)
diff --git a/webv2/utilities/utilities.go b/webv2/utilities/utilities.go
index 337eced..500ebbe 100644
--- a/webv2/utilities/utilities.go
+++ b/webv2/utilities/utilities.go
@@ -71,14 +71,14 @@ func Difference(listone, listtwo []string) []string {
 }
 
 // IsColumnPresent check string is present in given list.
-func IsColumnPresent(columns []string, col string) string {
+func IsColumnPresent(columns []string, col string) int {
 
-	for _, c := range columns {
+	for i, c := range columns {
 		if c == col {
-			return col
+			return i
 		}
 	}
-	return ""
+	return -1
 }
 
 // RemoveSchemaIssue removes issue from the given list.
@@ -129,6 +129,10 @@ func RemoveSchemaIssues(schemaissue []internal.SchemaIssue) []internal.SchemaIss
 
 	case IsSchemaIssuePresent(schemaissue, internal.InterleavedAddColumn):
 		schemaissue = RemoveSchemaIssue(schemaissue, internal.InterleavedAddColumn)
+		fallthrough
+
+	case IsSchemaIssuePresent(schemaissue, internal.InterleavedRenameColumn):
+		schemaissue = RemoveSchemaIssue(schemaissue, internal.InterleavedRenameColumn)
 	}
 
 	return schemaissue
diff --git a/webv2/web.go b/webv2/web.go
index d5aab75..749b448 100644
--- a/webv2/web.go
+++ b/webv2/web.go
@@ -644,6 +644,18 @@ func setParentTable(w http.ResponseWriter, r *http.Request) {
 		}
 
 		sessionState.Conv.Issues[table][column] = schemaissue
+	} else {
+		// Remove "Table cart can be converted as Interleaved Table" suggestion from columns
+		// of the table if interleaving is not possible.
+		for _, column := range sessionState.Conv.SpSchema[table].ColNames {
+			schemaIssue := []internal.SchemaIssue{}
+			for _, v := range sessionState.Conv.Issues[table][column] {
+				if v != internal.InterleavedOrder {
+					schemaIssue = append(schemaIssue, v)
+				}
+			}
+			sessionState.Conv.Issues[table][column] = schemaIssue
+		}
 	}
 
 	index.IndexSuggestion()
@@ -720,6 +732,7 @@ func parentTableHelper(table string, update bool) *TableInterleaveStatus {
 
 				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedNotInOrder)
 				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedAddColumn)
+				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedRenameColumn)
 				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedOrder)
 
 				sessionState.Conv.Issues[table][column] = schemaissue
@@ -741,6 +754,7 @@ func parentTableHelper(table string, update bool) *TableInterleaveStatus {
 				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedNotInOrder)
 				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedOrder)
 				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedAddColumn)
+				schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedRenameColumn)
 
 				schemaissue = append(schemaissue, internal.InterleavedNotInOrder)
 
@@ -1526,6 +1540,11 @@ func checkPrimaryKeyPrefix(table string, refTable string, fk ddl.Foreignkey, tab
 	childPks := sessionState.Conv.SpSchema[table].Pks
 	parentPks := sessionState.Conv.SpSchema[refTable].Pks
 
+	childPkCols := []string{}
+	for _, k := range childPks {
+		childPkCols = append(childPkCols, k.Col)
+	}
+
 	interleaved := []ddl.IndexKey{}
 
 	for i := 0; i < len(parentPks); i++ {
@@ -1562,52 +1581,64 @@ func checkPrimaryKeyPrefix(table string, refTable string, fk ddl.Foreignkey, tab
 
 	}
 
-	caninterleaved := []string{}
+	canInterleavedOnAdd := []string{}
+	canInterleavedOnRename := []string{}
 	for i := 0; i < len(diff); i++ {
 
-		str := utilities.IsColumnPresent(fk.ReferColumns, diff[i].Col)
+		parentColIndex := utilities.IsColumnPresent(fk.ReferColumns, diff[i].Col)
+		if parentColIndex == -1 {
+			continue
+		}
+		childColIndex := utilities.IsColumnPresent(childPkCols, fk.Columns[parentColIndex])
+		if childColIndex == -1 {
+			canInterleavedOnAdd = append(canInterleavedOnAdd, fk.Columns[parentColIndex])
+		} else {
+			canInterleavedOnRename = append(canInterleavedOnRename, fk.Columns[parentColIndex])
+		}
+	}
 
-		caninterleaved = append(caninterleaved, str)
+	if len(canInterleavedOnRename) > 0 {
+		updateInterleaveSuggestion(canInterleavedOnRename, table, internal.InterleavedRenameColumn)
+	} else if len(canInterleavedOnAdd) > 0 {
+		updateInterleaveSuggestion(canInterleavedOnAdd, table, internal.InterleavedAddColumn)
 	}
 
-	if len(caninterleaved) > 0 {
+	if len(interleaved) > 0 {
+		return true
+	}
 
-		for i := 0; i < len(caninterleaved); i++ {
+	return false
+}
 
-			sessionState := session.GetSessionState()
+func updateInterleaveSuggestion(columns []string, table string, issue internal.SchemaIssue) {
+	for i := 0; i < len(columns); i++ {
 
-			schemaissue := []internal.SchemaIssue{}
+		sessionState := session.GetSessionState()
 
-			schemaissue = sessionState.Conv.Issues[table][caninterleaved[i]]
+		schemaissue := []internal.SchemaIssue{}
 
-			schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedOrder)
-			schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedNotInOrder)
-			schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedAddColumn)
+		schemaissue = sessionState.Conv.Issues[table][columns[i]]
 
-			schemaissue = append(schemaissue, internal.InterleavedAddColumn)
+		schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedOrder)
+		schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedNotInOrder)
+		schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedAddColumn)
+		schemaissue = utilities.RemoveSchemaIssue(schemaissue, internal.InterleavedRenameColumn)
 
-			if len(schemaissue) > 0 {
+		schemaissue = append(schemaissue, issue)
 
-				if sessionState.Conv.Issues[table] == nil {
+		if len(schemaissue) > 0 {
 
-					s := map[string][]internal.SchemaIssue{
-						caninterleaved[i]: schemaissue,
-					}
-					sessionState.Conv.Issues[table] = s
-				} else {
-					sessionState.Conv.Issues[table][caninterleaved[i]] = schemaissue
-				}
+			if sessionState.Conv.Issues[table] == nil {
 
+				s := map[string][]internal.SchemaIssue{
+					columns[i]: schemaissue,
+				}
+				sessionState.Conv.Issues[table] = s
+			} else {
+				sessionState.Conv.Issues[table][columns[i]] = schemaissue
 			}
-
 		}
 	}
-
-	if len(interleaved) > 0 {
-		return true
-	}
-
-	return false
 }
 
 // SessionState stores information for the current migration session.


Test patch:
diff --git a/spanner/ddl/ast_test.go b/spanner/ddl/ast_test.go
index 0a46e14..7dc7f14 100644
--- a/spanner/ddl/ast_test.go
+++ b/spanner/ddl/ast_test.go
@@ -88,7 +88,7 @@ func TestPrintColumnDefPG(t *testing.T) {
 		{in: ColumnDef{Name: "col1", T: Type{Name: Int64, IsArray: true}}, expected: "col1 VARCHAR(2621440)"},
 		{in: ColumnDef{Name: "col1", T: Type{Name: Int64}, NotNull: true}, expected: "col1 INT8 NOT NULL"},
 		{in: ColumnDef{Name: "col1", T: Type{Name: Int64, IsArray: true}, NotNull: true}, expected: "col1 VARCHAR(2621440) NOT NULL"},
-		{in: ColumnDef{Name: "col1", T: Type{Name: Int64}}, protectIds: true, expected: "\"col1\" INT8"},
+		{in: ColumnDef{Name: "col1", T: Type{Name: Int64}}, protectIds: true, expected: "col1 INT8"},
 	}
 	for _, tc := range tests {
 		s, _ := tc.in.PrintColumnDef(Config{ProtectIds: tc.protectIds, TargetDb: constants.TargetExperimentalPostgres})
@@ -106,7 +106,7 @@ func TestPrintIndexKey(t *testing.T) {
 		{in: IndexKey{Col: "col1"}, expected: "col1"},
 		{in: IndexKey{Col: "col1", Desc: true}, expected: "col1 DESC"},
 		{in: IndexKey{Col: "col1"}, protectIds: true, expected: "`col1`"},
-		{in: IndexKey{Col: "col1"}, protectIds: true, targetDb: constants.TargetExperimentalPostgres, expected: "\"col1\""},
+		{in: IndexKey{Col: "col1"}, protectIds: true, targetDb: constants.TargetExperimentalPostgres, expected: "col1"},
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.in.PrintIndexKey(Config{ProtectIds: tc.protectIds, TargetDb: tc.targetDb}))
@@ -231,11 +231,11 @@ func TestPrintCreateTablePG(t *testing.T) {
 			"quote",
 			true,
 			t1,
-			"CREATE TABLE \"mytable\" (\n" +
-				"	\"col1\" INT8 NOT NULL,\n" +
-				"	\"col2\" VARCHAR(2621440),\n" +
-				"	\"col3\" BYTEA,\n" +
-				"	PRIMARY KEY (\"col1\" DESC)\n" +
+			"CREATE TABLE mytable (\n" +
+				"	col1 INT8 NOT NULL,\n" +
+				"	col2 VARCHAR(2621440),\n" +
+				"	col3 BYTEA,\n" +
+				"	PRIMARY KEY (col1 DESC)\n" +
 				")",
 		},
 		{
@@ -283,8 +283,8 @@ func TestPrintCreateIndex(t *testing.T) {
 		{"no quote non unique", false, "", ci[0], "CREATE INDEX myindex ON mytable (col1 DESC, col2)"},
 		{"quote non unique", true, "", ci[0], "CREATE INDEX `myindex` ON `mytable` (`col1` DESC, `col2`)"},
 		{"unique key", true, "", ci[1], "CREATE UNIQUE INDEX `myindex2` ON `mytable` (`col1` DESC, `col2`)"},
-		{"quote non unique PG", true, constants.TargetExperimentalPostgres, ci[0], "CREATE INDEX \"myindex\" ON \"mytable\" (\"col1\" DESC, \"col2\")"},
-		{"unique key PG", true, constants.TargetExperimentalPostgres, ci[1], "CREATE UNIQUE INDEX \"myindex2\" ON \"mytable\" (\"col1\" DESC, \"col2\")"},
+		{"quote non unique PG", true, constants.TargetExperimentalPostgres, ci[0], "CREATE INDEX myindex ON mytable (col1 DESC, col2)"},
+		{"unique key PG", true, constants.TargetExperimentalPostgres, ci[1], "CREATE UNIQUE INDEX myindex2 ON mytable (col1 DESC, col2)"},
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.index.PrintCreateIndex(Config{ProtectIds: tc.protectIds, TargetDb: tc.targetDb}))
@@ -318,7 +318,7 @@ func TestPrintForeignKey(t *testing.T) {
 		{"no quote", false, "", "CONSTRAINT fk_test FOREIGN KEY (c1, c2) REFERENCES ref_table (ref_c1, ref_c2)", fk[0]},
 		{"quote", true, "", "CONSTRAINT `fk_test` FOREIGN KEY (`c1`, `c2`) REFERENCES `ref_table` (`ref_c1`, `ref_c2`)", fk[0]},
 		{"no constraint name", false, "", "FOREIGN KEY (c1) REFERENCES ref_table (ref_c1)", fk[1]},
-		{"quote PG", true, constants.TargetExperimentalPostgres, "CONSTRAINT \"fk_test\" FOREIGN KEY (\"c1\", \"c2\") REFERENCES \"ref_table\" (\"ref_c1\", \"ref_c2\")", fk[0]},
+		{"quote PG", true, constants.TargetExperimentalPostgres, "CONSTRAINT fk_test FOREIGN KEY (c1, c2) REFERENCES ref_table (ref_c1, ref_c2)", fk[0]},
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.fk.PrintForeignKey(Config{ProtectIds: tc.protectIds, TargetDb: tc.targetDb}))
@@ -353,7 +353,7 @@ func TestPrintForeignKeyAlterTable(t *testing.T) {
 		{"no quote", "table1", false, "", "ALTER TABLE table1 ADD CONSTRAINT fk_test FOREIGN KEY (c1, c2) REFERENCES ref_table (ref_c1, ref_c2)", fk[0]},
 		{"quote", "table1", true, "", "ALTER TABLE `table1` ADD CONSTRAINT `fk_test` FOREIGN KEY (`c1`, `c2`) REFERENCES `ref_table` (`ref_c1`, `ref_c2`)", fk[0]},
 		{"no constraint name", "table1", false, "", "ALTER TABLE table1 ADD FOREIGN KEY (c1) REFERENCES ref_table (ref_c1)", fk[1]},
-		{"quote PG", "table1", true, constants.TargetExperimentalPostgres, "ALTER TABLE \"table1\" ADD CONSTRAINT \"fk_test\" FOREIGN KEY (\"c1\", \"c2\") REFERENCES \"ref_table\" (\"ref_c1\", \"ref_c2\")", fk[0]},
+		{"quote PG", "table1", true, constants.TargetExperimentalPostgres, "ALTER TABLE table1 ADD CONSTRAINT fk_test FOREIGN KEY (c1, c2) REFERENCES ref_table (ref_c1, ref_c2)", fk[0]},
 	}
 	for _, tc := range tests {
 		assert.Equal(t, tc.expected, tc.fk.PrintForeignKeyAlterTable(Config{ProtectIds: tc.protectIds, TargetDb: tc.targetDb}, tc.table))