Repository: duckdb/duckdb (language: python)

Issue:
Transform varint to string before throwing error message
cc: @Tishj 


Discussion / hints:

Fix patch:
diff --git a/tools/pythonpkg/src/native/python_objects.cpp b/tools/pythonpkg/src/native/python_objects.cpp
index d9555e7dad2a..554f0c74818d 100644
--- a/tools/pythonpkg/src/native/python_objects.cpp
+++ b/tools/pythonpkg/src/native/python_objects.cpp
@@ -8,6 +8,7 @@
 #include "duckdb/common/operator/cast_operators.hpp"
 #include "duckdb_python/pyconnection/pyconnection.hpp"
 #include "duckdb/common/operator/add.hpp"
+#include "duckdb/common/types/varint.hpp"
 #include "duckdb/core_functions/to_interval.hpp"
 
 #include "datetime.h" // Python datetime initialize #1
@@ -678,6 +679,10 @@ py::object PythonObject::FromValue(const Value &val, const LogicalType &type,
 		auto uuid_value = val.GetValueUnsafe<hugeint_t>();
 		return import_cache.uuid.UUID()(UUID::ToString(uuid_value));
 	}
+	case LogicalTypeId::VARINT: {
+		auto varint_value = val.GetValueUnsafe<string_t>();
+		return py::str(Varint::VarIntToVarchar(varint_value));
+	}
 	case LogicalTypeId::INTERVAL: {
 		auto interval_value = val.GetValueUnsafe<interval_t>();
 		int64_t days = duckdb::Interval::DAYS_PER_MONTH * interval_value.months + interval_value.days;


Test patch:
diff --git a/scripts/sqllogictest/parser/parser.py b/scripts/sqllogictest/parser/parser.py
index f91706d1a9f6..96d9679e58ba 100644
--- a/scripts/sqllogictest/parser/parser.py
+++ b/scripts/sqllogictest/parser/parser.py
@@ -99,6 +99,62 @@ def __init__(self):
             "<integral>": ["tinyint", "smallint", "integer", "bigint", "hugeint"],
             "<signed>": ["tinyint", "smallint", "integer", "bigint", "hugeint"],
             "<unsigned>": ["utinyint", "usmallint", "uinteger", "ubigint", "uhugeint"],
+            "<unsigned>": ["utinyint", "usmallint", "uinteger", "ubigint", "uhugeint"],
+            "<all_types_columns>": [
+                "bool",
+                "tinyint",
+                "smallint",
+                "int",
+                "bigint",
+                "hugeint",
+                "uhugeint",
+                "utinyint",
+                "usmallint",
+                "uint",
+                "ubigint",
+                "date",
+                "time",
+                "timestamp",
+                "timestamp_s",
+                "timestamp_ms",
+                "timestamp_ns",
+                "time_tz",
+                "timestamp_tz",
+                "float",
+                "double",
+                "dec_4_1",
+                "dec_9_4",
+                "dec_18_6",
+                "dec38_10",
+                "uuid",
+                "interval",
+                "varchar",
+                "blob",
+                "bit",
+                "small_enum",
+                "medium_enum",
+                "large_enum",
+                "int_array",
+                "double_array",
+                "date_array",
+                "timestamp_array",
+                "timestamptz_array",
+                "varchar_array",
+                "nested_int_array",
+                "struct",
+                "struct_of_arrays",
+                "array_of_structs",
+                "map",
+                "union",
+                "fixed_int_array",
+                "fixed_varchar_array",
+                "fixed_nested_int_array",
+                "fixed_nested_varchar_array",
+                "fixed_struct_array",
+                "struct_of_fixed_array",
+                "fixed_array_of_int_list",
+                "list_of_fixed_int_array",
+            ],
         }
 
     def peek(self):
diff --git a/scripts/sqllogictest/result.py b/scripts/sqllogictest/result.py
index 984d01f00c9a..72f3d895257d 100644
--- a/scripts/sqllogictest/result.py
+++ b/scripts/sqllogictest/result.py
@@ -405,6 +405,8 @@ def __init__(
 
         # Now re-open the current database
         read_only = 'access_mode' in self.config and self.config['access_mode'] == 'read_only'
+        if 'access_mode' not in self.config:
+            self.config['access_mode'] = 'automatic'
         self.database = duckdb.connect(path, read_only, self.config)
 
         # Load any previously loaded extensions again
@@ -781,7 +783,9 @@ def get_connection(self, name: Optional[str] = None) -> duckdb.DuckDBPyConnectio
 
     def execute_load(self, load: Load):
         if self.in_loop():
-            self.fail("load cannot be called in a loop")
+            # FIXME: should add support for this, the CPP tester supports this
+            self.skiptest("load cannot be called in a loop")
+            # self.fail("load cannot be called in a loop")
 
         readonly = load.readonly
 
@@ -842,23 +846,26 @@ def is_query_result(sql_query, statement) -> bool:
 
             if is_query_result(sql_query, statement):
                 original_rel = conn.query(sql_query)
-                original_types = original_rel.types
-                # We create new names for the columns, because they might be duplicated
-                aliased_columns = [f'c{i}' for i in range(len(original_types))]
-
-                expressions = [f'"{name}"::VARCHAR' for name, sql_type in zip(aliased_columns, original_types)]
-                aliased_table = ", ".join(aliased_columns)
-                expression_list = ", ".join(expressions)
-                try:
-                    # Select from the result, converting the Values to the right type for comparison
-                    transformed_query = (
-                        f"select {expression_list} from original_rel unnamed_subquery_blabla({aliased_table})"
-                    )
-                    stringified_rel = conn.query(transformed_query)
-                except duckdb.Error as e:
-                    self.fail(f"Could not select from the ValueRelation: {str(e)}")
-                result = stringified_rel.fetchall()
-                query_result = QueryResult(result, original_types)
+                if original_rel is None:
+                    query_result = QueryResult([(0,)], ['BIGINT'])
+                else:
+                    original_types = original_rel.types
+                    # We create new names for the columns, because they might be duplicated
+                    aliased_columns = [f'c{i}' for i in range(len(original_types))]
+
+                    expressions = [f'"{name}"::VARCHAR' for name, sql_type in zip(aliased_columns, original_types)]
+                    aliased_table = ", ".join(aliased_columns)
+                    expression_list = ", ".join(expressions)
+                    try:
+                        # Select from the result, converting the Values to the right type for comparison
+                        transformed_query = (
+                            f"select {expression_list} from original_rel unnamed_subquery_blabla({aliased_table})"
+                        )
+                        stringified_rel = conn.query(transformed_query)
+                    except duckdb.Error as e:
+                        self.fail(f"Could not select from the ValueRelation: {str(e)}")
+                    result = stringified_rel.fetchall()
+                    query_result = QueryResult(result, original_types)
             elif duckdb.ExpectedResultType.CHANGED_ROWS in statement.expected_result_type:
                 conn.execute(sql_query)
                 result = conn.fetchall()
diff --git a/tools/pythonpkg/scripts/sqllogictest_python.py b/tools/pythonpkg/scripts/sqllogictest_python.py
index 91a2d1e77bf8..3b4b9f9c26c0 100644
--- a/tools/pythonpkg/scripts/sqllogictest_python.py
+++ b/tools/pythonpkg/scripts/sqllogictest_python.py
@@ -42,6 +42,11 @@ def __init__(self, build_directory: Optional[str] = None):
                 'test/sql/parser/invisible_spaces.test',  # <-- Parser is getting tripped up on the invisible spaces
                 'test/sql/copy/csv/code_cov/csv_state_machine_invalid_utf.test',  # <-- ConversionException is empty, see Python Mega Issue (duckdb-internal #1488)
                 'test/sql/copy/csv/test_csv_timestamp_tz.test',  # <-- ICU is always loaded
+                'test/fuzzer/duckfuzz/duck_fuzz_column_binding_tests.test',  # <-- ICU is always loaded
+                'test/sql/pragma/test_custom_optimizer_profiling.test',  # Because of logic related to enabling 'restart' statement capabilities, this will not measure the right statement
+                'test/sql/pragma/test_custom_profiling_settings.test',  # Because of logic related to enabling 'restart' statement capabilities, this will not measure the right statement
+                'test/sql/copy/csv/test_copy.test',  # JSON is always loaded
+                'test/sql/copy/csv/test_timestamptz_12926.test',  # ICU is always loaded
             ]
         )
         # TODO: get this from the `duckdb` package