mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Support serial columns in Posgres, which is different from auto_increment on MySQL. Affects grid editing and table designer. Closes #279
This commit is contained in:
@ -347,7 +347,7 @@ end;
|
|||||||
procedure TCopyTableForm.btnOKClick(Sender: TObject);
|
procedure TCopyTableForm.btnOKClick(Sender: TObject);
|
||||||
var
|
var
|
||||||
CreateCode, InsertCode, TargetTable, DataCols, Msg: String;
|
CreateCode, InsertCode, TargetTable, DataCols, Msg: String;
|
||||||
TableExistence: String;
|
TableExistence, AutoIncName: String;
|
||||||
ParentNode, Node: PVirtualNode;
|
ParentNode, Node: PVirtualNode;
|
||||||
DoData, AutoIncGetsKey, AutoIncRemoved, TableHasAutoInc: Boolean;
|
DoData, AutoIncGetsKey, AutoIncRemoved, TableHasAutoInc: Boolean;
|
||||||
SelectedColumns: TTableColumnList;
|
SelectedColumns: TTableColumnList;
|
||||||
@ -409,9 +409,11 @@ begin
|
|||||||
|
|
||||||
// Columns code. Remove auto_increment attribute if pkey was unchecked, to overcome
|
// Columns code. Remove auto_increment attribute if pkey was unchecked, to overcome
|
||||||
// "there can be only one auto column and it must be defined as a key"
|
// "there can be only one auto column and it must be defined as a key"
|
||||||
|
AutoIncName := 'unknown';
|
||||||
for Column in SelectedColumns do begin
|
for Column in SelectedColumns do begin
|
||||||
AutoIncGetsKey := False;
|
AutoIncGetsKey := False;
|
||||||
AutoIncRemoved := False;
|
AutoIncRemoved := False;
|
||||||
|
AutoIncName := Column.AutoIncName;
|
||||||
if Column.DefaultType = cdtAutoInc then begin
|
if Column.DefaultType = cdtAutoInc then begin
|
||||||
for Key in SelectedKeys do begin
|
for Key in SelectedKeys do begin
|
||||||
// Don't check index type, MySQL allows auto-increment columns on nearly all indexes
|
// Don't check index type, MySQL allows auto-increment columns on nearly all indexes
|
||||||
@ -486,7 +488,7 @@ begin
|
|||||||
Screen.Cursor := crDefault;
|
Screen.Cursor := crDefault;
|
||||||
Msg := E.Message;
|
Msg := E.Message;
|
||||||
if FConnection.LastErrorCode = ER_WRONG_AUTO_KEY then
|
if FConnection.LastErrorCode = ER_WRONG_AUTO_KEY then
|
||||||
Msg := Msg + CRLF + CRLF + f_('Please select the required index for the %s flag.', ['auto_increment']);
|
Msg := Msg + CRLF + CRLF + f_('Please select the required index for the %s flag.', [AutoIncName]);
|
||||||
ErrorDialog(Msg);
|
ErrorDialog(Msg);
|
||||||
ModalResult := mrNone;
|
ModalResult := mrNone;
|
||||||
end;
|
end;
|
||||||
|
@ -61,6 +61,7 @@ type
|
|||||||
function CastAsText: String;
|
function CastAsText: String;
|
||||||
property Status: TEditingStatus read FStatus write SetStatus;
|
property Status: TEditingStatus read FStatus write SetStatus;
|
||||||
property Connection: TDBConnection read FConnection;
|
property Connection: TDBConnection read FConnection;
|
||||||
|
function AutoIncName: String;
|
||||||
end;
|
end;
|
||||||
PTableColumn = ^TTableColumn;
|
PTableColumn = ^TTableColumn;
|
||||||
TTableColumnList = class(TObjectList<TTableColumn>)
|
TTableColumnList = class(TObjectList<TTableColumn>)
|
||||||
@ -425,7 +426,7 @@ type
|
|||||||
spGlobalStatus, spCommandsCounters, spSessionVariables, spGlobalVariables,
|
spGlobalStatus, spCommandsCounters, spSessionVariables, spGlobalVariables,
|
||||||
spISSchemaCol,
|
spISSchemaCol,
|
||||||
spUSEQuery, spKillQuery, spKillProcess,
|
spUSEQuery, spKillQuery, spKillProcess,
|
||||||
spFuncLength, spFuncCeil, spFuncLeft, spFuncNow,
|
spFuncLength, spFuncCeil, spFuncLeft, spFuncNow, spFuncLastAutoIncNumber,
|
||||||
spLockedTables, spDisableForeignKeyChecks, spEnableForeignKeyChecks,
|
spLockedTables, spDisableForeignKeyChecks, spEnableForeignKeyChecks,
|
||||||
spOrderAsc, spOrderDesc);
|
spOrderAsc, spOrderDesc);
|
||||||
|
|
||||||
@ -3071,6 +3072,7 @@ begin
|
|||||||
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
||||||
FSQLSpecifities[spFuncLeft] := IfThen(Parameters.IsProxySQLAdmin, 'SUBSTR(%s, 1, %d)', 'LEFT(%s, %d)');
|
FSQLSpecifities[spFuncLeft] := IfThen(Parameters.IsProxySQLAdmin, 'SUBSTR(%s, 1, %d)', 'LEFT(%s, %d)');
|
||||||
FSQLSpecifities[spFuncNow] := IfThen(Parameters.IsProxySQLAdmin, 'CURRENT_TIMESTAMP', 'NOW()');
|
FSQLSpecifities[spFuncNow] := IfThen(Parameters.IsProxySQLAdmin, 'CURRENT_TIMESTAMP', 'NOW()');
|
||||||
|
FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()';
|
||||||
FSQLSpecifities[spLockedTables] := '';
|
FSQLSpecifities[spLockedTables] := '';
|
||||||
FSQLSpecifities[spDisableForeignKeyChecks] := 'SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0';
|
FSQLSpecifities[spDisableForeignKeyChecks] := 'SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0';
|
||||||
FSQLSpecifities[spEnableForeignKeyChecks] := 'SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1)';
|
FSQLSpecifities[spEnableForeignKeyChecks] := 'SET FOREIGN_KEY_CHECKS=IFNULL(@OLD_FOREIGN_KEY_CHECKS, 1)';
|
||||||
@ -3094,6 +3096,7 @@ begin
|
|||||||
FSQLSpecifities[spFuncCeil] := 'CEILING';
|
FSQLSpecifities[spFuncCeil] := 'CEILING';
|
||||||
FSQLSpecifities[spFuncLeft] := 'LEFT(%s, %d)';
|
FSQLSpecifities[spFuncLeft] := 'LEFT(%s, %d)';
|
||||||
FSQLSpecifities[spFuncNow] := 'GETDATE()';
|
FSQLSpecifities[spFuncNow] := 'GETDATE()';
|
||||||
|
FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()';
|
||||||
FSQLSpecifities[spLockedTables] := '';
|
FSQLSpecifities[spLockedTables] := '';
|
||||||
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
||||||
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
||||||
@ -3119,6 +3122,7 @@ begin
|
|||||||
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
||||||
FSQLSpecifities[spFuncLeft] := 'SUBSTRING(%s, 1, %d)';
|
FSQLSpecifities[spFuncLeft] := 'SUBSTRING(%s, 1, %d)';
|
||||||
FSQLSpecifities[spFuncNow] := 'NOW()';
|
FSQLSpecifities[spFuncNow] := 'NOW()';
|
||||||
|
FSQLSpecifities[spFuncLastAutoIncNumber] := 'LASTVAL()';
|
||||||
FSQLSpecifities[spLockedTables] := '';
|
FSQLSpecifities[spLockedTables] := '';
|
||||||
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
||||||
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
||||||
@ -3143,6 +3147,7 @@ begin
|
|||||||
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
||||||
FSQLSpecifities[spFuncLeft] := 'SUBSTR(%s, 1, %d)';
|
FSQLSpecifities[spFuncLeft] := 'SUBSTR(%s, 1, %d)';
|
||||||
FSQLSpecifities[spFuncNow] := 'DATETIME()';
|
FSQLSpecifities[spFuncNow] := 'DATETIME()';
|
||||||
|
FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()';
|
||||||
FSQLSpecifities[spLockedTables] := '';
|
FSQLSpecifities[spLockedTables] := '';
|
||||||
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
||||||
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
||||||
@ -3170,6 +3175,7 @@ begin
|
|||||||
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
FSQLSpecifities[spFuncCeil] := 'CEIL';
|
||||||
FSQLSpecifities[spFuncLeft] := 'SUBSTR(%s, 1, %d)';
|
FSQLSpecifities[spFuncLeft] := 'SUBSTR(%s, 1, %d)';
|
||||||
FSQLSpecifities[spFuncNow] := ' cast(''now'' as timestamp) from rdb$database';
|
FSQLSpecifities[spFuncNow] := ' cast(''now'' as timestamp) from rdb$database';
|
||||||
|
FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()';
|
||||||
FSQLSpecifities[spLockedTables] := '';
|
FSQLSpecifities[spLockedTables] := '';
|
||||||
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
FSQLSpecifities[spDisableForeignKeyChecks] := '';
|
||||||
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
FSQLSpecifities[spEnableForeignKeyChecks] := '';
|
||||||
@ -5605,6 +5611,9 @@ begin
|
|||||||
// from an expression:
|
// from an expression:
|
||||||
Result := not Value.Contains('(');
|
Result := not Value.Contains('(');
|
||||||
end;
|
end;
|
||||||
|
end else if FParameters.IsAnyPostgreSQL then begin
|
||||||
|
// text only if starting with '
|
||||||
|
Result := Value.StartsWith('''');
|
||||||
end else begin
|
end else begin
|
||||||
// MS SQL, PG and SQLite:
|
// MS SQL, PG and SQLite:
|
||||||
Result := True;
|
Result := True;
|
||||||
@ -5684,20 +5693,30 @@ begin
|
|||||||
|
|
||||||
DefText := ColQuery.Col('COLUMN_DEFAULT');
|
DefText := ColQuery.Col('COLUMN_DEFAULT');
|
||||||
Col.OnUpdateType := cdtNothing;
|
Col.OnUpdateType := cdtNothing;
|
||||||
if ExecRegExpr('\bauto_increment\b', ExtraText.ToLowerInvariant) then begin
|
if ColQuery.Col('COLUMN_DEFAULT').StartsWith('nextval(', True) then begin
|
||||||
|
// PG auto increment
|
||||||
Col.DefaultType := cdtAutoInc;
|
Col.DefaultType := cdtAutoInc;
|
||||||
Col.DefaultText := 'AUTO_INCREMENT';
|
Col.DefaultText := ColQuery.Col('COLUMN_DEFAULT');
|
||||||
end else if DefText.ToLowerInvariant = 'null' then begin
|
end
|
||||||
|
else if ExecRegExpr('\bauto_increment\b', ExtraText.ToLowerInvariant) then begin
|
||||||
|
// MySQL auto increment
|
||||||
|
Col.DefaultType := cdtAutoInc;
|
||||||
|
Col.DefaultText := Col.AutoIncName;
|
||||||
|
end
|
||||||
|
else if DefText.ToLowerInvariant = 'null' then begin
|
||||||
Col.DefaultType := cdtNull;
|
Col.DefaultType := cdtNull;
|
||||||
end else if ColQuery.IsNull('COLUMN_DEFAULT') then begin
|
end
|
||||||
|
else if ColQuery.IsNull('COLUMN_DEFAULT') then begin
|
||||||
if Col.AllowNull then
|
if Col.AllowNull then
|
||||||
Col.DefaultType := cdtNull
|
Col.DefaultType := cdtNull
|
||||||
else
|
else
|
||||||
Col.DefaultType := cdtNothing;
|
Col.DefaultType := cdtNothing;
|
||||||
end else if IsTextDefault(DefText, Col.DataType) then begin
|
end
|
||||||
|
else if IsTextDefault(DefText, Col.DataType) then begin
|
||||||
Col.DefaultType := cdtText;
|
Col.DefaultType := cdtText;
|
||||||
Col.DefaultText := IfThen(DefText.StartsWith(''''), ExtractLiteral(DefText, ''), DefText);
|
Col.DefaultText := IfThen(DefText.StartsWith(''''), ExtractLiteral(DefText, ''), DefText);
|
||||||
end else begin
|
end
|
||||||
|
else begin
|
||||||
Col.DefaultType := cdtExpression;
|
Col.DefaultType := cdtExpression;
|
||||||
Col.DefaultText := DefText;
|
Col.DefaultText := DefText;
|
||||||
end;
|
end;
|
||||||
@ -5770,7 +5789,7 @@ begin
|
|||||||
Col.OnUpdateType := cdtNothing;
|
Col.OnUpdateType := cdtNothing;
|
||||||
if ExecRegExpr('^auto_increment$', ExtraText.ToLowerInvariant) then begin
|
if ExecRegExpr('^auto_increment$', ExtraText.ToLowerInvariant) then begin
|
||||||
Col.DefaultType := cdtAutoInc;
|
Col.DefaultType := cdtAutoInc;
|
||||||
Col.DefaultText := 'AUTO_INCREMENT';
|
Col.DefaultText := Col.AutoIncName;
|
||||||
end else if ColQuery.IsNull('Default') then begin
|
end else if ColQuery.IsNull('Default') then begin
|
||||||
Col.DefaultType := cdtNothing;
|
Col.DefaultType := cdtNothing;
|
||||||
end else if IsTextDefault(DefText, Col.DataType) then begin
|
end else if IsTextDefault(DefText, Col.DataType) then begin
|
||||||
@ -9545,7 +9564,7 @@ begin
|
|||||||
if Assigned(ColAttr) and (ColAttr.DefaultType = cdtAutoInc) then begin
|
if Assigned(ColAttr) and (ColAttr.DefaultType = cdtAutoInc) then begin
|
||||||
Row[i].NewText := UnformatNumber(Row[i].NewText);
|
Row[i].NewText := UnformatNumber(Row[i].NewText);
|
||||||
if Row[i].NewText = '0' then
|
if Row[i].NewText = '0' then
|
||||||
Row[i].NewText := Connection.GetVar('SELECT LAST_INSERT_ID()');
|
Row[i].NewText := Connection.GetVar('SELECT ' + Connection.GetSQLSpecifity(spFuncLastAutoIncNumber));
|
||||||
Row[i].NewIsNull := False;
|
Row[i].NewIsNull := False;
|
||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
@ -10500,7 +10519,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
if InParts(cpType) then begin
|
if InParts(cpType) then begin
|
||||||
Result := Result + DataType.Name;
|
case FConnection.Parameters.NetTypeGroup of
|
||||||
|
ngPgSQL: begin
|
||||||
|
if DefaultType = cdtAutoInc then
|
||||||
|
Result := Result + 'SERIAL'
|
||||||
|
else
|
||||||
|
Result := Result + DataType.Name;
|
||||||
|
end;
|
||||||
|
else Result := Result + DataType.Name;
|
||||||
|
end;
|
||||||
|
|
||||||
if (LengthSet <> '') and DataType.HasLength then
|
if (LengthSet <> '') and DataType.HasLength then
|
||||||
Result := Result + '(' + LengthSet + ')';
|
Result := Result + '(' + LengthSet + ')';
|
||||||
if (DataType.Category in [dtcInteger, dtcReal]) and Unsigned then
|
if (DataType.Category in [dtcInteger, dtcReal]) and Unsigned then
|
||||||
@ -10523,7 +10551,12 @@ begin
|
|||||||
// cdtNothing: leave out whole clause
|
// cdtNothing: leave out whole clause
|
||||||
cdtText: Result := Result + 'DEFAULT '+FConnection.EscapeString(DefaultText);
|
cdtText: Result := Result + 'DEFAULT '+FConnection.EscapeString(DefaultText);
|
||||||
cdtNull: Result := Result + 'DEFAULT NULL';
|
cdtNull: Result := Result + 'DEFAULT NULL';
|
||||||
cdtAutoInc: Result := Result + 'AUTO_INCREMENT';
|
cdtAutoInc: begin
|
||||||
|
case FConnection.Parameters.NetTypeGroup of
|
||||||
|
ngPgSQL:;
|
||||||
|
else Result := Result + AutoIncName;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
cdtExpression: begin
|
cdtExpression: begin
|
||||||
if FConnection.Parameters.IsMySQL(True) and (FConnection.ServerVersionInt >= 80013) then
|
if FConnection.Parameters.IsMySQL(True) and (FConnection.ServerVersionInt >= 80013) then
|
||||||
Result := Result + 'DEFAULT ('+DefaultText+')'
|
Result := Result + 'DEFAULT ('+DefaultText+')'
|
||||||
@ -10631,6 +10664,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TTableColumn.AutoIncName: String;
|
||||||
|
begin
|
||||||
|
case FConnection.Parameters.NetTypeGroup of
|
||||||
|
ngPgSQL: Result := 'SERIAL';
|
||||||
|
else Result := 'AUTO_INCREMENT';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TTableColumnList.Assign(Source: TTableColumnList);
|
procedure TTableColumnList.Assign(Source: TTableColumnList);
|
||||||
var
|
var
|
||||||
Item, ItemCopy: TTableColumn;
|
Item, ItemCopy: TTableColumn;
|
||||||
|
@ -1358,7 +1358,7 @@ begin
|
|||||||
FRadioAutoInc.Width := FRadioAutoInc.Parent.Width - 2 * FRadioAutoInc.Left;
|
FRadioAutoInc.Width := FRadioAutoInc.Parent.Width - 2 * FRadioAutoInc.Left;
|
||||||
FRadioAutoInc.OnClick := RadioClick;
|
FRadioAutoInc.OnClick := RadioClick;
|
||||||
FRadioAutoInc.OnKeyDown := DoKeyDown;
|
FRadioAutoInc.OnKeyDown := DoKeyDown;
|
||||||
FRadioAutoInc.Caption := 'AUTO_INCREMENT';
|
FRadioAutoInc.Caption := Col.AutoIncName;
|
||||||
|
|
||||||
FBtnOk := TButton.Create(FPanel);
|
FBtnOk := TButton.Create(FPanel);
|
||||||
FBtnOk.Parent := FPanel;
|
FBtnOk.Parent := FPanel;
|
||||||
@ -1522,7 +1522,7 @@ begin
|
|||||||
cdtText: Col.DefaultText := FTextEdit.Text;
|
cdtText: Col.DefaultText := FTextEdit.Text;
|
||||||
cdtNull: Col.DefaultText := 'NULL';
|
cdtNull: Col.DefaultText := 'NULL';
|
||||||
cdtExpression: Col.DefaultText := FExpressionEdit.Text;
|
cdtExpression: Col.DefaultText := FExpressionEdit.Text;
|
||||||
cdtAutoInc: Col.DefaultText := 'AUTO_INCREMENT';
|
cdtAutoInc: Col.DefaultText := Col.AutoIncName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FOnUpdateEdit.Text <> '' then
|
if FOnUpdateEdit.Text <> '' then
|
||||||
|
@ -1297,7 +1297,7 @@ begin
|
|||||||
cdtText: CellText := Col.Connection.EscapeString(Col.DefaultText);
|
cdtText: CellText := Col.Connection.EscapeString(Col.DefaultText);
|
||||||
cdtNull: CellText := 'NULL';
|
cdtNull: CellText := 'NULL';
|
||||||
cdtExpression: CellText := Col.DefaultText;
|
cdtExpression: CellText := Col.DefaultText;
|
||||||
cdtAutoInc: CellText := 'AUTO_INCREMENT';
|
cdtAutoInc: CellText := Col.AutoIncName;
|
||||||
end;
|
end;
|
||||||
case Col.OnUpdateType of
|
case Col.OnUpdateType of
|
||||||
// cdtNothing: leave clause away
|
// cdtNothing: leave clause away
|
||||||
|
Reference in New Issue
Block a user