func (t *LockTables) WithChildren(children ...sql.Node) (sql.Node, error) {
	if len(children) != len(t.Locks) {
		return nil, sql.ErrInvalidChildrenNumber.New(t, len(children), len(t.Locks))
	}
	var locks = make([]*TableLock, len(t.Locks))
	for i, n := range children {
		locks[i] = &TableLock{
			Table: n,
			Write: t.Locks[i].Write,
		}
	}
	return &LockTables{t.Catalog, locks}, nil
}
WithChildren implements the Node interface.
package plan
import (
	"fmt"
	"github.com/src-d/go-mysql-server/sql"
	errors "gopkg.in/src-d/go-errors.v1"
)
type TableLock struct {
	Table sql.Node
	Write bool
}
type LockTables struct {
	Catalog *sql.Catalog
	Locks   []*TableLock
}
func NewLockTables(locks []*TableLock) *LockTables {
	return &LockTables{Locks: locks}
}
func (t *LockTables) Children() []sql.Node {
	var children = make([]sql.Node, len(t.Locks))
	for i, l := range t.Locks {
		children[i] = l.Table
	}
	return children
}
func (t *LockTables) Resolved() bool {
	for _, l := range t.Locks {
		if !l.Table.Resolved() {
			return false
		}
	}
	return true
}
func (t *LockTables) Schema() sql.Schema { return nil }
func (t *LockTables) RowIter(ctx *sql.Context) (sql.RowIter, error) {
	span, ctx := ctx.Span("plan.LockTables")
	defer span.Finish()
	id := ctx.ID()
	for _, l := range t.Locks {
		lockable, err := getLockable(l.Table)
		if err != nil {
			ctx.Warn(0, err.Error())
			continue
		}
		if err := lockable.Lock(ctx, l.Write); err != nil {
			ctx.Error(0, "unable to lock table: %s", err)
		} else {
			t.Catalog.LockTable(id, lockable.Name())
		}
	}
	return sql.RowsToRowIter(), nil
}
func (t *LockTables) String() string {
	var children = make([]string, len(t.Locks))
	for i, l := range t.Locks {
		if l.Write {
			children[i] = fmt.Sprintf("[WRITE] %s", l.Table.String())
		} else {
			children[i] = fmt.Sprintf("[READ] %s", l.Table.String())
		}
	}
	p := sql.NewTreePrinter()
	_ = p.WriteNode("LockTables")
	_ = p.WriteChildren(children...)
	return p.String()
}