Attached patch does what is described in the title, hopefully. Continuations in other pgbench backslash-commands should be dealt with elsewhere...

Also attached is a small test script.

Here is another approach, with "infered" continuations: no backslash is needed, the parsing is pursued if the last token of the line cannot end an expression (eg an operator) or if there is an unclosed parenthesis.

I think that backslashes are less surprising for the classically minded user, but this one is more fun:-) Also, this version changes a little more the scanner because on each token the next state (continued or not) must be decided.

--
Fabien.
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index 285608d..f066be1 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -826,13 +826,17 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
       <literal>%</>) with their usual precedence and associativity,
       <link linkend="pgbench-builtin-functions">function calls</>, and
       parentheses.
+      Expressions can spead several lines till completed: the parsing is
+      pursued if a token at the end of the line cannot end an expression
+      or if there is an unclosed parenthesis.
      </para>
 
      <para>
       Examples:
 <programlisting>
 \set ntellers 10 * :scale
-\set aid (1021 * random(1, 100000 * :scale)) % (100000 * :scale) + 1
+\set aid (1021 * random(1, 100000 * :scale)) %
+           (100000 * :scale) + 1
 </programlisting></para>
     </listitem>
    </varlistentry>
diff --git a/src/bin/pgbench/exprscan.l b/src/bin/pgbench/exprscan.l
index 20891a3..1b0d4d0 100644
--- a/src/bin/pgbench/exprscan.l
+++ b/src/bin/pgbench/exprscan.l
@@ -43,6 +43,16 @@ static bool last_was_newline = false;
 extern int	expr_yyget_column(yyscan_t yyscanner);
 extern void expr_yyset_column(int column_no, yyscan_t yyscanner);
 
+/* the expression cannot end on this token */
+#define TO_COEX					   \
+	cur_state->start_state = COEX; \
+	BEGIN(COEX)
+
+/* continuation if unclosed parentheses */
+#define TO_EXPR															\
+	cur_state->start_state = cur_state->paren_depth > 0 ? COEX : EXPR;	\
+	BEGIN(cur_state->start_state)
+
 %}
 
 /* Except for the prefix, these options should match psqlscan.l */
@@ -67,7 +77,7 @@ nonspace		[^ \t\r\f\v\n]
 newline			[\n]
 
 /* Exclusive states */
-%x EXPR
+%x EXPR COEX
 
 %%
 
@@ -104,46 +114,64 @@ newline			[\n]
 					return 0;
 				}
 
+	/* COEX (continued expression) state */
+
+<COEX>{
+
+{newline}		{ /* ignore */ }
+
+}
+
 	/* EXPR state */
 
 <EXPR>{
 
-"+"				{ return '+'; }
-"-"				{ return '-'; }
-"*"				{ return '*'; }
-"/"				{ return '/'; }
-"%"				{ return '%'; }
-"("				{ return '('; }
-")"				{ return ')'; }
-","				{ return ','; }
+{newline}		{
+					/* report end of command */
+					last_was_newline = true;
+					return 0;
+				}
+}
+
+	/* EXPR & COEX states common rules */
+
+<EXPR,COEX>{
+
+"+"				{ TO_COEX; return '+'; }
+"-"				{ TO_COEX; return '-'; }
+"*"				{ TO_COEX; return '*'; }
+"/"				{ TO_COEX; return '/'; }
+"%"				{ TO_COEX; return '%'; }
+"("				{ cur_state->paren_depth++; TO_COEX; return '('; }
+")"				{ cur_state->paren_depth--; TO_EXPR; return ')'; }
+","				{ TO_COEX; return ','; }
 
 :{alnum}+		{
 					yylval->str = pg_strdup(yytext + 1);
+					TO_EXPR;
 					return VARIABLE;
 				}
 {digit}+		{
 					yylval->ival = strtoint64(yytext);
+					TO_EXPR;
 					return INTEGER_CONST;
 				}
 {digit}+(\.{digit}*)?([eE][-+]?{digit}+)?	{
 					yylval->dval = atof(yytext);
+					TO_EXPR;
 					return DOUBLE_CONST;
 				}
 \.{digit}+([eE][-+]?{digit}+)?	{
 					yylval->dval = atof(yytext);
+					TO_EXPR;
 					return DOUBLE_CONST;
 				}
 {alpha}{alnum}*	{
 					yylval->str = pg_strdup(yytext);
+					TO_COEX;
 					return FUNCTION;
 				}
 
-{newline}		{
-					/* report end of command */
-					last_was_newline = true;
-					return 0;
-				}
-
 {space}+		{ /* ignore */ }
 
 .				{

Attachment: cont2.sql
Description: application/sql

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to