mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 23:47:12 +00:00
test(operator): write more unit tests
This commit is contained in:
parent
e96eb187e4
commit
6edcaeaebc
@ -42,11 +42,42 @@ func (operator *Operator) RenameTable(table *Table, newName TableName) [][]byte
|
||||
}
|
||||
|
||||
func (operator *Operator) AlterTable(oldTable *Table, oldTableUniqueConstraints []*UniqueConstraint, newTable *Table) [][]byte {
|
||||
// The following has to be done in order:
|
||||
// - Drop constraints
|
||||
// - Drop columns (some columns might be part of constraints therefore this depends on Step 1)
|
||||
// - Add columns, then modify columns
|
||||
// - Rename table
|
||||
// - Add constraints (some constraints might be part of columns therefore this depends on Step 3, constraint names also depend on table name which is changed in Step 4)
|
||||
// - Create unique indices from unique constraints for the new table
|
||||
|
||||
sql := [][]byte{}
|
||||
|
||||
// Check if the name has changed
|
||||
if oldTable.Name != newTable.Name {
|
||||
sql = append(sql, operator.RenameTable(oldTable, newTable.Name)...)
|
||||
// Drop primary key constraint if it is in the old table but not in the new table.
|
||||
if oldTable.PrimaryKeyConstraint != nil && newTable.PrimaryKeyConstraint == nil {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, oldTable.PrimaryKeyConstraint)...)
|
||||
}
|
||||
|
||||
// Drop primary key constraint if it is in the old table and the new table but they are different.
|
||||
if oldTable.PrimaryKeyConstraint != nil && newTable.PrimaryKeyConstraint != nil && !oldTable.PrimaryKeyConstraint.Equals(newTable.PrimaryKeyConstraint) {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, newTable.PrimaryKeyConstraint)...)
|
||||
}
|
||||
|
||||
// Drop foreign key constraints that are in the old table but not in the new table.
|
||||
for _, fkConstraint := range oldTable.ForeignKeyConstraints {
|
||||
if index := operator.findForeignKeyConstraint(newTable, fkConstraint); index == -1 {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, fkConstraint)...)
|
||||
}
|
||||
}
|
||||
|
||||
// Drop all unique constraints.
|
||||
for _, uniqueConstraint := range oldTableUniqueConstraints {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, uniqueConstraint)...)
|
||||
}
|
||||
|
||||
// Reduce number of drops for engines with no SCreateAndDropConstraint.
|
||||
if !operator.support.SCreateAndDropConstraint && len(sql) > 0 {
|
||||
// Do not send the unique constraints to recreate table. We will change them to indexes at the end.
|
||||
sql = operator.RecreateTable(oldTable, nil)
|
||||
}
|
||||
|
||||
// Drop columns that are in the old table but not in the new table.
|
||||
@ -64,8 +95,24 @@ func (operator *Operator) AlterTable(oldTable *Table, oldTableUniqueConstraints
|
||||
}
|
||||
|
||||
// Modify columns that are in the new table and in the old table
|
||||
alterColumnSQLs := [][]byte{}
|
||||
for _, column := range newTable.Columns {
|
||||
sql = append(sql, operator.AlterColumn(oldTable, oldTableUniqueConstraints, column)...)
|
||||
alterColumnSQLs = append(alterColumnSQLs, operator.AlterColumn(oldTable, oldTableUniqueConstraints, column)...)
|
||||
}
|
||||
|
||||
// Reduce number of drops for engines with no SAlterTableAlterColumnSetAndDrop.
|
||||
if !operator.support.SAlterTableAlterColumnSetAndDrop && len(alterColumnSQLs) > 0 {
|
||||
// Do not send the unique constraints to recreate table. We will change them to indexes at the end.
|
||||
sql = append(sql, operator.RecreateTable(oldTable, nil)...)
|
||||
}
|
||||
|
||||
if operator.support.SAlterTableAlterColumnSetAndDrop && len(alterColumnSQLs) > 0 {
|
||||
sql = append(sql, alterColumnSQLs...)
|
||||
}
|
||||
|
||||
// Check if the name has changed
|
||||
if oldTable.Name != newTable.Name {
|
||||
sql = append(sql, operator.RenameTable(oldTable, newTable.Name)...)
|
||||
}
|
||||
|
||||
// If the old table does not have a primary key constraint and the new table does, we need to create it.
|
||||
@ -76,19 +123,8 @@ func (operator *Operator) AlterTable(oldTable *Table, oldTableUniqueConstraints
|
||||
}
|
||||
|
||||
if oldTable.PrimaryKeyConstraint != nil {
|
||||
if newTable.PrimaryKeyConstraint == nil {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, oldTable.PrimaryKeyConstraint)...)
|
||||
} else {
|
||||
if !oldTable.PrimaryKeyConstraint.Equals(newTable.PrimaryKeyConstraint) {
|
||||
sql = append(sql, operator.CreateConstraint(oldTable, oldTableUniqueConstraints, newTable.PrimaryKeyConstraint)...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drop foreign key constraints that are in the old table but not in the new table.
|
||||
for _, fkConstraint := range oldTable.ForeignKeyConstraints {
|
||||
if index := operator.findForeignKeyConstraint(newTable, fkConstraint); index == -1 {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, fkConstraint)...)
|
||||
if !oldTable.PrimaryKeyConstraint.Equals(newTable.PrimaryKeyConstraint) {
|
||||
sql = append(sql, operator.CreateConstraint(oldTable, oldTableUniqueConstraints, newTable.PrimaryKeyConstraint)...)
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,12 +135,12 @@ func (operator *Operator) AlterTable(oldTable *Table, oldTableUniqueConstraints
|
||||
}
|
||||
}
|
||||
|
||||
// Drop all unique constraints and create indices for the new table.
|
||||
// Create indices for the new table.
|
||||
for _, uniqueConstraint := range oldTableUniqueConstraints {
|
||||
sql = append(sql, operator.DropConstraint(oldTable, oldTableUniqueConstraints, uniqueConstraint)...)
|
||||
sql = append(sql, uniqueConstraint.ToIndex(oldTable.Name).ToCreateSQL(operator.fmter))
|
||||
}
|
||||
|
||||
// Remove duplicate SQLs.
|
||||
return slices.CompactFunc(sql, func(a, b []byte) bool {
|
||||
return string(a) == string(b)
|
||||
})
|
||||
@ -286,7 +322,11 @@ func (operator *Operator) DropConstraint(table *Table, uniqueConstraints []*Uniq
|
||||
return [][]byte{uniqueConstraints[uniqueConstraintIndex].ToDropSQL(operator.fmter, table.Name)}
|
||||
}
|
||||
|
||||
return operator.RecreateTable(table, append(uniqueConstraints[:uniqueConstraintIndex], uniqueConstraints[uniqueConstraintIndex+1:]...))
|
||||
var copyOfUniqueConstraints []*UniqueConstraint
|
||||
copyOfUniqueConstraints = append(copyOfUniqueConstraints, uniqueConstraints[:uniqueConstraintIndex]...)
|
||||
copyOfUniqueConstraints = append(copyOfUniqueConstraints, uniqueConstraints[uniqueConstraintIndex+1:]...)
|
||||
|
||||
return operator.RecreateTable(table, copyOfUniqueConstraints)
|
||||
}
|
||||
|
||||
if operator.support.SCreateAndDropConstraint {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package sqlschema
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -707,8 +708,7 @@ func TestOperatorAlterTable(t *testing.T) {
|
||||
table *Table
|
||||
uniqueConstraints []*UniqueConstraint
|
||||
newTable *Table
|
||||
support OperatorSupport
|
||||
expectedSQLs [][]byte
|
||||
expected map[OperatorSupport][][]byte
|
||||
}{
|
||||
{
|
||||
name: "NoOperation",
|
||||
@ -725,9 +725,12 @@ func TestOperatorAlterTable(t *testing.T) {
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{},
|
||||
},
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {},
|
||||
},
|
||||
support: OperatorSupport{},
|
||||
expectedSQLs: [][]byte{},
|
||||
},
|
||||
{
|
||||
name: "RenameTable",
|
||||
@ -742,10 +745,15 @@ func TestOperatorAlterTable(t *testing.T) {
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{},
|
||||
},
|
||||
support: OperatorSupport{},
|
||||
expectedSQLs: [][]byte{
|
||||
[]byte(`ALTER TABLE "users" RENAME TO "users_new"`),
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
[]byte(`ALTER TABLE "users" RENAME TO "users_new"`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
[]byte(`ALTER TABLE "users" RENAME TO "users_new"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -764,149 +772,227 @@ func TestOperatorAlterTable(t *testing.T) {
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
{Name: "age", DataType: DataTypeInteger, Nullable: true, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{},
|
||||
},
|
||||
support: OperatorSupport{
|
||||
SAlterTableAddAndDropColumnIfNotExistsAndExists: true,
|
||||
},
|
||||
expectedSQLs: [][]byte{
|
||||
[]byte(`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "age" INTEGER`),
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
[]byte(`ALTER TABLE "users" ADD COLUMN "age" INTEGER`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
[]byte(`ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "age" INTEGER`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AddColumn_NullableNoDefault_SAlterTableAddAndDropColumnIfNotExistsAndExistsFalse",
|
||||
name: "CreatePrimaryKeyConstraint",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{
|
||||
ColumnNames: []ColumnName{"id"},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{},
|
||||
},
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"))`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id") SELECT "id" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
[]byte(`ALTER TABLE "users" ADD CONSTRAINT "pk_users" PRIMARY KEY ("id")`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DropPrimaryKeyConstraint_AlterColumnNullable",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: true, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{ColumnNames: []ColumnName{"id"}},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{},
|
||||
},
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
// first drop to remove the primary key constraint
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT)`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name") SELECT "id", "name" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
// second drop to make the column nullable
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL)`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name") SELECT "id", "name" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "pk_users"`),
|
||||
[]byte(`ALTER TABLE "users" ALTER COLUMN "name" SET NOT NULL`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DropForeignKeyConstraint_DropColumn",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "org_id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{
|
||||
{ReferencingColumnName: "org_id", ReferencedTableName: "orgs", ReferencedColumnName: "id"},
|
||||
},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{},
|
||||
},
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
// first drop to remove the foreign key constraint
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "org_id" INTEGER NOT NULL)`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "org_id") SELECT "id", "org_id" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
// second drop to remove the column
|
||||
[]byte(`ALTER TABLE "users" DROP COLUMN "org_id"`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
// first drop to remove the foreign key constraint
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "fk_users_org_id"`),
|
||||
// second drop to remove the column
|
||||
[]byte(`ALTER TABLE "users" DROP COLUMN IF EXISTS "org_id"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DropMultipleConstraints",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
{Name: "age", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "org_id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "team_id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{ColumnNames: []ColumnName{"id"}},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{
|
||||
{ReferencingColumnName: "org_id", ReferencedTableName: "orgs", ReferencedColumnName: "id"},
|
||||
{ReferencingColumnName: "team_id", ReferencedTableName: "teams", ReferencedColumnName: "id"},
|
||||
},
|
||||
},
|
||||
uniqueConstraints: []*UniqueConstraint{
|
||||
{ColumnNames: []ColumnName{"name", "age"}},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
{Name: "age", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "org_id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "team_id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{
|
||||
{ReferencingColumnName: "team_id", ReferencedTableName: "teams", ReferencedColumnName: "id"},
|
||||
},
|
||||
},
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL, "age" INTEGER NOT NULL, "org_id" INTEGER NOT NULL, "team_id" INTEGER NOT NULL, CONSTRAINT "fk_users_team_id" FOREIGN KEY ("team_id") REFERENCES "teams" ("id"))`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name", "age", "org_id", "team_id") SELECT "id", "name", "age", "org_id", "team_id" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
[]byte(`CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_name_age" ON "users" ("name", "age")`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "pk_users"`),
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "fk_users_org_id"`),
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "uq_users_name_age"`),
|
||||
[]byte(`CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_name_age" ON "users" ("name", "age")`),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DropUniqueConstraints_AlterMultipleColumns",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: true, Default: ""},
|
||||
{Name: "age", DataType: DataTypeInteger, Nullable: true, Default: ""},
|
||||
},
|
||||
},
|
||||
support: OperatorSupport{
|
||||
SAlterTableAddAndDropColumnIfNotExistsAndExists: false,
|
||||
},
|
||||
expectedSQLs: [][]byte{
|
||||
[]byte(`ALTER TABLE "users" ADD COLUMN "age" INTEGER`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "CreatePrimaryKeyConstraint_SCreateAndDropConstraintTrue",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{
|
||||
ColumnNames: []ColumnName{"id"},
|
||||
},
|
||||
},
|
||||
support: OperatorSupport{
|
||||
SCreateAndDropConstraint: true,
|
||||
},
|
||||
expectedSQLs: [][]byte{
|
||||
[]byte(`ALTER TABLE "users" ADD CONSTRAINT "pk_users" PRIMARY KEY ("id")`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "CreatePrimaryKeyConstraint_SCreateAndDropConstrainttFalse",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{
|
||||
ColumnNames: []ColumnName{"id"},
|
||||
},
|
||||
},
|
||||
support: OperatorSupport{
|
||||
SCreateAndDropConstraint: false,
|
||||
},
|
||||
expectedSQLs: [][]byte{
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"))`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id") SELECT "id" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DropPrimaryKeyConstraint_AlterColumnNullable_SAlterTableAddAndDropColumnIfNotExistsAndExistsFalse_SAlterTableAlterColumnSetAndDropFalse_SCreateAndDropConstraintFalse",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: true, Default: ""},
|
||||
{Name: "email", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{ColumnNames: []ColumnName{"id"}},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{
|
||||
{ReferencingColumnName: "org_id", ReferencedTableName: "orgs", ReferencedColumnName: "id"},
|
||||
},
|
||||
},
|
||||
uniqueConstraints: []*UniqueConstraint{
|
||||
{ColumnNames: []ColumnName{"email"}},
|
||||
{name: "my_name_constraint", ColumnNames: []ColumnName{"name"}},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
},
|
||||
},
|
||||
support: OperatorSupport{
|
||||
SAlterTableAddAndDropColumnIfNotExistsAndExists: false,
|
||||
SAlterTableAlterColumnSetAndDrop: false,
|
||||
SCreateAndDropConstraint: false,
|
||||
},
|
||||
expectedSQLs: [][]byte{
|
||||
// first drop to make the column nullable
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"))`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name") SELECT "id", "name" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
// second drop to remove the primary key constraint
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL)`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name") SELECT "id", "name" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "DropPrimaryKeyConstraint_AlterColumnNullable_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropTrue_SCreateAndDropConstraintTrue",
|
||||
table: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: true, Default: ""},
|
||||
{Name: "age", DataType: DataTypeInteger, Nullable: false, Default: "0"},
|
||||
{Name: "email", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
},
|
||||
PrimaryKeyConstraint: &PrimaryKeyConstraint{ColumnNames: []ColumnName{"id"}},
|
||||
},
|
||||
newTable: &Table{
|
||||
Name: "users",
|
||||
Columns: []*Column{
|
||||
{Name: "id", DataType: DataTypeInteger, Nullable: false, Default: ""},
|
||||
{Name: "name", DataType: DataTypeText, Nullable: false, Default: ""},
|
||||
ForeignKeyConstraints: []*ForeignKeyConstraint{
|
||||
{ReferencingColumnName: "org_id", ReferencedTableName: "orgs", ReferencedColumnName: "id"},
|
||||
},
|
||||
},
|
||||
support: OperatorSupport{
|
||||
SAlterTableAddAndDropColumnIfNotExistsAndExists: true,
|
||||
SAlterTableAlterColumnSetAndDrop: true,
|
||||
SCreateAndDropConstraint: true,
|
||||
},
|
||||
expectedSQLs: [][]byte{
|
||||
[]byte(`ALTER TABLE "users" ALTER COLUMN "name" SET NOT NULL`),
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "pk_users"`),
|
||||
expected: map[OperatorSupport][][]byte{
|
||||
{SCreateAndDropConstraint: false, SAlterTableAddAndDropColumnIfNotExistsAndExists: false, SAlterTableAlterColumnSetAndDrop: false}: {
|
||||
// first drop to remove unique constraint
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT, "age" INTEGER, "email" INTEGER NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"), CONSTRAINT "fk_users_org_id" FOREIGN KEY ("org_id") REFERENCES "orgs" ("id"))`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name", "age", "email") SELECT "id", "name", "age", "email" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
// second drop to change all columns
|
||||
[]byte(`CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL, "age" INTEGER NOT NULL DEFAULT 0, "email" INTEGER NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"), CONSTRAINT "fk_users_org_id" FOREIGN KEY ("org_id") REFERENCES "orgs" ("id"))`),
|
||||
[]byte(`INSERT INTO "users__temp" ("id", "name", "age", "email") SELECT "id", "name", "age", "email" FROM "users"`),
|
||||
[]byte(`DROP TABLE IF EXISTS "users"`),
|
||||
[]byte(`ALTER TABLE "users__temp" RENAME TO "users"`),
|
||||
// create unique index for the constraint
|
||||
[]byte(`CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_email" ON "users" ("email")`),
|
||||
[]byte(`CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_name" ON "users" ("name")`),
|
||||
},
|
||||
{SCreateAndDropConstraint: true, SAlterTableAddAndDropColumnIfNotExistsAndExists: true, SAlterTableAlterColumnSetAndDrop: true}: {
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "uq_users_email"`),
|
||||
[]byte(`ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "my_name_constraint"`),
|
||||
[]byte(`ALTER TABLE "users" ALTER COLUMN "name" SET NOT NULL`),
|
||||
[]byte(`ALTER TABLE "users" ALTER COLUMN "age" SET NOT NULL`),
|
||||
[]byte(`ALTER TABLE "users" ALTER COLUMN "age" SET DEFAULT 0`),
|
||||
[]byte(`CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_email" ON "users" ("email")`),
|
||||
[]byte(`CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_name" ON "users" ("name")`),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -914,11 +1000,17 @@ func TestOperatorAlterTable(t *testing.T) {
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
fmter := NewFormatter(schema.NewNopFormatter().Dialect())
|
||||
operator := NewOperator(fmter, testCase.support)
|
||||
for support, sqls := range testCase.expected {
|
||||
operator := NewOperator(fmter, support)
|
||||
clonedTable := testCase.table.Clone()
|
||||
|
||||
actuals := operator.AlterTable(testCase.table, testCase.uniqueConstraints, testCase.newTable)
|
||||
assert.Equal(t, testCase.expectedSQLs, actuals)
|
||||
assert.Equal(t, testCase.newTable, testCase.table)
|
||||
actuals := operator.AlterTable(clonedTable, testCase.uniqueConstraints, testCase.newTable)
|
||||
for _, sql := range actuals {
|
||||
fmt.Println(string(sql))
|
||||
}
|
||||
assert.Equal(t, sqls, actuals)
|
||||
assert.EqualValues(t, testCase.newTable, clonedTable)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user