Skip to content

Commit 296f94c

Browse files
committed
feat: fixes for DuckDB 1.2
1 parent 925235b commit 296f94c

File tree

3 files changed

+137
-115
lines changed

3 files changed

+137
-115
lines changed

duckdb

Submodule duckdb updated 2851 files

src/shell_file_system.cpp

Lines changed: 135 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "duckdb/common/helper.hpp"
66
#include "duckdb/common/limits.hpp"
77

8-
98
#ifndef _WIN32
109
#include <dirent.h>
1110
#include <fcntl.h>
@@ -31,156 +30,179 @@
3130

3231
#endif
3332

33+
namespace duckdb
34+
{
3435

35-
namespace duckdb {
36-
37-
struct ShellFileHandle : public FileHandle {
38-
public:
39-
ShellFileHandle(FileSystem &file_system, string path, FILE *pipe) : FileHandle(file_system, std::move(path)), pipe(pipe) {
40-
}
41-
~ShellFileHandle() override {
42-
ShellFileHandle::Close();
43-
}
36+
struct ShellFileHandle : public FileHandle
37+
{
38+
public:
39+
ShellFileHandle(FileSystem &file_system, string path, FILE *pipe, FileOpenFlags flags) : FileHandle(file_system, std::move(path), std::move(flags)), pipe(pipe)
40+
{
41+
}
42+
~ShellFileHandle() override
43+
{
44+
ShellFileHandle::Close();
45+
}
4446

45-
FILE *pipe;
47+
FILE *pipe;
4648

47-
public:
48-
void Close() override {
49-
if(!pipe) {
50-
return;
51-
}
49+
public:
50+
void Close() override
51+
{
52+
if (!pipe)
53+
{
54+
return;
55+
}
5256

53-
int result;
57+
int result;
5458

5559
#ifndef _WIN32
56-
result = pclose(pipe);
60+
result = pclose(pipe);
5761
#else
58-
result = _pclose(pipe);
62+
result = _pclose(pipe);
5963
#endif
60-
// Indicate that the pipe has been closed.
61-
pipe = NULL;
64+
// Indicate that the pipe has been closed.
65+
pipe = NULL;
6266

63-
if(result == -1) {
64-
throw IOException("Could not close pipe \"%s\": %s", {{"errno", std::to_string(errno)}}, path,
65-
strerror(errno));
66-
} else {
67+
if (result == -1)
68+
{
69+
throw IOException("Could not close pipe \"%s\": %s", {{"errno", std::to_string(errno)}}, path,
70+
strerror(errno));
71+
}
72+
else
73+
{
6774
#ifndef _WIN32
68-
if(WIFEXITED(result)) {
69-
int exit_status = WEXITSTATUS(result);
70-
if (exit_status != 0) {
71-
throw IOException("Pipe process exited with non-zero exit code=\"%d\": %s", exit_status, path);
72-
} else if (WIFSIGNALED(result)) {
73-
int signal_number = WTERMSIG(result);
74-
throw IOException("Pipe process exited with signal signal=\"%d\": %s", signal_number, path);
75-
} else if(exit_status != 0) {
76-
throw IOException("Pipe process exited abnormally: %s", path);
75+
if (WIFEXITED(result))
76+
{
77+
int exit_status = WEXITSTATUS(result);
78+
if (exit_status != 0)
79+
{
80+
throw IOException("Pipe process exited with non-zero exit code=\"%d\": %s", exit_status, path);
81+
}
82+
else if (WIFSIGNALED(result))
83+
{
84+
int signal_number = WTERMSIG(result);
85+
throw IOException("Pipe process exited with signal signal=\"%d\": %s", signal_number, path);
86+
}
87+
else if (exit_status != 0)
88+
{
89+
throw IOException("Pipe process exited abnormally: %s", path);
90+
}
7791
}
78-
}
7992
#endif
80-
}
93+
}
94+
};
8195
};
82-
};
83-
84-
void ShellFileSystem::Reset(FileHandle &handle) {
85-
throw InternalException("Cannot reset shell file system");
86-
}
8796

88-
89-
int64_t ShellFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes) {
90-
FILE *pipe = handle.Cast<ShellFileHandle>().pipe;
91-
92-
if (!pipe) {
93-
return 0;
94-
}
95-
96-
int64_t bytes_read = fread(buffer, 1, nr_bytes, pipe);
97-
if (bytes_read == -1)
97+
void ShellFileSystem::Reset(FileHandle &handle)
9898
{
99-
throw IOException("Could not read from pipe \"%s\": %s", {{"errno", std::to_string(errno)}}, handle.path,
100-
strerror(errno));
101-
}
102-
if (bytes_read == 0) {
103-
// Since the last read() returned 0 bytes, presume that EOF has been encountered, and rather than
104-
// having the close, by doing this if there are errors with the pipe they are caught in the query
105-
// rather than in the destructor.
106-
handle.Close();
99+
throw InternalException("Cannot reset shell file system");
107100
}
108-
return bytes_read;
109-
}
110101

102+
int64_t ShellFileSystem::Read(FileHandle &handle, void *buffer, int64_t nr_bytes)
103+
{
104+
FILE *pipe = handle.Cast<ShellFileHandle>().pipe;
111105

112-
int64_t ShellFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) {
113-
FILE *pipe = handle.Cast<ShellFileHandle>().pipe;
114-
int64_t bytes_written = 0;
106+
if (!pipe)
107+
{
108+
return 0;
109+
}
115110

116-
while (nr_bytes > 0)
117-
{
118-
auto bytes_to_write = MinValue<idx_t>(idx_t(NumericLimits<int32_t>::Maximum()), idx_t(nr_bytes));
119-
int64_t current_bytes_written = fwrite(buffer, 1, bytes_to_write, pipe);
120-
if (current_bytes_written <= 0) {
121-
throw IOException("Could not write to pipe \"%s\": %s", {{"errno", std::to_string(errno)}}, handle.path,
111+
int64_t bytes_read = fread(buffer, 1, nr_bytes, pipe);
112+
if (bytes_read == -1)
113+
{
114+
throw IOException("Could not read from pipe \"%s\": %s", {{"errno", std::to_string(errno)}}, handle.path,
122115
strerror(errno));
123116
}
124-
bytes_written += current_bytes_written;
125-
buffer = (void *)(data_ptr_cast(buffer) + current_bytes_written);
126-
nr_bytes -= current_bytes_written;
117+
if (bytes_read == 0)
118+
{
119+
// Since the last read() returned 0 bytes, presume that EOF has been encountered, and rather than
120+
// having the close, by doing this if there are errors with the pipe they are caught in the query
121+
// rather than in the destructor.
122+
handle.Close();
123+
}
124+
return bytes_read;
127125
}
128126

129-
return bytes_written;
130-
}
127+
int64_t ShellFileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes)
128+
{
129+
FILE *pipe = handle.Cast<ShellFileHandle>().pipe;
130+
int64_t bytes_written = 0;
131+
132+
while (nr_bytes > 0)
133+
{
134+
auto bytes_to_write = MinValue<idx_t>(idx_t(NumericLimits<int32_t>::Maximum()), idx_t(nr_bytes));
135+
int64_t current_bytes_written = fwrite(buffer, 1, bytes_to_write, pipe);
136+
if (current_bytes_written <= 0)
137+
{
138+
throw IOException("Could not write to pipe \"%s\": %s", {{"errno", std::to_string(errno)}}, handle.path,
139+
strerror(errno));
140+
}
141+
bytes_written += current_bytes_written;
142+
buffer = (void *)(data_ptr_cast(buffer) + current_bytes_written);
143+
nr_bytes -= current_bytes_written;
144+
}
145+
146+
return bytes_written;
147+
}
131148

132-
int64_t ShellFileSystem::GetFileSize(FileHandle &handle) {
133-
// You can't know the size of the data that will come over a pipe
134-
// some code uses the size to allocate buffers, so don't return
135-
// a very large number.
136-
return 0;
137-
}
149+
int64_t ShellFileSystem::GetFileSize(FileHandle &handle)
150+
{
151+
// You can't know the size of the data that will come over a pipe
152+
// some code uses the size to allocate buffers, so don't return
153+
// a very large number.
154+
return 0;
155+
}
138156

139-
unique_ptr<FileHandle> ShellFileSystem::OpenFile(const string &path, FileOpenFlags flags,
140-
optional_ptr<FileOpener> opener) {
141-
FILE *pipe;
142-
if (path.front() == '|')
157+
unique_ptr<FileHandle> ShellFileSystem::OpenFile(const string &path, FileOpenFlags flags,
158+
optional_ptr<FileOpener> opener)
143159
{
144-
// We want to write to the pipe.
160+
FILE *pipe;
161+
if (path.front() == '|')
162+
{
163+
// We want to write to the pipe.
145164
#ifndef _WIN32
146-
pipe = popen(path.substr(1, path.size()).c_str(), "w");
165+
pipe = popen(path.substr(1, path.size()).c_str(), "w");
147166
#else
148-
pipe = _popen(path.substr(1, path.size()).c_str(), "w");
167+
pipe = _popen(path.substr(1, path.size()).c_str(), "w");
149168
#endif
150-
}
151-
else
152-
{
153-
// We want to read from the pipe
169+
}
170+
else
171+
{
172+
// We want to read from the pipe
154173
#ifndef _WIN32
155-
pipe = popen(path.substr(0, path.size()-1).c_str(), "r");
174+
pipe = popen(path.substr(0, path.size() - 1).c_str(), "r");
156175
#else
157-
pipe = _popen(path.substr(0, path.size()-1).c_str(), "r");
176+
pipe = _popen(path.substr(0, path.size() - 1).c_str(), "r");
158177
#endif
159-
}
178+
}
160179

161180
#ifndef _WIN32
162-
Value value;
163-
bool ignore_sigpipe = false;
164-
if (FileOpener::TryGetCurrentSetting(opener, "ignore_sigpipe", value))
165-
{
166-
ignore_sigpipe = value.GetValue<bool>();
167-
}
181+
Value value;
182+
bool ignore_sigpipe = false;
183+
if (FileOpener::TryGetCurrentSetting(opener, "ignore_sigpipe", value))
184+
{
185+
ignore_sigpipe = value.GetValue<bool>();
186+
}
168187

169-
if(ignore_sigpipe) {
170-
signal(SIGPIPE, SIG_IGN);
171-
}
188+
if (ignore_sigpipe)
189+
{
190+
signal(SIGPIPE, SIG_IGN);
191+
}
172192
#endif
173193

174-
return make_uniq<ShellFileHandle>(*this, path, pipe);
175-
}
194+
return make_uniq<ShellFileHandle>(*this, path, pipe, flags);
195+
}
176196

177-
bool ShellFileSystem::CanHandleFile(const string &fpath) {
178-
if (fpath.empty()) {
179-
return false;
197+
bool ShellFileSystem::CanHandleFile(const string &fpath)
198+
{
199+
if (fpath.empty())
200+
{
201+
return false;
202+
}
203+
// If the filename ends with | or starts with |
204+
// it can be handled by this file system.
205+
return fpath.back() == '|' || fpath.front() == '|';
180206
}
181-
// If the filename ends with | or starts with |
182-
// it can be handled by this file system.
183-
return fpath.back() == '|' || fpath.front() == '|';
184-
}
185207

186208
} // namespace duckdb

0 commit comments

Comments
 (0)