Skip to content

Commit fb8a39a

Browse files
Update vendored DuckDB sources to b611ab5
1 parent b611ab5 commit fb8a39a

31 files changed

+336
-55
lines changed

src/duckdb/extension/core_functions/function_list.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,7 @@ static const StaticFunctionDefinition core_functions[] = {
261261
DUCKDB_SCALAR_FUNCTION_SET(MakeDateFun),
262262
DUCKDB_SCALAR_FUNCTION(MakeTimeFun),
263263
DUCKDB_SCALAR_FUNCTION_SET(MakeTimestampFun),
264+
DUCKDB_SCALAR_FUNCTION_SET(MakeTimestampNsFun),
264265
DUCKDB_SCALAR_FUNCTION(MapFun),
265266
DUCKDB_SCALAR_FUNCTION(MapConcatFun),
266267
DUCKDB_SCALAR_FUNCTION(MapEntriesFun),

src/duckdb/extension/core_functions/include/core_functions/scalar/date_functions.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,15 @@ struct MakeTimestampFun {
285285
static ScalarFunctionSet GetFunctions();
286286
};
287287

288+
struct MakeTimestampNsFun {
289+
static constexpr const char *Name = "make_timestamp_ns";
290+
static constexpr const char *Parameters = "nanos";
291+
static constexpr const char *Description = "The timestamp for the given nanoseconds since epoch";
292+
static constexpr const char *Example = "make_timestamp(1732117793000000000)";
293+
294+
static ScalarFunctionSet GetFunctions();
295+
};
296+
288297
struct MicrosecondsFun {
289298
static constexpr const char *Name = "microsecond";
290299
static constexpr const char *Parameters = "ts";

src/duckdb/extension/core_functions/scalar/date/date_part.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,6 +2065,19 @@ ScalarFunctionSet EpochFun::GetFunctions() {
20652065
return GetTimePartFunction<DatePart::EpochOperator, double>(LogicalType::DOUBLE);
20662066
}
20672067

2068+
struct GetEpochNanosOperator {
2069+
static int64_t Operation(timestamp_ns_t timestamp) {
2070+
return Timestamp::GetEpochNanoSeconds(timestamp);
2071+
}
2072+
};
2073+
2074+
static void ExecuteGetNanosFromTimestampNs(DataChunk &input, ExpressionState &state, Vector &result) {
2075+
D_ASSERT(input.ColumnCount() == 1);
2076+
2077+
auto func = GetEpochNanosOperator::Operation;
2078+
UnaryExecutor::Execute<timestamp_ns_t, int64_t>(input.data[0], result, input.size(), func);
2079+
}
2080+
20682081
ScalarFunctionSet EpochNsFun::GetFunctions() {
20692082
using OP = DatePart::EpochNanosecondsOperator;
20702083
auto operator_set = GetTimePartFunction<OP>();
@@ -2074,6 +2087,9 @@ ScalarFunctionSet EpochNsFun::GetFunctions() {
20742087
auto tstz_stats = OP::template PropagateStatistics<timestamp_t>;
20752088
operator_set.AddFunction(
20762089
ScalarFunction({LogicalType::TIMESTAMP_TZ}, LogicalType::BIGINT, tstz_func, nullptr, nullptr, tstz_stats));
2090+
2091+
operator_set.AddFunction(
2092+
ScalarFunction({LogicalType::TIMESTAMP_NS}, LogicalType::BIGINT, ExecuteGetNanosFromTimestampNs));
20772093
return operator_set;
20782094
}
20792095

src/duckdb/extension/core_functions/scalar/date/make_date.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ struct MakeTimestampOperator {
102102
}
103103

104104
template <typename T, typename RESULT_TYPE>
105-
static RESULT_TYPE Operation(T micros) {
106-
return timestamp_t(micros);
105+
static RESULT_TYPE Operation(T value) {
106+
return RESULT_TYPE(value);
107107
}
108108
};
109109

@@ -121,6 +121,15 @@ static void ExecuteMakeTimestamp(DataChunk &input, ExpressionState &state, Vecto
121121
SenaryExecutor::Execute<T, T, T, T, T, double, timestamp_t>(input, result, func);
122122
}
123123

124+
template <typename T>
125+
static void ExecuteMakeTimestampNs(DataChunk &input, ExpressionState &state, Vector &result) {
126+
D_ASSERT(input.ColumnCount() == 1);
127+
128+
auto func = MakeTimestampOperator::Operation<T, timestamp_ns_t>;
129+
UnaryExecutor::Execute<T, timestamp_ns_t>(input.data[0], result, input.size(), func);
130+
return;
131+
}
132+
124133
ScalarFunctionSet MakeDateFun::GetFunctions() {
125134
ScalarFunctionSet make_date("make_date");
126135
make_date.AddFunction(ScalarFunction({LogicalType::INTEGER}, LogicalType::DATE, MakeDateFromEpoch));
@@ -149,4 +158,11 @@ ScalarFunctionSet MakeTimestampFun::GetFunctions() {
149158
return operator_set;
150159
}
151160

161+
ScalarFunctionSet MakeTimestampNsFun::GetFunctions() {
162+
ScalarFunctionSet operator_set("make_timestamp_ns");
163+
operator_set.AddFunction(
164+
ScalarFunction({LogicalType::BIGINT}, LogicalType::TIMESTAMP_NS, ExecuteMakeTimestampNs<int64_t>));
165+
return operator_set;
166+
}
167+
152168
} // namespace duckdb

src/duckdb/src/common/assert.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ void DuckDBAssertInternal(bool condition, const char *condition_name, const char
1010
if (condition) {
1111
return;
1212
}
13-
throw InternalException("Assertion triggered in file \"%s\" on line %d: %s%s", file, linenr, condition_name,
14-
Exception::GetStackTrace());
13+
throw InternalException("Assertion triggered in file \"%s\" on line %d: %s", file, linenr, condition_name);
1514
}
1615

1716
} // namespace duckdb

src/duckdb/src/common/error_data.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "duckdb/common/string_util.hpp"
55
#include "duckdb/common/to_string.hpp"
66
#include "duckdb/common/types.hpp"
7+
#include "duckdb/common/stacktrace.hpp"
78
#include "duckdb/parser/parsed_expression.hpp"
89
#include "duckdb/parser/query_error_context.hpp"
910
#include "duckdb/parser/tableref.hpp"
@@ -102,12 +103,28 @@ void ErrorData::ConvertErrorToJSON() {
102103
final_message = raw_message;
103104
}
104105

106+
void ErrorData::FinalizeError() {
107+
auto entry = extra_info.find("stack_trace_pointers");
108+
if (entry != extra_info.end()) {
109+
auto stack_trace = StackTrace::ResolveStacktraceSymbols(entry->second);
110+
extra_info["stack_trace"] = std::move(stack_trace);
111+
extra_info.erase("stack_trace_pointers");
112+
}
113+
}
114+
105115
void ErrorData::AddErrorLocation(const string &query) {
106-
auto entry = extra_info.find("position");
107-
if (entry == extra_info.end()) {
108-
return;
116+
if (!query.empty()) {
117+
auto entry = extra_info.find("position");
118+
if (entry != extra_info.end()) {
119+
raw_message = QueryErrorContext::Format(query, raw_message, std::stoull(entry->second));
120+
}
121+
}
122+
{
123+
auto entry = extra_info.find("stack_trace");
124+
if (entry != extra_info.end()) {
125+
raw_message += "\n\nStack Trace:\n" + entry->second;
126+
}
109127
}
110-
raw_message = QueryErrorContext::Format(query, raw_message, std::stoull(entry->second));
111128
final_message = ConstructFinalMessage();
112129
}
113130

src/duckdb/src/common/exception.cpp

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
#include <stdio.h>
1212
#include <stdlib.h>
1313
#endif
14-
#ifdef DUCKDB_DEBUG_STACKTRACE
15-
#include <execinfo.h>
16-
#endif
14+
#include "duckdb/common/stacktrace.hpp"
1715

1816
namespace duckdb {
1917

@@ -32,13 +30,16 @@ string Exception::ToJSON(ExceptionType type, const string &message) {
3230
}
3331

3432
string Exception::ToJSON(ExceptionType type, const string &message, const unordered_map<string, string> &extra_info) {
35-
#ifdef DUCKDB_DEBUG_STACKTRACE
36-
auto extended_extra_info = extra_info;
37-
extended_extra_info["stack_trace"] = Exception::GetStackTrace();
38-
return StringUtil::ExceptionToJSONMap(type, message, extended_extra_info);
39-
#else
40-
return StringUtil::ExceptionToJSONMap(type, message, extra_info);
33+
#ifndef DUCKDB_DEBUG_STACKTRACE
34+
// by default we only enable stack traces for internal exceptions
35+
if (type == ExceptionType::INTERNAL)
4136
#endif
37+
{
38+
auto extended_extra_info = extra_info;
39+
extended_extra_info["stack_trace_pointers"] = StackTrace::GetStacktracePointers();
40+
return StringUtil::ExceptionToJSONMap(type, message, extended_extra_info);
41+
}
42+
return StringUtil::ExceptionToJSONMap(type, message, extra_info);
4243
}
4344

4445
bool Exception::UncaughtException() {
@@ -73,22 +74,8 @@ bool Exception::InvalidatesDatabase(ExceptionType exception_type) {
7374
}
7475
}
7576

76-
string Exception::GetStackTrace(int max_depth) {
77-
#ifdef DUCKDB_DEBUG_STACKTRACE
78-
string result;
79-
auto callstack = unique_ptr<void *[]>(new void *[max_depth]);
80-
int frames = backtrace(callstack.get(), max_depth);
81-
char **strs = backtrace_symbols(callstack.get(), frames);
82-
for (int i = 0; i < frames; i++) {
83-
result += strs[i];
84-
result += "\n";
85-
}
86-
free(strs);
87-
return "\n" + result;
88-
#else
89-
// Stack trace not available. Toggle DUCKDB_DEBUG_STACKTRACE in exception.cpp to enable stack traces.
90-
return "";
91-
#endif
77+
string Exception::GetStackTrace(idx_t max_depth) {
78+
return StackTrace::GetStackTrace(max_depth);
9279
}
9380

9481
string Exception::ConstructMessageRecursive(const string &msg, std::vector<ExceptionFormatValue> &values) {
@@ -333,6 +320,7 @@ FatalException::FatalException(ExceptionType type, const string &msg) : Exceptio
333320
InternalException::InternalException(const string &msg) : Exception(ExceptionType::INTERNAL, msg) {
334321
#ifdef DUCKDB_CRASH_ON_ASSERT
335322
Printer::Print("ABORT THROWN BY INTERNAL EXCEPTION: " + msg);
323+
Printer::Print(StackTrace::GetStackTrace());
336324
abort();
337325
#endif
338326
}

src/duckdb/src/common/stacktrace.cpp

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#include "duckdb/common/stacktrace.hpp"
2+
#include "duckdb/common/string_util.hpp"
3+
#include "duckdb/common/to_string.hpp"
4+
5+
#if defined(__GLIBC__) || defined(__APPLE__)
6+
#include <execinfo.h>
7+
#include <cxxabi.h>
8+
#endif
9+
10+
namespace duckdb {
11+
12+
#if defined(__GLIBC__) || defined(__APPLE__)
13+
static string UnmangleSymbol(string symbol) {
14+
// find the mangled name
15+
idx_t mangle_start = symbol.size();
16+
idx_t mangle_end = 0;
17+
for (idx_t i = 0; i < symbol.size(); ++i) {
18+
if (symbol[i] == '_') {
19+
mangle_start = i;
20+
break;
21+
}
22+
}
23+
for (idx_t i = mangle_start; i < symbol.size(); i++) {
24+
if (StringUtil::CharacterIsSpace(symbol[i])) {
25+
mangle_end = i;
26+
break;
27+
}
28+
}
29+
if (mangle_start >= mangle_end) {
30+
return symbol;
31+
}
32+
string mangled_symbol = symbol.substr(mangle_start, mangle_end - mangle_start);
33+
34+
int status;
35+
auto demangle_result = abi::__cxa_demangle(mangled_symbol.c_str(), nullptr, nullptr, &status);
36+
if (status != 0 || !demangle_result) {
37+
return symbol;
38+
}
39+
string result;
40+
result += symbol.substr(0, mangle_start);
41+
result += demangle_result;
42+
result += symbol.substr(mangle_end);
43+
free(demangle_result);
44+
return result;
45+
}
46+
47+
string StackTrace::GetStacktracePointers(idx_t max_depth) {
48+
string result;
49+
auto callstack = unique_ptr<void *[]>(new void *[max_depth]);
50+
int frames = backtrace(callstack.get(), NumericCast<int32_t>(max_depth));
51+
// skip two frames (these are always StackTrace::...)
52+
for (idx_t i = 2; i < NumericCast<idx_t>(frames); i++) {
53+
if (!result.empty()) {
54+
result += ";";
55+
}
56+
result += to_string(CastPointerToValue(callstack[i]));
57+
}
58+
return result;
59+
}
60+
61+
string StackTrace::ResolveStacktraceSymbols(const string &pointers) {
62+
auto splits = StringUtil::Split(pointers, ";");
63+
idx_t frame_count = splits.size();
64+
auto callstack = unique_ptr<void *[]>(new void *[frame_count]);
65+
for (idx_t i = 0; i < frame_count; i++) {
66+
callstack[i] = cast_uint64_to_pointer(StringUtil::ToUnsigned(splits[i]));
67+
}
68+
string result;
69+
char **strs = backtrace_symbols(callstack.get(), NumericCast<int>(frame_count));
70+
for (idx_t i = 0; i < frame_count; i++) {
71+
result += UnmangleSymbol(strs[i]);
72+
result += "\n";
73+
}
74+
free(reinterpret_cast<void *>(strs));
75+
return "\n" + result;
76+
}
77+
78+
#else
79+
string StackTrace::GetStacktracePointers(idx_t max_depth) {
80+
return string();
81+
}
82+
83+
string StackTrace::ResolveStacktraceSymbols(const string &pointers) {
84+
return string();
85+
}
86+
#endif
87+
88+
} // namespace duckdb

src/duckdb/src/common/string_util.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ bool StringUtil::Contains(const string &haystack, const char &needle_char) {
5353
return (haystack.find(needle_char) != string::npos);
5454
}
5555

56+
idx_t StringUtil::ToUnsigned(const string &str) {
57+
return std::stoull(str);
58+
}
59+
5660
void StringUtil::LTrim(string &str) {
5761
auto it = str.begin();
5862
while (it != str.end() && CharacterIsSpace(*it)) {

src/duckdb/src/common/types/timestamp.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,11 @@ int64_t Timestamp::GetEpochNanoSeconds(timestamp_t timestamp) {
457457
return result;
458458
}
459459

460+
int64_t Timestamp::GetEpochNanoSeconds(timestamp_ns_t timestamp) {
461+
D_ASSERT(Timestamp::IsFinite(timestamp));
462+
return timestamp.value;
463+
}
464+
460465
int64_t Timestamp::GetEpochRounded(timestamp_t input, int64_t power_of_ten) {
461466
D_ASSERT(Timestamp::IsFinite(input));
462467
// Round away from the epoch.

0 commit comments

Comments
 (0)