From 7be7f3ed830b50ac1a0ddccb0eea4ffd68ff128f Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Sun, 1 Feb 2026 11:50:08 +0100 Subject: [PATCH] fix: allow $$ as delimiter again on non-PostgreSQL connections, and ` on non-MySQL connections Refs #2385 --- source/apphelpers.pas | 36 +++++++++++++++++++++++++----------- source/dbconnection.pas | 4 ++-- source/main.pas | 12 ++++++------ source/table_editor.pas | 4 ++-- source/view.pas | 2 +- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/source/apphelpers.pas b/source/apphelpers.pas index d0a21639..3021c853 100644 --- a/source/apphelpers.pas +++ b/source/apphelpers.pas @@ -76,10 +76,13 @@ type TSQLBatch = class(TObjectList) private FSQL: String; + FQuotes: THashedStringList; procedure SetSQL(Value: String); function GetSize: Integer; function GetSQLWithoutComments: String; overload; public + constructor Create(NetTypeGroup: TNetTypeGroup); + destructor Destroy; overload; class function GetSQLWithoutComments(FullSQL: String): String; overload; property Size: Integer read GetSize; property SQL: String read FSQL write SetSQL; @@ -3394,6 +3397,26 @@ end; { TSQLBatch } +constructor TSQLBatch.Create(NetTypeGroup: TNetTypeGroup); +begin + inherited Create; + FQuotes := THashedStringList.Create; + FQuotes.CaseSensitive := True; + FQuotes.Sorted := True; + FQuotes.Add('"'); + FQuotes.Add(''''); + case NetTypeGroup of + ngMySQL: FQuotes.Add('`'); // MySQL/MariaDB only + ngPgSQL: FQuotes.Add('$$'); // PostgreSQL only ($abc$ unsupported) + end; +end; + +destructor TSQLBatch.Destroy; +begin + FQuotes.Free; + inherited; +end; + function TSQLBatch.GetSize: Integer; var Query: TSQLSentence; @@ -3413,7 +3436,6 @@ var InString, InComment, InBigComment, InEscape: Boolean; Marker: TSQLSentence; rx: TRegExpr; - Quotes: THashedStringList; const NewLines = [#13, #10]; WhiteSpaces = NewLines + [#9, ' ']; @@ -3425,13 +3447,6 @@ begin i := 0; LastLeftOffset := 1; Delim := Mainform.Delimiter; - Quotes := THashedStringList.Create; - Quotes.CaseSensitive := True; - Quotes.Sorted := True; - Quotes.Add('"'); - Quotes.Add(''''); - Quotes.Add('`'); // MySQL/MariaDB only - Quotes.Add('$$'); // PostgreSQL only ($abc$ unsupported) InString := False; // c is in "enclosed string" or `identifier` InComment := False; // c is in one-line comment (# or --) @@ -3462,10 +3477,10 @@ begin if InBigComment and (not InComment) and (not InString) and (c + n = '*/') then InBigComment := False; // Check for enclosed literals, so a query delimiter can be ignored - if (not InEscape) and (not InComment) and (not InBigComment) and (Quotes.Contains(c) or Quotes.Contains(cn)) then begin + if (not InEscape) and (not InComment) and (not InBigComment) and (FQuotes.Contains(c) or FQuotes.Contains(cn)) then begin if not InString then begin InString := True; - LastQuote := IfThen(Quotes.Contains(c), c, cn); + LastQuote := IfThen(FQuotes.Contains(c), c, cn); end else if (c = LastQuote) or (cn = LastQuote) then begin InString := False; @@ -3512,7 +3527,6 @@ begin end; end; - Quotes.Free; end; function TSQLBatch.GetSQLWithoutComments: String; diff --git a/source/dbconnection.pas b/source/dbconnection.pas index 0c0cada7..c87cf9af 100644 --- a/source/dbconnection.pas +++ b/source/dbconnection.pas @@ -4175,7 +4175,7 @@ var Batch: TSQLBatch; begin Result := TDBQueryList.Create(False); - Batch := TSQLBatch.Create; + Batch := TSQLBatch.Create(FParameters.NetTypeGroup); Batch.SQL := FLastQuerySQL; for i:=Low(FLastRawResults) to High(FLastRawResults) do begin r := Parameters.CreateQuery(Self); @@ -5132,7 +5132,7 @@ var i: Integer; begin Query(SQL, True); - Batch := TSQLBatch.Create; + Batch := TSQLBatch.Create(FParameters.NetTypeGroup); Batch.SQL := SQL; FreeAndNil(FPrefetchResults); FPrefetchResults := TDBQueryList.Create(True); diff --git a/source/main.pas b/source/main.pas index f6b6374f..d75eeab3 100644 --- a/source/main.pas +++ b/source/main.pas @@ -3205,7 +3205,7 @@ var begin // Return SQL query on cursor position Result := ''; - BatchAll := TSQLBatch.Create; + BatchAll := TSQLBatch.Create(ActiveConnection.Parameters.NetTypeGroup); BatchAll.SQL := Tab.Memo.Text; PrevQuery := nil; for Query in BatchAll do begin @@ -3241,7 +3241,7 @@ begin DoExecute := True; ShowStatusMsg(_('Splitting SQL queries ...')); - Batch := TSQLBatch.Create; + Batch := TSQLBatch.Create(ActiveConnection.Parameters.NetTypeGroup); if Sender = actExecuteSelection then begin Batch.SQL := Tab.Memo.SelText; Tab.LeftOffsetInMemo := Tab.Memo.SelStart; @@ -4167,7 +4167,7 @@ begin ErrorCount := 0; RowsAffected := 0; LinesRemain := ''; - Queries := TSQLBatch.Create; + Queries := TSQLBatch.Create(Conn.Parameters.NetTypeGroup); try // Start file operations @@ -4373,7 +4373,7 @@ begin if not FileExists(StartupScript) then ErrorDialog(f_('Startup script file not found: %s', [StartupScript])) else begin - StartupBatch := TSQLBatch.Create; + StartupBatch := TSQLBatch.Create(Connection.Parameters.NetTypeGroup); StartupBatch.SQL := ReadTextfile(StartupScript, nil); for Query in StartupBatch do try Connection.Query(Query.SQL); @@ -5345,7 +5345,7 @@ begin Msg := _('Empty value.') else begin rx := TRegExpr.Create; - rx.Expression := '(/\*|--|#|\''|\"|`|\$\$)'; + rx.Expression := '(/\*|--|#|\''|\")'; if rx.Exec(Value) then Msg := _('Start-of-comment tokens or string literal markers are not allowed.') end; @@ -6984,7 +6984,7 @@ begin CurrentQuery := 'SELECT * FROM '+ActiveDbObj.QuotedName+' WHERE ' + Editor.Text; end else begin // In a query tab - Queries := TSQLBatch.Create; + Queries := TSQLBatch.Create(Conn.Parameters.NetTypeGroup); Queries.SQL := Editor.Text; for Query in Queries do begin if (Query.LeftOffset <= Editor.SelStart) and (Editor.SelStart < Query.RightOffset) then begin diff --git a/source/table_editor.pas b/source/table_editor.pas index c4e3e3ab..3c714a72 100644 --- a/source/table_editor.pas +++ b/source/table_editor.pas @@ -924,7 +924,7 @@ begin AddQuery(FKeys[i].SQLCode(DBObject.Name)); end; - Result := TSQLBatch.Create; + Result := TSQLBatch.Create(DBObject.Connection.Parameters.NetTypeGroup); Result.SQL := SQL; FreeAndNil(Specs); @@ -1018,7 +1018,7 @@ begin end; end; - Result := TSQLBatch.Create; + Result := TSQLBatch.Create(DBObject.Connection.Parameters.NetTypeGroup); Result.SQL := Trim(SQL); end; diff --git a/source/view.pas b/source/view.pas index 1b364c17..a30ff75b 100644 --- a/source/view.pas +++ b/source/view.pas @@ -250,7 +250,7 @@ begin sql := sql + 'RENAME TABLE '+ViewName + ' TO '+RenameView + ';' + sLineBreak; end; - Result := TSQLBatch.Create; + Result := TSQLBatch.Create(DBObject.Connection.Parameters.NetTypeGroup); Result.SQL := Trim(SQL); end;