diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 5e38f46..3530570 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -3361,8 +3361,13 @@ psql_completion(const char *text, int start, int end)
 	else if (HeadMatches("ALTER", "DATABASE|FUNCTION|PROCEDURE|ROLE|ROUTINE|USER") &&
 			 TailMatches("SET", MatchAny))
 		COMPLETE_WITH("FROM CURRENT", "TO");
-	/* Suggest possible variable values */
-	else if (TailMatches("SET", MatchAny, "TO|="))
+
+	/*
+	 * Suggest possible variable values in SET variable TO|=, along with the
+	 * preceding ALTER syntaxes.
+	 */
+	else if (TailMatches("SET", MatchAny, "TO|=") &&
+			 !TailMatches("UPDATE", MatchAny, "SET", MatchAny, "TO|="))
 	{
 		/* special cased code for individual GUCs */
 		if (TailMatches("DateStyle", "TO|="))
@@ -3390,8 +3395,18 @@ psql_completion(const char *text, int start, int end)
 			else if (guctype && strcmp(guctype, "bool") == 0)
 				COMPLETE_WITH("on", "off", "true", "false", "yes", "no",
 							  "1", "0", "DEFAULT");
-			else
-				COMPLETE_WITH("DEFAULT");
+
+			/*
+			 * Note: if we didn't recognize the GUC name, it's important to
+			 * not offer any completions, as most likely we've misinterpreted
+			 * the context and this isn't a GUC-setting command at all.  If we
+			 * did recognize the GUC but it's not enum or bool type, it still
+			 * seems better to do nothing.  We used to offer (only) "DEFAULT"
+			 * as a possible completion, but that turns out to be a bad idea,
+			 * because with a single completion libreadline will decide that
+			 * that's the only legal text and throw away whatever the user
+			 * might've typed already.
+			 */
 
 			if (guctype)
 				free(guctype);
