diff --git a/source/copytable.pas b/source/copytable.pas index ccf4e3b8..9be28274 100644 --- a/source/copytable.pas +++ b/source/copytable.pas @@ -347,7 +347,7 @@ end; procedure TCopyTableForm.btnOKClick(Sender: TObject); var CreateCode, InsertCode, TargetTable, DataCols, Msg: String; - TableExistence: String; + TableExistence, AutoIncName: String; ParentNode, Node: PVirtualNode; DoData, AutoIncGetsKey, AutoIncRemoved, TableHasAutoInc: Boolean; SelectedColumns: TTableColumnList; @@ -409,9 +409,11 @@ begin // 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" + AutoIncName := 'unknown'; for Column in SelectedColumns do begin AutoIncGetsKey := False; AutoIncRemoved := False; + AutoIncName := Column.AutoIncName; if Column.DefaultType = cdtAutoInc then begin for Key in SelectedKeys do begin // Don't check index type, MySQL allows auto-increment columns on nearly all indexes @@ -486,7 +488,7 @@ begin Screen.Cursor := crDefault; Msg := E.Message; 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); ModalResult := mrNone; end; diff --git a/source/dbconnection.pas b/source/dbconnection.pas index adc26345..845492e1 100644 --- a/source/dbconnection.pas +++ b/source/dbconnection.pas @@ -61,6 +61,7 @@ type function CastAsText: String; property Status: TEditingStatus read FStatus write SetStatus; property Connection: TDBConnection read FConnection; + function AutoIncName: String; end; PTableColumn = ^TTableColumn; TTableColumnList = class(TObjectList) @@ -425,7 +426,7 @@ type spGlobalStatus, spCommandsCounters, spSessionVariables, spGlobalVariables, spISSchemaCol, spUSEQuery, spKillQuery, spKillProcess, - spFuncLength, spFuncCeil, spFuncLeft, spFuncNow, + spFuncLength, spFuncCeil, spFuncLeft, spFuncNow, spFuncLastAutoIncNumber, spLockedTables, spDisableForeignKeyChecks, spEnableForeignKeyChecks, spOrderAsc, spOrderDesc); @@ -3071,6 +3072,7 @@ begin FSQLSpecifities[spFuncCeil] := 'CEIL'; FSQLSpecifities[spFuncLeft] := IfThen(Parameters.IsProxySQLAdmin, 'SUBSTR(%s, 1, %d)', 'LEFT(%s, %d)'); FSQLSpecifities[spFuncNow] := IfThen(Parameters.IsProxySQLAdmin, 'CURRENT_TIMESTAMP', 'NOW()'); + FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()'; FSQLSpecifities[spLockedTables] := ''; 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)'; @@ -3094,6 +3096,7 @@ begin FSQLSpecifities[spFuncCeil] := 'CEILING'; FSQLSpecifities[spFuncLeft] := 'LEFT(%s, %d)'; FSQLSpecifities[spFuncNow] := 'GETDATE()'; + FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()'; FSQLSpecifities[spLockedTables] := ''; FSQLSpecifities[spDisableForeignKeyChecks] := ''; FSQLSpecifities[spEnableForeignKeyChecks] := ''; @@ -3119,6 +3122,7 @@ begin FSQLSpecifities[spFuncCeil] := 'CEIL'; FSQLSpecifities[spFuncLeft] := 'SUBSTRING(%s, 1, %d)'; FSQLSpecifities[spFuncNow] := 'NOW()'; + FSQLSpecifities[spFuncLastAutoIncNumber] := 'LASTVAL()'; FSQLSpecifities[spLockedTables] := ''; FSQLSpecifities[spDisableForeignKeyChecks] := ''; FSQLSpecifities[spEnableForeignKeyChecks] := ''; @@ -3143,6 +3147,7 @@ begin FSQLSpecifities[spFuncCeil] := 'CEIL'; FSQLSpecifities[spFuncLeft] := 'SUBSTR(%s, 1, %d)'; FSQLSpecifities[spFuncNow] := 'DATETIME()'; + FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()'; FSQLSpecifities[spLockedTables] := ''; FSQLSpecifities[spDisableForeignKeyChecks] := ''; FSQLSpecifities[spEnableForeignKeyChecks] := ''; @@ -3170,6 +3175,7 @@ begin FSQLSpecifities[spFuncCeil] := 'CEIL'; FSQLSpecifities[spFuncLeft] := 'SUBSTR(%s, 1, %d)'; FSQLSpecifities[spFuncNow] := ' cast(''now'' as timestamp) from rdb$database'; + FSQLSpecifities[spFuncLastAutoIncNumber] := 'LAST_INSERT_ID()'; FSQLSpecifities[spLockedTables] := ''; FSQLSpecifities[spDisableForeignKeyChecks] := ''; FSQLSpecifities[spEnableForeignKeyChecks] := ''; @@ -5605,6 +5611,9 @@ begin // from an expression: Result := not Value.Contains('('); end; + end else if FParameters.IsAnyPostgreSQL then begin + // text only if starting with ' + Result := Value.StartsWith(''''); end else begin // MS SQL, PG and SQLite: Result := True; @@ -5684,20 +5693,30 @@ begin DefText := ColQuery.Col('COLUMN_DEFAULT'); 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.DefaultText := 'AUTO_INCREMENT'; - end else if DefText.ToLowerInvariant = 'null' then begin + Col.DefaultText := ColQuery.Col('COLUMN_DEFAULT'); + 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; - end else if ColQuery.IsNull('COLUMN_DEFAULT') then begin + end + else if ColQuery.IsNull('COLUMN_DEFAULT') then begin if Col.AllowNull then Col.DefaultType := cdtNull else 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.DefaultText := IfThen(DefText.StartsWith(''''), ExtractLiteral(DefText, ''), DefText); - end else begin + end + else begin Col.DefaultType := cdtExpression; Col.DefaultText := DefText; end; @@ -5770,7 +5789,7 @@ begin Col.OnUpdateType := cdtNothing; if ExecRegExpr('^auto_increment$', ExtraText.ToLowerInvariant) then begin Col.DefaultType := cdtAutoInc; - Col.DefaultText := 'AUTO_INCREMENT'; + Col.DefaultText := Col.AutoIncName; end else if ColQuery.IsNull('Default') then begin Col.DefaultType := cdtNothing; end else if IsTextDefault(DefText, Col.DataType) then begin @@ -9545,7 +9564,7 @@ begin if Assigned(ColAttr) and (ColAttr.DefaultType = cdtAutoInc) then begin Row[i].NewText := UnformatNumber(Row[i].NewText); 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; break; end; @@ -10500,7 +10519,16 @@ begin end; 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 Result := Result + '(' + LengthSet + ')'; if (DataType.Category in [dtcInteger, dtcReal]) and Unsigned then @@ -10523,7 +10551,12 @@ begin // cdtNothing: leave out whole clause cdtText: Result := Result + 'DEFAULT '+FConnection.EscapeString(DefaultText); 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 if FConnection.Parameters.IsMySQL(True) and (FConnection.ServerVersionInt >= 80013) then Result := Result + 'DEFAULT ('+DefaultText+')' @@ -10631,6 +10664,16 @@ begin 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); var Item, ItemCopy: TTableColumn; diff --git a/source/grideditlinks.pas b/source/grideditlinks.pas index 4fe34caf..bb56cf85 100644 --- a/source/grideditlinks.pas +++ b/source/grideditlinks.pas @@ -1358,7 +1358,7 @@ begin FRadioAutoInc.Width := FRadioAutoInc.Parent.Width - 2 * FRadioAutoInc.Left; FRadioAutoInc.OnClick := RadioClick; FRadioAutoInc.OnKeyDown := DoKeyDown; - FRadioAutoInc.Caption := 'AUTO_INCREMENT'; + FRadioAutoInc.Caption := Col.AutoIncName; FBtnOk := TButton.Create(FPanel); FBtnOk.Parent := FPanel; @@ -1522,7 +1522,7 @@ begin cdtText: Col.DefaultText := FTextEdit.Text; cdtNull: Col.DefaultText := 'NULL'; cdtExpression: Col.DefaultText := FExpressionEdit.Text; - cdtAutoInc: Col.DefaultText := 'AUTO_INCREMENT'; + cdtAutoInc: Col.DefaultText := Col.AutoIncName; end; if FOnUpdateEdit.Text <> '' then diff --git a/source/table_editor.pas b/source/table_editor.pas index 7608231c..336323eb 100644 --- a/source/table_editor.pas +++ b/source/table_editor.pas @@ -1297,7 +1297,7 @@ begin cdtText: CellText := Col.Connection.EscapeString(Col.DefaultText); cdtNull: CellText := 'NULL'; cdtExpression: CellText := Col.DefaultText; - cdtAutoInc: CellText := 'AUTO_INCREMENT'; + cdtAutoInc: CellText := Col.AutoIncName; end; case Col.OnUpdateType of // cdtNothing: leave clause away