Skip to content

Commit b173394

Browse files
authored
fix(plugin-mysql): classify BINARY/VARBINARY as blob to prevent accidental data wipe on edit (#1217)
1 parent ca45984 commit b173394

2 files changed

Lines changed: 3 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9898

9999
### Fixed
100100

101+
- MySQL/MariaDB: `BINARY(N)` and `VARBINARY(N)` columns are no longer classified as text. The plugin's type switch returned `"CHAR"` for type code 254 and `"VARCHAR"` for type code 253 without consulting the binary flag, so binary columns came through as `.text` instead of `.blob`. The data grid then allowed inline edit on those cells, the editor opened with an empty field (because `PluginCellValue.bytes(_).asText` returns `nil`), and focus-out marked the cell as modified-to-empty. A single accidental click was enough to schedule destruction of the original bytes on Save. Case 253 now returns `"VARBINARY"` and case 254 returns `"BINARY"` when the binary flag is set, so these cells route through the blob editor (chevron-triggered) instead of inline text edit
101102
- Data grid: dropdown / boolean / date / JSON / blob cells now show or hide their chevron accessory when the cell's editability changes (refresh, safe-mode toggle, view-to-table switch). The performance pass in #1212 made `configure` skip `needsDisplay = true` when nothing visible changed, but the editability flag was updated unconditionally without flagging a redraw, so chevrons could stick in their stale state (visible in `audit_log.payload` JSON cells after save / refresh / reopen)
102103
- MySQL/MariaDB: JSON column detection no longer flickers across refreshes. The plugin reads `mariadb_field_attr(MARIADB_FIELD_ATTR_FORMAT_NAME)` to recognize JSON-stored-as-LONGTEXT. The returned `MARIADB_CONST_STRING` is a length-prefixed buffer (not null-terminated), but we were reading it with `String(cString:)`, which scans bytes until the next `\0` and so reads past the buffer into adjacent memory. When that memory happened to contain a null byte the comparison passed and we tagged the column `JSON`; when it contained garbage the comparison failed and we fell through to `LONGTEXT`. Read exactly `attr.length` bytes via `String(data: Data(bytes:count:), encoding: .utf8)`
103104
- Welcome window sometimes failed to open on launch (and Dock-icon clicks did nothing) when the previous session restored only main connection windows. `WindowOpenerBridge` was mounted only in the Welcome scene and used `.onAppear`, so if Welcome got `orderOut`'d before its first appearance the bridge never wired and every `openWelcome()` call queued forever. The bridge now mounts in all four SwiftUI scenes (Welcome, ConnectionForm, IntegrationsActivity, Settings) and uses `.task` so wiring fires reliably whenever any scene materializes

Plugins/MySQLDriverPlugin/MariaDBPluginConnection.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ func mysqlTypeToString(_ fieldPtr: UnsafePointer<MYSQL_FIELD>) -> String {
131131
} else {
132132
return length > 65_535 ? "LONGTEXT" : "TEXT"
133133
}
134-
case 253: return "VARCHAR"
135-
case 254: return "CHAR"
134+
case 253: return isBinary ? "VARBINARY" : "VARCHAR"
135+
case 254: return isBinary ? "BINARY" : "CHAR"
136136
case 255: return "GEOMETRY"
137137
default: return "UNKNOWN"
138138
}

0 commit comments

Comments
 (0)