@@ -287,6 +287,7 @@ typedef struct
287287int type ;/* command type (SQL_COMMAND or META_COMMAND) */
288288int argc ;/* number of command words */
289289char * argv [MAX_ARGS ];/* command word list */
290+ int cols [MAX_ARGS ];/* corresponding column starting from 1 */
290291PgBenchExpr * expr ;/* parsed expression */
291292}Command ;
292293
@@ -2185,6 +2186,32 @@ parseQuery(Command *cmd, const char *raw_sql)
21852186return true;
21862187}
21872188
2189+ void
2190+ syntax_error (const char * source ,const int lineno ,
2191+ const char * line ,const char * command ,
2192+ const char * msg ,const char * more ,const int column )
2193+ {
2194+ fprintf (stderr ,"%s:%d: %s" ,source ,lineno ,msg );
2195+ if (more != NULL )
2196+ fprintf (stderr ," (%s)" ,more );
2197+ if (column != -1 )
2198+ fprintf (stderr ," at column %d" ,column );
2199+ fprintf (stderr ," in command \"%s\"\n" ,command );
2200+ if (line != NULL )
2201+ {
2202+ fprintf (stderr ,"%s\n" ,line );
2203+ if (column != -1 )
2204+ {
2205+ int i ;
2206+
2207+ for (i = 0 ;i < column - 1 ;i ++ )
2208+ fprintf (stderr ," " );
2209+ fprintf (stderr ,"^ error found here\n" );
2210+ }
2211+ }
2212+ exit (1 );
2213+ }
2214+
21882215/* Parse a command; return a Command struct, or NULL if it's a comment */
21892216static Command *
21902217process_commands (char * buf ,const char * source ,const int lineno )
@@ -2229,6 +2256,7 @@ process_commands(char *buf, const char *source, const int lineno)
22292256
22302257while (tok != NULL )
22312258{
2259+ my_commands -> cols [j ]= tok - buf + 1 ;
22322260my_commands -> argv [j ++ ]= pg_strdup (tok );
22332261my_commands -> argc ++ ;
22342262if (max_args >=0 && my_commands -> argc >=max_args )
@@ -2246,9 +2274,10 @@ process_commands(char *buf, const char *source, const int lineno)
22462274
22472275if (my_commands -> argc < 4 )
22482276{
2249- fprintf ( stderr , "%s: missing argument\n" ,my_commands -> argv [0 ]);
2250- exit ( 1 );
2277+ syntax_error ( source , lineno , my_commands -> line ,my_commands -> argv [0 ],
2278+ "missing arguments" , NULL , - 1 );
22512279}
2280+
22522281/* argc >= 4 */
22532282
22542283if (my_commands -> argc == 4 || /* uniform without/with "uniform" keyword */
@@ -2263,41 +2292,38 @@ process_commands(char *buf, const char *source, const int lineno)
22632292{
22642293if (my_commands -> argc < 6 )
22652294{
2266- fprintf ( stderr , "%s(%s): missing threshold argument\n" ,my_commands -> argv [ 0 ] ,my_commands -> argv [4 ]);
2267- exit ( 1 );
2295+ syntax_error ( source , lineno ,my_commands -> line ,my_commands -> argv [0 ],
2296+ "missing threshold argument" , my_commands -> argv [ 4 ], - 1 );
22682297}
22692298else if (my_commands -> argc > 6 )
22702299{
2271- fprintf (stderr ,"%s(%s): too many arguments (extra:" ,
2272- my_commands -> argv [0 ],my_commands -> argv [4 ]);
2273- for (j = 6 ;j < my_commands -> argc ;j ++ )
2274- fprintf (stderr ," %s" ,my_commands -> argv [j ]);
2275- fprintf (stderr ,")\n" );
2276- exit (1 );
2300+ syntax_error (source ,lineno ,my_commands -> line ,my_commands -> argv [0 ],
2301+ "too many arguments" ,my_commands -> argv [4 ],
2302+ my_commands -> cols [6 ]);
22772303}
22782304}
22792305else /* cannot parse, unexpected arguments */
22802306{
2281- fprintf (stderr ,"%s: unexpected arguments (bad:" ,my_commands -> argv [0 ]);
2282- for (j = 4 ;j < my_commands -> argc ;j ++ )
2283- fprintf (stderr ," %s" ,my_commands -> argv [j ]);
2284- fprintf (stderr ,")\n" );
2285- exit (1 );
2307+ syntax_error (source ,lineno ,my_commands -> line ,my_commands -> argv [0 ],
2308+ "unexpected argument" ,my_commands -> argv [4 ],
2309+ my_commands -> cols [4 ]);
22862310}
22872311}
22882312else if (pg_strcasecmp (my_commands -> argv [0 ],"set" )== 0 )
22892313{
22902314if (my_commands -> argc < 3 )
22912315{
2292- fprintf ( stderr , "%s: missing argument\n" ,my_commands -> argv [0 ]);
2293- exit ( 1 );
2316+ syntax_error ( source , lineno , my_commands -> line ,my_commands -> argv [0 ],
2317+ "missing argument" , NULL , - 1 );
22942318}
22952319
2296- expr_scanner_init (my_commands -> argv [2 ]);
2320+ expr_scanner_init (my_commands -> argv [2 ],source ,lineno ,
2321+ my_commands -> line ,my_commands -> argv [0 ],
2322+ my_commands -> cols [2 ]- 1 );
22972323
22982324if (expr_yyparse ()!= 0 )
22992325{
2300- fprintf ( stderr , "%s: parse error\n" , my_commands -> argv [ 0 ]);
2326+ /* dead code: exit done from syntax_error called by yyerror */
23012327exit (1 );
23022328}
23032329
@@ -2309,8 +2335,8 @@ process_commands(char *buf, const char *source, const int lineno)
23092335{
23102336if (my_commands -> argc < 2 )
23112337{
2312- fprintf ( stderr , "%s: missing argument\n" ,my_commands -> argv [0 ]);
2313- exit ( 1 );
2338+ syntax_error ( source , lineno , my_commands -> line ,my_commands -> argv [0 ],
2339+ "missing argument" , NULL , - 1 );
23142340}
23152341
23162342/*
@@ -2339,12 +2365,13 @@ process_commands(char *buf, const char *source, const int lineno)
23392365pg_strcasecmp (my_commands -> argv [2 ],"ms" )!= 0 &&
23402366pg_strcasecmp (my_commands -> argv [2 ],"s" )!= 0 )
23412367{
2342- fprintf ( stderr , "%s: unknown time unit '%s' - must be us, ms or s\n" ,
2343- my_commands -> argv [ 0 ], my_commands -> argv [ 2 ]);
2344- exit ( 1 );
2368+ syntax_error ( source , lineno , my_commands -> line , my_commands -> argv [ 0 ] ,
2369+ "unknown time unit, must be us, ms or s" ,
2370+ my_commands -> argv [ 2 ], my_commands -> cols [ 2 ] );
23452371}
23462372}
23472373
2374+ /* this should be an error?! */
23482375for (j = 3 ;j < my_commands -> argc ;j ++ )
23492376fprintf (stderr ,"%s: extra argument \"%s\" ignored\n" ,
23502377my_commands -> argv [0 ],my_commands -> argv [j ]);
@@ -2353,22 +2380,22 @@ process_commands(char *buf, const char *source, const int lineno)
23532380{
23542381if (my_commands -> argc < 3 )
23552382{
2356- fprintf ( stderr , "%s: missing argument\n" ,my_commands -> argv [0 ]);
2357- exit ( 1 );
2383+ syntax_error ( source , lineno , my_commands -> line ,my_commands -> argv [0 ],
2384+ "missing argument" , NULL , - 1 );
23582385}
23592386}
23602387else if (pg_strcasecmp (my_commands -> argv [0 ],"shell" )== 0 )
23612388{
23622389if (my_commands -> argc < 1 )
23632390{
2364- fprintf ( stderr , "%s: missing command\n" ,my_commands -> argv [0 ]);
2365- exit ( 1 );
2391+ syntax_error ( source , lineno , my_commands -> line ,my_commands -> argv [0 ],
2392+ "missing command" , NULL , - 1 );
23662393}
23672394}
23682395else
23692396{
2370- fprintf ( stderr , "Invalid command %s\n" ,my_commands -> argv [0 ]);
2371- exit ( 1 );
2397+ syntax_error ( source , lineno , my_commands -> line ,my_commands -> argv [0 ],
2398+ "invalid command" , NULL , - 1 );
23722399}
23732400}
23742401else