Skip to content

Commit

Permalink
Creating NOT VALID constraints only in post-snapshot-import mode in i…
Browse files Browse the repository at this point in the history
…mport-schema
  • Loading branch information
priyanshi-yb committed Dec 4, 2024
1 parent 936b885 commit 9c3b0fa
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 11 deletions.
10 changes: 8 additions & 2 deletions yb-voyager/cmd/importSchema.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,14 @@ func importSchema() error {
dumpStatements(finalFailedSqlStmts, filepath.Join(exportDir, "schema", "failed.sql"))
}

if flagPostSnapshotImport && flagRefreshMViews {
refreshMViews(conn)
if flagPostSnapshotImport {
err = importSchemaInternal(exportDir, []string{"TABLE"}, nil)
if err != nil {
return err
}
if flagRefreshMViews {
refreshMViews(conn)
}
} else {
utils.PrintAndLog("\nNOTE: Materialized Views are not populated by default. To populate them, pass --refresh-mviews while executing `import schema --post-snapshot-import`.")
}
Expand Down
46 changes: 43 additions & 3 deletions yb-voyager/cmd/importSchemaYugabyteDB.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
log "github.com/sirupsen/logrus"
"golang.org/x/exp/slices"

"github.com/yugabyte/yb-voyager/yb-voyager/src/queryparser"
"github.com/yugabyte/yb-voyager/yb-voyager/src/utils"
)

Expand All @@ -49,6 +50,21 @@ func importSchemaInternal(exportDir string, importObjectList []string,
return nil
}

func isNotValidConstraint(stmt string) (bool, error) {
ddlObj, err := queryparser.ParseAndProcessDDL(stmt)
if err != nil {
return false, fmt.Errorf("error in parsing and process DDL[%s]:%v", stmt, err)
}
alter, ok := ddlObj.(*queryparser.AlterTable)
if !ok {
return false, nil
}
if alter.IsAddConstraintType() && alter.ConstraintNotValid {
return true, nil
}
return false, nil
}

func executeSqlFile(file string, objType string, skipFn func(string, string) bool) error {
log.Infof("Execute SQL file %q on target %q", file, tconf.Host)
conn := newTargetConn()
Expand All @@ -74,10 +90,13 @@ func executeSqlFile(file string, objType string, skipFn func(string, string) boo

if objType == "TABLE" {
stmt := strings.ToUpper(sqlInfo.stmt)
skip := strings.Contains(stmt, "ALTER TABLE") && strings.Contains(stmt, "REPLICA IDENTITY")
// Check if the statement should be skipped
skip, err := shouldSkipDDL(stmt)
if err != nil {
return fmt.Errorf("error checking whether to skip DDL: %v", err)
}
if skip {
//skipping DDLS like ALTER TABLE ... REPLICA IDENTITY .. as this is not supported in YB
log.Infof("Skipping DDL: %s", sqlInfo.stmt)
log.Infof("Skipping DDL: %s", stmt)
continue
}
}
Expand All @@ -90,6 +109,27 @@ func executeSqlFile(file string, objType string, skipFn func(string, string) boo
return nil
}

func shouldSkipDDL(stmt string) (bool, error) {
skipReplicaIdentity := strings.Contains(stmt, "ALTER TABLE") && strings.Contains(stmt, "REPLICA IDENTITY")
isNotValid, err := isNotValidConstraint(stmt)
if err != nil {
return false, fmt.Errorf("error checking whether stmt is to add not valid constraint: %v", stmt, err)
}
if skipReplicaIdentity {
//skipping DDLS like ALTER TABLE ... REPLICA IDENTITY .. as this is not supported in YB
log.Infof("Skipping DDL: %s", stmt)
return true, nil
}
if isNotValid && !bool(flagPostSnapshotImport) {
//Skipping the ALTER TABLE ... ADD CONSTRAINT ... NOT VALID DDLs in import schema without post-snapshot-import flag
return true, nil
}
if bool(flagPostSnapshotImport) && !isNotValid {
return true, nil
}
return false, nil
}

func executeSqlStmtWithRetries(conn **pgx.Conn, sqlInfo sqlInfo, objType string) error {
var err error
log.Infof("On %s run query:\n%s\n", tconf.Host, sqlInfo.formattedStmt)
Expand Down
21 changes: 15 additions & 6 deletions yb-voyager/src/queryparser/ddl_processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,11 +555,17 @@ func (atProcessor *AlterTableProcessor) Process(parseTree *pg_query.ParseResult)
similar to CREATE table 2nd case where constraint is at the end of column definitions mentioning the constraint only
so here as well while adding constraint checking the type of constraint and the deferrable field of it.
ALTER TABLE test ADD CONSTRAINT chk check (id<>'') NOT VALID;
stmts:{stmt:...subtype:AT_AddConstraint def:{constraint:{contype:CONSTR_CHECK conname:"chk" location:22
raw_expr:{a_expr:{kind:AEXPR_OP name:{string:{sval:"<>"}} lexpr:{column_ref:{fields:{string:{sval:"id"}} location:43}} rexpr:{a_const:{sval:{}
location:47}} location:45}} skip_validation:true}} behavior:DROP_RESTRICT}} objtype:OBJECT_TABLE}} stmt_len:60}
*/
constraint := cmd.GetDef().GetConstraint()
alter.ConstraintType = constraint.Contype
alter.ConstraintName = constraint.Conname
alter.IsDeferrable = constraint.Deferrable
alter.ConstraintNotValid = constraint.SkipValidation // this is set for the NOT VALID clause
alter.ConstraintColumns = parseColumnsFromKeys(constraint.GetKeys())

case pg_query.AlterTableType_AT_DisableRule:
Expand Down Expand Up @@ -590,10 +596,11 @@ type AlterTable struct {
NumSetAttributes int
NumStorageOptions int
//In case AlterType - ADD_CONSTRAINT
ConstraintType pg_query.ConstrType
ConstraintName string
IsDeferrable bool
ConstraintColumns []string
ConstraintType pg_query.ConstrType
ConstraintName string
ConstraintNotValid bool
IsDeferrable bool
ConstraintColumns []string
}

func (a *AlterTable) GetObjectName() string {
Expand All @@ -606,6 +613,10 @@ func (a *AlterTable) AddPrimaryKeyOrUniqueCons() bool {
return a.ConstraintType == PRIMARY_CONSTR_TYPE || a.ConstraintType == UNIQUE_CONSTR_TYPE
}

func (a *AlterTable) IsAddConstraintType() bool {
return a.AlterType == pg_query.AlterTableType_AT_AddConstraint
}

//===========POLICY PROCESSOR ================================

// PolicyProcessor handles parsing CREATE POLICY statements
Expand Down Expand Up @@ -869,5 +880,3 @@ var deferrableConstraintsList = []pg_query.ConstrType{
pg_query.ConstrType_CONSTR_ATTR_DEFERRED,
pg_query.ConstrType_CONSTR_ATTR_IMMEDIATE,
}


0 comments on commit 9c3b0fa

Please sign in to comment.