Skip to content

Commit bf9ac38

Browse files
JelteFdentiny
andauthored
Don't convert unsupported numerics to double by default (#795)
This stops converting unsupported NUMERIC sizes to doubles. This behaviour is still supported, but it is now opt-in. This means pg_duckdb won't silently reduce precision. It also starts requiring users to specify precision when using NUMERIC types in a table definition, because the default precision is different between PostgreSQL and DuckDB. Closes #471 --------- Co-authored-by: dentiny <[email protected]>
1 parent e01527d commit bf9ac38

16 files changed

+158
-31
lines changed

include/pgduckdb/pg/types.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace pgduckdb::pg {
66
bool IsArrayType(Oid type_oid);
77
bool IsDomainType(Oid type_oid);
88
bool IsArrayDomainType(Oid type_oid);
9-
Oid GetBaseDuckColumnType(Oid attribute_type_oid);
9+
Oid GetBaseTypeAndTypmod(Oid attribute_type_oid, int32_t *type_modifier);
1010
Datum StringToNumeric(const char *str);
1111
Datum StringToVarbit(const char *str);
1212
const char *VarbitToString(Datum pg_varbit);

include/pgduckdb/pgduckdb_guc.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ void InitGUC();
55

66
extern bool duckdb_force_execution;
77
extern bool duckdb_unsafe_allow_mixed_transactions;
8+
extern bool duckdb_convert_unsupported_numeric_to_double;
89
extern bool duckdb_log_pg_explain;
910
extern int duckdb_maximum_threads;
1011
extern char *duckdb_maximum_memory;

include/pgduckdb/pgduckdb_types.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ constexpr int64_t PGDUCKDB_MAX_TIMESTAMP_VALUE = 9223371244800000000;
3131
constexpr int64_t PGDUCKDB_MIN_TIMESTAMP_VALUE = -210866803200000000;
3232

3333
duckdb::LogicalType ConvertPostgresToDuckColumnType(Form_pg_attribute &attribute);
34-
Oid GetPostgresDuckDBType(const duckdb::LogicalType &type);
34+
Oid GetPostgresDuckDBType(const duckdb::LogicalType &type, bool throw_error = false);
3535
int32_t GetPostgresDuckDBTypemod(const duckdb::LogicalType &type);
3636
duckdb::Value ConvertPostgresParameterToDuckValue(Datum value, Oid postgres_type);
3737
void ConvertPostgresToDuckValue(Oid attr_type, Datum value, duckdb::Vector &result, uint64_t offset);

src/pg/types.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ IsArrayDomainType(Oid type_oid) {
3535
}
3636

3737
static Oid
38-
GetBaseDuckColumnType_C(Oid attribute_type_oid) {
38+
GetBaseTypeAndTypmod_C(Oid attribute_type_oid, int32 *type_modifier) {
3939
Oid typoid = attribute_type_oid;
4040
if (get_typtype(attribute_type_oid) == TYPTYPE_DOMAIN) {
4141
/* It is a domain type that needs to be reduced to its base type */
42-
typoid = getBaseType(attribute_type_oid);
42+
typoid = getBaseTypeAndTypmod(attribute_type_oid, type_modifier);
4343
} else if (type_is_array(attribute_type_oid)) {
4444
Oid eltoid = get_base_element_type(attribute_type_oid);
4545
if (OidIsValid(eltoid) && get_typtype(eltoid) == TYPTYPE_DOMAIN) {
@@ -50,9 +50,15 @@ GetBaseDuckColumnType_C(Oid attribute_type_oid) {
5050
return typoid;
5151
}
5252

53+
/*
54+
* If the given type is a domain, return its base type and type_modifier;
55+
* If the type is an array of a domain type, return the type of array-base
56+
* type. This leaves the type_modifier unchanged.
57+
* Otherwise, return the type's own OID, and leave *type_modifier unchanged.
58+
*/
5359
Oid
54-
GetBaseDuckColumnType(Oid attribute_type_oid) {
55-
return PostgresFunctionGuard(GetBaseDuckColumnType_C, attribute_type_oid);
60+
GetBaseTypeAndTypmod(Oid attribute_type_oid, int32 *type_modifier) {
61+
return PostgresFunctionGuard(GetBaseTypeAndTypmod_C, attribute_type_oid, type_modifier);
5662
}
5763

5864
static Datum

src/pgduckdb_guc.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ DefineCustomDuckDBVariable(const char *name, const char *short_desc, T *var, T m
111111

112112
bool duckdb_force_execution = false;
113113
bool duckdb_unsafe_allow_mixed_transactions = false;
114+
bool duckdb_convert_unsupported_numeric_to_double = false;
114115
bool duckdb_log_pg_explain = false;
115116
int duckdb_max_workers_per_postgres_scan = 2;
116117
char *duckdb_motherduck_session_hint = strdup("");
@@ -137,6 +138,10 @@ InitGUC() {
137138
"Allow mixed transactions between DuckDB and Postgres",
138139
&duckdb_unsafe_allow_mixed_transactions);
139140

141+
DefineCustomVariable("duckdb.convert_unsupported_numeric_to_double",
142+
"Convert NUMERIC types of unsupported precision to DOUBLE",
143+
&duckdb_convert_unsupported_numeric_to_double);
144+
140145
DefineCustomVariable("duckdb.log_pg_explain", "Logs the EXPLAIN plan of a Postgres scan at the NOTICE log level",
141146
&duckdb_log_pg_explain);
142147

src/pgduckdb_node.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,8 @@ Duckdb_BeginCustomScan_Cpp(CustomScanState *cscanstate, EState *estate, int /*ef
131131
}
132132

133133
for (size_t i = 0; i < prepared_result_types.size(); i++) {
134-
Oid postgres_column_oid = pgduckdb::GetPostgresDuckDBType(prepared_result_types[i]);
135-
if (!OidIsValid(postgres_column_oid)) {
136-
elog(ERROR, "(PGDuckDB/CreatePlan) Cache lookup failed for type %u", postgres_column_oid);
137-
}
134+
Oid postgres_column_oid = pgduckdb::GetPostgresDuckDBType(prepared_result_types[i], true);
135+
138136
TargetEntry *target_entry =
139137
list_nth_node(TargetEntry, duckdb_scan_state->custom_scan->custom_scan_tlist, i);
140138
Var *var = castNode(Var, target_entry->expr);

src/pgduckdb_planner.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,9 @@ CreatePlan(Query *query, bool throw_error) {
6464
auto &prepared_result_types = prepared_query->GetTypes();
6565

6666
for (size_t i = 0; i < prepared_result_types.size(); i++) {
67-
Oid postgresColumnOid = pgduckdb::GetPostgresDuckDBType(prepared_result_types[i]);
67+
Oid postgresColumnOid = pgduckdb::GetPostgresDuckDBType(prepared_result_types[i], throw_error);
6868

6969
if (!OidIsValid(postgresColumnOid)) {
70-
elog(elevel, "(PGDuckDB/CreatePlan) Cache lookup failed for type %u", postgresColumnOid);
7170
return nullptr;
7271
}
7372

src/pgduckdb_ruleutils.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "duckdb.hpp"
22
#include "pgduckdb/pg/string_utils.hpp"
3+
#include "pgduckdb/pgduckdb_types.hpp"
34

45
extern "C" {
56
#include "postgres.h"
@@ -635,6 +636,15 @@ pgduckdb_get_tabledef(Oid relation_oid) {
635636

636637
const char *column_name = NameStr(column->attname);
637638

639+
/*
640+
* Check that this type is known by DuckDB, and throw the appropriate
641+
* error otherwise. This is particularly important for NUMERIC without
642+
* precision specified. Because that means something very different in
643+
* Postgres
644+
*/
645+
auto duck_type = pgduckdb::ConvertPostgresToDuckColumnType(column);
646+
pgduckdb::GetPostgresDuckDBType(duck_type, true);
647+
638648
const char *column_type_name = format_type_with_typemod(column->atttypid, column->atttypmod);
639649

640650
if (first_column_printed) {

src/pgduckdb_types.cpp

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "duckdb/common/types/blob.hpp"
66
#include "duckdb/common/types/uuid.hpp"
77

8+
#include "pgduckdb/pgduckdb_guc.hpp"
89
#include "pgduckdb/pgduckdb_types.hpp"
910
#include "pgduckdb/pgduckdb_metadata_cache.hpp"
1011
#include "pgduckdb/pgduckdb_utils.hpp"
@@ -1211,7 +1212,8 @@ numeric_typmod_scale(int32 typmod) {
12111212

12121213
duckdb::LogicalType
12131214
ConvertPostgresToBaseDuckColumnType(Form_pg_attribute &attribute) {
1214-
Oid typoid = pg::GetBaseDuckColumnType(attribute->atttypid);
1215+
int32 type_modifier = attribute->atttypmod;
1216+
Oid typoid = pg::GetBaseTypeAndTypmod(attribute->atttypid, &type_modifier);
12151217
switch (typoid) {
12161218
case BOOLOID:
12171219
case BOOLARRAYOID:
@@ -1265,12 +1267,40 @@ ConvertPostgresToBaseDuckColumnType(Form_pg_attribute &attribute) {
12651267
return duckdb::LogicalTypeId::DOUBLE;
12661268
case NUMERICOID:
12671269
case NUMERICARRAYOID: {
1268-
auto &typmod = attribute->atttypmod;
1269-
auto precision = numeric_typmod_precision(typmod);
1270-
auto scale = numeric_typmod_scale(typmod);
1271-
if (typmod == -1 || precision < 0 || scale < 0 || precision > 38) {
1272-
auto extra_type_info = duckdb::make_shared_ptr<NumericAsDouble>();
1273-
return duckdb::LogicalType(duckdb::LogicalTypeId::DOUBLE, std::move(extra_type_info));
1270+
auto precision = numeric_typmod_precision(type_modifier);
1271+
auto scale = numeric_typmod_scale(type_modifier);
1272+
1273+
/*
1274+
* DuckDB decimals only support up to 38 digits. So we cannot convert
1275+
* NUMERICs of higher precision losslessly. We do allow conversion to
1276+
* doubles.
1277+
* https://duckdb.org/docs/stable/sql/data_types/numeric.html#fixed-point-decimals
1278+
*/
1279+
if (type_modifier == -1 || precision < 1 || precision > 38 || scale < 0 || scale > 38 || scale > precision) {
1280+
if (duckdb_convert_unsupported_numeric_to_double) {
1281+
auto extra_type_info = duckdb::make_shared_ptr<NumericAsDouble>();
1282+
return duckdb::LogicalType(duckdb::LogicalTypeId::DOUBLE, std::move(extra_type_info));
1283+
}
1284+
1285+
/* We don't allow conversion then! */
1286+
if (type_modifier == -1) {
1287+
return duckdb::LogicalType::USER(
1288+
"DuckDB requires the precision of a NUMERIC to be set. You can choose to convert these NUMERICs to "
1289+
"a DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'");
1290+
} else if (precision < 1 || precision > 38) {
1291+
return duckdb::LogicalType::USER(
1292+
"DuckDB only supports NUMERIC with a precision of 1-38. You can choose to convert these NUMERICs "
1293+
"to a DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'");
1294+
} else if (scale < 0 || scale > 38) {
1295+
return duckdb::LogicalType::USER(
1296+
"DuckDB only supports NUMERIC with a scale of 0-38. You can choose to convert these NUMERICs to a "
1297+
"DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'");
1298+
} else {
1299+
return duckdb::LogicalType::USER(
1300+
"DuckDB does not support NUMERIC with a scale that is larger than the precision. You can choose to "
1301+
"convert these NUMERICs to a DOUBLE by using 'SET "
1302+
"duckdb.duckdb.convert_unsupported_numeric_to_double = true'");
1303+
}
12741304
}
12751305

12761306
return duckdb::LogicalType::DECIMAL(precision, scale);
@@ -1295,7 +1325,8 @@ ConvertPostgresToBaseDuckColumnType(Form_pg_attribute &attribute) {
12951325
} else if (typoid == pgduckdb::DuckdbStructOid()) {
12961326
return duckdb::LogicalTypeId::STRUCT;
12971327
}
1298-
return duckdb::LogicalType::USER("UnsupportedPostgresType (Oid=" + std::to_string(attribute->atttypid) + ")");
1328+
return duckdb::LogicalType::USER(
1329+
"No conversion to DuckDB available for type with oid=" + std::to_string(attribute->atttypid) + ")");
12991330
}
13001331
}
13011332

@@ -1339,7 +1370,7 @@ ConvertPostgresToDuckColumnType(Form_pg_attribute &attribute) {
13391370
}
13401371

13411372
Oid
1342-
GetPostgresArrayDuckDBType(const duckdb::LogicalType &type) {
1373+
GetPostgresArrayDuckDBType(const duckdb::LogicalType &type, bool throw_error) {
13431374
switch (type.id()) {
13441375
case duckdb::LogicalTypeId::BOOLEAN:
13451376
return BOOLARRAYOID;
@@ -1385,16 +1416,30 @@ GetPostgresArrayDuckDBType(const duckdb::LogicalType &type) {
13851416
return UUIDARRAYOID;
13861417
case duckdb::LogicalTypeId::BLOB:
13871418
return BYTEAARRAYOID;
1419+
case duckdb::LogicalTypeId::VARINT:
1420+
return NUMERICARRAYOID;
1421+
case duckdb::LogicalTypeId::USER: {
1422+
std::string type_name = duckdb::UserType::GetTypeName(type);
1423+
if (throw_error) {
1424+
throw duckdb::NotImplementedException("Unsupported Postgres type: " + type_name);
1425+
} else {
1426+
pd_log(WARNING, "Unsupported Postgres type: %s", type_name.c_str());
1427+
return InvalidOid;
1428+
}
1429+
}
13881430
default: {
1389-
elog(WARNING, "(PGDuckDB/GetPostgresDuckDBType) Unsupported `LIST` subtype %d to Postgres type",
1390-
static_cast<uint8_t>(type.id()));
1391-
return InvalidOid;
1431+
if (throw_error) {
1432+
throw duckdb::NotImplementedException("Unsupported DuckDB `LIST` subtype: " + type.ToString());
1433+
} else {
1434+
pd_log(WARNING, "Unsupported DuckDB `LIST` subtype: %s", type.ToString().c_str());
1435+
return InvalidOid;
1436+
}
13921437
}
13931438
}
13941439
}
13951440

13961441
Oid
1397-
GetPostgresDuckDBType(const duckdb::LogicalType &type) {
1442+
GetPostgresDuckDBType(const duckdb::LogicalType &type, bool throw_error) {
13981443
switch (type.id()) {
13991444
case duckdb::LogicalTypeId::BOOLEAN:
14001445
return BOOLOID;
@@ -1454,7 +1499,7 @@ GetPostgresDuckDBType(const duckdb::LogicalType &type) {
14541499
auto &child_type = pgduckdb::GetChildType(*duck_type);
14551500
duck_type = &child_type;
14561501
}
1457-
return GetPostgresArrayDuckDBType(*duck_type);
1502+
return GetPostgresArrayDuckDBType(*duck_type, throw_error);
14581503
}
14591504
case duckdb::LogicalTypeId::BLOB:
14601505
return BYTEAOID;
@@ -1464,10 +1509,23 @@ GetPostgresDuckDBType(const duckdb::LogicalType &type) {
14641509
return pgduckdb::DuckdbMapOid();
14651510
case duckdb::LogicalTypeId::ENUM:
14661511
return VARCHAROID;
1512+
case duckdb::LogicalTypeId::USER: {
1513+
std::string type_name = duckdb::UserType::GetTypeName(type);
1514+
if (throw_error) {
1515+
throw duckdb::NotImplementedException("Unsupported Postgres type: " + type_name);
1516+
} else {
1517+
pd_log(WARNING, "Unsupported Postgres type: %s", type_name.c_str());
1518+
return InvalidOid;
1519+
}
1520+
}
14671521
default: {
1468-
elog(WARNING, "(PGDuckDB/GetPostgresDuckDBType) Could not convert DuckDB type: %s to Postgres type",
1469-
type.ToString().c_str());
1470-
return InvalidOid;
1522+
if (throw_error) {
1523+
throw duckdb::NotImplementedException("Could not convert DuckDB type: " + type.ToString() +
1524+
" to Postgres type");
1525+
} else {
1526+
pd_log(WARNING, "Could not convert DuckDB type: %s to Postgres type", type.ToString().c_str());
1527+
return InvalidOid;
1528+
}
14711529
}
14721530
}
14731531
}

test/regression/expected/array_type_support.out

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ INSERT INTO numeric_array_1d SELECT CAST(a as NUMERIC[]) FROM (VALUES
280280
('{}')
281281
) t(a);
282282
SELECT * FROM numeric_array_1d;
283+
WARNING: Unsupported Postgres type: DuckDB requires the precision of a NUMERIC to be set. You can choose to convert these NUMERICs to a DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'
283284
a
284285
--------------------
285286
{1.1,2.2,3.3}
@@ -288,6 +289,17 @@ SELECT * FROM numeric_array_1d;
288289
{}
289290
(4 rows)
290291

292+
SET duckdb.convert_unsupported_numeric_to_double = true;
293+
SELECT * FROM numeric_array_1d;
294+
a
295+
--------------------
296+
{1.1,2.2,3.3}
297+
298+
{4.4,5.5,NULL,7.7}
299+
{}
300+
(4 rows)
301+
302+
RESET duckdb.convert_unsupported_numeric_to_double;
291303
-- UUID (single dimension)
292304
CREATE TABLE uuid_array_1d(a UUID[]);
293305
INSERT INTO uuid_array_1d SELECT CAST(a as UUID[]) FROM (VALUES
@@ -555,6 +567,18 @@ INSERT INTO numeric_array_2d VALUES
555567
(NULL),
556568
('{}'),
557569
('{{11.1,12.2},{NULL,14.4}}');
570+
SELECT * FROM numeric_array_2d;
571+
WARNING: Unsupported Postgres type: DuckDB requires the precision of a NUMERIC to be set. You can choose to convert these NUMERICs to a DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'
572+
a
573+
--------------------------------
574+
{{1.1,2.2},{3.3,4.4}}
575+
{{5.5,6.6,7.7},{8.8,9.9,10.1}}
576+
577+
{}
578+
{{11.1,12.2},{NULL,14.4}}
579+
(5 rows)
580+
581+
SET duckdb.convert_unsupported_numeric_to_double = true;
558582
SELECT * FROM numeric_array_2d;
559583
a
560584
--------------------------------
@@ -565,6 +589,7 @@ SELECT * FROM numeric_array_2d;
565589
{{11.1,12.2},{NULL,14.4}}
566590
(5 rows)
567591

592+
RESET duckdb.convert_unsupported_numeric_to_double;
568593
-- UUID (two dimensions)
569594
CREATE TABLE uuid_array_2d(a UUID[][]);
570595
INSERT INTO uuid_array_2d VALUES

test/regression/expected/json_functions_duckdb.out

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,7 @@ SELECT public.json_array_length('{"not_an_array": {"key": "value"}}', '$.not_an_
163163
-- BUG: This fails due to not being able to convert the UBIGINT array to a
164164
-- postgres type yet.
165165
SELECT public.json_array_length('{"a": [1, 2, 3, 4, 5], "b": [1]}', ARRAY['$.a', 'b']) AS array_length;
166-
WARNING: (PGDuckDB/GetPostgresDuckDBType) Unsupported `LIST` subtype 31 to Postgres type
167-
ERROR: (PGDuckDB/CreatePlan) Cache lookup failed for type 0
166+
ERROR: (PGDuckDB/CreatePlan) Not implemented Error: Unsupported DuckDB `LIST` subtype: UBIGINT
168167
-- </JSON_ARRAY_LENGTH>
169168
-- <JSON_CONTAINS>
170169
-- Simple JSON array with numeric needle

test/regression/expected/temporary_tables.out

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,9 @@ CREATE TEMP TABLE t(A text COMPRESSION "pglz");
163163
ERROR: Column compression is not supported in DuckDB
164164
CREATE TEMP TABLE t(a int) WITH (fillfactor = 50);
165165
ERROR: Storage options are not supported in DuckDB
166+
-- Should fail because user should specify the precision of the NUMERIC.
167+
CREATE TEMP TABLE large_numeric_tbl (a NUMERIC) USING duckdb;
168+
ERROR: (PGDuckDB/duckdb_create_table_trigger_cpp) Not implemented Error: Unsupported Postgres type: DuckDB requires the precision of a NUMERIC to be set. You can choose to convert these NUMERICs to a DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'
166169
CREATE TEMP TABLE cities_duckdb (
167170
name text,
168171
population real,

test/regression/expected/type_support.out

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,16 @@ INSERT INTO numeric_as_double SELECT a FROM (VALUES
326326
(NULL),
327327
(458234502034234234234.000012)
328328
) t(a);
329+
SELECT * FROM numeric_as_double;
330+
WARNING: Unsupported Postgres type: DuckDB requires the precision of a NUMERIC to be set. You can choose to convert these NUMERICs to a DOUBLE by using 'SET duckdb.duckdb.convert_unsupported_numeric_to_double = true'
331+
a
332+
------------------------------
333+
0.234234234
334+
335+
458234502034234234234.000012
336+
(3 rows)
337+
338+
SET duckdb.convert_unsupported_numeric_to_double = true;
329339
SELECT * FROM numeric_as_double;
330340
a
331341
-----------------------
@@ -334,6 +344,7 @@ SELECT * FROM numeric_as_double;
334344
4.582345020342342e+20
335345
(3 rows)
336346

347+
RESET duckdb.convert_unsupported_numeric_to_double;
337348
-- NUMERIC with a physical type of SMALLINT
338349
CREATE TABLE smallint_numeric(a NUMERIC(4, 2));
339350
INSERT INTO smallint_numeric SELECT a FROM (VALUES

test/regression/sql/array_type_support.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ INSERT INTO numeric_array_1d SELECT CAST(a as NUMERIC[]) FROM (VALUES
174174
('{}')
175175
) t(a);
176176
SELECT * FROM numeric_array_1d;
177+
SET duckdb.convert_unsupported_numeric_to_double = true;
178+
SELECT * FROM numeric_array_1d;
179+
RESET duckdb.convert_unsupported_numeric_to_double;
177180

178181
-- UUID (single dimension)
179182
CREATE TABLE uuid_array_1d(a UUID[]);
@@ -338,6 +341,9 @@ INSERT INTO numeric_array_2d VALUES
338341
('{}'),
339342
('{{11.1,12.2},{NULL,14.4}}');
340343
SELECT * FROM numeric_array_2d;
344+
SET duckdb.convert_unsupported_numeric_to_double = true;
345+
SELECT * FROM numeric_array_2d;
346+
RESET duckdb.convert_unsupported_numeric_to_double;
341347

342348
-- UUID (two dimensions)
343349
CREATE TABLE uuid_array_2d(a UUID[][]);

0 commit comments

Comments
 (0)