func (c *checkHelper) init(p *planner, tn *parser.TableName, tableDesc *sqlbase.TableDescriptor) error { if len(tableDesc.Checks) == 0 { return nil } c.qvals = make(qvalMap) c.cols = tableDesc.Columns sourceInfo := newSourceInfoForSingleTable(*tn, makeResultColumns(tableDesc.Columns)) c.exprs = make([]parser.TypedExpr, len(tableDesc.Checks)) exprStrings := make([]string, len(tableDesc.Checks)) for i, check := range tableDesc.Checks { exprStrings[i] = check.Expr } exprs, err := parser.ParseExprsTraditional(exprStrings) if err != nil { return err } for i, raw := range exprs { typedExpr, err := p.analyzeExpr(raw, multiSourceInfo{sourceInfo}, c.qvals, parser.TypeBool, false, "") if err != nil { return err } c.exprs[i] = typedExpr } return nil }
func makeDefaultExprs( cols []sqlbase.ColumnDescriptor, parse *parser.Parser, evalCtx *parser.EvalContext, ) ([]parser.TypedExpr, error) { // Check to see if any of the columns have DEFAULT expressions. If there // are no DEFAULT expressions, we don't bother with constructing the // defaults map as the defaults are all NULL. haveDefaults := false for _, col := range cols { if col.DefaultExpr != nil { haveDefaults = true break } } if !haveDefaults { return nil, nil } // Build the default expressions map from the parsed SELECT statement. defaultExprs := make([]parser.TypedExpr, 0, len(cols)) exprStrings := make([]string, 0, len(cols)) for _, col := range cols { if col.DefaultExpr != nil { exprStrings = append(exprStrings, *col.DefaultExpr) } } exprs, err := parser.ParseExprsTraditional(exprStrings) if err != nil { return nil, err } defExprIdx := 0 for _, col := range cols { if col.DefaultExpr == nil { defaultExprs = append(defaultExprs, parser.DNull) continue } expr := exprs[defExprIdx] typedExpr, err := parser.TypeCheck(expr, nil, col.Type.ToDatumType()) if err != nil { return nil, err } if typedExpr, err = parse.NormalizeExpr(evalCtx, typedExpr); err != nil { return nil, err } defaultExprs = append(defaultExprs, typedExpr) defExprIdx++ } return defaultExprs, nil }
// RenameColumn renames the column. // Privileges: CREATE on table. // notes: postgres requires CREATE on the table. // mysql requires ALTER, CREATE, INSERT on the table. func (p *planner) RenameColumn(n *parser.RenameColumn) (planNode, error) { newColName := string(n.NewName) if newColName == "" { return nil, errEmptyColumnName } if err := n.Table.NormalizeTableName(p.session.Database); err != nil { return nil, err } dbDesc, err := p.getDatabaseDesc(n.Table.Database()) if err != nil { return nil, err } if dbDesc == nil { return nil, sqlbase.NewUndefinedDatabaseError(n.Table.Database()) } // Check if table exists. tbKey := tableKey{dbDesc.ID, n.Table.Table()}.Key() gr, err := p.txn.Get(tbKey) if err != nil { return nil, err } if !gr.Exists() { if n.IfExists { // Noop. return &emptyNode{}, nil } // Key does not exist, but we want it to: error out. return nil, fmt.Errorf("table %q does not exist", n.Table.Table()) } tableDesc, err := p.getTableDesc(n.Table) if err != nil { return nil, err } if tableDesc == nil { return nil, sqlbase.NewUndefinedTableError(n.Table.String()) } colName := string(n.Name) status, i, err := tableDesc.FindColumnByName(colName) // n.IfExists only applies to table, no need to check here. if err != nil { return nil, err } var column *sqlbase.ColumnDescriptor if status == sqlbase.DescriptorActive { column = &tableDesc.Columns[i] } else { column = tableDesc.Mutations[i].GetColumn() } if err := p.checkPrivilege(tableDesc, privilege.CREATE); err != nil { return nil, err } if sqlbase.EqualName(colName, newColName) { // Noop. return &emptyNode{}, nil } if _, _, err := tableDesc.FindColumnByName(newColName); err == nil { return nil, fmt.Errorf("column name %q already exists", newColName) } preFn := func(expr parser.Expr) (err error, recurse bool, newExpr parser.Expr) { if qname, ok := expr.(*parser.QualifiedName); ok { if err := qname.NormalizeColumnName(); err != nil { return err, false, nil } if qname.Column() == colName { qname.Indirect[0] = parser.NameIndirection(newColName) qname.ClearString() } return nil, false, qname } return nil, true, expr } exprStrings := make([]string, len(tableDesc.Checks)) for i, check := range tableDesc.Checks { exprStrings[i] = check.Expr } exprs, err := parser.ParseExprsTraditional(exprStrings) if err != nil { return nil, err } for i := range tableDesc.Checks { expr, err := parser.SimpleVisit(exprs[i], preFn) if err != nil { return nil, err } if after := expr.String(); after != tableDesc.Checks[i].Expr { tableDesc.Checks[i].Expr = after } } // Rename the column in the indexes. tableDesc.RenameColumn(column.ID, newColName) column.Name = newColName if err := tableDesc.SetUpVersion(); err != nil { return nil, err } descKey := sqlbase.MakeDescMetadataKey(tableDesc.GetID()) if err := tableDesc.Validate(); err != nil { return nil, err } if err := p.txn.Put(descKey, sqlbase.WrapDescriptor(tableDesc)); err != nil { return nil, err } p.notifySchemaChange(tableDesc.ID, sqlbase.InvalidMutationID) return &emptyNode{}, nil }
// RenameColumn renames the column. // Privileges: CREATE on table. // notes: postgres requires CREATE on the table. // mysql requires ALTER, CREATE, INSERT on the table. func (p *planner) RenameColumn(n *parser.RenameColumn) (planNode, error) { // Check if table exists. tn, err := n.Table.NormalizeWithDatabaseName(p.session.Database) if err != nil { return nil, err } tableDesc, err := p.getTableDesc(tn) if err != nil { return nil, err } if tableDesc == nil { if n.IfExists { // Noop. return &emptyNode{}, nil } // Key does not exist, but we want it to: error out. return nil, fmt.Errorf("table %q does not exist", tn.Table()) } if err := p.checkPrivilege(tableDesc, privilege.CREATE); err != nil { return nil, err } if n.NewName == "" { return nil, errEmptyColumnName } normNewColName := sqlbase.NormalizeName(n.NewName) normColName := sqlbase.NormalizeName(n.Name) status, i, err := tableDesc.FindColumnByNormalizedName(normColName) // n.IfExists only applies to table, no need to check here. if err != nil { return nil, err } var column *sqlbase.ColumnDescriptor if status == sqlbase.DescriptorActive { column = &tableDesc.Columns[i] } else { column = tableDesc.Mutations[i].GetColumn() } if normColName == normNewColName { // Noop. return &emptyNode{}, nil } if _, _, err := tableDesc.FindColumnByNormalizedName(normNewColName); err == nil { return nil, fmt.Errorf("column name %q already exists", n.NewName) } preFn := func(expr parser.Expr) (err error, recurse bool, newExpr parser.Expr) { if vBase, ok := expr.(parser.VarName); ok { v, err := vBase.NormalizeVarName() if err != nil { return err, false, nil } if c, ok := v.(*parser.ColumnItem); ok { if sqlbase.NormalizeName(c.ColumnName) == normColName { c.ColumnName = n.NewName } } return nil, false, v } return nil, true, expr } exprStrings := make([]string, len(tableDesc.Checks)) for i, check := range tableDesc.Checks { exprStrings[i] = check.Expr } exprs, err := parser.ParseExprsTraditional(exprStrings) if err != nil { return nil, err } for i := range tableDesc.Checks { expr, err := parser.SimpleVisit(exprs[i], preFn) if err != nil { return nil, err } if after := expr.String(); after != tableDesc.Checks[i].Expr { tableDesc.Checks[i].Expr = after } } // Rename the column in the indexes. tableDesc.RenameColumnNormalized(column.ID, normNewColName) column.Name = normNewColName if err := tableDesc.SetUpVersion(); err != nil { return nil, err } descKey := sqlbase.MakeDescMetadataKey(tableDesc.GetID()) if err := tableDesc.Validate(p.txn); err != nil { return nil, err } if err := p.txn.Put(descKey, sqlbase.WrapDescriptor(tableDesc)); err != nil { return nil, err } p.notifySchemaChange(tableDesc.ID, sqlbase.InvalidMutationID) return &emptyNode{}, nil }