[GRASS-dev] DBMI parse error question

Glynn Clements glynn at gclements.plus.com
Wed Feb 28 02:15:47 EST 2007


Markus Neteler wrote:

> Hi,
> 
> I try to import a map from PostgreSQL into GRASS/DBF driver
> with v.in.db, but get
> 
> DBMI-DBF driver error:
> SQL parser error in statement:
> create table ticks_feltre_2002_2006_sites ( ID integer, comune varchar(250), localita varchar(250), microsito varchar(250), data date, ora time, larve integer, ninfe integer, adm integer, adf integer, adtot integer, tcelsius double precision, umidrel double precision, note varchar(250), mapsheet varchar(250), mgrs varchar(250), stazione varchar(250), periodo_prelievo varchar(250), north double precision, east double precision, siteid integer )
> Cannot create table
> 
> but I don't see where the evil is:
> 
> echo " ID integer, comune varchar(250), localita varchar(250), microsito varchar(250), data date, ora time, larve integer, ninfe integer, adm integer, adf integer, adtot integer, tcelsius double precision, umidrel double precision, note varchar(250), mapsheet varchar(250), mgrs varchar(250), stazione varchar(250), periodo_prelievo varchar(250), north double precision, east double precision, siteid integer" | tr -s ',' '\n' | sort
>  adf integer
>  adm integer
>  adtot integer
>  comune varchar(250)
>  data date
>  east double precision
>  ID integer
>  larve integer
>  localita varchar(250)
>  mapsheet varchar(250)
>  mgrs varchar(250)
>  microsito varchar(250)
>  ninfe integer
>  north double precision
>  note varchar(250)
>  ora time
>  periodo_prelievo varchar(250)
>  siteid integer
>  stazione varchar(250)
>  tcelsius double precision
>  umidrel double precision
> 
> Any ideas?

As Hamish points out, it's "ora time" ("time" isn't a valid type for the
DBF driver).

> Of course it would be fancy to have a more reasonable
> error message. This error uses to pop up if preserved words are used
> as column names, but I don't see any (even, it should tell me in an
> ideal world).

Try defining YYERROR_VERBOSE in yac.y, i.e.:

--- lib/db/sqlp/yac.y	5 Feb 2007 10:45:38 -0000	1.25
+++ lib/db/sqlp/yac.y	28 Feb 2007 06:46:04 -0000
@@ -25,6 +25,7 @@
 #include <grass/sqlp.h>
 
 #define YYDEBUG 1
+#define YYERROR_VERBOSE 1
 
 %}

This should give error messages of the form "unexpected X, expecting Y",
where X and Y are the terminal (token) names used in the grammar.

[Except that db.execute completely ignores the error message returned by
the parser in sqlpStmt->errmsg. Actually, AFAICT, it's the DBF driver
which completely ignores the error message ("grep errmsg *" in
db/drivers/dbf comes up blank).]

That's still not ideal, as the error messages won't identify the
specific value; e.g. for the above case, you just get "unexpected NAME".

If you want more detailed error messages, you have to add explicit rules
which match each erroneous case and use YYERROR to flag an error, e.g.:

y_columndef:
		NAME VARCHAR '(' INTNUM ')'	{ sqpColumnDef( $1, SQLP_VARCHAR, $4, 0 ); }
	|	NAME INT 			{ sqpColumnDef( $1, SQLP_INTEGER,  0, 0 ); }
	|	NAME INTEGER 			{ sqpColumnDef( $1, SQLP_INTEGER,  0, 0 ); }
	|	NAME DOUBLE			{ sqpColumnDef( $1, SQLP_DOUBLE,   0, 0 ); }
	|	NAME DOUBLE PRECISION		{ sqpColumnDef( $1, SQLP_DOUBLE,   0, 0 ); }
	|	NAME DATE			{ sqpColumnDef( $1, SQLP_DATE,     0, 0 ); }
+	|	NAME NAME	{
+					char buff[1000];
+					sprintf(buf, "%s: invalid type: %s", $1, $2);
+					yyerror(buf);
+					YYERROR;
+				}
	;

Adding the above to yac.y (and hacking yyerror() to actually print the
error rather than just return it so that the driver can ignore it)
results in "ora: invalid type: time".

The problem here is that you essentially need to enumerate all of the
different syntax errors which you want to catch. You also need to ensure
that you don't make a rule too broad and end up treating valid
statements as syntax errors.

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list