[RFC]: DDL column classes for ENUM, SET and the remaining MySQL column types
Maintainer thường phản hồi trong vòng 1 ngày
@simon-mundy đang làm issue này rồi.
Từ ngày 4/9/2026.
Đánh giá
Issue này chưa được đánh giá.
Mô tả
Proposed Version
0.6.0
Basic Information
Currently Sql\Ddl\Column has 22 classes (the Laminas set plus Double, Json and SmallInteger from #138) and no way to express anything else. Column::$type is protected with no setter and no constructor argument (Column.php#L31, #L33-L38), so the only way to get an ENUM, SET, TINYINT, MEDIUMINT, BIT, YEAR, sized TEXT/BLOB or spatial column is to subclass. This proposal adds those classes, with ENUM/SET values emitted as Argument\Value so nothing caller-supplied reaches SQL as a literal, and fixes Text/Blob silently dropping their length.
Background
The read side is already ahead of the write side. PhpDb\Mysql\Metadata\Source parses enum(...)/set(...) into erratas['permitted_values'] (Source.php#L92-L103) and the enum path is integration-tested against the test_enum fixture (there is no SET fixture in mysql.sql). Nothing consumes permitted_values, and nothing can turn it back into DDL.
Text and Blob override $specification to %s %s (Text.php#L9-L11, Blob.php#L9-L12), so new Text('t', 100) renders TEXT and MySQL's TEXT(n) size selection is unreachable.
The phpdb-mysql-ddl-overrides branch on simon-mundy/phpdb-mysql already has Enum, Set, TinyInteger, MediumInteger, Bit, Year, the sized Text/Blob variants and all eight spatial types — in the adapter namespace PhpDb\Mysql\Sql\Ddl. It is 69 commits behind 0.5.x, pinned to a core branch that no longer exists, and predates the literal-slot rule (Enum quotes values with "'" . $v . "'" and no escaping). Useful for the design and the tests; not something to rebase.
Considerations
- Core or adapter — that is the real question. Core already hosts
Jsonand the MySQL-flavouredON UPDATE CURRENT_TIMESTAMPinAbstractTimestampColumn, so I have assumed core here with the adapter rendering onlySRID. The fork branch went the other way. - The sized Text/Blob variants must suppress the length entirely: MySQL rejects
TINYTEXT(100),MEDIUMBLOB(100)andLONGTEXT(10)with 1064. Column::setOption()is typedbool|string, so until it is widened (#169, also raised in phpdb-mysql#81) an int SRID goes through the constructor$optionsarray or as a string.- Clean rendering depends on the
AbstractLengthColumnValueError fix and theIntegerlength-position fix (#176 and #178). - Every rendering below (
YEAR NOT NULL,BIT(1),ENUM('a', 'b'),POINT SRID 4326) has been executed on MySQL 8.4.10 (reproduced on 8.0.46). - MariaDB and decorator work beyond
SRIDare out of scope.
Proposal(s)
In this order:
EnumandSet. Constructor(string $name, array $values, bool $nullable = false, string|int|float|bool|Literal|Value|null $default = null, array $options = []). Spec%s %s(%s, %s, ...)with oneArgument\Valueper member, so every value is quoted by the platform. Empty$valuesthrowsInvalidArgumentException.TinyInteger(TINYINT) andMediumInteger(MEDIUMINT) extendingInteger, same asSmallInteger.Bit(BIT(M)) extendingAbstractLengthColumn;Year(YEAR, no width —YEAR(4)is deprecated from 8.0.19).TinyText,MediumText,LongTextextendingText;TinyBlob,MediumBlob,LongBlobextendingBlob.Text/Blobthemselves either honour the length (TEXT(n),BLOB(n)) or reject it — the silent drop goes. The sized variants never emit a length.- Spatial:
Geometry,Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection, with ansridoption.SRID nis MySQL syntax (8.0.3+), so rendering it belongs in the MySQL decorator; core only carries the option.
Test plan:
new Enum('status', ['active', 'inactive'])renders`status` ENUM('active', 'inactive') NOT NULLon the MySQL platform with each value going throughquoteValue();SetrendersSET(...)the same way.- Every new class gets a unit test in
test/unit/Sql/Ddl/Column/asserting the rendered SQL string, not justgetExpressionData()containment. Text/Bloblength handling is explicit and tested; the sized variants never emit a length.- Round trip: the
test_enumfixture read through the metadataSource(coreAbstractSource::getColumn(), values viaColumnObject::getErrata('permitted_values')) can be re-expressed as anEnumwith the same values — integration test in phpdb-mysql. Add atest_setfixture and do the same forSet. - No new class emits a caller-supplied string as an
Argument\Literal.
Appendix/Additional Info
- #92 (parent), #91 (backed enums), #138 (previous DDL additions).
- From an internal DDL audit (not published — the findings are reproduced above).
- Ngôn ngữ chính
- PHP
- Star
- 18
- Fork
- 8
- Merge trung bình
- 6 ngày 11 giờ
- Pull request đã merge (30 ngày)
- 14
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Không có mẫu pull request
- Không có hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của php-db/phpdb
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
RFC
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 1 ngày
-
RFC
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 38/100
Maintainer thường phản hồi trong vòng 1 ngày
-
RFC
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
RFC
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
coollabsio/shoutrrr#190 ·
-
Bug Enhancement Performance
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Feature Status: Needs Triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 73/100
Maintainer thường phản hồi trong vòng 1 ngày
-
frontend low-priority
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 77/100
mplodowski/dynamicpdf-plugin#336 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
AdvancedCustomFields/acf#1044 ·