Repository: edgedb/edgedb

Issue:
configure Postgres connections to have proper `IntervalStyle`
Current behavior:

```
edgedb> SELECT to_str(<duration>'-24674.045854s', 'HH24hMImSS.USs');
{'-06h-51m-14.-45854s'}
edgedb> SELECT <duration>'-6h51m14.045854s';
{-18525.954146s}
edgedb> SELECT <duration>'-6h -51m -14.045854s';
{-24674.045854s}
edgedb> SELECT <duration>'-6h-51m-14.045854s';
ERROR: InvalidValueError: invalid input syntax for type std::duration: "-6h-51m-14.045854s"
```

Postgres:
> According to the SQL standard all fields of an interval value must have the same sign, so a leading negative sign applies to all fields; for example the negative sign in the interval literal '-1 2:03:04' applies to both the days and hour/minute/second parts. PostgreSQL allows the fields to have different signs, and traditionally treats each field in the textual representation as independently signed, so that the hour/minute/second part is considered positive in this example. If IntervalStyle is set to sql_standard then a leading sign is considered to apply to all fields (but only if no additional signs appear). Otherwise the traditional PostgreSQL interpretation is used. To avoid ambiguity, it's recommended to attach an explicit sign to each field if any field is negative.

**Action:** We want to have IntervalStyle set to `sql_standard`.


Discussion:

Resolving patch:
diff --git a/edb/server/pgcluster.py b/edb/server/pgcluster.py
--- a/edb/server/pgcluster.py
+++ b/edb/server/pgcluster.py
@@ -152,6 +152,9 @@ async def connect(self, loop=None, **kwargs):
                 f'SET ROLE {self._default_session_auth};'
             )
 
+        await conn.execute(
+            "SET IntervalStyle = 'sql_standard';"
+        )
         return conn
 
     def get_runtime_params(self) -> BackendRuntimeParams:


Test patch:
diff --git a/tests/test_dump01.py b/tests/test_dump01.py
--- a/tests/test_dump01.py
+++ b/tests/test_dump01.py
@@ -818,7 +818,7 @@ async def _ensure_schema_data_integrity(self):
                 },
                 'str_duration': {
                     '20:00:00',
-                    '00:00:20',
+                    '0:00:20',
                 },
             }]
         )
diff --git a/tests/test_edgeql_datatypes.py b/tests/test_edgeql_datatypes.py
--- a/tests/test_edgeql_datatypes.py
+++ b/tests/test_edgeql_datatypes.py
@@ -72,7 +72,7 @@ async def test_edgeql_dt_datetime_01(self):
 
         await self.assert_query_result(
             r'''SELECT to_str(<duration>'4 hours' - <duration>'1 hour')''',
-            ['03:00:00'],
+            ['3:00:00'],
         )
 
         with self.assertRaisesRegex(
@@ -138,7 +138,7 @@ async def test_edgeql_dt_datetime_04(self):
         await self.assert_query_result(
             r'''SELECT <datetime>'2017-10-10T01:02:03.004005-02' -
                 <datetime>'2017-10-10T00:00:00+00';''',
-            ['03:02:03.004005'],
+            ['3:02:03.004005'],
             [timedelta(seconds=10923, microseconds=4005)],
         )
 
@@ -173,6 +173,19 @@ async def test_edgeql_dt_duration_05_err(self):
                 'invalid input syntax for type std::duration: "100 cats"'):
             await self.con.execute("SELECT <duration>'100 cats';")
 
+    async def test_edgeql_dt_duration_06_interval_style(self):
+        await self.assert_query_result(
+            r'''SELECT <duration>'-6h51m14.045854s';''',
+            ['-6:51:14.045854'],
+            [-timedelta(seconds=24674, microseconds=45854)],
+        )
+
+        await self.assert_query_result(
+            r'''SELECT <duration>'-6h -51m -14.045854s';''',
+            ['-6:51:14.045854'],
+            [-timedelta(seconds=24674, microseconds=45854)],
+        )
+
     async def test_edgeql_dt_local_datetime_01(self):
         await self.assert_query_result(
             r'''
diff --git a/tests/test_edgeql_functions.py b/tests/test_edgeql_functions.py
--- a/tests/test_edgeql_functions.py
+++ b/tests/test_edgeql_functions.py
@@ -1688,22 +1688,22 @@ async def test_edgeql_functions_to_duration_01(self):
 
         await self.assert_query_result(
             r'''SELECT <str>to_duration(minutes:=20);''',
-            ['00:20:00'],
+            ['0:20:00'],
         )
 
         await self.assert_query_result(
             r'''SELECT <str>to_duration(seconds:=20);''',
-            ['00:00:20'],
+            ['0:00:20'],
         )
 
         await self.assert_query_result(
             r'''SELECT <str>to_duration(seconds:=20.15);''',
-            ['00:00:20.15'],
+            ['0:00:20.15'],
         )
 
         await self.assert_query_result(
             r'''SELECT <str>to_duration(microseconds:=100);''',
-            ['00:00:00.0001'],
+            ['0:00:00.0001'],
         )
 
     async def test_edgeql_functions_to_duration_02(self):