In PostgreSQL 9.1, the line numbering of PL/pgSQL functions was changed
by this commit:
commit c3a05881de21438a29b6dc721ebd7d1e028a905a
Author: Robert Haas <[email protected]>
Date: Mon Aug 2 03:46:54 2010 +0000
Remove ancient PL/pgsql line numbering hack.
While this hack arguably has some benefit in terms of making PL/pgsql's
line numbering match the programmer's expectations, it also makes
PL/pgsql inconsistent with the remaining PLs, making it difficult for
clients to reliably determine where the error actually is. On balance,
it seems better to be consistent.
Pavel Stehule
The hack that was removed skipped an initial newline when counting line
numbers. The PL/pgSQL debugger has a similar hack, but it didn't get the
memo that it was removed in the backend, so the green current line
marker is off by one when connected to a 9.1 server. Attached is a patch
to fix that.
--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com
diff --git a/pgadmin/debugger/ctlCodeWindow.cpp b/pgadmin/debugger/ctlCodeWindow.cpp
index 5db7178..0745bab 100644
--- a/pgadmin/debugger/ctlCodeWindow.cpp
+++ b/pgadmin/debugger/ctlCodeWindow.cpp
@@ -510,18 +510,12 @@ void ctlCodeWindow::ResultBreakpoint( wxCommandEvent &event )
updateUI(result);
/* break point markup line number */
- unhilightCurrentLine();
-
int current_line = atoi(result.getString( wxT("linenumber")).ToAscii()) - 1;
if ( current_line < 0)
current_line = 1;
m_currentLineNumber = current_line;
- m_view->SetAnchor(m_view->PositionFromLine(!current_line ? 0 : current_line - 1));
- m_view->SetCurrentPos(m_view->PositionFromLine(!current_line ? 0 : current_line - 1));
- m_view->MarkerAdd(current_line - 1, MARKER_CURRENT);
- m_view->MarkerAdd(current_line - 1, MARKER_CURRENT_BG);
- m_view->EnsureCaretVisible();
+ hilightCurrentLine();
enableTools();
}
@@ -672,7 +666,10 @@ void ctlCodeWindow::ResultBreakpoints(wxCommandEvent &event)
for(int row = 0; row < result.getRowCount(); ++row)
{
- m_view->MarkerAdd(result.getLong(wxT("linenumber"), row) - 1, MARKER_BREAKPOINT);
+ int lineno = result.getLong(wxT("linenumber"), row);
+
+ lineno = lineno - m_displayedSourceOffset - 1;
+ m_view->MarkerAdd(lineno, MARKER_BREAKPOINT);
}
}
}
@@ -1018,7 +1015,7 @@ void ctlCodeWindow::cacheSource(const wxString &packageOID, const wxString &func
// getSource()
//
// This function retrieves the source code for a given function from the
-// PostgreSQL server. We don't actually wait for completionm, we just
+// PostgreSQL server. We don't actually wait for completion, we just
// schedule the request.
void ctlCodeWindow::getSource(const wxString &packageOID, const wxString &funcOID)
@@ -1067,12 +1064,23 @@ void ctlCodeWindow::displaySource(const wxString &packageOID, const wxString &fu
// Now erase any old code and write out the new listing
m_view->SetReadOnly( false );
- // Strip the leading blank line from the source as it looks ugly
+ // Strip the leading blank line from the source as it looks ugly.
+ // Before PostgreSQL 9.1, the server also did this when it calculated
+ // the line numbers for each statement. In 9.1 and above, the server
+ // no longer does this, so we have to compensate when we map line
+ // numbers we get from the server to line numbers we display.
+ // m_displayedSourceOffset indicates the number of lines hidden
+ // from the beginning, compared to the calculation the server does.
wxString src = codeCache.getSource();
src.Replace(wxT("\r"), wxT(""));
+ m_displayedSourceOffset = 0;
if (src.StartsWith(wxT("\n")))
+ {
+ if (m_dbgConn->BackendMinimumVersion(9, 1))
+ m_displayedSourceOffset = 1;
src = src.AfterFirst('\n');
+ }
m_view->SetText(src);
@@ -1080,6 +1088,14 @@ void ctlCodeWindow::displaySource(const wxString &packageOID, const wxString &fu
m_view->SetReadOnly(true);
}
+ hilightCurrentLine();
+
+ // Update the next lazy part of the user interface (the variable list)
+ m_updateVars = true;
+}
+
+void ctlCodeWindow::hilightCurrentLine()
+{
// Clear the current-line indicator
int lineNo = m_view->MarkerNext(0, MARKERINDEX_TO_MARKERMASK( MARKER_CURRENT));
int current_line = m_currentLineNumber;
@@ -1090,7 +1106,11 @@ void ctlCodeWindow::displaySource(const wxString &packageOID, const wxString &fu
m_view->MarkerDelete(lineNo, MARKER_CURRENT_BG);
}
- // Adjustment of the next position
+ // Adjust the offset for any hidden lines in the beginning.
+ if (current_line >= 1)
+ current_line -= m_displayedSourceOffset;
+
+ // XXX: I'm not sure why this is needed, but we've always done this.
if (current_line >= 1)
current_line--;
@@ -1106,9 +1126,6 @@ void ctlCodeWindow::displaySource(const wxString &packageOID, const wxString &fu
m_view->SetAnchor(m_view->PositionFromLine(current_line));
m_view->SetCurrentPos(m_view->PositionFromLine(current_line));
m_view->EnsureCaretVisible();
-
- // Update the next lazy part of the user interface (the variable list)
- m_updateVars = true;
}
////////////////////////////////////////////////////////////////////////////////
@@ -1221,10 +1238,13 @@ void ctlCodeWindow::OnResultSet( PGresult *result )
void ctlCodeWindow::setBreakpoint(int lineNumber)
{
+ lineNumber += m_displayedSourceOffset;
+ lineNumber++;
+
if (m_dbgConn->DebuggerApiVersion() <= DEBUGGER_V2_API)
- m_dbgConn->startCommand(wxString::Format(m_commandSetBreakpointV1, m_sessionHandle.c_str(), m_displayedPackageOid.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
+ m_dbgConn->startCommand(wxString::Format(m_commandSetBreakpointV1, m_sessionHandle.c_str(), m_displayedPackageOid.c_str(), m_displayedFuncOid.c_str(), lineNumber), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
else
- m_dbgConn->startCommand(wxString::Format(m_commandSetBreakpointV2, m_sessionHandle.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
+ m_dbgConn->startCommand(wxString::Format(m_commandSetBreakpointV2, m_sessionHandle.c_str(), m_displayedFuncOid.c_str(), lineNumber), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
m_updateBreakpoints = true;
}
@@ -1237,10 +1257,13 @@ void ctlCodeWindow::setBreakpoint(int lineNumber)
void ctlCodeWindow::clearBreakpoint( int lineNumber, bool requestUpdate )
{
+ lineNumber += m_displayedSourceOffset;
+ lineNumber++;
+
if (m_dbgConn->DebuggerApiVersion() <= DEBUGGER_V2_API)
- m_dbgConn->startCommand(wxString::Format(m_commandClearBreakpointV1, m_sessionHandle.c_str(), m_displayedPackageOid.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
+ m_dbgConn->startCommand(wxString::Format(m_commandClearBreakpointV1, m_sessionHandle.c_str(), m_displayedPackageOid.c_str(), m_displayedFuncOid.c_str(), lineNumber), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
else
- m_dbgConn->startCommand(wxString::Format(m_commandClearBreakpointV2, m_sessionHandle.c_str(), m_displayedFuncOid.c_str(), lineNumber + 1), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
+ m_dbgConn->startCommand(wxString::Format(m_commandClearBreakpointV2, m_sessionHandle.c_str(), m_displayedFuncOid.c_str(), lineNumber), GetEventHandler(), RESULT_ID_NEW_BREAKPOINT);
if (requestUpdate)
m_updateBreakpoints = true;
diff --git a/pgadmin/include/debugger/ctlCodeWindow.h b/pgadmin/include/debugger/ctlCodeWindow.h
index 30f0592..ceb6c2e 100644
--- a/pgadmin/include/debugger/ctlCodeWindow.h
+++ b/pgadmin/include/debugger/ctlCodeWindow.h
@@ -204,6 +204,7 @@ private:
wxString m_focusFuncOid; // Which function has the debug focus?
wxString m_displayedFuncOid; // Which function are we currently displaying? (function OID component)
wxString m_displayedPackageOid; // Which function are we currently displaying? (package OID component)
+ int m_displayedSourceOffset; // number of hidden lines at beginning of function source
wxString m_sessionHandle; // Handle to proxy's server session
wxString m_targetName; // User-friendly target name
@@ -213,6 +214,7 @@ private:
void getSource(const wxString &packageOID, const wxString &funcOID);
void cacheSource(const wxString &packageOID, const wxString &funcOID, const wxString &sourceCode, const wxString &signature);
void displaySource(const wxString &packageOID, const wxString &funcID);
+ void hilightCurrentLine();
void unhilightCurrentLine();
void launchWaitingDialog();
--
Sent via pgadmin-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgadmin-hackers