duckdb 0.8.2-dev2044.0 → 0.8.2-dev2068.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/configure.py +7 -2
- package/package.json +1 -1
- package/src/duckdb/src/common/adbc/adbc.cpp +18 -4
- package/src/duckdb/src/function/table/version/pragma_version.cpp +2 -2
- package/src/duckdb/src/include/duckdb/common/assert.hpp +1 -1
- package/src/duckdb/src/include/duckdb/core_functions/scalar/math_functions.hpp +3 -3
- package/src/duckdb/src/planner/expression/bound_window_expression.cpp +1 -4
- package/src/duckdb/third_party/concurrentqueue/lightweightsemaphore.h +3 -76
- package/src/duckdb/third_party/libpg_query/pg_functions.cpp +13 -0
- package/src/duckdb/third_party/libpg_query/src_backend_parser_scansup.cpp +9 -0
package/configure.py
CHANGED
@@ -31,6 +31,7 @@ if os.environ.get('DUCKDB_NODE_BUILD_CACHE') == '1' and os.path.isfile(cache_fil
|
|
31
31
|
windows_options = cache['windows_options']
|
32
32
|
cflags = cache['cflags']
|
33
33
|
elif 'DUCKDB_NODE_BINDIR' in os.environ:
|
34
|
+
|
34
35
|
def find_library_path(libdir, libname):
|
35
36
|
flist = os.listdir(libdir)
|
36
37
|
for fname in flist:
|
@@ -38,6 +39,7 @@ elif 'DUCKDB_NODE_BINDIR' in os.environ:
|
|
38
39
|
if os.path.isfile(fpath) and package_build.file_is_lib(fname, libname):
|
39
40
|
return fpath
|
40
41
|
raise Exception(f"Failed to find library {libname} in {libdir}")
|
42
|
+
|
41
43
|
# existing build
|
42
44
|
existing_duckdb_dir = os.environ['DUCKDB_NODE_BINDIR']
|
43
45
|
cflags = os.environ['DUCKDB_NODE_CFLAGS']
|
@@ -48,7 +50,7 @@ elif 'DUCKDB_NODE_BINDIR' in os.environ:
|
|
48
50
|
|
49
51
|
result_libraries = package_build.get_libraries(existing_duckdb_dir, libraries, extensions)
|
50
52
|
libraries = []
|
51
|
-
for
|
53
|
+
for libdir, libname in result_libraries:
|
52
54
|
if libdir is None:
|
53
55
|
continue
|
54
56
|
libraries.append(find_library_path(libdir, libname))
|
@@ -72,7 +74,7 @@ elif 'DUCKDB_NODE_BINDIR' in os.environ:
|
|
72
74
|
'include_list': include_list,
|
73
75
|
'libraries': libraries,
|
74
76
|
'cflags': cflags,
|
75
|
-
'windows_options': windows_options
|
77
|
+
'windows_options': windows_options,
|
76
78
|
}
|
77
79
|
with open(cache_file, 'wb+') as f:
|
78
80
|
pickle.dump(cache, f)
|
@@ -90,9 +92,11 @@ else:
|
|
90
92
|
windows_options = ['/GR']
|
91
93
|
cflags = ['-frtti']
|
92
94
|
|
95
|
+
|
93
96
|
def sanitize_path(x):
|
94
97
|
return x.replace('\\', '/')
|
95
98
|
|
99
|
+
|
96
100
|
source_list = [sanitize_path(x) for x in source_list]
|
97
101
|
include_list = [sanitize_path(x) for x in include_list]
|
98
102
|
libraries = [sanitize_path(x) for x in libraries]
|
@@ -100,6 +104,7 @@ libraries = [sanitize_path(x) for x in libraries]
|
|
100
104
|
with open(gyp_in, 'r') as f:
|
101
105
|
input_json = json.load(f)
|
102
106
|
|
107
|
+
|
103
108
|
def replace_entries(node, replacement_map):
|
104
109
|
if type(node) == type([]):
|
105
110
|
for key in replacement_map.keys():
|
package/package.json
CHANGED
@@ -52,12 +52,14 @@ duckdb_adbc::AdbcStatusCode duckdb_adbc_init(size_t count, struct duckdb_adbc::A
|
|
52
52
|
|
53
53
|
namespace duckdb_adbc {
|
54
54
|
|
55
|
+
enum class IngestionMode { CREATE = 0, APPEND = 1 };
|
55
56
|
struct DuckDBAdbcStatementWrapper {
|
56
57
|
::duckdb_connection connection;
|
57
58
|
::duckdb_arrow result;
|
58
59
|
::duckdb_prepared_statement statement;
|
59
60
|
char *ingestion_table_name;
|
60
61
|
ArrowArrayStream *ingestion_stream;
|
62
|
+
IngestionMode ingestion_mode = IngestionMode::CREATE;
|
61
63
|
};
|
62
64
|
static AdbcStatusCode QueryInternal(struct AdbcConnection *connection, struct ArrowArrayStream *out, const char *query,
|
63
65
|
struct AdbcError *error);
|
@@ -428,7 +430,7 @@ void stream_schema(uintptr_t factory_ptr, duckdb::ArrowSchemaWrapper &schema) {
|
|
428
430
|
}
|
429
431
|
|
430
432
|
AdbcStatusCode Ingest(duckdb_connection connection, const char *table_name, struct ArrowArrayStream *input,
|
431
|
-
struct AdbcError *error) {
|
433
|
+
struct AdbcError *error, IngestionMode ingestion_mode) {
|
432
434
|
|
433
435
|
auto status = SetErrorMaybe(connection, error, "Invalid connection");
|
434
436
|
if (status != ADBC_STATUS_OK) {
|
@@ -446,12 +448,11 @@ AdbcStatusCode Ingest(duckdb_connection connection, const char *table_name, stru
|
|
446
448
|
}
|
447
449
|
auto cconn = (duckdb::Connection *)connection;
|
448
450
|
|
449
|
-
auto has_table = cconn->TableInfo(table_name);
|
450
451
|
auto arrow_scan = cconn->TableFunction("arrow_scan", {duckdb::Value::POINTER((uintptr_t)input),
|
451
452
|
duckdb::Value::POINTER((uintptr_t)stream_produce),
|
452
453
|
duckdb::Value::POINTER((uintptr_t)get_schema)});
|
453
454
|
try {
|
454
|
-
if (
|
455
|
+
if (ingestion_mode == IngestionMode::CREATE) {
|
455
456
|
// We create the table based on an Arrow Scanner
|
456
457
|
arrow_scan->Create(table_name);
|
457
458
|
} else {
|
@@ -505,6 +506,7 @@ AdbcStatusCode StatementNew(struct AdbcConnection *connection, struct AdbcStatem
|
|
505
506
|
statement_wrapper->result = nullptr;
|
506
507
|
statement_wrapper->ingestion_stream = nullptr;
|
507
508
|
statement_wrapper->ingestion_table_name = nullptr;
|
509
|
+
statement_wrapper->ingestion_mode = IngestionMode::CREATE;
|
508
510
|
return ADBC_STATUS_OK;
|
509
511
|
}
|
510
512
|
|
@@ -557,7 +559,7 @@ AdbcStatusCode StatementExecuteQuery(struct AdbcStatement *statement, struct Arr
|
|
557
559
|
if (wrapper->ingestion_stream && wrapper->ingestion_table_name) {
|
558
560
|
auto stream = wrapper->ingestion_stream;
|
559
561
|
wrapper->ingestion_stream = nullptr;
|
560
|
-
return Ingest(wrapper->connection, wrapper->ingestion_table_name, stream, error);
|
562
|
+
return Ingest(wrapper->connection, wrapper->ingestion_table_name, stream, error, wrapper->ingestion_mode);
|
561
563
|
}
|
562
564
|
|
563
565
|
auto res = duckdb_execute_prepared_arrow(wrapper->statement, &wrapper->result);
|
@@ -643,6 +645,18 @@ AdbcStatusCode StatementSetOption(struct AdbcStatement *statement, const char *k
|
|
643
645
|
wrapper->ingestion_table_name = strdup(value);
|
644
646
|
return ADBC_STATUS_OK;
|
645
647
|
}
|
648
|
+
if (strcmp(key, ADBC_INGEST_OPTION_MODE) == 0) {
|
649
|
+
if (strcmp(value, ADBC_INGEST_OPTION_MODE_CREATE) == 0) {
|
650
|
+
wrapper->ingestion_mode = IngestionMode::CREATE;
|
651
|
+
return ADBC_STATUS_OK;
|
652
|
+
} else if (strcmp(value, ADBC_INGEST_OPTION_MODE_APPEND) == 0) {
|
653
|
+
wrapper->ingestion_mode = IngestionMode::APPEND;
|
654
|
+
return ADBC_STATUS_OK;
|
655
|
+
} else {
|
656
|
+
SetError(error, "Invalid ingestion mode");
|
657
|
+
return ADBC_STATUS_INVALID_ARGUMENT;
|
658
|
+
}
|
659
|
+
}
|
646
660
|
return ADBC_STATUS_INVALID_ARGUMENT;
|
647
661
|
}
|
648
662
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
#ifndef DUCKDB_VERSION
|
2
|
-
#define DUCKDB_VERSION "0.8.2-
|
2
|
+
#define DUCKDB_VERSION "0.8.2-dev2068"
|
3
3
|
#endif
|
4
4
|
#ifndef DUCKDB_SOURCE_ID
|
5
|
-
#define DUCKDB_SOURCE_ID "
|
5
|
+
#define DUCKDB_SOURCE_ID "83481168e0"
|
6
6
|
#endif
|
7
7
|
#include "duckdb/function/table/system_functions.hpp"
|
8
8
|
#include "duckdb/main/database.hpp"
|
@@ -10,7 +10,7 @@
|
|
10
10
|
|
11
11
|
#pragma once
|
12
12
|
|
13
|
-
#if (defined(DUCKDB_USE_STANDARD_ASSERT) || !defined(DEBUG)) && !defined(DUCKDB_FORCE_ASSERT)
|
13
|
+
#if (defined(DUCKDB_USE_STANDARD_ASSERT) || !defined(DEBUG)) && !defined(DUCKDB_FORCE_ASSERT) && !defined(__MVS__)
|
14
14
|
|
15
15
|
#include <assert.h>
|
16
16
|
#define D_ASSERT assert
|
@@ -101,9 +101,9 @@ struct AtanFun {
|
|
101
101
|
|
102
102
|
struct Atan2Fun {
|
103
103
|
static constexpr const char *Name = "atan2";
|
104
|
-
static constexpr const char *Parameters = "x
|
105
|
-
static constexpr const char *Description = "computes the arctangent (
|
106
|
-
static constexpr const char *Example = "atan2(0
|
104
|
+
static constexpr const char *Parameters = "y,x";
|
105
|
+
static constexpr const char *Description = "computes the arctangent (y, x)";
|
106
|
+
static constexpr const char *Example = "atan2(1.0, 0.0)";
|
107
107
|
|
108
108
|
static ScalarFunction GetFunction();
|
109
109
|
};
|
@@ -61,10 +61,7 @@ bool BoundWindowExpression::KeysAreCompatible(const BoundWindowExpression &other
|
|
61
61
|
return false;
|
62
62
|
}
|
63
63
|
for (idx_t i = 0; i < orders.size(); i++) {
|
64
|
-
if (orders[i].
|
65
|
-
return false;
|
66
|
-
}
|
67
|
-
if (!Expression::Equals(*orders[i].expression, *other.orders[i].expression)) {
|
64
|
+
if (!orders[i].Equals(other.orders[i])) {
|
68
65
|
return false;
|
69
66
|
}
|
70
67
|
}
|
@@ -29,6 +29,7 @@ extern "C" {
|
|
29
29
|
#include <chrono>
|
30
30
|
#elif defined(__MVS__)
|
31
31
|
#include <zos-semaphore.h>
|
32
|
+
#include <chrono>
|
32
33
|
#endif
|
33
34
|
|
34
35
|
namespace duckdb_moodycamel
|
@@ -162,9 +163,9 @@ public:
|
|
162
163
|
}
|
163
164
|
}
|
164
165
|
};
|
165
|
-
#elif defined(__unix__)
|
166
|
+
#elif defined(__unix__) || defined(__MVS__)
|
166
167
|
//---------------------------------------------------------
|
167
|
-
// Semaphore (POSIX, Linux)
|
168
|
+
// Semaphore (POSIX, Linux, zOS aka MVS)
|
168
169
|
//---------------------------------------------------------
|
169
170
|
class Semaphore
|
170
171
|
{
|
@@ -256,80 +257,6 @@ public:
|
|
256
257
|
}
|
257
258
|
}
|
258
259
|
};
|
259
|
-
#elif defined(__MVS__)
|
260
|
-
//---------------------------------------------------------
|
261
|
-
// Semaphore (MVS aka z/OS)
|
262
|
-
//---------------------------------------------------------
|
263
|
-
class Semaphore
|
264
|
-
{
|
265
|
-
private:
|
266
|
-
sem_t m_sema;
|
267
|
-
|
268
|
-
Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
269
|
-
Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION;
|
270
|
-
|
271
|
-
public:
|
272
|
-
Semaphore(int initialCount = 0)
|
273
|
-
{
|
274
|
-
assert(initialCount >= 0);
|
275
|
-
int rc = sem_init(&m_sema, 0, initialCount);
|
276
|
-
assert(rc == 0);
|
277
|
-
(void)rc;
|
278
|
-
}
|
279
|
-
|
280
|
-
~Semaphore()
|
281
|
-
{
|
282
|
-
sem_destroy(&m_sema);
|
283
|
-
}
|
284
|
-
|
285
|
-
bool wait()
|
286
|
-
{
|
287
|
-
// http://stackoverflow.com/questions/2013181/gdb-causes-sem-wait-to-fail-with-eintr-error
|
288
|
-
int rc;
|
289
|
-
do {
|
290
|
-
rc = sem_wait(&m_sema);
|
291
|
-
} while (rc == -1 && errno == EINTR);
|
292
|
-
return rc == 0;
|
293
|
-
}
|
294
|
-
|
295
|
-
bool try_wait()
|
296
|
-
{
|
297
|
-
int rc;
|
298
|
-
do {
|
299
|
-
rc = sem_trywait(&m_sema);
|
300
|
-
} while (rc == -1 && errno == EINTR);
|
301
|
-
return rc == 0;
|
302
|
-
}
|
303
|
-
|
304
|
-
bool timed_wait(std::uint64_t usecs)
|
305
|
-
{
|
306
|
-
struct timespec ts;
|
307
|
-
const int usecs_in_1_sec = 1000000;
|
308
|
-
const int nsecs_in_1_sec = 1000000000;
|
309
|
-
|
310
|
-
ts.tv_sec = usecs / usecs_in_1_sec;
|
311
|
-
ts.tv_nsec = (usecs % usecs_in_1_sec) * 1000;
|
312
|
-
|
313
|
-
int rc;
|
314
|
-
do {
|
315
|
-
rc = sem_timedwait(&m_sema, &ts);
|
316
|
-
} while (rc == -1 && errno == EINTR);
|
317
|
-
return rc == 0;
|
318
|
-
}
|
319
|
-
|
320
|
-
void signal()
|
321
|
-
{
|
322
|
-
while (sem_post(&m_sema) == -1);
|
323
|
-
}
|
324
|
-
|
325
|
-
void signal(int count)
|
326
|
-
{
|
327
|
-
while (count-- > 0)
|
328
|
-
{
|
329
|
-
while (sem_post(&m_sema) == -1);
|
330
|
-
}
|
331
|
-
}
|
332
|
-
};
|
333
260
|
#else
|
334
261
|
#error Unsupported platform! (No semaphore wrapper available)
|
335
262
|
#endif
|
@@ -8,6 +8,9 @@
|
|
8
8
|
#include <mutex>
|
9
9
|
#include <cstring>
|
10
10
|
|
11
|
+
#ifdef __MVS__
|
12
|
+
#include <zos-tls.h>
|
13
|
+
#endif
|
11
14
|
|
12
15
|
// max parse tree size approx 100 MB, should be enough
|
13
16
|
#define PG_MALLOC_SIZE 10240
|
@@ -26,7 +29,17 @@ struct pg_parser_state_str {
|
|
26
29
|
size_t malloc_ptr_size;
|
27
30
|
};
|
28
31
|
|
32
|
+
#ifdef __MVS__
|
33
|
+
// --------------------------------------------------------
|
34
|
+
// Permanent - WIP
|
35
|
+
// static __tlssim<parser_state> pg_parser_state_impl();
|
36
|
+
// #define pg_parser_state (*pg_parser_state_impl.access())
|
37
|
+
// --------------------------------------------------------
|
38
|
+
// Temporary
|
39
|
+
static parser_state pg_parser_state;
|
40
|
+
#else
|
29
41
|
static __thread parser_state pg_parser_state;
|
42
|
+
#endif
|
30
43
|
|
31
44
|
#ifndef __GNUC__
|
32
45
|
__thread PGNode *duckdb_newNodeMacroHolder;
|
@@ -30,6 +30,10 @@
|
|
30
30
|
#include "parser/scansup.hpp"
|
31
31
|
#include "mb/pg_wchar.hpp"
|
32
32
|
|
33
|
+
#ifdef __MVS__
|
34
|
+
#include <zos-tls.h>
|
35
|
+
#endif
|
36
|
+
|
33
37
|
namespace duckdb_libpgquery {
|
34
38
|
|
35
39
|
/* ----------------
|
@@ -60,7 +64,12 @@ char *downcase_truncate_identifier(const char *ident, int len, bool warn) {
|
|
60
64
|
return downcase_identifier(ident, len, warn, true);
|
61
65
|
}
|
62
66
|
|
67
|
+
#ifdef __MVS__
|
68
|
+
static __tlssim<bool> pg_preserve_identifier_case_impl(false);
|
69
|
+
#define pg_preserve_identifier_case (*pg_preserve_identifier_case_impl.access())
|
70
|
+
#else
|
63
71
|
static __thread bool pg_preserve_identifier_case = false;
|
72
|
+
#endif
|
64
73
|
|
65
74
|
void set_preserve_identifier_case(bool preserve) {
|
66
75
|
pg_preserve_identifier_case = preserve;
|