@@ -287,6 +287,7 @@ typedef struct
287287	int 			type ;			/* command type (SQL_COMMAND or META_COMMAND) */ 
288288	int 			argc ;			/* number of command words */ 
289289	char 	   * argv [MAX_ARGS ]; /* command word list */ 
290+ 	int 			cols [MAX_ARGS ]; /* corresponding column starting from 1 */ 
290291	PgBenchExpr  * expr ;			/* parsed expression */ 
291292} Command ;
292293
@@ -2185,6 +2186,32 @@ parseQuery(Command *cmd, const char *raw_sql)
21852186	return  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
22302257		while  (tok  !=  NULL )
22312258		{
2259+ 			my_commands -> cols [j ] =  tok  -  buf  +  1 ;
22322260			my_commands -> argv [j ++ ] =  pg_strdup (tok );
22332261			my_commands -> argc ++ ;
22342262			if  (max_args  >= 0  &&  my_commands -> argc  >= max_args )
@@ -2246,9 +2274,10 @@ process_commands(char *buf, const char *source, const int lineno)
22462274
22472275			if  (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
22542283			if  (my_commands -> argc  ==  4  ||  /* uniform without/with "uniform" keyword */ 
@@ -2263,41 +2292,38 @@ process_commands(char *buf, const char *source, const int lineno)
22632292			{
22642293				if  (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				}
22692298				else  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			}
22792305			else  /* 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		}
22882312		else  if  (pg_strcasecmp (my_commands -> argv [0 ], "set" ) ==  0 )
22892313		{
22902314			if  (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
22982324			if  (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 */ 
23012327				exit (1 );
23022328			}
23032329
@@ -2309,8 +2335,8 @@ process_commands(char *buf, const char *source, const int lineno)
23092335		{
23102336			if  (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)
23392365					pg_strcasecmp (my_commands -> argv [2 ], "ms" ) !=  0  && 
23402366					pg_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?! */ 
23482375			for  (j  =  3 ; j  <  my_commands -> argc ; j ++ )
23492376				fprintf (stderr , "%s: extra argument \"%s\" ignored\n" ,
23502377						my_commands -> argv [0 ], my_commands -> argv [j ]);
@@ -2353,22 +2380,22 @@ process_commands(char *buf, const char *source, const int lineno)
23532380		{
23542381			if  (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		}
23602387		else  if  (pg_strcasecmp (my_commands -> argv [0 ], "shell" ) ==  0 )
23612388		{
23622389			if  (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		}
23682395		else 
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	}
23742401	else 
0 commit comments