Repository: duckdb/duckdb (language: python)

Issue:
CLI - incorrect decimal representation in ".mode insert"
### What happens?

Decimals are being represented incorrectly in ".mode insert". It looks like there is an implicit cast to `float`.

### To Reproduce

```
create table t (a decimal(38,18));
insert into t values (3.14), (2.71);

from t;
```

Output (decimals are precise):
```
┌──────────────────────┐
│          a           │
│    decimal(38,18)    │
├──────────────────────┤
│ 3.140000000000000000 │
│ 2.710000000000000000 │
└──────────────────────┘

```

```
.mode insert

from t;
```

Output (decimals are imprecise):
```
INSERT INTO "table"(a) VALUES(3.1400000000000001243);
INSERT INTO "table"(a) VALUES(2.7099999999999999644);
```


### OS:

macOS 14.5 (M1)

### DuckDB Version:

1.0.0

### DuckDB Client:

CLI

### Full Name:

Milan Opath

### Affiliation:

independent

### What is the latest build you tested with? If possible, we recommend testing with the latest nightly build.

I have tested with a stable release

### Did you include all relevant data sets for reproducing the issue?

Yes

### Did you include all code required to reproduce the issue?

- [X] Yes, I have

### Did you include all relevant configuration (e.g., CPU architecture, Python version, Linux distribution) to reproduce the issue?

- [X] Yes, I have
CLI - incorrect decimal representation in ".mode insert"
### What happens?

Decimals are being represented incorrectly in ".mode insert". It looks like there is an implicit cast to `float`.

### To Reproduce

```
create table t (a decimal(38,18));
insert into t values (3.14), (2.71);

from t;
```

Output (decimals are precise):
```
┌──────────────────────┐
│          a           │
│    decimal(38,18)    │
├──────────────────────┤
│ 3.140000000000000000 │
│ 2.710000000000000000 │
└──────────────────────┘

```

```
.mode insert

from t;
```

Output (decimals are imprecise):
```
INSERT INTO "table"(a) VALUES(3.1400000000000001243);
INSERT INTO "table"(a) VALUES(2.7099999999999999644);
```


### OS:

macOS 14.5 (M1)

### DuckDB Version:

1.0.0

### DuckDB Client:

CLI

### Full Name:

Milan Opath

### Affiliation:

independent

### What is the latest build you tested with? If possible, we recommend testing with the latest nightly build.

I have tested with a stable release

### Did you include all relevant data sets for reproducing the issue?

Yes

### Did you include all code required to reproduce the issue?

- [X] Yes, I have

### Did you include all relevant configuration (e.g., CPU architecture, Python version, Linux distribution) to reproduce the issue?

- [X] Yes, I have


Discussion / hints:
@milancio42 thanks, I could reproduce the issue.
@milancio42 thanks, I could reproduce the issue.

Fix patch:
diff --git a/tools/shell/shell.c b/tools/shell/shell.c
index 4fea104d5734..fa0d95a1a266 100644
--- a/tools/shell/shell.c
+++ b/tools/shell/shell.c
@@ -11493,7 +11493,7 @@ static int shell_callback(
       }
       if (strcmp(azArg[0], "logical_plan") == 0
             || strcmp(azArg[0], "logical_opt") == 0
-            || strcmp(azArg[0], "physical_plan") == 0) { 
+            || strcmp(azArg[0], "physical_plan") == 0) {
         utf8_printf(p->out, "\n┌─────────────────────────────┐\n");
         utf8_printf(p->out, "│┌───────────────────────────┐│\n");
         if (strcmp(azArg[0], "logical_plan") == 0) {
@@ -11682,7 +11682,6 @@ static int shell_callback(
         }else if( aiType && aiType[i]==SQLITE_INTEGER ){
           utf8_printf(p->out,"%s", azArg[i]);
         }else if( aiType && aiType[i]==SQLITE_FLOAT ){
-          char z[50];
           double r = sqlite3_column_double(p->pStmt, i);
           sqlite3_uint64 ur;
           memcpy(&ur,&r,sizeof(r));
@@ -11691,8 +11690,7 @@ static int shell_callback(
           }else if( ur==0xfff0000000000000LL ){
             raw_printf(p->out, "-1e999");
           }else{
-            sqlite3_snprintf(50,z,"%!.20g", r);
-            raw_printf(p->out, "%s", z);
+            utf8_printf(p->out,"%s", azArg[i]);
           }
         }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
           const void *pBlob = sqlite3_column_blob(p->pStmt, i);


Test patch:
diff --git a/tools/shell/tests/conftest.py b/tools/shell/tests/conftest.py
index 71a7cd50ac24..84dba9b4e37a 100644
--- a/tools/shell/tests/conftest.py
+++ b/tools/shell/tests/conftest.py
@@ -36,6 +36,12 @@ def check_stdout(self, expected: Union[str, List[str], bytes]):
         assert self.status_code == 0
         assert expected in self.stdout
 
+    def check_not_exist(self, not_exist: Union[str, List[str], bytes]):
+        if isinstance(not_exist, list):
+            not_exist = '\n'.join(not_exist)
+        assert self.status_code == 0
+        assert not_exist not in self.stdout
+
     def check_stderr(self, expected: str):
         assert expected in self.stderr
 
diff --git a/tools/shell/tests/test_shell_basics.py b/tools/shell/tests/test_shell_basics.py
index df2a6a9d8c5b..e36edbb582b0 100644
--- a/tools/shell/tests/test_shell_basics.py
+++ b/tools/shell/tests/test_shell_basics.py
@@ -619,10 +619,16 @@ def test_mode_insert(shell):
     test = (
         ShellTest(shell)
         .statement(".mode insert")
-        .statement("SELECT NULL, 42, 'fourty-two', 42.0;")
+        .statement("SELECT NULL, 42, 'fourty-two', 42.0, 3.14, 2.71;")
     )
     result = test.run()
     result.check_stdout('fourty-two')
+    result.check_stdout('3.14')
+    result.check_stdout('2.71')
+    result.check_not_exist('3.140000')
+    result.check_not_exist('2.709999')
+    result.check_not_exist('3.139999')
+    result.check_not_exist('2.710000')
 
 def test_mode_line(shell):
     test = (