libgda r3298 - in trunk: . libgda/sql-parser providers/firebird providers/mysql providers/postgres providers/skel-implementation/capi tests/parser



Author: vivien
Date: Sat Jan 24 19:56:09 2009
New Revision: 3298
URL: http://svn.gnome.org/viewvc/libgda?rev=3298&view=rev

Log:
2009-01-24  Vivien Malerba <malerba gnome-db org>

        * providers/skel-implementation/capi/gen_def.c:
        * providers/skel-implementation/capi/Makefile.am:
        * providers/firebird/gen_def.c:
        * providers/firebird/Makefile.am:
        * providers/mysql/gen_def.c:
        * providers/mysql/Makefile.am:
        * providers/postgres/gen_def.c:
        * providers/postgres/Makefile.am: corrected parser's symbols translations
        * libgda/sql-parser/parser.y: allow identifiers to be enclosed between
        single quotes
        * libgda/sql-parser/gda-statement-struct-util.c:
        gda_sql_identifier_remove_quotes() also accepts single quotes around
        identifiers
        * libgda/sql-parser/gda-sql-parser.c: added debug information
        * tests/parser/testdata.xml: added more test cases

        This fixes bug #568844


Modified:
   trunk/ChangeLog
   trunk/libgda/sql-parser/gda-sql-parser.c
   trunk/libgda/sql-parser/gda-statement-struct-util.c
   trunk/libgda/sql-parser/parser.y
   trunk/providers/firebird/Makefile.am
   trunk/providers/firebird/gen_def.c
   trunk/providers/mysql/Makefile.am
   trunk/providers/mysql/gen_def.c
   trunk/providers/postgres/Makefile.am
   trunk/providers/postgres/gen_def.c
   trunk/providers/skel-implementation/capi/Makefile.am
   trunk/providers/skel-implementation/capi/gen_def.c
   trunk/tests/parser/testdata.xml

Modified: trunk/libgda/sql-parser/gda-sql-parser.c
==============================================================================
--- trunk/libgda/sql-parser/gda-sql-parser.c	(original)
+++ trunk/libgda/sql-parser/gda-sql-parser.c	Sat Jan 24 19:56:09 2009
@@ -566,6 +566,8 @@
 			
 			switch (parser->priv->mode) {
 			case GDA_SQL_PARSER_MODE_PARSE:
+				/*g_print ("TRANS %d => %d\n", parser->priv->context->token_type,
+				  parser_trans [parser->priv->context->token_type]);*/
 				_parse (parser->priv->lemon_parser, 
 					parser_trans [parser->priv->context->token_type], value, &piface);
 				break;

Modified: trunk/libgda/sql-parser/gda-statement-struct-util.c
==============================================================================
--- trunk/libgda/sql-parser/gda-statement-struct-util.c	(original)
+++ trunk/libgda/sql-parser/gda-statement-struct-util.c	Sat Jan 24 19:56:09 2009
@@ -308,9 +308,16 @@
  * @str: a quoted string
  *
  * Prepares @str to be compared:
- * - if surrounded by double quotes, then just remove the quotes
+ * - if surrounded by double quotes or single quotes, then just remove the quotes
  * - otherwise convert to lower case
  *
+ * The quoted string:
+ * <itemizedlist>
+ *   <listitem><para>must start and finish with the same single or double quotes character</para></listitem>
+ *   <listitem><para>can contain the delimiter character (the single or double quotes) in the string if every instance
+ *     of it is preceeded with a backslash character or with the delimiter character itself</para></listitem>
+ * </itemizedlist>
+ *
  * WARNING: @str must NOT be a composed identifier (&lt;part1&gt;."&lt;part2&gt;" for example)
  * 
  * Returns: @str
@@ -320,7 +327,7 @@
 {
 	if (!str)
 		return NULL;
-	if (*str == '"')
+	if ((*str == '"') || (*str == '\''))
 		return _remove_quotes (str);
 	else {
 		gchar *ptr;

Modified: trunk/libgda/sql-parser/parser.y
==============================================================================
--- trunk/libgda/sql-parser/parser.y	(original)
+++ trunk/libgda/sql-parser/parser.y	Sat Jan 24 19:56:09 2009
@@ -243,6 +243,7 @@
   REINDEX RENAME CTIME_KW IF
   DELIMITER COMMIT ROLLBACK ISOLATION LEVEL SERIALIZABLE READ COMMITTED 
   UNCOMMITTED REPEATABLE WRITE ONLY SAVEPOINT RELEASE COMMENT FORCE WAIT NOWAIT BATCH.
+%fallback TEXTUAL STRING.
 
 // Define operator precedence early so that this is the first occurance
 // of the operator tokens in the grammer.  Keeping the operators together

Modified: trunk/providers/firebird/Makefile.am
==============================================================================
--- trunk/providers/firebird/Makefile.am	(original)
+++ trunk/providers/firebird/Makefile.am	Sat Jan 24 19:56:09 2009
@@ -15,7 +15,7 @@
 	- $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
 
 gen_def$(EXEEXT_FOR_BUILD): gen_def.c
-	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/parser_tokens.h"\" $(srcdir)/gen_def.c
+	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
 
 firebird_token_types.h: gen_def$(EXEEXT_FOR_BUILD) parser.h
 	./gen_def$(EXEEXT_FOR_BUILD) > firebird_token_types.h

Modified: trunk/providers/firebird/gen_def.c
==============================================================================
--- trunk/providers/firebird/gen_def.c	(original)
+++ trunk/providers/firebird/gen_def.c	Sat Jan 24 19:56:09 2009
@@ -59,11 +59,13 @@
 	HashEntry *rawstring_entry;
 
 	memset (entries, 0, sizeof (entries));
+	/* printf ("Imposed header: %s\n", IMPOSED_HEADER); */
 	fd_imposed = fopen (IMPOSED_HEADER, "r");
 	if (!fd_imposed) {
 		printf ("Can't open '%s':%s\n", IMPOSED_HEADER, strerror (errno));
 		return 1;
 	}
+	/* printf ("Parser header: %s\n", PARSER_HEADER); */
 	fd_parser = fopen (PARSER_HEADER, "r");
 	if (!fd_parser) {
 		printf ("Can't open '%s':%s\n", PARSER_HEADER, strerror (errno));
@@ -93,11 +95,11 @@
 	for (i = 0; i < nb_entries; i++) {
 		HashEntry *entry = &(entries[i]);
 		if (i!= 0)
-			printf (",");
+			printf (",\n");
 		if (entry->parser_value >= 0)
-			printf ("%d", entry->parser_value);
+			printf ("/* %03d */ %d", i, entry->parser_value);
 		else
-			printf ("%d", illegal_entry->parser_value);
+			printf ("/* %03d */ %d", i, illegal_entry->parser_value);
 	}
 	printf ("};\n");
 
@@ -127,10 +129,8 @@
 	HashEntry *entry;
 	
 	z = line;
-	if (strncmp (z, "#define ", 8)) {
-		printf ("Expected '#define', not found");
-		exit (1);
-	}
+	if (strncmp (z, "#define ", 8))
+		return;
 	z += 8;
 	token = z + 2;
 	for (; *z && *z != ' '; z++);
@@ -138,7 +138,7 @@
 	z++;
 	for (; *z == ' '; z++);
 	value = atoi (z);
-	/*printf ("%d Token: /%s/, value=%d\n", type, token, value);*/
+	/* printf ("%d Token: /%s/, value=%d\n", type, token, value); */
 
 	entry = find_entry_for_token (token);
 	if (!entry) {

Modified: trunk/providers/mysql/Makefile.am
==============================================================================
--- trunk/providers/mysql/Makefile.am	(original)
+++ trunk/providers/mysql/Makefile.am	Sat Jan 24 19:56:09 2009
@@ -15,7 +15,7 @@
 	- $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
 
 gen_def$(EXEEXT_FOR_BUILD): gen_def.c
-	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/parser_tokens.h"\" $(srcdir)/gen_def.c
+	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
 
 mysql_token_types.h: gen_def$(EXEEXT_FOR_BUILD) parser.h
 	./gen_def$(EXEEXT_FOR_BUILD) > mysql_token_types.h

Modified: trunk/providers/mysql/gen_def.c
==============================================================================
--- trunk/providers/mysql/gen_def.c	(original)
+++ trunk/providers/mysql/gen_def.c	Sat Jan 24 19:56:09 2009
@@ -59,11 +59,13 @@
 	HashEntry *rawstring_entry;
 
 	memset (entries, 0, sizeof (entries));
+	/* printf ("Imposed header: %s\n", IMPOSED_HEADER); */
 	fd_imposed = fopen (IMPOSED_HEADER, "r");
 	if (!fd_imposed) {
 		printf ("Can't open '%s':%s\n", IMPOSED_HEADER, strerror (errno));
 		return 1;
 	}
+	/* printf ("Parser header: %s\n", PARSER_HEADER); */
 	fd_parser = fopen (PARSER_HEADER, "r");
 	if (!fd_parser) {
 		printf ("Can't open '%s':%s\n", PARSER_HEADER, strerror (errno));
@@ -93,11 +95,11 @@
 	for (i = 0; i < nb_entries; i++) {
 		HashEntry *entry = &(entries[i]);
 		if (i!= 0)
-			printf (",");
+			printf (",\n");
 		if (entry->parser_value >= 0)
-			printf ("%d", entry->parser_value);
+			printf ("/* %03d */ %d", i, entry->parser_value);
 		else
-			printf ("%d", illegal_entry->parser_value);
+			printf ("/* %03d */ %d", i, illegal_entry->parser_value);
 	}
 	printf ("};\n");
 
@@ -127,10 +129,8 @@
 	HashEntry *entry;
 	
 	z = line;
-	if (strncmp (z, "#define ", 8)) {
-		printf ("Expected '#define', not found");
-		exit (1);
-	}
+	if (strncmp (z, "#define ", 8))
+		return;
 	z += 8;
 	token = z + 2;
 	for (; *z && *z != ' '; z++);
@@ -138,7 +138,7 @@
 	z++;
 	for (; *z == ' '; z++);
 	value = atoi (z);
-	/*printf ("%d Token: /%s/, value=%d\n", type, token, value);*/
+	/* printf ("%d Token: /%s/, value=%d\n", type, token, value); */
 
 	entry = find_entry_for_token (token);
 	if (!entry) {

Modified: trunk/providers/postgres/Makefile.am
==============================================================================
--- trunk/providers/postgres/Makefile.am	(original)
+++ trunk/providers/postgres/Makefile.am	Sat Jan 24 19:56:09 2009
@@ -12,7 +12,7 @@
 	- $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
 
 gen_def$(EXEEXT_FOR_BUILD): gen_def.c
-	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/parser_tokens.h"\" $(srcdir)/gen_def.c
+	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
 
 postgres_token_types.h: gen_def$(EXEEXT_FOR_BUILD) parser.h
 	./gen_def$(EXEEXT_FOR_BUILD) > postgres_token_types.h

Modified: trunk/providers/postgres/gen_def.c
==============================================================================
--- trunk/providers/postgres/gen_def.c	(original)
+++ trunk/providers/postgres/gen_def.c	Sat Jan 24 19:56:09 2009
@@ -59,11 +59,13 @@
 	HashEntry *rawstring_entry;
 
 	memset (entries, 0, sizeof (entries));
+	/* printf ("Imposed header: %s\n", IMPOSED_HEADER); */
 	fd_imposed = fopen (IMPOSED_HEADER, "r");
 	if (!fd_imposed) {
 		printf ("Can't open '%s':%s\n", IMPOSED_HEADER, strerror (errno));
 		return 1;
 	}
+	/* printf ("Parser header: %s\n", PARSER_HEADER); */
 	fd_parser = fopen (PARSER_HEADER, "r");
 	if (!fd_parser) {
 		printf ("Can't open '%s':%s\n", PARSER_HEADER, strerror (errno));
@@ -93,11 +95,11 @@
 	for (i = 0; i < nb_entries; i++) {
 		HashEntry *entry = &(entries[i]);
 		if (i!= 0)
-			printf (",");
+			printf (",\n");
 		if (entry->parser_value >= 0)
-			printf ("%d", entry->parser_value);
+			printf ("/* %03d */ %d", i, entry->parser_value);
 		else
-			printf ("%d", illegal_entry->parser_value);
+			printf ("/* %03d */ %d", i, illegal_entry->parser_value);
 	}
 	printf ("};\n");
 
@@ -127,10 +129,8 @@
 	HashEntry *entry;
 	
 	z = line;
-	if (strncmp (z, "#define ", 8)) {
-		printf ("Expected '#define', not found");
-		exit (1);
-	}
+	if (strncmp (z, "#define ", 8))
+		return;
 	z += 8;
 	token = z + 2;
 	for (; *z && *z != ' '; z++);
@@ -138,7 +138,7 @@
 	z++;
 	for (; *z == ' '; z++);
 	value = atoi (z);
-	/*printf ("%d Token: /%s/, value=%d\n", type, token, value);*/
+	/* printf ("%d Token: /%s/, value=%d\n", type, token, value); */
 
 	entry = find_entry_for_token (token);
 	if (!entry) {

Modified: trunk/providers/skel-implementation/capi/Makefile.am
==============================================================================
--- trunk/providers/skel-implementation/capi/Makefile.am	(original)
+++ trunk/providers/skel-implementation/capi/Makefile.am	Sat Jan 24 19:56:09 2009
@@ -16,7 +16,7 @@
 	- $(top_builddir)/libgda/sql-parser/lemon$(EXEEXT_FOR_BUILD) -q -d $(srcdir)/parser.y $(top_srcdir)/libgda/sql-parser/lempar.c
 
 gen_def$(EXEEXT_FOR_BUILD): gen_def.c
-	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/parser_tokens.h"\" $(srcdir)/gen_def.c
+	$(CC_FOR_BUILD) -o gen_def$(EXEEXT_FOR_BUILD) -DIMPOSED_HEADER=\""$(top_srcdir)/libgda/sql-parser/token_types.h"\" $(srcdir)/gen_def.c
 
 capi_token_types.h: gen_def$(EXEEXT_FOR_BUILD) parser.h
 	./gen_def$(EXEEXT_FOR_BUILD) > capi_token_types.h

Modified: trunk/providers/skel-implementation/capi/gen_def.c
==============================================================================
--- trunk/providers/skel-implementation/capi/gen_def.c	(original)
+++ trunk/providers/skel-implementation/capi/gen_def.c	Sat Jan 24 19:56:09 2009
@@ -59,11 +59,13 @@
 	HashEntry *rawstring_entry;
 
 	memset (entries, 0, sizeof (entries));
+	/* printf ("Imposed header: %s\n", IMPOSED_HEADER); */
 	fd_imposed = fopen (IMPOSED_HEADER, "r");
 	if (!fd_imposed) {
 		printf ("Can't open '%s':%s\n", IMPOSED_HEADER, strerror (errno));
 		return 1;
 	}
+	/* printf ("Parser header: %s\n", PARSER_HEADER); */
 	fd_parser = fopen (PARSER_HEADER, "r");
 	if (!fd_parser) {
 		printf ("Can't open '%s':%s\n", PARSER_HEADER, strerror (errno));
@@ -93,11 +95,11 @@
 	for (i = 0; i < nb_entries; i++) {
 		HashEntry *entry = &(entries[i]);
 		if (i!= 0)
-			printf (",");
+			printf (",\n");
 		if (entry->parser_value >= 0)
-			printf ("%d", entry->parser_value);
+			printf ("/* %03d */ %d", i, entry->parser_value);
 		else
-			printf ("%d", illegal_entry->parser_value);
+			printf ("/* %03d */ %d", i, illegal_entry->parser_value);
 	}
 	printf ("};\n");
 
@@ -127,10 +129,8 @@
 	HashEntry *entry;
 	
 	z = line;
-	if (strncmp (z, "#define ", 8)) {
-		printf ("Expected '#define', not found");
-		exit (1);
-	}
+	if (strncmp (z, "#define ", 8))
+		return;
 	z += 8;
 	token = z + 2;
 	for (; *z && *z != ' '; z++);
@@ -138,7 +138,7 @@
 	z++;
 	for (; *z == ' '; z++);
 	value = atoi (z);
-	/*printf ("%d Token: /%s/, value=%d\n", type, token, value);*/
+	/* printf ("%d Token: /%s/, value=%d\n", type, token, value); */
 
 	entry = find_entry_for_token (token);
 	if (!entry) {

Modified: trunk/tests/parser/testdata.xml
==============================================================================
--- trunk/tests/parser/testdata.xml	(original)
+++ trunk/tests/parser/testdata.xml	Sat Jan 24 19:56:09 2009
@@ -1002,4 +1002,25 @@
     <expected>{"statements":[{"statement":{"sql":"(select A union select B) intersect select C;","stmt_type":"COMPOUND","contents":{"compount_type":"INTERSECT","select_stmts":[{"sql":null,"stmt_type":"COMPOUND","contents":{"compount_type":"UNION","select_stmts":[{"sql":null,"stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"A"},"field_name":"A"}]}},{"sql":null,"stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"B"},"field_name":"B"}]}}]}},{"sql":null,"stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"C"},"field_name":"C"}]}}]}}}]}</expected>
   </test>
 
+  <!-- Single quoting table name, does not work for PostgreSQL -->
+  <test id="singlequotes">
+    <sql>SELECT * FROM 'table'</sql>
+    <expected>{"statements":[{"statement":{"sql":"SELECT * FROM 'table'","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"'table'"},"table_name":"'table'"}]}}}}]}</expected>
+  </test>
+
+  <test id="Pgsinglequotes" provider="PostgreSQL">
+  <sql>SELECT * FROM 'table'</sql>
+    <expected>{"statements":[{"statement":{"sql":"SELECT * FROM 'table'","stmt_type":"UNKNOWN","contents":[{"value":"SELECT"},{"value":" "},{"value":"*"},{"value":" "},{"value":"FROM"},{"value":" "},{"value":"'table'"}]}}]}</expected>
+  </test>
+
+  <!-- Double quoting table name, works for PostgreSQL as well -->
+  <test id="dblequotes">
+    <sql>SELECT * FROM "table"</sql>
+    <expected>{"statements":[{"statement":{"sql":"SELECT * FROM \"table\"","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"\"table\""},"table_name":"\"table\""}]}}}}]}</expected>
+  </test>
+
+  <test id="Pgdblequotes" provider="PostgreSQL">
+  <sql>SELECT * FROM "table"</sql>
+    <expected>{"statements":[{"statement":{"sql":"SELECT * FROM \"table\"","stmt_type":"SELECT","contents":{"distinct":"false","fields":[{"expr":{"value":"*"}}],"from":{"targets":[{"expr":{"value":"\"table\""},"table_name":"\"table\""}]}}}}]}</expected>
+  </test>
 </testdata>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]