duckdb 0.3.2-dev696.0 → 0.3.2-dev709.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/package.json +1 -1
- package/src/duckdb.cpp +55 -31
- package/src/duckdb.hpp +2 -2
- package/src/statement.cpp +16 -1
- package/test/data_type_support.test.js +14 -0
package/package.json
CHANGED
package/src/duckdb.cpp
CHANGED
|
@@ -138060,6 +138060,7 @@ typedef struct PGCreateEnumStmt
|
|
|
138060
138060
|
namespace duckdb {
|
|
138061
138061
|
|
|
138062
138062
|
class ColumnDefinition;
|
|
138063
|
+
class StackChecker;
|
|
138063
138064
|
struct OrderByNode;
|
|
138064
138065
|
struct CopyInfo;
|
|
138065
138066
|
struct CommonTableExpressionInfo;
|
|
@@ -138070,10 +138071,10 @@ struct GroupingExpressionMap;
|
|
|
138070
138071
|
class Transformer {
|
|
138071
138072
|
static constexpr const idx_t DEFAULT_MAX_EXPRESSION_DEPTH = 1000;
|
|
138072
138073
|
|
|
138074
|
+
friend class StackChecker;
|
|
138075
|
+
|
|
138073
138076
|
public:
|
|
138074
|
-
explicit Transformer(Transformer *parent = nullptr, idx_t max_expression_depth_p = DEFAULT_MAX_EXPRESSION_DEPTH)
|
|
138075
|
-
: parent(parent), max_expression_depth(parent ? parent->max_expression_depth : max_expression_depth_p) {
|
|
138076
|
-
}
|
|
138077
|
+
explicit Transformer(Transformer *parent = nullptr, idx_t max_expression_depth_p = DEFAULT_MAX_EXPRESSION_DEPTH);
|
|
138077
138078
|
|
|
138078
138079
|
//! Transforms a Postgres parse tree into a set of SQL Statements
|
|
138079
138080
|
bool TransformParseTree(duckdb_libpgquery::PGList *tree, vector<unique_ptr<SQLStatement>> &statements);
|
|
@@ -138285,14 +138286,23 @@ private:
|
|
|
138285
138286
|
unique_ptr<SampleOptions> TransformSampleOptions(duckdb_libpgquery::PGNode *options);
|
|
138286
138287
|
|
|
138287
138288
|
private:
|
|
138288
|
-
//!
|
|
138289
|
-
|
|
138290
|
-
|
|
138291
|
-
|
|
138292
|
-
|
|
138289
|
+
//! Current stack depth
|
|
138290
|
+
idx_t stack_depth;
|
|
138291
|
+
|
|
138292
|
+
void InitializeStackCheck();
|
|
138293
|
+
StackChecker StackCheck(idx_t extra_stack = 1);
|
|
138294
|
+
};
|
|
138295
|
+
|
|
138296
|
+
class StackChecker {
|
|
138297
|
+
public:
|
|
138298
|
+
StackChecker(Transformer &transformer, idx_t stack_usage);
|
|
138299
|
+
~StackChecker();
|
|
138300
|
+
StackChecker(StackChecker &&) noexcept;
|
|
138301
|
+
StackChecker(const StackChecker &) = delete;
|
|
138293
138302
|
|
|
138294
|
-
|
|
138295
|
-
|
|
138303
|
+
private:
|
|
138304
|
+
Transformer &transformer;
|
|
138305
|
+
idx_t stack_usage;
|
|
138296
138306
|
};
|
|
138297
138307
|
|
|
138298
138308
|
} // namespace duckdb
|
|
@@ -140340,7 +140350,7 @@ unique_ptr<ParsedExpression> Transformer::TransformArrayAccess(duckdb_libpgquery
|
|
|
140340
140350
|
throw NotImplementedException("Unimplemented subscript type");
|
|
140341
140351
|
}
|
|
140342
140352
|
list_size++;
|
|
140343
|
-
StackCheck(list_size
|
|
140353
|
+
StackCheck(list_size);
|
|
140344
140354
|
}
|
|
140345
140355
|
return result;
|
|
140346
140356
|
}
|
|
@@ -140667,7 +140677,7 @@ unique_ptr<ParsedExpression> Transformer::TransformExpression(duckdb_libpgquery:
|
|
|
140667
140677
|
return nullptr;
|
|
140668
140678
|
}
|
|
140669
140679
|
|
|
140670
|
-
StackCheck();
|
|
140680
|
+
auto stack_checker = StackCheck();
|
|
140671
140681
|
|
|
140672
140682
|
switch (node->type) {
|
|
140673
140683
|
case duckdb_libpgquery::T_PGColumnRef:
|
|
@@ -144158,7 +144168,7 @@ namespace duckdb {
|
|
|
144158
144168
|
|
|
144159
144169
|
unique_ptr<QueryNode> Transformer::TransformSelectNode(duckdb_libpgquery::PGSelectStmt *stmt) {
|
|
144160
144170
|
D_ASSERT(stmt->type == duckdb_libpgquery::T_PGSelectStmt);
|
|
144161
|
-
StackCheck();
|
|
144171
|
+
auto stack_checker = StackCheck();
|
|
144162
144172
|
|
|
144163
144173
|
unique_ptr<QueryNode> node;
|
|
144164
144174
|
|
|
@@ -144544,7 +144554,7 @@ unique_ptr<TableRef> Transformer::TransformFrom(duckdb_libpgquery::PGList *root)
|
|
|
144544
144554
|
cur_root = result.get();
|
|
144545
144555
|
}
|
|
144546
144556
|
list_size++;
|
|
144547
|
-
StackCheck(list_size
|
|
144557
|
+
StackCheck(list_size);
|
|
144548
144558
|
}
|
|
144549
144559
|
return move(result);
|
|
144550
144560
|
}
|
|
@@ -144695,7 +144705,7 @@ unique_ptr<TableRef> Transformer::TransformRangeFunction(duckdb_libpgquery::PGRa
|
|
|
144695
144705
|
namespace duckdb {
|
|
144696
144706
|
|
|
144697
144707
|
unique_ptr<TableRef> Transformer::TransformTableRefNode(duckdb_libpgquery::PGNode *n) {
|
|
144698
|
-
StackCheck();
|
|
144708
|
+
auto stack_checker = StackCheck();
|
|
144699
144709
|
|
|
144700
144710
|
switch (n->type) {
|
|
144701
144711
|
case duckdb_libpgquery::T_PGRangeVar:
|
|
@@ -144740,9 +144750,27 @@ unique_ptr<TableRef> Transformer::TransformTableRefNode(duckdb_libpgquery::PGNod
|
|
|
144740
144750
|
|
|
144741
144751
|
namespace duckdb {
|
|
144742
144752
|
|
|
144753
|
+
StackChecker::StackChecker(Transformer &transformer_p, idx_t stack_usage_p)
|
|
144754
|
+
: transformer(transformer_p), stack_usage(stack_usage_p) {
|
|
144755
|
+
transformer.stack_depth += stack_usage;
|
|
144756
|
+
}
|
|
144757
|
+
|
|
144758
|
+
StackChecker::~StackChecker() {
|
|
144759
|
+
transformer.stack_depth -= stack_usage;
|
|
144760
|
+
}
|
|
144761
|
+
|
|
144762
|
+
StackChecker::StackChecker(StackChecker &&other) noexcept
|
|
144763
|
+
: transformer(other.transformer), stack_usage(other.stack_usage) {
|
|
144764
|
+
other.stack_usage = 0;
|
|
144765
|
+
}
|
|
144766
|
+
|
|
144767
|
+
Transformer::Transformer(Transformer *parent, idx_t max_expression_depth_p)
|
|
144768
|
+
: parent(parent), max_expression_depth(parent ? parent->max_expression_depth : max_expression_depth_p),
|
|
144769
|
+
stack_depth(DConstants::INVALID_INDEX) {
|
|
144770
|
+
}
|
|
144771
|
+
|
|
144743
144772
|
bool Transformer::TransformParseTree(duckdb_libpgquery::PGList *tree, vector<unique_ptr<SQLStatement>> &statements) {
|
|
144744
|
-
|
|
144745
|
-
InitializeStackCheck(&stack_check_var);
|
|
144773
|
+
InitializeStackCheck();
|
|
144746
144774
|
for (auto entry = tree->head; entry != nullptr; entry = entry->next) {
|
|
144747
144775
|
SetParamCount(0);
|
|
144748
144776
|
auto stmt = TransformStatement((duckdb_libpgquery::PGNode *)entry->data.ptr_value);
|
|
@@ -144753,24 +144781,20 @@ bool Transformer::TransformParseTree(duckdb_libpgquery::PGList *tree, vector<uni
|
|
|
144753
144781
|
return true;
|
|
144754
144782
|
}
|
|
144755
144783
|
|
|
144756
|
-
void Transformer::InitializeStackCheck(
|
|
144757
|
-
|
|
144784
|
+
void Transformer::InitializeStackCheck() {
|
|
144785
|
+
stack_depth = 0;
|
|
144758
144786
|
}
|
|
144759
144787
|
|
|
144760
|
-
|
|
144761
|
-
|
|
144762
|
-
|
|
144788
|
+
StackChecker Transformer::StackCheck(idx_t extra_stack) {
|
|
144789
|
+
auto node = this;
|
|
144790
|
+
while (node->parent) {
|
|
144791
|
+
node = node->parent;
|
|
144763
144792
|
}
|
|
144764
|
-
|
|
144765
|
-
if (
|
|
144766
|
-
throw
|
|
144767
|
-
}
|
|
144768
|
-
idx_t stack_size = root - ¤t_stack_var + extra_stack;
|
|
144769
|
-
if (stack_size > MAX_STACK_SIZE) {
|
|
144770
|
-
throw ParserException(
|
|
144771
|
-
"Stack usage in parsing is too high: the query tree is too deep (stack usage %lld, max stack usage %lld)",
|
|
144772
|
-
stack_size, MAX_STACK_SIZE);
|
|
144793
|
+
D_ASSERT(node->stack_depth != DConstants::INVALID_INDEX);
|
|
144794
|
+
if (node->stack_depth + extra_stack >= max_expression_depth) {
|
|
144795
|
+
throw ParserException("Max expression depth limit of %lld exceeded", max_expression_depth);
|
|
144773
144796
|
}
|
|
144797
|
+
return StackChecker(*node, extra_stack);
|
|
144774
144798
|
}
|
|
144775
144799
|
|
|
144776
144800
|
unique_ptr<SQLStatement> Transformer::TransformStatement(duckdb_libpgquery::PGNode *stmt) {
|
package/src/duckdb.hpp
CHANGED
|
@@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
10
10
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
|
-
#define DUCKDB_SOURCE_ID "
|
|
14
|
-
#define DUCKDB_VERSION "0.3.2-
|
|
13
|
+
#define DUCKDB_SOURCE_ID "0cb16079e"
|
|
14
|
+
#define DUCKDB_VERSION "0.3.2-dev709"
|
|
15
15
|
//===----------------------------------------------------------------------===//
|
|
16
16
|
// DuckDB
|
|
17
17
|
//
|
package/src/statement.cpp
CHANGED
|
@@ -135,6 +135,10 @@ static Napi::Value convert_chunk(Napi::Env &env, std::vector<std::string> names,
|
|
|
135
135
|
|
|
136
136
|
for (duckdb::idx_t col_idx = 0; col_idx < chunk.ColumnCount(); col_idx++) {
|
|
137
137
|
Napi::Value value;
|
|
138
|
+
// set up a new Napi::Object for some data types, e.g. INTERVAL
|
|
139
|
+
Napi::Object object_value;
|
|
140
|
+
|
|
141
|
+
bool is_object_value {false};
|
|
138
142
|
|
|
139
143
|
auto dval = chunk.GetValue(col_idx, row_idx);
|
|
140
144
|
if (dval.is_null) {
|
|
@@ -159,6 +163,13 @@ static Napi::Value convert_chunk(Napi::Env &env, std::vector<std::string> names,
|
|
|
159
163
|
case duckdb::LogicalTypeId::HUGEINT: {
|
|
160
164
|
value = Napi::Number::New(env, dval.GetValue<double>());
|
|
161
165
|
} break;
|
|
166
|
+
case duckdb::LogicalTypeId::INTERVAL: {
|
|
167
|
+
is_object_value = true;
|
|
168
|
+
object_value = Napi::Object::New(env);
|
|
169
|
+
object_value.Set("months", dval.value_.interval.months);
|
|
170
|
+
object_value.Set("days", dval.value_.interval.days);
|
|
171
|
+
object_value.Set("micros", dval.value_.interval.micros);
|
|
172
|
+
} break;
|
|
162
173
|
#if (NAPI_VERSION > 4)
|
|
163
174
|
case duckdb::LogicalTypeId::DATE: {
|
|
164
175
|
const auto scale = duckdb::Interval::SECS_PER_DAY * duckdb::Interval::MSECS_PER_SEC;
|
|
@@ -185,7 +196,11 @@ static Napi::Value convert_chunk(Napi::Env &env, std::vector<std::string> names,
|
|
|
185
196
|
.ThrowAsJavaScriptException();
|
|
186
197
|
return env.Null();
|
|
187
198
|
}
|
|
188
|
-
|
|
199
|
+
if (is_object_value == true) {
|
|
200
|
+
row_result.Set(node_names[col_idx], object_value);
|
|
201
|
+
} else {
|
|
202
|
+
row_result.Set(node_names[col_idx], value);
|
|
203
|
+
}
|
|
189
204
|
}
|
|
190
205
|
result.Set(row_idx, row_result);
|
|
191
206
|
}
|
|
@@ -20,4 +20,18 @@ describe("data type support", function () {
|
|
|
20
20
|
done();
|
|
21
21
|
});
|
|
22
22
|
});
|
|
23
|
+
it("supports INTERVAL values", function (done) {
|
|
24
|
+
db.prepare(`SELECT
|
|
25
|
+
INTERVAL 1 MINUTE as minutes,
|
|
26
|
+
INTERVAL 5 DAY as days,
|
|
27
|
+
INTERVAL 4 MONTH as months,
|
|
28
|
+
INTERVAL 4 MONTH + INTERVAL 5 DAY + INTERVAL 1 MINUTE as combined;`).each((err, row) => {
|
|
29
|
+
assert(err === null);
|
|
30
|
+
assert.deepEqual(row.minutes, { months: 0, days: 0, micros: 60 * 1000 * 1000});
|
|
31
|
+
assert.deepEqual(row.days, { months: 0, days: 5, micros: 0});
|
|
32
|
+
assert.deepEqual(row.months, {months: 4, days: 0, micros: 0});
|
|
33
|
+
assert.deepEqual(row.combined, {months: 4, days: 5, micros: 60 * 1000 * 1000});
|
|
34
|
+
done();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
23
37
|
});
|