code: func builtinSubstringIndex(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
  	// The meaning of the elements of args.
  	// args[0] -> StrExpr
  	// args[1] -> Delim
  	// args[2] -> Count
  	str, err := args[0].ToString()
  	if err != nil {
  		return d, errors.Errorf("Substring_Index invalid args, need string but get %T", args[0].GetValue())
  	}
  
  	delim, err := args[1].ToString()
  	if err != nil {
  		return d, errors.Errorf("Substring_Index invalid delim, need string but get %T", args[1].GetValue())
  	}
  	if len(delim) == 0 {
  		d.SetString("")
  		return d, nil
  	}
  
  	c, err := args[2].ToInt64(ctx.GetSessionVars().StmtCtx)
  	if err != nil {
  		return d, errors.Trace(err)
  	}
  	count := int(c)
  	strs := strings.Split(str, delim)
  	var (
  		start = 0
  		end   = len(strs)
  	)
  	if count > 0 {
  		// If count is positive, everything to the left of the final delimiter (counting from the left) is returned.
  		if count < end {
  			end = count
  		}
  	} else {
  		// If count is negative, everything to the right of the final delimiter (counting from the right) is returned.
  		count = -count
  		if count < end {
  			start = end - count
  		}
  	}
  	substrs := strs[start:end]
  	d.SetString(strings.Join(substrs, delim))
  	return d, nil
  }
docs: // See https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_substring-index