blob: 760d36ea59d3ed906e3520f849df3b26d1e59bd7 [file]
package backup
/*
* This file contains structs and functions related to backing up metadata shared
* among many or all object types (privileges, owners, and comments) on the
* coordinator that needs to be restored before data is restored.
*/
import (
"github.com/apache/cloudberry-backup/toc"
"github.com/apache/cloudberry-backup/utils"
"github.com/apache/cloudberry-go-libs/gplog"
"github.com/pkg/errors"
)
/*
* There's no built-in function to generate constraint definitions like there is for other types of
* metadata, so this function constructs them.
*/
func PrintConstraintStatements(metadataFile *utils.FileWithByteCount, objToc *toc.TOC, constraints []Constraint, conMetadata MetadataMap) {
allConstraints := make([]Constraint, 0)
allFkConstraints := make([]Constraint, 0)
/*
* Because FOREIGN KEY constraints must be backed up after PRIMARY KEY
* constraints, we separate the two types then concatenate the lists,
* so FOREIGN KEY are guaranteed to be printed last.
*/
for _, constraint := range constraints {
if constraint.ConType == "f" {
allFkConstraints = append(allFkConstraints, constraint)
} else {
allConstraints = append(allConstraints, constraint)
}
}
constraints = append(allConstraints, allFkConstraints...)
alterStr := "\n\nALTER %s %s ADD CONSTRAINT %s %s;\n"
for _, constraint := range constraints {
start := metadataFile.ByteCount
// ConIsLocal should always return true from GetConstraints because we filter out constraints that are inherited using the INHERITS clause, or inherited from a parent partition table. This field only accurately reflects constraints in GPDB6+ because check constraints on parent tables must propogate to children. For GPDB versions 5 or lower, this field will default to false.
objStr := "TABLE ONLY"
if constraint.IsPartitionParent || (constraint.ConType == "c" && constraint.ConIsLocal) {
objStr = toc.OBJ_TABLE
}
metadataFile.MustPrintf(alterStr, objStr, constraint.OwningObject, constraint.Name, constraint.Def.String)
section, entry := constraint.GetMetadataEntry()
tier := globalTierMap[constraint.GetUniqueID()]
objToc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount, tier)
PrintObjectMetadata(metadataFile, objToc, conMetadata[constraint.GetUniqueID()], constraint, constraint.OwningObject, tier)
}
}
func PrintCreateSchemaStatements(metadataFile *utils.FileWithByteCount, objToc *toc.TOC, schemas []Schema, schemaMetadata MetadataMap) {
for _, schema := range schemas {
start := metadataFile.ByteCount
metadataFile.MustPrintln()
if schema.Name != "public" {
metadataFile.MustPrintf("\nCREATE SCHEMA %s;", schema.Name)
}
section, entry := schema.GetMetadataEntry()
tier := globalTierMap[schema.GetUniqueID()]
objToc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount, tier)
PrintObjectMetadata(metadataFile, objToc, schemaMetadata[schema.GetUniqueID()], schema, "", tier)
}
}
func PrintAccessMethodStatements(metadataFile *utils.FileWithByteCount, objToc *toc.TOC, accessMethods []AccessMethod, accessMethodMetadata MetadataMap) {
for _, method := range accessMethods {
start := metadataFile.ByteCount
methodTypeStr := ""
switch method.Type {
case "t":
// these are not strictly object types but they share use with them so we use the consts here
methodTypeStr = toc.OBJ_TABLE
case "i":
methodTypeStr = toc.OBJ_INDEX
default:
gplog.Fatal(errors.Errorf("Invalid access method type: expected 't' or 'i', got '%s'\n", method.Type), "")
}
metadataFile.MustPrintf("\n\nCREATE ACCESS METHOD %s TYPE %s HANDLER %s;", method.Name, methodTypeStr, method.Handler)
section, entry := method.GetMetadataEntry()
tier := globalTierMap[method.GetUniqueID()]
objToc.AddMetadataEntry(section, entry, start, metadataFile.ByteCount, tier)
PrintObjectMetadata(metadataFile, objToc, accessMethodMetadata[method.GetUniqueID()], method, "", tier)
}
}