diff --git a/src/bin/pgbench/exprscan.l b/src/bin/pgbench/exprscan.l
index 825dacc..12b5f7e 100644
*** a/src/bin/pgbench/exprscan.l
--- b/src/bin/pgbench/exprscan.l
***************
*** 6,17 ****
   *
   * This lexer supports two operating modes:
   *
!  * In INITIAL state, just parse off whitespace-separated words (this mode
!  * is basically equivalent to strtok(), which is what we used to use).
   *
   * In EXPR state, lex for the simple expression syntax of exprparse.y.
   *
!  * In either mode, stop upon hitting newline or end of string.
   *
   * Note that this lexer operates within the framework created by psqlscan.l,
   *
--- 6,18 ----
   *
   * This lexer supports two operating modes:
   *
!  * In INITIAL state, just parse off whitespace-separated words.  (This mode
!  * is basically equivalent to strtok(), which is what we used to use.)
   *
   * In EXPR state, lex for the simple expression syntax of exprparse.y.
   *
!  * In either mode, stop upon hitting newline, end of string, or unquoted
!  * backslash (except that backslash-newline is silently swallowed).
   *
   * Note that this lexer operates within the framework created by psqlscan.l,
   *
*************** extern void expr_yyset_column(int column
*** 61,69 ****
  alpha			[a-zA-Z_]
  digit			[0-9]
  alnum			[a-zA-Z0-9_]
! /* {space} + {nonspace} + {newline} should cover all characters */
  space			[ \t\r\f\v]
! nonspace		[^ \t\r\f\v\n]
  newline			[\n]
  
  /* Exclusive states */
--- 62,71 ----
  alpha			[a-zA-Z_]
  digit			[0-9]
  alnum			[a-zA-Z0-9_]
! /* {space} + {nonspace} + {backslash} + {newline} should cover all characters */
  space			[ \t\r\f\v]
! nonspace		[^ \t\r\f\v\\\n]
! backslash		[\\]
  newline			[\n]
  
  /* Exclusive states */
*************** newline			[\n]
*** 98,103 ****
--- 100,113 ----
  
  {space}+		{ /* ignore */ }
  
+ {backslash}{newline}	{ /* ignore */ }
+ 
+ {backslash}		{
+ 					/* do not eat, and report end of command */
+ 					yyless(0);
+ 					return 0;
+ 				}
+ 
  {newline}		{
  					/* report end of command */
  					last_was_newline = true;
*************** newline			[\n]
*** 130,143 ****
  					return FUNCTION;
  				}
  
  {newline}		{
  					/* report end of command */
  					last_was_newline = true;
  					return 0;
  				}
  
- {space}+		{ /* ignore */ }
- 
  .				{
  					/*
  					 * must strdup yytext so that expr_yyerror_more doesn't
--- 140,161 ----
  					return FUNCTION;
  				}
  
+ {space}+		{ /* ignore */ }
+ 
+ {backslash}{newline}	{ /* ignore */ }
+ 
+ {backslash}		{
+ 					/* do not eat, and report end of command */
+ 					yyless(0);
+ 					return 0;
+ 				}
+ 
  {newline}		{
  					/* report end of command */
  					last_was_newline = true;
  					return 0;
  				}
  
  .				{
  					/*
  					 * must strdup yytext so that expr_yyerror_more doesn't
*************** expr_yyerror_more(yyscan_t yyscanner, co
*** 177,183 ****
  	/*
  	 * While parsing an expression, we may not have collected the whole line
  	 * yet from the input source.  Lex till EOL so we can report whole line.
! 	 * (If we're at EOF, it's okay to call yylex() an extra time.)
  	 */
  	if (!last_was_newline)
  	{
--- 195,201 ----
  	/*
  	 * While parsing an expression, we may not have collected the whole line
  	 * yet from the input source.  Lex till EOL so we can report whole line.
! 	 * (If we're at backslash/EOF, it's okay to call yylex() an extra time.)
  	 */
  	if (!last_was_newline)
  	{
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 4196b0e..e947f77 100644
*** a/src/bin/pgbench/pgbench.c
--- b/src/bin/pgbench/pgbench.c
*************** syntax_error(const char *source, int lin
*** 2413,2426 ****
  	fprintf(stderr, "\n");
  	if (line != NULL)
  	{
! 		fprintf(stderr, "%s\n", line);
! 		if (column >= 0)
  		{
  			int			i;
  
! 			for (i = 0; i < column; i++)
! 				fprintf(stderr, " ");
! 			fprintf(stderr, "^ error found here\n");
  		}
  	}
  	exit(1);
--- 2413,2455 ----
  	fprintf(stderr, "\n");
  	if (line != NULL)
  	{
! 		/*
! 		 * Multi-line backslash commands make this harder than you'd think; we
! 		 * have to identify which line to put the error cursor on.  So print
! 		 * one line at a time.
! 		 */
! 		for (;;)
  		{
+ 			const char *nlpos = strchr(line, '\n');
+ 			int			len;
  			int			i;
  
! 			if (nlpos)
! 			{
! 				/*
! 				 * It's tempting to use fprintf("%.*s"), but that can fail if
! 				 * glibc has a different idea of the encoding than we do.
! 				 */
! 				len = nlpos - line + 1;
! 				for (i = 0; i < len; i++)
! 					fputc(line[i], stderr);
! 			}
! 			else
! 			{
! 				len = column + 1;		/* ensure we print ^ if not done */
! 				fprintf(stderr, "%s\n", line);
! 			}
! 			if (column >= 0 && column < len)
! 			{
! 				for (i = 0; i < column; i++)
! 					fputc(' ', stderr);
! 				fprintf(stderr, "^ error found here\n");
! 			}
! 			column -= len;
! 			if (nlpos)
! 				line = nlpos + 1;
! 			else
! 				break;
  		}
  	}
  	exit(1);
