Skip to content

Commit 130c26e

Browse files
committed
feat: support invisible indexes on MySQL 8.0+ and ignored indexes on MariaDB 10.6+
Refs #1388
1 parent 6302851 commit 130c26e

File tree

3 files changed

+85
-41
lines changed

3 files changed

+85
-41
lines changed

source/dbconnection.pas

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ TTableKey = class(TPersistent)
8888
Name, OldName: String;
8989
IndexType, OldIndexType, Algorithm, Comment: String;
9090
Columns, SubParts, Collations: TStringList;
91-
Modified, Added: Boolean;
91+
Modified, Added, Visible: Boolean;
9292
constructor Create(AOwner: TDBConnection);
9393
destructor Destroy; override;
9494
procedure Assign(Source: TPersistent); override;
@@ -431,7 +431,8 @@ TDBLogItem = class(TObject)
431431
frCreateTrigger,
432432
frCreateEvent,
433433
frInvisibleColumns,
434-
frCompressedColumns
434+
frCompressedColumns,
435+
frInvisibleIndexes
435436
);
436437

437438
TDBConnection = class(TComponent)
@@ -6215,6 +6216,10 @@ function TMySQLConnection.GetTableKeys(Table: TDBObject): TTableKeyList;
62156216
if ExecRegExpr('(BTREE|HASH)', KeyQuery.Col('Index_type')) then
62166217
NewKey.Algorithm := KeyQuery.Col('Index_type');
62176218
NewKey.Comment := KeyQuery.Col('Index_comment', True);
6219+
if KeyQuery.ColumnExists('Visible') then // mysql 8
6220+
NewKey.Visible := SameText(KeyQuery.Col('Visible'), 'yes')
6221+
else if KeyQuery.ColumnExists('Ignored') then // mariadb 10.6
6222+
NewKey.Visible := SameText(KeyQuery.Col('Ignored'), 'NO');
62186223
end;
62196224
if KeyQuery.ColumnExists('Expression') and (not KeyQuery.IsNull('Expression')) then begin
62206225
// Functional key part: enclose expression within parentheses to distinguish them from columns (issue #1777)
@@ -6723,6 +6728,8 @@ function TDBConnection.Has(Item: TFeatureOrRequirement): Boolean;
67236728
frCreateEvent: Result := ServerVersionInt >= 50100;
67246729
frInvisibleColumns: Result := (FParameters.IsMariaDB and (ServerVersionInt >= 100303)) or
67256730
(FParameters.IsMySQL(True) and (ServerVersionInt >= 80023));
6731+
frInvisibleIndexes: Result := (FParameters.IsMariaDB and (ServerVersionInt >= 100600)) or
6732+
(FParameters.IsMySQL(True) and (ServerVersionInt >= 80000));
67266733
frCompressedColumns: Result := (FParameters.IsMariaDB and (ServerVersionInt >= 100301));
67276734
end;
67286735
else Result := False;
@@ -11002,6 +11009,7 @@ constructor TTableKey.Create(AOwner: TDBConnection);
1100211009
Columns.OnChange := Modification;
1100311010
Subparts.OnChange := Modification;
1100411011
Collations.OnChange := Modification;
11012+
Visible := True;
1100511013
end;
1100611014

1100711015
destructor TTableKey.Destroy;
@@ -11024,6 +11032,7 @@ procedure TTableKey.Assign(Source: TPersistent);
1102411032
OldIndexType := s.OldIndexType;
1102511033
Algorithm := s.Algorithm;
1102611034
Comment := s.Comment;
11035+
Visible := s.Visible;
1102711036
Columns.Assign(s.Columns);
1102811037
SubParts.Assign(s.SubParts);
1102911038
Collations.Assign(s.Collations);
@@ -11141,6 +11150,14 @@ function TTableKey.SQLCode(TableName: String=''): String;
1114111150

1114211151
if not Comment.IsEmpty then
1114311152
Result := Result + ' COMMENT ' + FConnection.EscapeString(Comment);
11153+
11154+
if FConnection.Has(frInvisibleIndexes) then begin
11155+
if FConnection.Parameters.IsMySQL(True) then
11156+
Result := Result + ' ' + IfThen(Visible, 'VISIBLE', 'INVISIBLE')
11157+
else
11158+
Result := Result + ' ' + IfThen(Visible, 'NOT IGNORED', 'IGNORED');
11159+
end;
11160+
1114411161
end
1114511162
else begin
1114611163
// SQLite syntax:

source/table_editor.dfm

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ object frmTableEditor: TfrmTableEditor
4141
object lblName: TLabel
4242
Left = 4
4343
Top = 6
44-
Width = 31
45-
Height = 13
44+
Width = 35
45+
Height = 15
4646
Caption = 'Name:'
4747
end
4848
object lblComment: TLabel
4949
Left = 4
5050
Top = 33
51-
Width = 49
52-
Height = 13
51+
Width = 57
52+
Height = 15
5353
Caption = 'Comment:'
5454
end
5555
object editName: TEdit
5656
Left = 96
5757
Top = 3
5858
Width = 589
59-
Height = 21
59+
Height = 23
6060
Anchors = [akLeft, akTop, akRight]
6161
TabOrder = 0
6262
Text = 'editName'
@@ -112,7 +112,7 @@ object frmTableEditor: TfrmTableEditor
112112
object lblMaxRows: TLabel
113113
Left = 4
114114
Top = 52
115-
Width = 115
115+
Width = 114
116116
Height = 15
117117
Caption = 'Maximum row count:'
118118
end
@@ -133,7 +133,7 @@ object frmTableEditor: TfrmTableEditor
133133
object lblInsertMethod: TLabel
134134
Left = 358
135135
Top = 98
136-
Width = 84
136+
Width = 85
137137
Height = 15
138138
Caption = 'INSERT method:'
139139
end
@@ -275,7 +275,7 @@ object frmTableEditor: TfrmTableEditor
275275
Options = [coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus]
276276
Position = 0
277277
Text = 'Name'
278-
Width = 226
278+
Width = 176
279279
end
280280
item
281281
Options = [coEnabled, coParentBidiMode, coParentColor, coResizable, coShowDropMark, coVisible, coAllowFocus]
@@ -297,6 +297,10 @@ object frmTableEditor: TfrmTableEditor
297297
Position = 4
298298
Text = 'Direction'
299299
Width = 80
300+
end
301+
item
302+
Position = 5
303+
Text = 'Visibility'
300304
end>
301305
end
302306
object tlbIndexes: TToolBar
@@ -512,8 +516,10 @@ object frmTableEditor: TfrmTableEditor
512516
Caption = 'Table'
513517
end>
514518
ColumnClick = False
519+
HotTrack = True
515520
ReadOnly = True
516521
RowSelect = True
522+
SmallImages = MainForm.VirtualImageListMain
517523
TabOrder = 2
518524
ViewStyle = vsReport
519525
Visible = False

source/table_editor.pas

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,13 @@ TfrmTableEditor = class(TFrame)
236236
const ColNumInvisible = 13;
237237
const ColNumCompressed = 14;
238238
const ColNumsCheckboxes = [ColNumUnsigned, ColNumAllownull, ColNumZerofill, ColNumInvisible, ColNumCompressed];
239+
// Columns in index tree
240+
const IndexColNumName = 0;
241+
const IndexColNumType = 1;
242+
const IndexColNumAlgorithm = 2;
243+
const IndexColNumComment = 3;
244+
const IndexColNumDirection = 4;
245+
const IndexColNumVisibility = 5;
239246
procedure ValidateColumnControls;
240247
procedure ValidateIndexControls;
241248
procedure MoveFocusedIndexPart(NewIdx: Cardinal);
@@ -2079,8 +2086,10 @@ procedure TfrmTableEditor.treeIndexesGetImageIndex(Sender: TBaseVirtualTree;
20792086
begin
20802087
// Icon image showing type of index
20812088
VT := Sender as TVirtualStringTree;
2082-
if Column <> 0 then Exit;
2083-
if not (Kind in [ikNormal, ikSelected]) then Exit;
2089+
if Column <> IndexColNumName then
2090+
Exit;
2091+
if not (Kind in [ikNormal, ikSelected]) then
2092+
Exit;
20842093
case VT.GetNodeLevel(Node) of
20852094
0: ImageIndex := FKeys[Node.Index].ImageIndex;
20862095
1: begin
@@ -2105,27 +2114,29 @@ procedure TfrmTableEditor.treeIndexesGetText(Sender: TBaseVirtualTree;
21052114
0: begin
21062115
TblKey := FKeys[Node.Index];
21072116
case Column of
2108-
0: if TblKey.IsPrimary then
2117+
IndexColNumName: if TblKey.IsPrimary then
21092118
CellText := TblKey.IndexType + ' KEY' // Fixed name "PRIMARY KEY", cannot be changed
21102119
else
21112120
CellText := TblKey.Name;
2112-
1: CellText := TblKey.IndexType;
2113-
2: CellText := TblKey.Algorithm;
2114-
3: CellText := TblKey.Comment;
2115-
4: CellText := ''; // Column collation
2121+
IndexColNumType: CellText := TblKey.IndexType;
2122+
IndexColNumAlgorithm: CellText := TblKey.Algorithm;
2123+
IndexColNumComment: CellText := TblKey.Comment;
2124+
IndexColNumDirection: CellText := ''; // Column collation
2125+
IndexColNumVisibility: CellText := IfThen(TblKey.Visible, 'Visible', 'Invisible');
21162126
end;
21172127
end;
21182128
1: begin
21192129
TblKey := FKeys[Node.Parent.Index];
21202130
case Column of
2121-
0: CellText := TblKey.Columns[Node.Index];
2122-
1: CellText := TblKey.SubParts[Node.Index];
2123-
2: CellText := ''; // Index algorithm
2124-
3: CellText := ''; // Index comment
2125-
4: begin
2131+
IndexColNumName: CellText := TblKey.Columns[Node.Index];
2132+
IndexColNumType: CellText := TblKey.SubParts[Node.Index];
2133+
IndexColNumAlgorithm: CellText := ''; // Index algorithm
2134+
IndexColNumComment: CellText := ''; // Index comment
2135+
IndexColNumDirection: begin
21262136
CellText := TblKey.Collations[Node.Index];
21272137
CellText := IfThen(CellText.ToLower = 'a', 'ASC', 'DESC');
21282138
end;
2139+
IndexColNumVisibility: CellText := '';
21292140
end;
21302141
end;
21312142
end;
@@ -2344,13 +2355,17 @@ procedure TfrmTableEditor.treeIndexesEditing(Sender: TBaseVirtualTree;
23442355
Allowed := False;
23452356
if VT.GetNodeLevel(Node) = 0 then begin
23462357
// Disallow renaming primary key, and direction/collation of key node level
2347-
if (Column = 0) and (VT.Text[Node, 1] <> TTableKey.PRIMARY) then
2348-
Allowed := True
2349-
else
2350-
Allowed := Column in [1,2,3];
2351-
end else case Column of
2352-
0: Allowed := True;
2353-
1: begin
2358+
case Column of
2359+
IndexColNumName: Allowed := (VT.Text[Node, 1] <> TTableKey.PRIMARY);
2360+
IndexColNumType: Allowed := True;
2361+
IndexColNumAlgorithm: Allowed := True;
2362+
IndexColNumComment: Allowed := True;
2363+
IndexColNumVisibility: Allowed := DBObject.Connection.Has(frInvisibleIndexes);
2364+
end;
2365+
end
2366+
else case Column of
2367+
IndexColNumName: Allowed := True;
2368+
IndexColNumType: begin
23542369
// Column length is allowed for (var)char/text types only, even mandantory for text and blobs
23552370
IndexedColName := VT.Text[Node, 0];
23562371
for i:=0 to FColumns.Count-1 do begin
@@ -2360,7 +2375,7 @@ procedure TfrmTableEditor.treeIndexesEditing(Sender: TBaseVirtualTree;
23602375
end;
23612376
end;
23622377
end;
2363-
4: Allowed := True; // Collation
2378+
IndexColNumDirection: Allowed := True; // Collation
23642379
end;
23652380
end;
23662381

@@ -2377,18 +2392,23 @@ procedure TfrmTableEditor.treeIndexesCreateEditor(Sender: TBaseVirtualTree;
23772392
// Start cell editor
23782393
VT := Sender as TVirtualStringTree;
23792394
Level := (Sender as TVirtualStringtree).GetNodeLevel(Node);
2380-
if (Level = 0) and (Column = 1) then begin
2395+
if (Level = 0) and (Column = IndexColNumType) then begin
23812396
// Index type pulldown
23822397
EnumEditor := TEnumEditorLink.Create(VT, True, nil);
23832398
EnumEditor.ValueList := TStringList.Create;
23842399
EnumEditor.ValueList.CommaText := TTableKey.PRIMARY +','+ TTableKey.KEY +','+ TTableKey.UNIQUE +','+ TTableKey.FULLTEXT +','+ TTableKey.SPATIAL;
23852400
EditLink := EnumEditor;
2386-
end else if (Level = 0) and (Column = 2) then begin
2401+
end else if (Level = 0) and (Column = IndexColNumAlgorithm) then begin
23872402
// Algorithm pulldown
23882403
EnumEditor := TEnumEditorLink.Create(VT, True, nil);
23892404
EnumEditor.ValueList := Explode(',', ',BTREE,HASH,RTREE');
23902405
EditLink := EnumEditor;
2391-
end else if (Level = 1) and (Column = 0) then begin
2406+
end else if (Level = 0) and (Column = IndexColNumVisibility) then begin
2407+
// Visibility pulldown
2408+
EnumEditor := TEnumEditorLink.Create(VT, True, nil);
2409+
EnumEditor.ValueList := Explode(',', 'Visible,Invisible');
2410+
EditLink := EnumEditor;
2411+
end else if (Level = 1) and (Column = IndexColNumName) then begin
23922412
// Column names pulldown
23932413
EnumEditor := TEnumEditorLink.Create(VT, True, nil);
23942414
ColNode := listColumns.GetFirst;
@@ -2399,7 +2419,7 @@ procedure TfrmTableEditor.treeIndexesCreateEditor(Sender: TBaseVirtualTree;
23992419
end;
24002420
EnumEditor.AllowCustomText := True; // Allows adding a subpart in index parts: "TextCol(20)"
24012421
EditLink := EnumEditor;
2402-
end else if (Level = 1) and (Column = 4) then begin
2422+
end else if (Level = 1) and (Column = IndexColNumDirection) then begin
24032423
EnumEditor := TEnumEditorLink.Create(VT, True, nil);
24042424
EnumEditor.ValueList := Explode(',', ',ASC,DESC');
24052425
EditLink := EnumEditor;
@@ -2421,22 +2441,23 @@ procedure TfrmTableEditor.treeIndexesNewText(Sender: TBaseVirtualTree;
24212441
0: begin
24222442
TblKey := FKeys[Node.Index];
24232443
case Column of
2424-
0: TblKey.Name := NewText;
2425-
1: begin
2444+
IndexColNumName: TblKey.Name := NewText;
2445+
IndexColNumType: begin
24262446
TblKey.IndexType := NewText;
24272447
if NewText = TTableKey.PRIMARY then
24282448
TblKey.Name := TTableKey.PRIMARY;
24292449
end;
2430-
2: TblKey.Algorithm := NewText;
2431-
3: TblKey.Comment := NewText;
2450+
IndexColNumAlgorithm: TblKey.Algorithm := NewText;
2451+
IndexColNumComment: TblKey.Comment := NewText;
2452+
IndexColNumVisibility: TblKey.Visible := SameText(NewText, 'Visible');
24322453
end;
24332454
// Needs to be called manually for Name and IndexType properties:
24342455
TblKey.Modification(Sender);
24352456
end;
24362457
1: begin
24372458
TblKey := FKeys[Node.Parent.Index];
24382459
case Column of
2439-
0: begin
2460+
IndexColNumName: begin
24402461
// Detect input of "col(123)" and move "123" into subpart
24412462
rx := TRegExpr.Create;
24422463
rx.Expression := '.+\((\d+)\)';
@@ -2446,8 +2467,8 @@ procedure TfrmTableEditor.treeIndexesNewText(Sender: TBaseVirtualTree;
24462467
end else
24472468
TblKey.Columns[Node.Index] := NewText;
24482469
end;
2449-
1: TblKey.SubParts[Node.Index] := NewText;
2450-
4: begin
2470+
IndexColNumType: TblKey.SubParts[Node.Index] := NewText;
2471+
IndexColNumDirection: begin
24512472
if NewText.ToLower = 'asc' then
24522473
TblKey.Collations[Node.Index] := 'A'
24532474
else

0 commit comments

Comments
 (0)