2025-07-08 00:21:26 +05:30
package sqlschema
import (
2025-07-21 16:05:28 +05:30
"fmt"
2025-07-08 00:21:26 +05:30
"testing"
"github.com/stretchr/testify/assert"
"github.com/uptrace/bun/schema"
)
// See table_test.go for more test cases on creating tables.
func TestOperatorCreateTable ( t * testing . T ) {
testCases := [ ] struct {
name string
table * Table
expectedSQLs [ ] [ ] byte
} {
{
name : "PrimaryKey_ForeignKey_NotNullable" ,
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
{ Name : "org_id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint {
{ ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
} ,
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` CREATE TABLE IF NOT EXISTS "users" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL, "org_id" INTEGER NOT NULL, CONSTRAINT "pk_users" PRIMARY KEY ("id"), CONSTRAINT "fk_users_org_id" FOREIGN KEY ("org_id") REFERENCES "orgs" ("id")) ` ) ,
} ,
} ,
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
fmter := NewFormatter ( schema . NewNopFormatter ( ) . Dialect ( ) )
operator := NewOperator ( fmter , OperatorSupport { } )
actuals := operator . CreateTable ( testCase . table )
assert . Equal ( t , testCase . expectedSQLs , actuals )
} )
}
}
func TestOperatorAddColumn ( t * testing . T ) {
testCases := [ ] struct {
name string
table * Table
column * Column
val any
uniqueConstraints [ ] * UniqueConstraint
support OperatorSupport
expectedSQLs [ ] [ ] byte
expectedTable * Table
} {
{
2025-07-21 13:06:26 +05:30
name : "NullableNoDefault_DoesNotExist_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
column : & Column { Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
val : nil ,
support : OperatorSupport {
2025-07-21 13:06:26 +05:30
SAlterTableAddAndDropColumnIfNotExistsAndExists : true ,
SAlterTableAlterColumnSetAndDrop : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "name" TEXT ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
} ,
} ,
} ,
{
2025-07-21 13:06:26 +05:30
name : "MismatchingDataType_DoesExist_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
} ,
} ,
column : & Column { Name : "name" , DataType : DataTypeBigInt , Nullable : true , Default : "" } ,
val : nil ,
support : OperatorSupport {
2025-07-21 13:06:26 +05:30
SAlterTableAddAndDropColumnIfNotExistsAndExists : true ,
SAlterTableAlterColumnSetAndDrop : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
} ,
} ,
} ,
{
2025-07-21 13:06:26 +05:30
name : "NotNullableNoDefaultNoVal_DoesNotExist_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
column : & Column { Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
val : nil ,
support : OperatorSupport {
2025-07-21 13:06:26 +05:30
SAlterTableAddAndDropColumnIfNotExistsAndExists : true ,
SAlterTableAlterColumnSetAndDrop : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "name" TEXT ` ) ,
[ ] byte ( ` UPDATE "users" SET "name" = '' ` ) ,
[ ] byte ( ` ALTER TABLE "users" ALTER COLUMN "name" SET NOT NULL ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-21 13:06:26 +05:30
name : "NotNullableNoDefault_DoesNotExist_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
column : & Column { Name : "num" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
val : int64 ( 100 ) ,
support : OperatorSupport {
2025-07-21 13:06:26 +05:30
SAlterTableAddAndDropColumnIfNotExistsAndExists : true ,
SAlterTableAlterColumnSetAndDrop : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "num" INTEGER ` ) ,
[ ] byte ( ` UPDATE "users" SET "num" = 100 ` ) ,
[ ] byte ( ` ALTER TABLE "users" ALTER COLUMN "num" SET NOT NULL ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "num" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-21 13:06:26 +05:30
name : "NotNullableNoDefault_DoesNotExist_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropFalse" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
column : & Column { Name : "num" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
val : int64 ( 100 ) ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "name" } } ,
} ,
support : OperatorSupport {
2025-07-21 13:06:26 +05:30
SAlterTableAddAndDropColumnIfNotExistsAndExists : true ,
SAlterTableAlterColumnSetAndDrop : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" ADD COLUMN IF NOT EXISTS "num" INTEGER ` ) ,
[ ] byte ( ` UPDATE "users" SET "num" = 100 ` ) ,
[ ] byte ( ` CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL, "name" TEXT NOT NULL, "num" INTEGER NOT NULL) ` ) ,
[ ] byte ( ` INSERT INTO "users__temp" ("id", "name", "num") SELECT "id", "name", "num" 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" ON "users" ("name") ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
{ Name : "num" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-21 13:06:26 +05:30
name : "MismatchingDataType_DoesExist_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue_SAlterTableAlterColumnSetAndDropFalse" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
} ,
} ,
column : & Column { Name : "name" , DataType : DataTypeBigInt , Nullable : false , Default : "" } ,
val : nil ,
support : OperatorSupport {
2025-07-21 13:06:26 +05:30
SAlterTableAddAndDropColumnIfNotExistsAndExists : true ,
SAlterTableAlterColumnSetAndDrop : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
} ,
} ,
} ,
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
fmter := NewFormatter ( schema . NewNopFormatter ( ) . Dialect ( ) )
operator := NewOperator ( fmter , testCase . support )
actuals := operator . AddColumn ( testCase . table , testCase . uniqueConstraints , testCase . column , testCase . val )
assert . Equal ( t , testCase . expectedSQLs , actuals )
assert . Equal ( t , testCase . expectedTable , testCase . table )
} )
}
}
func TestOperatorDropConstraint ( t * testing . T ) {
testCases := [ ] struct {
name string
table * Table
constraint Constraint
uniqueConstraints [ ] * UniqueConstraint
support OperatorSupport
expectedSQLs [ ] [ ] byte
expectedTable * Table
} {
{
2025-07-20 18:55:00 +05:30
name : "PrimaryKeyConstraint_DoesExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
} ,
constraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "pk_users" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "PrimaryKeyConstraint_DoesNotExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
constraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "PrimaryKeyConstraintDifferentName_DoesExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
name : "pk_users_different_name" ,
} ,
} ,
constraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "pk_users_different_name" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "PrimaryKeyConstraint_DoesExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
} ,
constraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` CREATE TABLE IF NOT EXISTS "users__temp" ("id" INTEGER NOT NULL) ` ) ,
[ ] byte ( ` INSERT INTO "users__temp" ("id") SELECT "id" FROM "users" ` ) ,
[ ] byte ( ` DROP TABLE IF EXISTS "users" ` ) ,
[ ] byte ( ` ALTER TABLE "users__temp" RENAME TO "users" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "PrimaryKeyConstraint_DoesNotExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
constraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "UniqueConstraint_DoesExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
constraint : & UniqueConstraint {
ColumnNames : [ ] ColumnName { "name" } ,
} ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "name" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "uq_users_name" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "UniqueConstraint_DoesNotExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
constraint : & UniqueConstraint {
ColumnNames : [ ] ColumnName { "name" } ,
} ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "UniqueConstraint_DoesExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
constraint : & UniqueConstraint {
ColumnNames : [ ] ColumnName { "name" } ,
} ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "name" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] 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" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "UniqueConstraint_DoesNotExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
constraint : & UniqueConstraint {
ColumnNames : [ ] ColumnName { "name" } ,
} ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "ForeignKeyConstraint_DoesExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
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" } ,
} ,
} ,
constraint : & ForeignKeyConstraint { ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "fk_users_org_id" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "org_id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "ForeignKeyConstraintDifferentName_DoesExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
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" , name : "my_fk" } ,
} ,
} ,
constraint : & ForeignKeyConstraint { ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] byte ( ` ALTER TABLE "users" DROP CONSTRAINT IF EXISTS "my_fk" ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "org_id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "ForeignKeyConstraint_DoesNotExist_SCreateAndDropConstraintTrue" ,
2025-07-08 00:21:26 +05:30
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" } ,
} ,
} ,
// Note that the name of the referencing column is different from the one in the table.
constraint : & ForeignKeyConstraint { ReferencingColumnName : "orgid" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : true ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & 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" } ,
} ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "ForeignKeyConstraint_DoesExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
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" } ,
} ,
} ,
constraint : & ForeignKeyConstraint { ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] 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" ` ) ,
// Note that a unique index is created because a unique constraint already existed for the table.
[ ] byte ( ` CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_id" ON "users" ("id") ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "org_id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "ForeignKeyConstraintDifferentName_DoesExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
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" , name : "my_fk" } ,
} ,
} ,
constraint : & ForeignKeyConstraint { ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte {
[ ] 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" ` ) ,
// Note that a unique index is created because a unique constraint already existed for the table.
[ ] byte ( ` CREATE UNIQUE INDEX IF NOT EXISTS "uq_users_id" ON "users" ("id") ` ) ,
} ,
expectedTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "org_id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
} ,
} ,
{
2025-07-20 18:55:00 +05:30
name : "ForeignKeyConstraint_DoesNotExist_SCreateAndDropConstraintFalse" ,
2025-07-08 00:21:26 +05:30
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" } ,
} ,
} ,
// Note that the name of the referencing column is different from the one in the table.
constraint : & ForeignKeyConstraint { ReferencingColumnName : "orgid" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "id" } } ,
} ,
support : OperatorSupport {
2025-07-20 18:55:00 +05:30
SCreateAndDropConstraint : false ,
2025-07-08 00:21:26 +05:30
} ,
expectedSQLs : [ ] [ ] byte { } ,
expectedTable : & 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" } ,
} ,
} ,
} ,
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
fmter := NewFormatter ( schema . NewNopFormatter ( ) . Dialect ( ) )
operator := NewOperator ( fmter , testCase . support )
actuals := operator . DropConstraint ( testCase . table , testCase . uniqueConstraints , testCase . constraint )
assert . Equal ( t , testCase . expectedSQLs , actuals )
assert . Equal ( t , testCase . expectedTable , testCase . table )
} )
}
}
2025-07-20 03:30:32 +05:30
2025-07-20 18:55:00 +05:30
func TestOperatorAlterTable ( t * testing . T ) {
2025-07-20 03:30:32 +05:30
testCases := [ ] struct {
name string
table * Table
uniqueConstraints [ ] * UniqueConstraint
newTable * Table
2025-07-21 16:05:28 +05:30
expected map [ OperatorSupport ] [ ] [ ] byte
2025-07-20 03:30:32 +05:30
} {
{
name : "NoOperation" ,
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 : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
} ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
} ,
expected : map [ OperatorSupport ] [ ] [ ] byte {
{ SCreateAndDropConstraint : false , SAlterTableAddAndDropColumnIfNotExistsAndExists : false , SAlterTableAlterColumnSetAndDrop : false } : { } ,
{ SCreateAndDropConstraint : true , SAlterTableAddAndDropColumnIfNotExistsAndExists : true , SAlterTableAlterColumnSetAndDrop : true } : { } ,
2025-07-20 03:30:32 +05:30
} ,
} ,
{
2025-07-21 13:06:26 +05:30
name : "RenameTable" ,
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
} ,
newTable : & Table {
Name : "users_new" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
2025-07-21 13:06:26 +05:30
} ,
2025-07-21 16:05:28 +05:30
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" ` ) ,
} ,
2025-07-21 13:06:26 +05:30
} ,
} ,
{
name : "AddColumn_NullableNoDefault_SAlterTableAddAndDropColumnIfNotExistsAndExistsTrue" ,
2025-07-20 03:30:32 +05:30
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 : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
{ Name : "age" , DataType : DataTypeInteger , Nullable : true , Default : "" } ,
} ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
2025-07-20 03:30:32 +05:30
} ,
2025-07-21 16:05:28 +05:30
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 ` ) ,
} ,
2025-07-20 03:30:32 +05:30
} ,
} ,
{
2025-07-21 16:05:28 +05:30
name : "CreatePrimaryKeyConstraint" ,
2025-07-20 03:30:32 +05:30
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 : "" } ,
} ,
2025-07-21 16:05:28 +05:30
PrimaryKeyConstraint : & PrimaryKeyConstraint {
ColumnNames : [ ] ColumnName { "id" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
2025-07-20 03:30:32 +05:30
} ,
2025-07-21 16:05:28 +05:30
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") ` ) ,
} ,
2025-07-20 03:30:32 +05:30
} ,
} ,
{
2025-07-21 16:05:28 +05:30
name : "DropPrimaryKeyConstraint_AlterColumnNullable" ,
2025-07-20 03:30:32 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
2025-07-20 03:30:32 +05:30
} ,
2025-07-21 16:05:28 +05:30
PrimaryKeyConstraint : & PrimaryKeyConstraint { ColumnNames : [ ] ColumnName { "id" } } ,
2025-07-20 03:30:32 +05:30
} ,
newTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
2025-07-20 03:30:32 +05:30
} ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
2025-07-20 03:30:32 +05:30
} ,
2025-07-21 16:05:28 +05:30
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 ` ) ,
} ,
2025-07-20 03:30:32 +05:30
} ,
} ,
{
2025-07-21 16:05:28 +05:30
name : "DropForeignKeyConstraint_DropColumn" ,
2025-07-20 03:30:32 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ Name : "org_id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint {
{ ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
2025-07-20 03:30:32 +05:30
} ,
} ,
newTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint { } ,
2025-07-20 03:30:32 +05:30
} ,
2025-07-21 16:05:28 +05:30
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" ` ) ,
} ,
2025-07-20 03:30:32 +05:30
} ,
} ,
2025-07-20 18:55:00 +05:30
{
2025-07-21 16:05:28 +05:30
name : "DropMultipleConstraints" ,
2025-07-20 18:55:00 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ 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 : "" } ,
2025-07-20 18:55:00 +05:30
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint { ColumnNames : [ ] ColumnName { "id" } } ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint {
{ ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
{ ReferencingColumnName : "team_id" , ReferencedTableName : "teams" , ReferencedColumnName : "id" } ,
} ,
} ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "name" , "age" } } ,
2025-07-20 18:55:00 +05:30
} ,
newTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ 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" } ,
2025-07-20 18:55:00 +05:30
} ,
} ,
2025-07-21 16:05:28 +05:30
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") ` ) ,
} ,
2025-07-20 18:55:00 +05:30
} ,
} ,
{
2025-07-21 16:05:28 +05:30
name : "DropUniqueConstraints_AlterMultipleColumns" ,
2025-07-20 18:55:00 +05:30
table : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : true , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ Name : "age" , DataType : DataTypeInteger , Nullable : true , Default : "" } ,
{ Name : "email" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
2025-07-20 18:55:00 +05:30
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint { ColumnNames : [ ] ColumnName { "id" } } ,
2025-07-21 16:05:28 +05:30
ForeignKeyConstraints : [ ] * ForeignKeyConstraint {
{ ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
} ,
} ,
uniqueConstraints : [ ] * UniqueConstraint {
{ ColumnNames : [ ] ColumnName { "email" } } ,
{ name : "my_name_constraint" , ColumnNames : [ ] ColumnName { "name" } } ,
2025-07-20 18:55:00 +05:30
} ,
newTable : & Table {
Name : "users" ,
Columns : [ ] * Column {
{ Name : "id" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
{ Name : "name" , DataType : DataTypeText , Nullable : false , Default : "" } ,
2025-07-21 16:05:28 +05:30
{ Name : "age" , DataType : DataTypeInteger , Nullable : false , Default : "0" } ,
{ Name : "email" , DataType : DataTypeInteger , Nullable : false , Default : "" } ,
} ,
PrimaryKeyConstraint : & PrimaryKeyConstraint { ColumnNames : [ ] ColumnName { "id" } } ,
ForeignKeyConstraints : [ ] * ForeignKeyConstraint {
{ ReferencingColumnName : "org_id" , ReferencedTableName : "orgs" , ReferencedColumnName : "id" } ,
2025-07-20 18:55:00 +05:30
} ,
} ,
2025-07-21 16:05:28 +05:30
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") ` ) ,
} ,
2025-07-20 18:55:00 +05:30
} ,
} ,
2025-07-20 03:30:32 +05:30
}
for _ , testCase := range testCases {
t . Run ( testCase . name , func ( t * testing . T ) {
fmter := NewFormatter ( schema . NewNopFormatter ( ) . Dialect ( ) )
2025-07-21 16:05:28 +05:30
for support , sqls := range testCase . expected {
operator := NewOperator ( fmter , support )
clonedTable := testCase . table . Clone ( )
2025-07-20 03:30:32 +05:30
2025-07-21 16:05:28 +05:30
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 )
}
2025-07-20 03:30:32 +05:30
} )
}
}