Autonomy Software C++ 24.5.1
Welcome to the Autonomy Software repository of the Mars Rover Design Team (MRDT) at Missouri University of Science and Technology (Missouri S&T)! API reference contains the source code and other resources for the development of the autonomy software for our Mars rover. The Autonomy Software project aims to compete in the University Rover Challenge (URC) by demonstrating advanced autonomous capabilities and robust navigation algorithms.
Loading...
Searching...
No Matches
duckdb::LocalFileSystem Class Reference
Inheritance diagram for duckdb::LocalFileSystem:
Collaboration diagram for duckdb::LocalFileSystem:

Public Member Functions

unique_ptr< FileHandleOpenFile (const string &path, FileOpenFlags flags, optional_ptr< FileOpener > opener=nullptr) override
 
void Read (FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) override
 
void Write (FileHandle &handle, void *buffer, int64_t nr_bytes, idx_t location) override
 
int64_t Read (FileHandle &handle, void *buffer, int64_t nr_bytes) override
 
int64_t Write (FileHandle &handle, void *buffer, int64_t nr_bytes) override
 Write nr_bytes from the buffer into the file, moving the file pointer forward by nr_bytes.
 
bool Trim (FileHandle &handle, idx_t offset_bytes, idx_t length_bytes) override
 
int64_t GetFileSize (FileHandle &handle) override
 Returns the file size of a file handle, returns -1 on error.
 
timestamp_t GetLastModifiedTime (FileHandle &handle) override
 Returns the file last modified time of a file handle, returns timespec with zero on all attributes on error.
 
string GetVersionTag (FileHandle &handle) override
 Returns a tag that uniquely identifies the version of the file.
 
FileType GetFileType (FileHandle &handle) override
 Returns the file last modified time of a file handle, returns timespec with zero on all attributes on error.
 
FileMetadata Stats (FileHandle &handle) override
 Returns the file stats of the attached handle.
 
void Truncate (FileHandle &handle, int64_t new_size) override
 
bool DirectoryExists (const string &directory, optional_ptr< FileOpener > opener=nullptr) override
 Check if a directory exists.
 
void CreateDirectory (const string &directory, optional_ptr< FileOpener > opener=nullptr) override
 Create a directory if it does not exist.
 
void RemoveDirectory (const string &directory, optional_ptr< FileOpener > opener=nullptr) override
 Recursively remove a directory and all files in it.
 
void MoveFile (const string &source, const string &target, optional_ptr< FileOpener > opener=nullptr) override
 
bool FileExists (const string &filename, optional_ptr< FileOpener > opener=nullptr) override
 Check if a file exists.
 
bool IsPipe (const string &filename, optional_ptr< FileOpener > opener=nullptr) override
 Check if path is a pipe.
 
void RemoveFile (const string &filename, optional_ptr< FileOpener > opener=nullptr) override
 Remove a file from disk.
 
void FileSync (FileHandle &handle) override
 Sync a file handle to disk.
 
bool IsPathAbsolute (const string &path) override
 Checks if path is is an absolute path.
 
string MakePathAbsolute (const string &input, optional_ptr< FileOpener > opener)
 
bool PathStartsWithDrive (const string &path)
 
bool CanHandleFile (const string &fpath) override
 Whether or not a sub-system can handle a specific file path.
 
void Seek (FileHandle &handle, idx_t location) override
 Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location.
 
idx_t SeekPosition (FileHandle &handle) override
 Return the current seek posiiton in the file.
 
bool CanSeek () override
 Whether or not we can seek into the file.
 
bool OnDiskFile (FileHandle &handle) override
 
std::string GetName () const override
 Return the name of the filesytem. Used for forming diagnosis messages.
 
vector< OpenFileInfoFetchFileWithoutGlob (const string &path, optional_ptr< FileOpener > opener, bool absolute_path)
 
string CanonicalizePath (const string &path_p, optional_ptr< FileOpener > opener) override
 Canonicalize a path.
 
- Public Member Functions inherited from duckdb::FileSystem
DUCKDB_API unique_ptr< FileHandleOpenFile (const OpenFileInfo &path, FileOpenFlags flags, optional_ptr< FileOpener > opener=nullptr)
 
virtual DUCKDB_API void CreateDirectoriesRecursive (const string &path, optional_ptr< FileOpener > opener=nullptr)
 Helper function that uses DirectoryExists and CreateDirectory to ensure all directories in path are created.
 
virtual DUCKDB_API bool ListFiles (const string &directory, const std::function< void(const string &, bool)> &callback, FileOpener *opener=nullptr)
 List files in a directory, invoking the callback method for each one with (filename, is_dir)
 
DUCKDB_API bool ListFiles (const string &directory, const std::function< void(OpenFileInfo &info)> &callback, optional_ptr< FileOpener > opener=nullptr)
 
virtual DUCKDB_API bool TryRemoveFile (const string &filename, optional_ptr< FileOpener > opener=nullptr)
 Remvoe a file from disk if it exists - if it does not exist, return false.
 
virtual DUCKDB_API void RemoveFiles (const vector< string > &filenames, optional_ptr< FileOpener > opener=nullptr)
 Remove multiple files from disk - does not error if any file does not exist.
 
virtual DUCKDB_API string GetHomeDirectory ()
 Gets the users home directory.
 
virtual DUCKDB_API string ExpandPath (const string &path)
 Expands a given path, including e.g. expanding the home directory of the user.
 
virtual DUCKDB_API string PathSeparator (const string &path)
 Path separator for path.
 
DUCKDB_API string JoinPath (const string &a, const string &path)
 Join two paths together.
 
template<typename... ARGS>
string JoinPath (const string &a, const string &b, ARGS... args)
 
DUCKDB_API string ConvertSeparators (const string &path)
 Convert separators in a path to the local separators (e.g. convert "/" into \ on windows)
 
DUCKDB_API string ExtractBaseName (const string &path)
 Extract the base name of a file (e.g. if the input is lib/example.dll the base name is 'example')
 
DUCKDB_API string ExtractExtension (const string &path)
 Extract the extension of a file (e.g. if the input is lib/example.dll the extension is 'dll')
 
DUCKDB_API string ExtractName (const string &path)
 Extract the name of a file (e.g if the input is lib/example.dll the name is 'example.dll')
 
virtual DUCKDB_API vector< OpenFileInfoGlob (const string &path, FileOpener *opener=nullptr)
 Runs a glob on the file system, returning a list of matching files.
 
DUCKDB_API unique_ptr< MultiFileListGlob (const string &path, const FileGlobInput &input, optional_ptr< FileOpener > opener)
 
DUCKDB_API unique_ptr< MultiFileListGlobFileList (const string &path, const FileGlobInput &input=FileGlobOptions::DISALLOW_EMPTY)
 
DUCKDB_API vector< OpenFileInfoGlobFiles (const string &pattern, const FileGlobInput &input=FileGlobOptions::DISALLOW_EMPTY)
 
virtual DUCKDB_API void RegisterSubSystem (unique_ptr< FileSystem > sub_fs)
 registers a sub-file system to handle certain file name prefixes, e.g. http:// etc.
 
virtual DUCKDB_API void RegisterSubSystem (FileCompressionType compression_type, unique_ptr< FileSystem > fs)
 
virtual DUCKDB_API void UnregisterSubSystem (const string &name)
 Unregister a sub-filesystem by name.
 
virtual DUCKDB_API unique_ptr< FileSystemExtractSubSystem (const string &name)
 
virtual DUCKDB_API vector< string > ListSubSystems ()
 List registered sub-filesystems, including builtin ones.
 
virtual DUCKDB_API void Reset (FileHandle &handle)
 Reset a file to the beginning (equivalent to Seek(handle, 0) for simple files)
 
virtual DUCKDB_API bool IsManuallySet ()
 If FS was manually set by the user.
 
virtual DUCKDB_API unique_ptr< FileHandleOpenCompressedFile (QueryContext context, unique_ptr< FileHandle > handle, bool write)
 
virtual DUCKDB_API void SetDisabledFileSystems (const vector< string > &names)
 
virtual DUCKDB_API bool SubSystemIsDisabled (const string &name)
 
virtual DUCKDB_API bool IsDisabledForPath (const string &path)
 Check if the filesystem that would handle this path is disabled.
 
template<class TARGET >
TARGETCast ()
 
template<class TARGET >
const TARGETCast () const
 

Static Public Member Functions

static std::string GetLastErrorAsString ()
 
static bool IsPrivateFile (const string &path_p, FileOpener *opener)
 Checks a file is private (checks for 600 on linux/macos, TODO: currently always returns true on windows)
 
- Static Public Member Functions inherited from duckdb::FileSystem
static DUCKDB_API FileSystemGetFileSystem (ClientContext &context)
 
static DUCKDB_API FileSystemGetFileSystem (DatabaseInstance &db)
 
static DUCKDB_API FileSystemGet (AttachedDatabase &db)
 
static DUCKDB_API void SetWorkingDirectory (const string &path)
 Sets the working directory.
 
static DUCKDB_API string GetWorkingDirectory ()
 Gets the working directory.
 
static DUCKDB_API string GetHomeDirectory (optional_ptr< FileOpener > opener)
 Gets the users home directory.
 
static DUCKDB_API string ExpandPath (const string &path, optional_ptr< FileOpener > opener)
 Expands a given path, including e.g. expanding the home directory of the user.
 
static DUCKDB_API optional_idx GetAvailableMemory ()
 Returns the system-available memory in bytes. Returns DConstants::INVALID_INDEX if the system function fails.
 
static DUCKDB_API optional_idx GetAvailableDiskSpace (const string &path)
 Returns the space available on the disk. Returns DConstants::INVALID_INDEX if the information was not available.
 
static DUCKDB_API string GetEnvVariable (const string &name)
 Returns the value of an environment variable - or the empty string if it is not set.
 
static DUCKDB_API bool HasGlob (const string &str)
 Whether there is a glob in the string.
 
static DUCKDB_API unique_ptr< FileSystemCreateLocal ()
 Create a LocalFileSystem.
 
static DUCKDB_API bool IsRemoteFile (const string &path)
 Whether or not a file is remote or local, based only on file path.
 
static DUCKDB_API bool IsRemoteFile (const string &path, string &extension)
 
static DUCKDB_API bool IsDirectory (const OpenFileInfo &info)
 

Protected Member Functions

bool ListFilesExtended (const string &directory, const std::function< void(OpenFileInfo &info)> &callback, optional_ptr< FileOpener > opener) override
 
bool SupportsListFilesExtended () const override
 
unique_ptr< MultiFileListGlobFilesExtended (const string &path, const FileGlobInput &input, optional_ptr< FileOpener > opener) override
 
bool SupportsGlobExtended () const override
 
bool TryCanonicalizeExistingPath (string &path_p)
 
- Protected Member Functions inherited from duckdb::FileSystem
virtual DUCKDB_API unique_ptr< FileHandleOpenFileExtended (const OpenFileInfo &path, FileOpenFlags flags, optional_ptr< FileOpener > opener)
 
virtual DUCKDB_API bool SupportsOpenFileExtended () const
 

Private Member Functions

void SetFilePointer (FileHandle &handle, idx_t location)
 Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location.
 
idx_t GetFilePointer (FileHandle &handle)
 

Member Function Documentation

◆ OpenFile()

unique_ptr< FileHandle > duckdb::LocalFileSystem::OpenFile ( const string &  path,
FileOpenFlags  flags,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Reimplemented from duckdb::FileSystem.

78690 {
78691 auto path = ExpandPath(path_p, opener);
78692 if (flags.Compression() != FileCompressionType::UNCOMPRESSED) {
78693 throw NotImplementedException("Unsupported compression type for default file system");
78694 }
78695
78696 flags.Verify();
78697
78698 int open_flags = 0;
78699 int rc;
78700 bool open_read = flags.OpenForReading();
78701 bool open_write = flags.OpenForWriting();
78702 if (open_read && open_write) {
78703 open_flags = O_RDWR;
78704 } else if (open_read) {
78705 open_flags = O_RDONLY;
78706 } else if (open_write) {
78707 open_flags = O_WRONLY;
78708 } else {
78709 throw InternalException("READ, WRITE or both should be specified when opening a file");
78710 }
78711 if (open_write) {
78712 // need Read or Write
78713 D_ASSERT(flags.OpenForWriting());
78714 open_flags |= O_CLOEXEC;
78715 if (flags.CreateFileIfNotExists()) {
78716 open_flags |= O_CREAT;
78717 } else if (flags.OverwriteExistingFile()) {
78718 open_flags |= O_CREAT | O_TRUNC;
78719 }
78720 if (flags.OpenForAppending()) {
78721 open_flags |= O_APPEND;
78722 }
78723 }
78724 if (flags.DirectIO()) {
78725#if defined(__sun) && defined(__SVR4)
78726 throw InvalidInputException("DIRECT_IO not supported on Solaris");
78727#endif
78728#if defined(__DARWIN__) || defined(__APPLE__) || defined(__OpenBSD__)
78729 // OSX does not have O_DIRECT, instead we need to use fcntl afterwards to support direct IO
78730#else
78731 open_flags |= O_DIRECT;
78732#endif
78733 }
78734
78735 // Determine permissions
78736 mode_t filesec;
78737 if (flags.CreatePrivateFile()) {
78738 open_flags |= O_EXCL; // Ensure we error on existing files or the permissions may not set
78739 filesec = 0600;
78740 } else {
78741 filesec = 0666;
78742 }
78743
78744 if (flags.ExclusiveCreate()) {
78745 open_flags |= O_EXCL;
78746 }
78747
78748 // Open the file
78749 int fd = open(path.c_str(), open_flags, filesec);
78750
78751 if (fd == -1) {
78752 if (flags.ReturnNullIfNotExists() && errno == ENOENT) {
78753 return nullptr;
78754 }
78755 if (flags.ReturnNullIfExists() && errno == EEXIST) {
78756 return nullptr;
78757 }
78758 throw IOException({{"errno", std::to_string(errno)}}, "Cannot open file \"%s\": %s", path, strerror(errno));
78759 }
78760
78761#if defined(__DARWIN__) || defined(__APPLE__)
78762 if (flags.DirectIO()) {
78763 // OSX requires fcntl for Direct IO
78764 rc = fcntl(fd, F_NOCACHE, 1);
78765 if (rc == -1) {
78766 throw IOException("Could not enable direct IO for file \"%s\": %s", path, strerror(errno));
78767 }
78768 }
78769#endif
78770
78771 if (flags.Lock() != FileLockType::NO_LOCK) {
78772 // set lock on file
78773 // but only if it is not an input/output stream
78774 auto file_type = StatsInternal(fd, path_p).file_type;
78775 if (file_type != FileType::FILE_TYPE_FIFO && file_type != FileType::FILE_TYPE_SOCKET) {
78776 struct flock fl;
78777 memset(&fl, 0, sizeof fl);
78778 fl.l_type = flags.Lock() == FileLockType::READ_LOCK ? F_RDLCK : F_WRLCK;
78779 fl.l_whence = SEEK_SET;
78780 fl.l_start = 0;
78781 fl.l_len = 0;
78782 rc = fcntl(fd, F_SETLK, &fl);
78783 // Retain the original error.
78784 int retained_errno = errno;
78785 bool has_error = rc == -1;
78786 string extended_error;
78787 if (has_error) {
78788 if (retained_errno == ENOTSUP) {
78789 // file lock not supported for this file system
78790 if (flags.Lock() == FileLockType::READ_LOCK) {
78791 // for read-only, we ignore not-supported errors
78792 has_error = false;
78793 errno = 0;
78794 } else {
78795 extended_error = "File locks are not supported for this file system, cannot open the file in "
78796 "read-write mode. Try opening the file in read-only mode";
78797 }
78798 }
78799 }
78800 if (has_error) {
78801 if (extended_error.empty()) {
78802 // try to find out who is holding the lock using F_GETLK
78803 rc = fcntl(fd, F_GETLK, &fl);
78804 if (rc == -1) { // fnctl does not want to help us
78805 extended_error = strerror(errno);
78806 } else {
78807 extended_error = AdditionalProcessInfo(*this, fl.l_pid);
78808 }
78809 if (flags.Lock() == FileLockType::WRITE_LOCK) {
78810 // maybe we can get a read lock instead and tell this to the user.
78811 fl.l_type = F_RDLCK;
78812 rc = fcntl(fd, F_SETLK, &fl);
78813 if (rc != -1) { // success!
78814 extended_error +=
78815 ". However, you would be able to open this database in read-only mode, e.g. by "
78816 "using the -readonly parameter in the CLI";
78817 }
78818 }
78819 }
78820 rc = close(fd);
78821 if (rc == -1) {
78822 extended_error += ". Also, failed closing file";
78823 }
78824 extended_error += ". See also https://duckdb.org/docs/stable/connect/concurrency";
78825 throw IOException({{"errno", std::to_string(retained_errno)}}, "Could not set lock on file \"%s\": %s",
78826 path, extended_error);
78827 }
78828 }
78829 }
78830
78831 auto file_handle = make_uniq<UnixFileHandle>(*this, path, fd, flags);
78832 if (opener) {
78833 file_handle->TryAddLogger(*opener);
78834 DUCKDB_LOG_FILE_SYSTEM_OPEN((*file_handle));
78835 }
78836 return std::move(file_handle);
78837}
static DUCKDB_API string ExpandPath(const string &path, optional_ptr< FileOpener > opener)
Expands a given path, including e.g. expanding the home directory of the user.
Definition duckdb.cpp:73909
Ptr< HDF5 > open(const String &HDF5Filename)
@ FILE_TYPE_SOCKET
Socket.
@ FILE_TYPE_FIFO
FIFO named pipe.

◆ Read() [1/2]

void duckdb::LocalFileSystem::Read ( FileHandle handle,
void buffer,
int64_t  nr_bytes,
idx_t  location 
)
overridevirtual

Read exactly nr_bytes from the specified location in the file. Fails if nr_bytes could not be read. This is equivalent to calling SetFilePointer(location) followed by calling Read().

Reimplemented from duckdb::FileSystem.

78858 {
78859 auto bytes_to_read = nr_bytes;
78860 int fd = handle.Cast<UnixFileHandle>().fd;
78861 auto read_buffer = char_ptr_cast(buffer);
78862 while (nr_bytes > 0) {
78863 int64_t bytes_read =
78864 pread(fd, read_buffer, UnsafeNumericCast<size_t>(nr_bytes), UnsafeNumericCast<off_t>(location));
78865 if (bytes_read == -1) {
78866 throw IOException({{"errno", std::to_string(errno)}}, "Could not read from file \"%s\": %s", handle.path,
78867 strerror(errno));
78868 }
78869 if (bytes_read == 0) {
78870 throw IOException(
78871 "Could not read enough bytes from file \"%s\": attempted to read %llu bytes from location %llu",
78872 handle.path, nr_bytes, location);
78873 }
78874 read_buffer += bytes_read;
78875 nr_bytes -= bytes_read;
78876 location += UnsafeNumericCast<idx_t>(bytes_read);
78877 }
78878
78879 DUCKDB_LOG_FILE_SYSTEM_READ(handle, bytes_to_read, location - UnsafeNumericCast<idx_t>(bytes_to_read));
78880}
::int64_t int64_t

◆ Write() [1/2]

void duckdb::LocalFileSystem::Write ( FileHandle handle,
void buffer,
int64_t  nr_bytes,
idx_t  location 
)
overridevirtual

Write exactly nr_bytes to the specified location in the file. Fails if nr_bytes could not be written. This is equivalent to calling SetFilePointer(location) followed by calling Write().

Reimplemented from duckdb::FileSystem.

78897 {
78898 int fd = handle.Cast<UnixFileHandle>().fd;
78899 auto write_buffer = char_ptr_cast(buffer);
78900
78901 auto bytes_to_write = nr_bytes;
78902 auto current_location = location;
78903
78904 while (bytes_to_write > 0) {
78905 int64_t bytes_written = pwrite(fd, write_buffer, UnsafeNumericCast<size_t>(bytes_to_write),
78906 UnsafeNumericCast<off_t>(current_location));
78907 if (bytes_written < 0) {
78908 throw IOException({{"errno", std::to_string(errno)}}, "Could not write file \"%s\": %s", handle.path,
78909 strerror(errno));
78910 }
78911 if (bytes_written == 0) {
78912 throw IOException({{"errno", std::to_string(errno)}},
78913 "Could not write to file \"%s\" - attempted to write 0 bytes: %s", handle.path,
78914 strerror(errno));
78915 }
78916 write_buffer += bytes_written;
78917 bytes_to_write -= bytes_written;
78918 current_location += UnsafeNumericCast<idx_t>(bytes_written);
78919 }
78920
78921 DUCKDB_LOG_FILE_SYSTEM_WRITE(handle, nr_bytes, location);
78922}

◆ Read() [2/2]

int64_t duckdb::LocalFileSystem::Read ( FileHandle handle,
void buffer,
int64_t  nr_bytes 
)
overridevirtual

Read nr_bytes from the specified file into the buffer, moving the file pointer forward by nr_bytes. Returns the amount of bytes read.

Reimplemented from duckdb::FileSystem.

78882 {
78883 auto &unix_handle = handle.Cast<UnixFileHandle>();
78884 int fd = unix_handle.fd;
78885 int64_t bytes_read = read(fd, buffer, UnsafeNumericCast<size_t>(nr_bytes));
78886 if (bytes_read == -1) {
78887 throw IOException({{"errno", std::to_string(errno)}}, "Could not read from file \"%s\": %s", handle.path,
78888 strerror(errno));
78889 }
78890
78891 DUCKDB_LOG_FILE_SYSTEM_READ(handle, bytes_read, unix_handle.current_pos);
78892 unix_handle.current_pos += UnsafeNumericCast<idx_t>(bytes_read);
78893
78894 return bytes_read;
78895}
void read(const FileNode &fn, optflow::GPCTree::Node &node, optflow::GPCTree::Node)
Here is the call graph for this function:

◆ Write() [2/2]

int64_t duckdb::LocalFileSystem::Write ( FileHandle handle,
void buffer,
int64_t  nr_bytes 
)
overridevirtual

Write nr_bytes from the buffer into the file, moving the file pointer forward by nr_bytes.

Reimplemented from duckdb::FileSystem.

78924 {
78925 auto &unix_handle = handle.Cast<UnixFileHandle>();
78926 int fd = unix_handle.fd;
78927
78928 auto bytes_to_write = nr_bytes;
78929 while (bytes_to_write > 0) {
78930 auto bytes_to_write_this_call =
78931 MinValue<idx_t>(idx_t(NumericLimits<int32_t>::Maximum()), idx_t(bytes_to_write));
78932 int64_t current_bytes_written = write(fd, buffer, bytes_to_write_this_call);
78933 if (current_bytes_written <= 0) {
78934 throw IOException({{"errno", std::to_string(errno)}}, "Could not write file \"%s\": %s", handle.path,
78935 strerror(errno));
78936 }
78937 buffer = (void *)(data_ptr_cast(buffer) + current_bytes_written);
78938 bytes_to_write -= current_bytes_written;
78939 }
78940
78941 DUCKDB_LOG_FILE_SYSTEM_WRITE(handle, nr_bytes, unix_handle.current_pos);
78942 unix_handle.current_pos += UnsafeNumericCast<idx_t>(nr_bytes);
78943
78944 return nr_bytes;
78945}
void write(FileStorage &fs, const String &name, const optflow::GPCTree::Node &node)
uint64_t idx_t
a saner size_t for loop indices etc
Definition duckdb.hpp:237
Here is the call graph for this function:

◆ Trim()

bool duckdb::LocalFileSystem::Trim ( FileHandle handle,
idx_t  offset_bytes,
idx_t  length_bytes 
)
overridevirtual

Excise a range of the file. The file-system is free to deallocate this range (sparse file support). Reads to the range will succeed but will return undefined data.

Reimplemented from duckdb::FileSystem.

78947 {
78948#if defined(__linux__)
78949 // FALLOC_FL_PUNCH_HOLE requires glibc 2.18 or up
78950#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 18)
78951 return false;
78952#else
78953 int fd = handle.Cast<UnixFileHandle>().fd;
78954 int res = fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, UnsafeNumericCast<int64_t>(offset_bytes),
78955 UnsafeNumericCast<int64_t>(length_bytes));
78956 return res == 0;
78957#endif
78958#else
78959 return false;
78960#endif
78961}

◆ GetFileSize()

int64_t duckdb::LocalFileSystem::GetFileSize ( FileHandle handle)
overridevirtual

Returns the file size of a file handle, returns -1 on error.

Reimplemented from duckdb::FileSystem.

78963 {
78964 const auto file_metadata = Stats(handle);
78965 return file_metadata.file_size;
78966}
FileMetadata Stats(FileHandle &handle) override
Returns the file stats of the attached handle.
Definition duckdb.cpp:78978
Here is the call graph for this function:

◆ GetLastModifiedTime()

timestamp_t duckdb::LocalFileSystem::GetLastModifiedTime ( FileHandle handle)
overridevirtual

Returns the file last modified time of a file handle, returns timespec with zero on all attributes on error.

Reimplemented from duckdb::FileSystem.

78968 {
78969 const auto file_metadata = Stats(handle);
78970 return file_metadata.last_modification_time;
78971}
Here is the call graph for this function:

◆ GetVersionTag()

string duckdb::LocalFileSystem::GetVersionTag ( FileHandle handle)
overridevirtual

Returns a tag that uniquely identifies the version of the file.

Reimplemented from duckdb::FileSystem.

79902 {
79903 // TODO: Fix using FileSystem::Stats for v1.5, which should also fix it for Windows
79904#ifdef _WIN32
79905 return "";
79906#else
79907 int fd = handle.Cast<UnixFileHandle>().fd;
79908 struct stat s;
79909 if (fstat(fd, &s) == -1) {
79910 throw IOException("Failed to get file size for file \"%s\": %s", handle.path, strerror(errno));
79911 }
79912 return GetPosixVersionTag(s);
79913#endif
79914}

◆ GetFileType()

FileType duckdb::LocalFileSystem::GetFileType ( FileHandle handle)
overridevirtual

Returns the file last modified time of a file handle, returns timespec with zero on all attributes on error.

Reimplemented from duckdb::FileSystem.

78973 {
78974 const auto file_metadata = Stats(handle);
78975 return file_metadata.file_type;
78976}
Here is the call graph for this function:

◆ Stats()

FileMetadata duckdb::LocalFileSystem::Stats ( FileHandle handle)
overridevirtual

Returns the file stats of the attached handle.

Reimplemented from duckdb::FileSystem.

78978 {
78979 int fd = handle.Cast<UnixFileHandle>().fd;
78980 auto file_metadata = StatsInternal(fd, handle.GetPath());
78981 return file_metadata;
78982}
Here is the caller graph for this function:

◆ Truncate()

void duckdb::LocalFileSystem::Truncate ( FileHandle handle,
int64_t  new_size 
)
overridevirtual

Truncate a file to a maximum size of new_size, new_size should be smaller than or equal to the current size of the file

Reimplemented from duckdb::FileSystem.

78984 {
78985 int fd = handle.Cast<UnixFileHandle>().fd;
78986 if (ftruncate(fd, new_size) != 0) {
78987 throw IOException({{"errno", std::to_string(errno)}}, "Could not truncate file \"%s\": %s", handle.path,
78988 strerror(errno));
78989 }
78990}

◆ DirectoryExists()

bool duckdb::LocalFileSystem::DirectoryExists ( const string &  directory,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Check if a directory exists.

Reimplemented from duckdb::FileSystem.

78992 {
78993 if (!directory.empty()) {
78994 auto normalized_dir = ExpandPath(directory, opener);
78995 if (access(normalized_dir.c_str(), 0) == 0) {
78996 struct stat status;
78997 stat(normalized_dir.c_str(), &status);
78998 if (S_ISDIR(status.st_mode)) {
78999 return true;
79000 }
79001 }
79002 }
79003 // if any condition fails
79004 return false;
79005}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ CreateDirectory()

void duckdb::LocalFileSystem::CreateDirectory ( const string &  directory,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Create a directory if it does not exist.

Reimplemented from duckdb::FileSystem.

79007 {
79008 struct stat st;
79009
79010 auto normalized_dir = ExpandPath(directory, opener);
79011 if (stat(normalized_dir.c_str(), &st) != 0) {
79012 /* Directory does not exist. EEXIST for race condition */
79013 if (mkdir(normalized_dir.c_str(), 0755) != 0 && errno != EEXIST) {
79014 throw IOException({{"errno", std::to_string(errno)}}, "Failed to create directory \"%s\": %s", directory,
79015 strerror(errno));
79016 }
79017 } else if (!S_ISDIR(st.st_mode)) {
79018 throw IOException({{"errno", std::to_string(errno)}},
79019 "Failed to create directory \"%s\": path exists but is not a directory!", directory);
79020 }
79021}
Here is the call graph for this function:

◆ RemoveDirectory()

void duckdb::LocalFileSystem::RemoveDirectory ( const string &  directory,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Recursively remove a directory and all files in it.

Reimplemented from duckdb::FileSystem.

79063 {
79064 auto normalized_dir = ExpandPath(directory, opener);
79065 RemoveDirectoryRecursive(normalized_dir.c_str());
79066}
Here is the call graph for this function:

◆ MoveFile()

void duckdb::LocalFileSystem::MoveFile ( const string &  source,
const string &  target,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Move a file from source path to the target, StorageManager relies on this being an atomic action for ACID properties

FIXME: rename does not guarantee atomicity or overwriting target file if it exists

Reimplemented from duckdb::FileSystem.

79169 {
79170 auto normalized_source = ExpandPath(source, opener);
79171 auto normalized_target = ExpandPath(target, opener);
79173 if (rename(normalized_source.c_str(), normalized_target.c_str()) != 0) {
79174 throw IOException({{"errno", to_string(errno)}}, "Could not rename file \"%s\" to \"%s\": %s", source, target,
79175 strerror(errno));
79176 }
79177}
Here is the call graph for this function:

◆ FileExists()

bool duckdb::LocalFileSystem::FileExists ( const string &  filename,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Check if a file exists.

Reimplemented from duckdb::FileSystem.

78440 {
78441 if (!filename.empty()) {
78442 auto normalized_file = ExpandPath(filename, opener);
78443 if (access(normalized_file.c_str(), 0) == 0) {
78444 struct stat status;
78445 stat(normalized_file.c_str(), &status);
78446 if (S_ISREG(status.st_mode)) {
78447 return true;
78448 }
78449 }
78450 }
78451 // if any condition fails
78452 return false;
78453}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ IsPipe()

bool duckdb::LocalFileSystem::IsPipe ( const string &  filename,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Check if path is a pipe.

Reimplemented from duckdb::FileSystem.

78455 {
78456 if (!filename.empty()) {
78457 auto normalized_file = ExpandPath(filename, opener);
78458 if (access(normalized_file.c_str(), 0) == 0) {
78459 struct stat status;
78460 stat(normalized_file.c_str(), &status);
78461 if (S_ISFIFO(status.st_mode)) {
78462 return true;
78463 }
78464 }
78465 }
78466 // if any condition fails
78467 return false;
78468}
Here is the call graph for this function:

◆ RemoveFile()

void duckdb::LocalFileSystem::RemoveFile ( const string &  filename,
optional_ptr< FileOpener opener = nullptr 
)
overridevirtual

Remove a file from disk.

Reimplemented from duckdb::FileSystem.

79068 {
79069 auto normalized_file = ExpandPath(filename, opener);
79070 if (std::remove(normalized_file.c_str()) != 0) {
79071 throw IOException({{"errno", std::to_string(errno)}}, "Could not remove file \"%s\": %s", filename,
79072 strerror(errno));
79073 }
79074}
Here is the call graph for this function:

◆ FileSync()

void duckdb::LocalFileSystem::FileSync ( FileHandle handle)
overridevirtual

Sync a file handle to disk.

Reimplemented from duckdb::FileSystem.

79138 {
79139 int fd = handle.Cast<UnixFileHandle>().fd;
79140
79141#if HAVE_FULLFSYNC
79142 // On macOS and iOS, fsync() doesn't guarantee durability past power failures. fcntl(F_FULLFSYNC) is required for
79143 // that purpose. Some filesystems don't support fcntl(F_FULLFSYNC), and require a fallback to fsync().
79144 if (::fcntl(fd, F_FULLFSYNC) == 0) {
79145 return;
79146 }
79147#endif // HAVE_FULLFSYNC
79148
79149#if HAVE_FDATASYNC
79150 bool sync_success = ::fdatasync(fd) == 0;
79151#else
79152 bool sync_success = ::fsync(fd) == 0;
79153#endif // HAVE_FDATASYNC
79154
79155 if (sync_success) {
79156 return;
79157 }
79158
79159 // Use fatal exception to handle fsyncgate issue: `fsync` only reports EIO for once, which makes it unretriable and
79160 // data loss unrecoverable.
79161 if (errno == EIO) {
79162 throw FatalException("fsync failed!");
79163 }
79164
79165 // For other types of errors, throw normal IO exception.
79166 throw IOException("Could not fsync file \"%s\": %s", handle.GetPath(), strerror(errno));
79167}

◆ IsPathAbsolute()

bool duckdb::LocalFileSystem::IsPathAbsolute ( const string &  path)
overridevirtual

Checks if path is is an absolute path.

Reimplemented from duckdb::FileSystem.

79196 {
79197 return FileSystem::IsPathAbsolute(path);
79198}
virtual DUCKDB_API bool IsPathAbsolute(const string &path)
Checks if path is is an absolute path.
Definition duckdb.cpp:73636
Here is the call graph for this function:

◆ MakePathAbsolute()

string duckdb::LocalFileSystem::MakePathAbsolute ( const string &  input,
optional_ptr< FileOpener opener 
)
79200 {
79201 auto path = ExpandPath(path_p, opener);
79202 if (!IsPathAbsolute(path)) {
79203 // path is not absolute - join with working directory
79204 return JoinPath(GetWorkingDirectory(), path);
79205 } else {
79206 // already absolute
79207 return path;
79208 }
79209}
DUCKDB_API string JoinPath(const string &a, const string &path)
Join two paths together.
Definition duckdb.cpp:73803
static DUCKDB_API string GetWorkingDirectory()
Gets the working directory.
Definition duckdb.cpp:73685
bool IsPathAbsolute(const string &path) override
Checks if path is is an absolute path.
Definition duckdb.cpp:79196

◆ PathStartsWithDrive()

bool duckdb::LocalFileSystem::PathStartsWithDrive ( const string &  path)
79192 {
79193 return false;
79194}

◆ CanHandleFile()

bool duckdb::LocalFileSystem::CanHandleFile ( const string &  fpath)
inlineoverridevirtual

Whether or not a sub-system can handle a specific file path.

Whether or not a sub-system can handle a specific file path

Reimplemented from duckdb::FileSystem.

78240 {
78242 return false;
78243 }

◆ Seek()

void duckdb::LocalFileSystem::Seek ( FileHandle handle,
idx_t  location 
)
overridevirtual

Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location.

Reimplemented from duckdb::FileSystem.

79916 {
79917 if (!CanSeek()) {
79918 throw IOException("Cannot seek in files of this type");
79919 }
79920 SetFilePointer(handle, location);
79921}
void SetFilePointer(FileHandle &handle, idx_t location)
Set the file pointer of a file handle to a specified location. Reads and writes will happen from this...
Definition duckdb.cpp:78839
bool CanSeek() override
Whether or not we can seek into the file.
Definition duckdb.cpp:79817
Here is the call graph for this function:

◆ SeekPosition()

idx_t duckdb::LocalFileSystem::SeekPosition ( FileHandle handle)
overridevirtual

Return the current seek posiiton in the file.

Reimplemented from duckdb::FileSystem.

79923 {
79924 if (!CanSeek()) {
79925 throw IOException("Cannot seek in files of this type");
79926 }
79927 return GetFilePointer(handle);
79928}
Here is the call graph for this function:

◆ CanSeek()

bool duckdb::LocalFileSystem::CanSeek ( )
overridevirtual

Whether or not we can seek into the file.

Reimplemented from duckdb::FileSystem.

79817 {
79818 return true;
79819}
Here is the caller graph for this function:

◆ OnDiskFile()

bool duckdb::LocalFileSystem::OnDiskFile ( FileHandle handle)
overridevirtual

Whether or not the FS handles plain files on disk. This is relevant for certain optimizations, as random reads in a file on-disk are much cheaper than e.g. random reads in a file over the network

Reimplemented from duckdb::FileSystem.

79821 {
79822 return true;
79823}

◆ GetName()

std::string duckdb::LocalFileSystem::GetName ( ) const
inlineoverridevirtual

Return the name of the filesytem. Used for forming diagnosis messages.

Implements duckdb::FileSystem.

78256 {
78257 return "LocalFileSystem";
78258 }

◆ GetLastErrorAsString()

std::string duckdb::LocalFileSystem::GetLastErrorAsString ( )
static

Returns the last Win32 error, in string format. Returns an empty string if there is no error, or on non-Windows systems.

79179 {
79180 return string();
79181}

◆ IsPrivateFile()

bool duckdb::LocalFileSystem::IsPrivateFile ( const string &  path_p,
FileOpener opener 
)
static

Checks a file is private (checks for 600 on linux/macos, TODO: currently always returns true on windows)

78670 {
78671 auto path = FileSystem::ExpandPath(path_p, opener);
78672
78673 struct stat st;
78674
78675 if (lstat(path.c_str(), &st) != 0) {
78676 throw IOException(
78677 "Failed to stat '%s' when checking file permissions, file may be missing or have incorrect permissions",
78678 path_p.c_str());
78679 }
78680
78681 // If group or other have any permission, the file is not private
78682 if (st.st_mode & (S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH)) {
78683 return false;
78684 }
78685
78686 return true;
78687}
Here is the call graph for this function:

◆ FetchFileWithoutGlob()

vector< OpenFileInfo > duckdb::LocalFileSystem::FetchFileWithoutGlob ( const string &  path,
optional_ptr< FileOpener opener,
bool  absolute_path 
)
79950 {
79951 vector<OpenFileInfo> result;
79952 if (FileExists(path, opener) || IsPipe(path, opener)) {
79953 result.emplace_back(path);
79954 } else if (!absolute_path) {
79955 Value value;
79956 if (opener && opener->TryGetCurrentSetting("file_search_path", value)) {
79957 auto search_paths_str = value.ToString();
79958 vector<std::string> search_paths = StringUtil::Split(search_paths_str, ',');
79959 for (const auto &search_path : search_paths) {
79960 auto joined_path = JoinPath(search_path, path);
79961 if (FileExists(joined_path, opener) || IsPipe(joined_path, opener)) {
79962 result.emplace_back(joined_path);
79963 }
79964 }
79965 }
79966 }
79967 return result;
79968}
bool FileExists(const string &filename, optional_ptr< FileOpener > opener=nullptr) override
Check if a file exists.
Definition duckdb.cpp:78440
bool IsPipe(const string &filename, optional_ptr< FileOpener > opener=nullptr) override
Check if path is a pipe.
Definition duckdb.cpp:78455
static DUCKDB_API vector< string > Split(const string &str, char delimiter)
Split the input string based on newline char.

◆ CanonicalizePath()

string duckdb::LocalFileSystem::CanonicalizePath ( const string &  path,
optional_ptr< FileOpener opener 
)
overridevirtual

Canonicalize a path.

Reimplemented from duckdb::FileSystem.

79825 {
79826 auto path_sep = PathSeparator(input);
79827 if (path_sep.size() != 1) {
79828 throw InternalException("path separator can only be a single byte for local file systems");
79829 }
79830 // make the path absolute
79831 string path = MakePathAbsolute(input, opener);
79832
79833 string current = path;
79834 string remainder;
79835 idx_t dot_dot_count = 0;
79836 bool is_drive = false;
79837 while (!current.empty()) {
79838 if (dot_dot_count == 0 && TryCanonicalizeExistingPath(current)) {
79839 // successfully canonicalized "current" - add remainder if we have any
79840 if (remainder.empty()) {
79841 return current;
79842 }
79843 if (StringUtil::EndsWith(current, path_sep)) {
79844 return current + remainder;
79845 }
79846 return current + path_sep + remainder;
79847 }
79848 if (is_drive) {
79849 // this is a drive only (e.g. C:\‍)
79850 // if we reach this, this is an unknown drive letter
79851 // use fallback canonicalize for the remainder
79852 return current + FileSystem::CanonicalizePath(remainder);
79853 }
79854 // move up one directory
79855 optional_idx sep_idx;
79856 for (idx_t i = current.size(); i > 0; i--) {
79857 // on windows we accept both separators (\ and /, and also :)
79858 if (current[i - 1] == path_sep[0] || current[i - 1] == '/') {
79859 sep_idx = i - 1;
79860 break;
79861 }
79862 }
79863 if (!sep_idx.IsValid()) {
79864 // exhausted the full path and nothing exists - break out
79865 current = string();
79866 break;
79867 }
79868 auto sep = sep_idx.GetIndex();
79869 auto component = current.substr(sep + 1);
79870 if (component == "..") {
79871 // dot dot - we need to move up a level
79872 // increment the count
79873 dot_dot_count++;
79874 } else if (!component.empty() && component != ".") {
79875 if (dot_dot_count > 0) {
79876 // just clear this directory
79877 dot_dot_count--;
79878 } else {
79879 // add component to remainder - unless it's dot or empty
79880 if (remainder.empty()) {
79881 remainder = component;
79882 } else {
79883 remainder = component + path_sep + remainder;
79884 }
79885 }
79886 }
79887 // continue with remainder
79888 current = current.substr(0, sep);
79889 if (current.size() == 2 && PathStartsWithDrive(current)) {
79890 // Windows only
79891 // C: and C:\\ mean different things (C: is relative, C:\\ is absolute)
79892 // we should have already normalized to C:\\ earlier on in this function
79893 // so turn this base drive letter into C:\\ for the final lookup
79894 is_drive = true;
79895 current += "\\";
79896 }
79897 }
79898 // failed to canonicalize path - fallback to generic canonicalization
79899 return FileSystem::CanonicalizePath(path);
79900}
virtual DUCKDB_API string PathSeparator(const string &path)
Path separator for path.
Definition duckdb.cpp:73641
virtual DUCKDB_API string CanonicalizePath(const string &path, optional_ptr< FileOpener > opener=nullptr)
Canonicalize a path.
Definition duckdb.cpp:74428
static DUCKDB_API bool EndsWith(const string &str, const string &suffix)
Returns true if the target string ends with the given suffix.
Here is the call graph for this function:

◆ ListFilesExtended()

bool duckdb::LocalFileSystem::ListFilesExtended ( const string &  directory,
const std::function< void(OpenFileInfo &info)> &  callback,
optional_ptr< FileOpener opener 
)
overrideprotectedvirtual

Reimplemented from duckdb::FileSystem.

79089 {
79090 auto normalized_dir = ExpandPath(directory, opener);
79091 auto dir = opendir(normalized_dir.c_str());
79092 if (!dir) {
79093 return false;
79094 }
79095
79096 // RAII wrapper around DIR to automatically free on exceptions in callback
79097 duckdb::unique_ptr<DIR, std::function<void(DIR *)>> dir_unique_ptr(dir, [](DIR *d) { closedir(d); });
79098
79099 struct dirent *ent;
79100 // loop over all files in the directory
79101 while ((ent = readdir(dir)) != nullptr) {
79102 OpenFileInfo info(ent->d_name);
79103 auto &name = info.path;
79104 // skip . .. and empty files
79105 if (name.empty() || name == "." || name == "..") {
79106 continue;
79107 }
79108 // now stat the file to figure out if it is a regular file or directory
79109 string full_path = JoinPath(normalized_dir, name);
79110 struct stat status;
79111 auto res = stat(full_path.c_str(), &status);
79112 if (res != 0) {
79113 continue;
79114 }
79115 if (!S_ISREG(status.st_mode) && !S_ISDIR(status.st_mode)) {
79116 // not a file or directory: skip
79117 continue;
79118 }
79119 // create extended info
79120 info.extended_info = make_shared_ptr<ExtendedOpenFileInfo>();
79121 auto &options = info.extended_info->options;
79122 // file type
79123 Value file_type(S_ISDIR(status.st_mode) ? "directory" : "file");
79124 options.emplace("type", std::move(file_type));
79125 // file size
79126 options.emplace("file_size", Value::BIGINT(UnsafeNumericCast<int64_t>(status.st_size)));
79127 // last modified time
79128 options.emplace("last_modified", Value::TIMESTAMP(Timestamp::FromTimeT(status.st_mtime)));
79129 // version tag
79130 options.emplace("etag", Value::BLOB_RAW(GetPosixVersionTag(status)));
79131
79132 // invoke callback
79133 callback(info);
79134 }
79135 return true;
79136}
static DUCKDB_API Value BIGINT(int64_t value)
Create a bigint Value from a specified value.
static DUCKDB_API Value TIMESTAMP(date_t date, dtime_t time)
Create a timestamp Value from a specified date/time combination.
Definition duckdb.hpp:960

◆ SupportsListFilesExtended()

bool duckdb::LocalFileSystem::SupportsListFilesExtended ( ) const
inlineoverrideprotectedvirtual

Reimplemented from duckdb::FileSystem.

78275 {
78276 return true;
78277 }

◆ GlobFilesExtended()

unique_ptr< MultiFileList > duckdb::LocalFileSystem::GlobFilesExtended ( const string &  path,
const FileGlobInput input,
optional_ptr< FileOpener opener 
)
overrideprotectedvirtual

Reimplemented from duckdb::FileSystem.

80210 {
80211 return make_uniq<LocalGlobResult>(*this, path, FileGlobOptions::ALLOW_EMPTY, opener);
80212}

◆ SupportsGlobExtended()

bool duckdb::LocalFileSystem::SupportsGlobExtended ( ) const
inlineoverrideprotectedvirtual

Reimplemented from duckdb::FileSystem.

78281 {
78282 return true;
78283 }

◆ TryCanonicalizeExistingPath()

bool duckdb::LocalFileSystem::TryCanonicalizeExistingPath ( string &  path_p)
protected
79183 {
79184 char resolved[PATH_MAX];
79185 if (!realpath(input.c_str(), resolved)) {
79186 return false;
79187 }
79188 input = resolved;
79189 return true;
79190}

◆ SetFilePointer()

void duckdb::LocalFileSystem::SetFilePointer ( FileHandle handle,
idx_t  location 
)
private

Set the file pointer of a file handle to a specified location. Reads and writes will happen from this location.

78839 {
78840 int fd = handle.Cast<UnixFileHandle>().fd;
78841 off_t offset = lseek(fd, UnsafeNumericCast<off_t>(location), SEEK_SET);
78842 if (offset == (off_t)-1) {
78843 throw IOException({{"errno", std::to_string(errno)}}, "Could not seek to location %lld for file \"%s\": %s",
78844 location, handle.path, strerror(errno));
78845 }
78846}
Here is the caller graph for this function:

◆ GetFilePointer()

idx_t duckdb::LocalFileSystem::GetFilePointer ( FileHandle handle)
private
78848 {
78849 int fd = handle.Cast<UnixFileHandle>().fd;
78850 off_t position = lseek(fd, 0, SEEK_CUR);
78851 if (position == (off_t)-1) {
78852 throw IOException({{"errno", std::to_string(errno)}}, "Could not get file position file \"%s\": %s",
78853 handle.path, strerror(errno));
78854 }
78855 return UnsafeNumericCast<idx_t>(position);
78856}

The documentation for this class was generated from the following file: