From 37a08eaaa3016ec3a65ba45b370733da8ef07762 Mon Sep 17 00:00:00 2001
From: Christian Kuhn <lolli@schwarzbu.ch>
Date: Tue, 18 Jun 2024 14:01:03 +0200
Subject: [PATCH] [TASK] Have TEXT for type=input length > 255
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Long VARCHAR() fields tend to eat up quite a bit of
"65k bytes maximum row size" space, especially with
utf8mb4.
The patch changes TCA type="input" fields longer than
255 chars from VARCHAR() to TEXT (65k bytes). This
looks like a sane tradeoff between limits and
storage efficiency.
Extension authors who need or want to override default
TCA schema details for whatever reason, can of course
do so by defining something specific in ext_tables.sql.

Resolves: #104146
Related: #101553
Related: #104098
Releases: main
Change-Id: I4a0b38e84ac1f12c9605c48188c6f28b400c59ca
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/84774
Reviewed-by: Garvin Hicking <gh@faktor-e.de>
Tested-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Stefan Bürk <stefan@buerk.tech>
Reviewed-by: Oliver Wand <wand@itaw.de>
Tested-by: Garvin Hicking <gh@faktor-e.de>
---
 .../Database/Schema/DefaultTcaSchema.php      | 16 +++++-
 .../Database/Schema/DefaultTcaSchemaTest.php  | 53 ++++++++++++++++++-
 2 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php b/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php
index 746d1590b7bd..c83ab72c6a2d 100644
--- a/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php
+++ b/typo3/sysext/core/Classes/Database/Schema/DefaultTcaSchema.php
@@ -767,13 +767,25 @@ class DefaultTcaSchema
                         break;
 
                     case 'input':
-                        $length = $fieldConfig['config']['max'] ?? null;
+                        $length = $fieldConfig['config']['max'] ?? 255;
                         $nullable = $fieldConfig['config']['nullable'] ?? false;
+                        if ($length > 255) {
+                            $tables[$tableName]->addColumn(
+                                $this->quote($fieldName),
+                                Types::TEXT,
+                                [
+                                    'length' => 65535,
+                                    'default' => $nullable ? null : '',
+                                    'notnull' => !$nullable,
+                                ]
+                            );
+                            break;
+                        }
                         $tables[$tableName]->addColumn(
                             $this->quote($fieldName),
                             Types::STRING,
                             [
-                                'length' => $length ?? 255,
+                                'length' => $length,
                                 'default' => '',
                                 'notnull' => !$nullable,
                             ]
diff --git a/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php b/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php
index bc9b55c7d3de..9ec757ab1f7b 100644
--- a/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php
+++ b/typo3/sysext/core/Tests/Unit/Database/Schema/DefaultTcaSchemaTest.php
@@ -1709,7 +1709,7 @@ final class DefaultTcaSchemaTest extends UnitTestCase
             'label' => 'aLabel',
             'config' => [
                 'type' => 'input',
-                'max' => 512,
+                'max' => 123,
             ],
         ];
         $result = $this->subject->enrich(['aTable' => $this->defaultTable]);
@@ -1717,7 +1717,7 @@ final class DefaultTcaSchemaTest extends UnitTestCase
             '`input`',
             Type::getType('string'),
             [
-                'length' => 512,
+                'length' => 123,
                 'default' => '',
                 'notnull' => true,
             ]
@@ -1749,6 +1749,55 @@ final class DefaultTcaSchemaTest extends UnitTestCase
         self::assertSame($expectedColumn->toArray(), $result['aTable']->getColumn('input')->toArray());
     }
 
+    #[Test]
+    public function enrichAddsInputAndUsesTextForLongColumns(): void
+    {
+        $this->mockDefaultConnectionPlatformInConnectionPool();
+        $GLOBALS['TCA']['aTable']['columns']['input'] = [
+            'label' => 'aLabel',
+            'config' => [
+                'type' => 'input',
+                'max' => 256,
+            ],
+        ];
+        $result = $this->subject->enrich(['aTable' => $this->defaultTable]);
+        $expectedColumn = new Column(
+            '`input`',
+            Type::getType('text'),
+            [
+                'length' => 65535,
+                'default' => '',
+                'notnull' => true,
+            ]
+        );
+        self::assertSame($expectedColumn->toArray(), $result['aTable']->getColumn('input')->toArray());
+    }
+
+    #[Test]
+    public function enrichAddsInputAndUsesTextForLongColumnsAndNullable(): void
+    {
+        $this->mockDefaultConnectionPlatformInConnectionPool();
+        $GLOBALS['TCA']['aTable']['columns']['input'] = [
+            'label' => 'aLabel',
+            'config' => [
+                'type' => 'input',
+                'max' => 512,
+                'nullable' => true,
+            ],
+        ];
+        $result = $this->subject->enrich(['aTable' => $this->defaultTable]);
+        $expectedColumn = new Column(
+            '`input`',
+            Type::getType('text'),
+            [
+                'length' => 65535,
+                'default' => null,
+                'notnull' => false,
+            ]
+        );
+        self::assertSame($expectedColumn->toArray(), $result['aTable']->getColumn('input')->toArray());
+    }
+
     #[Test]
     public function enrichAddsInlineWithMMSet(): void
     {
-- 
GitLab