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

Reply via email to