[libgda] Correction for bug #665917



commit 89094a9ff011afebe751fce5337b5145780c6856
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Dec 12 20:31:39 2011 +0100

    Correction for bug #665917

 libgda/gda-statement-extra.h        |    3 +-
 libgda/gda-statement.c              |   49 +++++++++++++++++++++++++++--------
 libgda/sqlite/gda-sqlite-provider.c |   29 ++++++++++++++++++++
 3 files changed, 69 insertions(+), 12 deletions(-)
---
diff --git a/libgda/gda-statement-extra.h b/libgda/gda-statement-extra.h
index 165cc14..eafd8f4 100644
--- a/libgda/gda-statement-extra.h
+++ b/libgda/gda-statement-extra.h
@@ -124,6 +124,7 @@ typedef gchar *(*GdaSqlRenderingValue)     (const GValue *value, GdaSqlRendering
  * @render_select_join: function to render a #GdaSqlSelectJoin
  * @render_select_from: function to render a #GdaSqlSelectFrom
  * @render_select_order: function to render a #GdaSqlSelectOrder
+ * @render_distinct: function to render the DISTINCT clause in a SELECT
  */
 struct _GdaSqlRenderingContext {
 	GdaStatementSqlFlag      flags;
@@ -162,6 +163,7 @@ struct _GdaSqlRenderingContext {
 	GdaSqlRenderingFunc      render_select_join;
 	GdaSqlRenderingFunc      render_select_from;
 	GdaSqlRenderingFunc      render_select_order;
+	GdaSqlRenderingFunc      render_distinct;
 
 	/*< private >*/
 	/* Padding for future expansion */
@@ -172,7 +174,6 @@ struct _GdaSqlRenderingContext {
 	void (*_gda_reserved5) (void);
 	void (*_gda_reserved6) (void);
 	void (*_gda_reserved7) (void);
-	void (*_gda_reserved8) (void);
 };
 
 /**
diff --git a/libgda/gda-statement.c b/libgda/gda-statement.c
index d85aba0..1393a2c 100644
--- a/libgda/gda-statement.c
+++ b/libgda/gda-statement.c
@@ -653,6 +653,7 @@ static gchar *default_render_select_target (GdaSqlSelectTarget *target, GdaSqlRe
 static gchar *default_render_select_join (GdaSqlSelectJoin *join, GdaSqlRenderingContext *context, GError **error);
 static gchar *default_render_select_from (GdaSqlSelectFrom *from, GdaSqlRenderingContext *context, GError **error);
 static gchar *default_render_select_order (GdaSqlSelectOrder *order, GdaSqlRenderingContext *context, GError **error);
+static gchar *default_render_distinct (GdaSqlStatementSelect *select, GdaSqlRenderingContext *context, GError **error);
 
 /**
  * gda_statement_to_sql_real:
@@ -714,6 +715,8 @@ gda_statement_to_sql_real (GdaStatement *stmt, GdaSqlRenderingContext *context,
 		context->render_select_from = (GdaSqlRenderingFunc) default_render_select_from;
 	if (!context->render_select_order)
 		context->render_select_order = (GdaSqlRenderingFunc) default_render_select_order;
+	if (!context->render_distinct)
+		context->render_distinct = (GdaSqlRenderingFunc) default_render_distinct;
 
 	cinfo = gda_sql_statement_get_contents_infos (stmt->priv->internal_struct->stmt_type);
 	if (cinfo->check_structure_func && !cinfo->check_structure_func (GDA_SQL_ANY_PART (stmt->priv->internal_struct->contents), 
@@ -1145,30 +1148,54 @@ default_render_compound (GdaSqlStatementCompound *stmt, GdaSqlRenderingContext *
 }
 
 static gchar *
-default_render_select (GdaSqlStatementSelect *stmt, GdaSqlRenderingContext *context, GError **error)
+default_render_distinct (GdaSqlStatementSelect *stmt, GdaSqlRenderingContext *context, GError **error)
 {
-	GString *string;
-	gchar *str;
-	GSList *list;
 	gboolean pretty = context->flags & GDA_STATEMENT_SQL_PRETTY;
-
 	g_return_val_if_fail (stmt, NULL);
 	g_return_val_if_fail (GDA_SQL_ANY_PART (stmt)->type == GDA_SQL_ANY_STMT_SELECT, NULL);
 
-	string = g_string_new ("SELECT ");
-	/* distinct */
 	if (stmt->distinct) {
-		g_string_append (string, "DISTINCT ");
+		GString *string;
+		string = g_string_new ("DISTINCT");
 		if (stmt->distinct_expr) {
+			gchar *str;
 			str = context->render_expr (stmt->distinct_expr, context, NULL, NULL, error);
-			if (!str) goto err;
-			g_string_append (string, "ON ");
+			if (!str) {
+				g_string_free (string, TRUE);
+				return NULL;
+			}
+			g_string_append (string, "ON (");
 			g_string_append (string, str);
-			g_string_append_c (string, ' ');
+			g_string_append (string, ") ");
 			g_free (str);
 		}
 		if (pretty)
 			g_string_append_c (string, '\n');
+		return g_string_free (string, FALSE);
+	}
+	else
+		return NULL;
+}
+
+static gchar *
+default_render_select (GdaSqlStatementSelect *stmt, GdaSqlRenderingContext *context, GError **error)
+{
+	GString *string;
+	gchar *str;
+	GSList *list;
+	gboolean pretty = context->flags & GDA_STATEMENT_SQL_PRETTY;
+
+	g_return_val_if_fail (stmt, NULL);
+	g_return_val_if_fail (GDA_SQL_ANY_PART (stmt)->type == GDA_SQL_ANY_STMT_SELECT, NULL);
+
+	string = g_string_new ("SELECT ");
+	/* distinct */
+	if (stmt->distinct) {
+		str = context->render_distinct (GDA_SQL_ANY_PART (stmt), context, error);
+		if (!str) goto err;
+		g_string_append (string, str);
+		g_string_append_c (string, ' ');
+		g_free (str);
 	}
 	
 	/* selected expressions */
diff --git a/libgda/sqlite/gda-sqlite-provider.c b/libgda/sqlite/gda-sqlite-provider.c
index c109a6a..c091241 100644
--- a/libgda/sqlite/gda-sqlite-provider.c
+++ b/libgda/sqlite/gda-sqlite-provider.c
@@ -1815,6 +1815,9 @@ static gchar *sqlite_render_operation (GdaSqlOperation *op, GdaSqlRenderingConte
 static gchar *sqlite_render_expr (GdaSqlExpr *expr, GdaSqlRenderingContext *context,
 				  gboolean *is_default, gboolean *is_null,
 				  GError **error);
+static gchar *sqlite_render_distinct (GdaSqlStatementSelect *stmt,
+				      GdaSqlRenderingContext *context, GError **error);
+
 static gchar *
 gda_sqlite_provider_statement_to_sql (GdaServerProvider *provider, GdaConnection *cnc,
 				      GdaStatement *stmt, GdaSet *params, GdaStatementSqlFlag flags,
@@ -1837,6 +1840,7 @@ gda_sqlite_provider_statement_to_sql (GdaServerProvider *provider, GdaConnection
 	context.render_operation = (GdaSqlRenderingFunc) sqlite_render_operation; /* specific REGEXP rendering */
 	context.render_compound = (GdaSqlRenderingFunc) sqlite_render_compound; /* don't surround each SELECT with parenthesis, EXCEPT ALL and INTERSECT ALL are not supported */
 	context.render_expr = sqlite_render_expr; /* render "FALSE" as 0 and TRUE as 1 */
+	context.render_distinct = (GdaSqlRenderingFunc) sqlite_render_distinct; /* DISTINCT ON (...) is not supported */
 
 	str = gda_statement_to_sql_real (stmt, &context, error);
 
@@ -1855,6 +1859,31 @@ gda_sqlite_provider_statement_to_sql (GdaServerProvider *provider, GdaConnection
 }
 
 /*
+ * The difference with the default implementation is that DISTINCT ON (...) is not supported
+ */
+static gchar *
+sqlite_render_distinct (GdaSqlStatementSelect *stmt, GdaSqlRenderingContext *context, GError **error)
+{
+	if (stmt->distinct) {
+		if (stmt->distinct_expr) {
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_NON_SUPPORTED_ERROR,
+				     "%s", _("SQLite does not support specifying fields to apply DISTINCT clause on"));
+			return NULL;
+		}
+		else {
+			gchar *tmp;
+			tmp = g_strdup ("DISTINCT\n");
+			if (! (context->flags & GDA_STATEMENT_SQL_PRETTY))
+				tmp [8] = 0;
+			return tmp;
+		}
+	}
+	else
+		return NULL;
+}
+
+/*
  * The difference with the default implementation is to avoid surrounding each SELECT with parenthesis
  * and that EXCEPT ALL and INTERSECT ALL are not supported
  */



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