func (nl *NamedLockFunction) GetLockName(ctx *sql.Context, row sql.Row) (*string, error) {
	if nl.Child == nil {
		return nil, nil
	}
	val, err := nl.Child.Eval(ctx, row)
	if err != nil {
		return nil, err
	}
	if val == nil {
		return nil, nil
	}
	lockName, ok := val.(string)
	if !ok {
		return nil, ErrIllegalLockNameArgType.New(nl.Child.Type().String(), nl.funcName)
	}
	return &lockName, nil
}
Eval implements the Expression interface.
package function
import (
	"fmt"
	"strings"
	"time"
	"gopkg.in/src-d/go-errors.v1"
	"github.com/dolthub/go-mysql-server/sql"
	"github.com/dolthub/go-mysql-server/sql/expression"
)
var ErrIllegalLockNameArgType = errors.NewKind("Illegal parameter data type %s for operation '%s'")
type lockFuncLogic func(ctx *sql.Context, ls *sql.LockSubsystem, lockName string) (interface{}, error)
func (nl *NamedLockFunction) evalLockLogic(ctx *sql.Context, fn lockFuncLogic, row sql.Row) (interface{}, error) {
	lock, err := nl.GetLockName(ctx, row)
	if err != nil {
		return nil, err
	}
	if lock == nil {
		return nil, nil
	}
	return fn(ctx, nl.ls, *lock)
}
type NamedLockFunction struct {
	expression.UnaryExpression
	ls       *sql.LockSubsystem
	funcName string
	retType  sql.Type
}
func (nl *NamedLockFunction) FunctionName() string {
	return nl.funcName
}