diff --git a/src/bin/psql/psql.c b/src/bin/psql/psql.c
index 9fff389efdebc9d3fec841be7bcb2e28a8def998..191752b66fd927d759f552cffdd5b55da5fe6564 100644
--- a/src/bin/psql/psql.c
+++ b/src/bin/psql/psql.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.88 1997/08/26 17:00:06 momjian Exp $
+ *    $Header: /cvsroot/pgsql/src/bin/psql/Attic/psql.c,v 1.89 1997/09/01 06:09:53 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -48,8 +48,28 @@
 # endif
 #endif
 
+/* This prompt string is assumed to have at least 3 characters by code in MainLoop().
+ * A character two characters from the end is replaced each time by a mode character.
+ */
 #define PROMPT "=> "
 
+#define PROMPT_READY	'='
+#define PROMPT_CONTINUE	'-'
+#define PROMPT_COMMENT	'*'
+#define PROMPT_QUOTE	'\''
+
+/* Backslash command handling:
+ *  0 - send currently constructed query to backend (i.e. we got a \g)
+ *  1 - skip processing of this line, continue building up query
+ *  2 - terminate processing of this query entirely
+ *  3 - new query supplied by edit
+ */
+#define CMD_UNKNOWN	-1
+#define CMD_SEND	0
+#define CMD_SKIP_LINE	1
+#define CMD_TERMINATE	2
+#define CMD_NEWEDIT	3
+
 #define MAX_QUERY_BUFFER 20000
 
 #define COPYBUFSIZ  8192
@@ -978,28 +998,28 @@ do_edit(const char *filename_arg, char *query, int *status_p)
     }
 
     if (error)
-	*status_p = 1;
+	*status_p = CMD_SKIP_LINE;
     else {
 	editFile(fname);
 	if ((fd = open(fname, O_RDONLY)) == -1) {
 	    perror(fname);
 	    if (!filename_arg)
 		unlink(fname);
-	    *status_p = 1;
+	    *status_p = CMD_SKIP_LINE;
 	} else {
 	    if ((cc = read(fd, query, MAX_QUERY_BUFFER)) == -1) {
 		perror(fname);
 		close(fd);
 		if (!filename_arg)
 		    unlink(fname);
-		*status_p = 1;
+		*status_p = CMD_SKIP_LINE;
 	    } else {
 		query[cc] = '\0';
 		close(fd);
 		if (!filename_arg)
 		    unlink(fname);
 		rightTrim(query);
-		*status_p = 3;
+		*status_p = CMD_NEWEDIT;
 	    }
 	}
     }
@@ -1118,17 +1138,19 @@ do_shell(const char *command)
  * Handles all the different commands that start with \ db_ptr is a pointer to
  * the TgDb* structure line is the current input line prompt_ptr is a pointer
  * to the prompt string, a pointer is used because the prompt can be used
- * with a connection to a new database returns a status: 0 - send currently
- * constructed query to backend (i.e. we got a \g) 1 - skip processing of
- * this line, continue building up query 2 - terminate processing of this
- * query entirely, 3 - new query supplied by edit
+ * with a connection to a new database.
+ * Returns a status:
+ *  0 - send currently constructed query to backend (i.e. we got a \g)
+ *  1 - skip processing of this line, continue building up query
+ *  2 - terminate processing of this query entirely
+ *  3 - new query supplied by edit
  */
 static int
 HandleSlashCmds(PsqlSettings * settings,
 		char *line,
 		char *query)
 {
-    int             status = 1;
+    int             status = CMD_SKIP_LINE;
     char           *optarg;
     /*
      * Pointer inside the <cmd> string to the argument of the slash command,
@@ -1188,7 +1210,7 @@ HandleSlashCmds(PsqlSettings * settings,
 	}
 	if (optarg && !(settings->opt.caption = strdup(optarg))) {
 	    perror("malloc");
-	    exit(1);
+	    exit(CMD_TERMINATE);
 	}
 	break;
     case 'c':{
@@ -1261,7 +1283,7 @@ HandleSlashCmds(PsqlSettings * settings,
 		lastfile = malloc(strlen(optarg + 1));
 		if (!lastfile) {
 		    perror("malloc");
-		    exit(1);
+		    exit(CMD_TERMINATE);
 		}
 		strcpy(lastfile, optarg);
 	    } else if (!lastfile) {
@@ -1293,10 +1315,10 @@ HandleSlashCmds(PsqlSettings * settings,
 	    	free(settings->opt.fieldSep);
 	    if (!(settings->opt.fieldSep = strdup(fs))) {
 		perror("malloc");
-		exit(1);
+		exit(CMD_TERMINATE);
 	    }
 	    if (!settings->quiet)
-		printf("field separater changed to '%s'\n", settings->opt.fieldSep);
+		printf("field separator changed to '%s'\n", settings->opt.fieldSep);
 	    break;
 	}
     case 'g':			/* \g means send query */
@@ -1304,9 +1326,9 @@ HandleSlashCmds(PsqlSettings * settings,
 	    settings->gfname = NULL;
 	else if (!(settings->gfname = strdup(optarg))) {
 	    perror("malloc");
-	    exit(1);
+	    exit(CMD_TERMINATE);
 	}
-	status = 0;
+	status = CMD_SEND;
 	break;
     case 'h':			/* help */
 	{
@@ -1346,7 +1368,7 @@ HandleSlashCmds(PsqlSettings * settings,
 	}
 	break;
     case 'q':			/* \q is quit */
-	status = 2;
+	status = CMD_TERMINATE;
 	break;
     case 'r':			/* reset(clear) the buffer */
 	query[0] = '\0';
@@ -1369,13 +1391,13 @@ HandleSlashCmds(PsqlSettings * settings,
 		free(settings->opt.fieldSep);
 	    settings->opt.fieldSep = strdup("|");
 	    if (!settings->quiet)
-		printf("field separater changed to '%s'\n", settings->opt.fieldSep);
+		printf("field separator changed to '%s'\n", settings->opt.fieldSep);
 	} else {
 	    if (settings->opt.fieldSep)
 	    	free(settings->opt.fieldSep);
 	    settings->opt.fieldSep = strdup(DEFAULT_FIELD_SEP);
 	    if (!settings->quiet)
-		printf("field separater changed to '%s'\n", settings->opt.fieldSep);
+		printf("field separator changed to '%s'\n", settings->opt.fieldSep);
 	}
 	break;
     case 'z': 			/* list table rights (grant/revoke) */
@@ -1391,7 +1413,7 @@ HandleSlashCmds(PsqlSettings * settings,
 	    settings->opt.tableOpt = NULL;
 	else if (!(settings->opt.tableOpt = strdup(optarg))) {
 	    perror("malloc");
-	    exit(1);
+	    exit(CMD_TERMINATE);
 	}
 	break;
     case 'x':
@@ -1407,31 +1429,33 @@ HandleSlashCmds(PsqlSettings * settings,
     }
     free(cmd);
     return status;
-}
+} /* HandleSlashCmds() */
 
-/*
- * MainLoop: main processing loop for reading lines of input and sending them
- * to the backend
- * 
- * this loop is re-entrant.  May be called by \i command which reads input from
- * a file
+/* MainLoop()
+ * Main processing loop for reading lines of input
+ *  and sending them to the backend.
  * 
- * db_ptr must be initialized and set
+ * This loop is re-entrant. May be called by \i command
+ *  which reads input from a file.
+ * db_ptr must be initialized and set.
  */
 
 static int
 MainLoop(PsqlSettings * settings, FILE * source)
 {
     char           *line;	/* line of input */
+    char           *xcomment;	/* start of extended comment */
     int             len;	/* length of the line */
     char            query[MAX_QUERY_BUFFER];	/* multi-line query storage */
     int             successResult = 1;
-    int             slashCmdStatus = 0;
+    int             slashCmdStatus = CMD_SEND;
     /*
-     * slashCmdStatus can be: 0 - send currently constructed query to backend
-     * (i.e. we got a \g) 1 - skip processing of this line, continue building
-     * up query 2 - terminate processing of this query entirely 3 - new query
-     * supplied by edit
+     * slashCmdStatus can be:
+     *  CMD_UNKNOWN	- send currently constructed query to backend (i.e. we got a \g)
+     *  CMD_SEND	- send currently constructed query to backend (i.e. we got a \g)
+     *  CMD_SKIP_LINE	- skip processing of this line, continue building up query
+     *  CMD_TERMINATE	- terminate processing of this query entirely
+     *  CMD_NEWEDIT	- new query supplied by edit
      */
 
     bool            querySent = false;
@@ -1441,8 +1465,6 @@ MainLoop(PsqlSettings * settings, FILE * source)
     /* We've reached the end of our command input. */
     bool            success;
     bool            in_quote;
-    bool            was_bslash;	/* backslash */
-    bool            was_dash;
     int             paren_level;
     char           *query_start;
 
@@ -1467,24 +1489,30 @@ MainLoop(PsqlSettings * settings, FILE * source)
 	GetNextLine = gets_fromFile;
 
     query[0] = '\0';
+    xcomment = NULL;
     in_quote = false;
     paren_level = 0;
-    slashCmdStatus = -1;	/* set default */
+    slashCmdStatus = CMD_UNKNOWN;	/* set default */
 
-    /* main loop for getting queries and executing them */
+    /* main loop to get queries and execute them */
     while (!eof) {
-	if (slashCmdStatus == 3) {
+	/* just returned from editing the line? then just copy to the input buffer */
+	if (slashCmdStatus == CMD_NEWEDIT) {
 	    paren_level = 0;
 	    line = strdup(query);
 	    query[0] = '\0';
+
+	/* otherwise, get another line and set interactive prompt if necessary */
 	} else {
 	    if (interactive && !settings->quiet) {
-	    	if (in_quote)
-	    	    settings->prompt[strlen(settings->prompt)-3] = '\'';
-	    	else if (query[0] != '\0' && !querySent)
-	    	    settings->prompt[strlen(settings->prompt)-3] = '-';
-	    	else
-	    	    settings->prompt[strlen(settings->prompt)-3] = '=';
+		if (in_quote)
+		    settings->prompt[strlen(settings->prompt)-3] = PROMPT_QUOTE;
+		else if (xcomment != NULL)
+		    settings->prompt[strlen(settings->prompt)-3] = PROMPT_COMMENT;
+		else if (query[0] != '\0' && !querySent)
+		    settings->prompt[strlen(settings->prompt)-3] = PROMPT_CONTINUE;
+		else
+		    settings->prompt[strlen(settings->prompt)-3] = PROMPT_READY;
 	    }
 	    line = GetNextLine(settings->prompt, source);
 #ifdef HAVE_HISTORY
@@ -1493,7 +1521,20 @@ MainLoop(PsqlSettings * settings, FILE * source)
 #endif
 	}
 
-	query_start = line;
+	/* query - pointer to current command
+	 * query_start - placeholder for next command
+	 */
+
+	/* not currently inside an extended comment? */
+	if (xcomment == NULL) {
+	    query_start = line;
+
+	/* otherwise, continue the extended comment... */
+	} else {
+	    query_start = line;
+	    xcomment = line;
+	};
+
 	if (line == NULL) {	/* No more input.  Time to quit */
 	    if (!settings->quiet)
 		printf("EOF\n");	/* Goes on prompt line */
@@ -1502,9 +1543,11 @@ MainLoop(PsqlSettings * settings, FILE * source)
 	    /* remove whitespaces on the right, incl. \n's */
 	    line = rightTrim(line);
 
+	    /* echo back if input is from file */
 	    if (!interactive && !settings->singleStep && !settings->quiet)
 		fprintf(stderr, "%s\n", line);
 
+	    /* nothing on line after trimming? then ignore */
 	    if (line[0] == '\0') {
 		free(line);
 		continue;
@@ -1516,43 +1559,65 @@ MainLoop(PsqlSettings * settings, FILE * source)
 		SendQuery(&success, settings, line, false, false, 0);
 		successResult &= success;
 		querySent = true;
+
 	    } else {
-		int             i;
-		was_bslash = false;
-		was_dash = false;
+		int i;
 
 		for (i = 0; i < len; i++) {
-		    if (!in_quote && line[i] == '\\') {
-			char            hold_char = line[i];
+		    if (querySent && !isspace(line[i])) {
+			query[0] = '\0';
+			querySent = false;
+		    }
+
+		    /* inside a quote? */
+		    if (in_quote && (line[i] != '\'')) {
+			continue;
+
+		    /* inside an extended comment? */
+		    } else if (xcomment != NULL) {
+			if (line[i] == '*' && line[i+1] == '/') {
+			    xcomment = NULL;
+			    i++;
+			};
+			continue;
+
+		    /* possible backslash command? */
+		    } else if (line[i] == '\\') {
+			char hold_char = line[i];
 
 			line[i] = '\0';
 			if (query_start[0] != '\0') {
 			    if (query[0] != '\0') {
 				strcat(query, "\n");
 				strcat(query, query_start);
-			    } else
+			    } else {
 				strcpy(query, query_start);
+			    };
 			}
 			line[i] = hold_char;
 			query_start = line + i;
 			break;	/* handle command */
-		    }
-		    if (querySent && !isspace(line[i])) {
-			query[0] = '\0';
-			querySent = false;
-		    }
-		    if (!in_quote && was_dash && line[i] == '-') {
+
+		    /* start an extended comment? */
+		    } else if (line[i] == '/' && line[i+1] == '*') {
+			xcomment = line + i;
+			i++;
+			continue;
+
+		    /* single-line comment? truncate line */
+		    } else if (line[i] == '-' && line[i+1] == '-') {
 			/* print comment at top of query */
 			if (settings->singleStep)
-			    fprintf(stdout, "%s\n", line + i - 1);
-			line[i - 1] = '\0';	/* remove comment */
+			    fprintf(stdout, "%s\n", line + i);
+			line[i] = '\0';	/* remove comment */
 			break;
-		    }
-		    was_dash = false;
 
-		    if (!in_quote && !paren_level &&
-			line[i] == ';') {
-			char            hold_char = line[i + 1];
+		    } else if (line[i] == '\'') {
+			in_quote ^= 1;
+
+		    /* semi-colon? then send query now */
+		    } else if (!paren_level && line[i] == ';') {
+			char hold_char = line[i + 1];
 
 			line[i + 1] = '\0';
 			if (query_start[0] != '\0') {
@@ -1567,34 +1632,34 @@ MainLoop(PsqlSettings * settings, FILE * source)
 			line[i + 1] = hold_char;
 			query_start = line + i + 1;
 			querySent = true;
-		    }
-		    if (was_bslash)
-			was_bslash = false;
-		    else if (line[i] == '\\')
-			was_bslash = true;
-		    else if (line[i] == '\'')
-			in_quote ^= 1;
-		    else if (!in_quote && line[i] == '(')
+
+		    } else if (line[i] == '(') {
 			paren_level++;
-		    else if (!in_quote && paren_level && line[i] == ')')
+
+		    } else if (paren_level && line[i] == ')') {
 			paren_level--;
-		    else if (!in_quote && line[i] == '-')
-			was_dash = true;
+		    };
 		}
 	    }
 
-	    slashCmdStatus = -1;
+	    /* nothing on line after trimming? then ignore */
+	    if (line[0] == '\0') {
+		free(line);
+		continue;
+	    }
+
+	    slashCmdStatus = CMD_UNKNOWN;
 	    if (!in_quote && query_start[0] == '\\') {
 		slashCmdStatus = HandleSlashCmds(settings,
 						 query_start,
 						 query);
-		if (slashCmdStatus == 1) {
+		if (slashCmdStatus == CMD_SKIP_LINE) {
 		    if (query[0] == '\0')
 			paren_level = 0;
 		    free(line);
 		    continue;
 		}
-		if (slashCmdStatus == 2) {
+		if (slashCmdStatus == CMD_TERMINATE) {
 		    free(line);
 		    break;
 		}
@@ -1617,15 +1682,23 @@ MainLoop(PsqlSettings * settings, FILE * source)
 		free(line); /* PURIFY */
 	    }
 
-	    if (slashCmdStatus == 0) {
+	    /* had a backslash-g? force the query to be sent */
+	    if (slashCmdStatus == CMD_SEND) {
+#if FALSE
+		if (! querySent) {
+		    SendQuery(&success, settings, query, false, false, 0);
+		    successResult &= success;
+		}
+#else
 		SendQuery(&success, settings, query, false, false, 0);
 		successResult &= success;
+#endif
 		querySent = true;
 	    }
 	}
     }				/* while */
     return successResult;
-}
+} /* MainLoop() */
 
 int
 main(int argc, char **argv)