[libgda/LIBGDA_4.2] Correction for bug #662922



commit e767a88e328c5384d2ab6e4af82e8021ff9f1624
Author: Vivien Malerba <malerba gnome-db org>
Date:   Mon Oct 31 23:32:06 2011 +0100

    Correction for bug #662922
    
    this correction:
    - GdaSqlBuilder now delays converting values to SQL to GdaStatement rendering
    - handle PostgreSQL 9's new HEX representation of binary data

 libgda/gda-sql-builder.c                    |   37 +++-----------
 libgda/gda-statement.c                      |   32 +++++++++--
 providers/postgres/gda-postgres-recordset.c |   75 ++++++++++++++++++++++++---
 3 files changed, 100 insertions(+), 44 deletions(-)
---
diff --git a/libgda/gda-sql-builder.c b/libgda/gda-sql-builder.c
index 353b166..8ffa4f7 100644
--- a/libgda/gda-sql-builder.c
+++ b/libgda/gda-sql-builder.c
@@ -818,38 +818,15 @@ gda_sql_builder_add_expr_value (GdaSqlBuilder *builder, GdaDataHandler *dh, cons
 	g_return_val_if_fail (builder->priv->main_stmt, 0);
 
 	gchar *str;
-
-	if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL)) {
-		GType type = G_VALUE_TYPE (value);
-		if (!dh)
-			dh = gda_data_handler_get_default (type);
-		else {
-			if (! gda_data_handler_accepts_g_type (dh, type)) {
-				g_warning (_("Unhandled data type '%s'"), g_type_name (type));
-				return 0;
-			}
-		}
-		if (!dh) {
-			g_warning (_("Unhandled data type '%s'"), g_type_name (type));
-			return 0;
-		}
-		str = gda_data_handler_get_sql_from_value (dh, value);
-	}
-	else
-		str = g_strdup ("NULL");
-
-	if (str) {
-		GdaSqlExpr *expr;
-		expr = gda_sql_expr_new (NULL);
-		expr->value = gda_value_new (G_TYPE_STRING);
-		g_value_take_string (expr->value, str);
-		return add_part (builder, (GdaSqlAnyPart *) expr);
-	}
+	GdaSqlExpr *expr;
+	expr = gda_sql_expr_new (NULL);
+	if (value && (G_VALUE_TYPE (value) != GDA_TYPE_NULL))
+		expr->value = gda_value_copy (value);
 	else {
-		g_warning (_("Could not convert value to type '%s'"),
-			   g_type_name (G_VALUE_TYPE (value)));
-		return 0;
+		expr->value = gda_value_new (G_TYPE_STRING);
+		g_value_set_string (expr->value, "NULL");
 	}
+	return add_part (builder, (GdaSqlAnyPart *) expr);
 }
 
 /**
diff --git a/libgda/gda-statement.c b/libgda/gda-statement.c
index bf9ef68..38d9f80 100644
--- a/libgda/gda-statement.c
+++ b/libgda/gda-statement.c
@@ -1506,14 +1506,34 @@ default_render_expr (GdaSqlExpr *expr, GdaSqlRenderingContext *context, gboolean
 				str = g_string_free (string, FALSE);
 			}
 		}
-		else {
-			str = gda_value_stringify (expr->value);
-			if (!str) goto err;
-			if (is_null && gda_value_is_null (expr->value))
+		else if (gda_value_is_null (expr->value)) {
+			str = g_strdup ("NULL");
+			if (is_null)
 				*is_null = TRUE;
-			else if (is_default && (G_VALUE_TYPE (expr->value) == G_TYPE_STRING) && 
-				 !g_ascii_strcasecmp (g_value_get_string (expr->value), "default"))
+		}
+		else if (G_VALUE_TYPE (expr->value) == G_TYPE_STRING) {
+			if (is_default && (G_VALUE_TYPE (expr->value) == G_TYPE_STRING) && 
+			    !g_ascii_strcasecmp (g_value_get_string (expr->value), "default"))
 				*is_default = TRUE;
+			str = g_value_dup_string (expr->value);
+		}
+		else {
+			GdaDataHandler *dh;
+			if (context->cnc) {
+				GdaServerProvider *prov;
+				prov = gda_connection_get_provider (context->cnc);
+				dh = gda_server_provider_get_data_handler_g_type (prov, context->cnc,
+										  G_VALUE_TYPE (expr->value));
+				if (!dh) goto err;
+			}
+			else
+				dh = gda_data_handler_get_default (G_VALUE_TYPE (expr->value));
+
+			if (dh)
+				str = gda_data_handler_get_sql_from_value (dh, expr->value);
+			else
+				str = gda_value_stringify (expr->value);
+			if (!str) goto err;
 		}
 	}
 	else if (expr->func) {
diff --git a/providers/postgres/gda-postgres-recordset.c b/providers/postgres/gda-postgres-recordset.c
index b5bfce0..690c48b 100644
--- a/providers/postgres/gda-postgres-recordset.c
+++ b/providers/postgres/gda-postgres-recordset.c
@@ -676,14 +676,73 @@ set_value (GdaConnection *cnc, GdaRow *row, GValue *value, GType type, const gch
 		 */
 		guchar *unescaped;
                 size_t pqlength = 0;
-
-		unescaped = PQunescapeBytea ((guchar*)thevalue, &pqlength);
-		if (unescaped != NULL) {
-			GdaBinary bin;
-			bin.data = unescaped;
-			bin.binary_length = pqlength;
-			gda_value_set_binary (value, &bin);
-			PQfreemem (unescaped);
+		PostgresConnectionData *cdata;
+		gboolean valueset = FALSE;
+
+		cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+		if (cdata) {
+			if ((thevalue[0] == '\\') && (thevalue[1] == 'x')) {
+				guint len;
+				len = strlen (thevalue + 2);
+				if (!(len % 2)) {
+					guint i;
+					const gchar *ptr;
+					pqlength = len / 2;
+					unescaped = g_new (guchar, pqlength);
+					for (i = 0, ptr = thevalue + 2; *ptr; i++, ptr += 2) {
+						gchar c;
+						c = ptr[0];
+						if ((c >= 'a') && (c <= 'z'))
+							unescaped [i] = c - 'a' + 10;
+						else if ((c >= 'A') && (c <= 'Z'))
+							unescaped [i] = c - 'A' + 10;
+						else if ((c >= '0') && (c <= '9'))
+							unescaped [i] = c - '0';
+						else
+							break;
+						unescaped [i] <<= 4;
+
+						c = ptr[1];
+						if ((c >= 'a') && (c <= 'z'))
+							unescaped [i] += c - 'a' + 10;
+						else if ((c >= 'A') && (c <= 'Z'))
+							unescaped [i] += c - 'A' + 10;
+						else if ((c >= '0') && (c <= '9'))
+							unescaped [i] += c - '0';
+						else
+							break;
+					}
+					if (! *ptr) {
+						GdaBinary *bin;
+						bin = g_new (GdaBinary, 1);
+						bin->data = unescaped;
+						bin->binary_length = pqlength;
+						gda_value_take_binary (value, bin);
+						valueset = TRUE;
+					}
+				}
+			}
+			else {
+				unescaped = PQunescapeBytea ((guchar*) thevalue, &pqlength);
+				if (unescaped) {
+					GdaBinary bin;
+					bin.data = unescaped;
+					bin.binary_length = pqlength;
+					gda_value_set_binary (value, &bin);
+					PQfreemem (unescaped);
+					valueset = TRUE;
+				}
+			}
+		}
+		if (!valueset) {
+			gchar *tmp;
+			tmp = g_strndup (thevalue, 20);
+			gda_row_invalidate_value (row, value);
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+				     GDA_SERVER_PROVIDER_DATA_ERROR,
+				     _("Invalid binary string representation '%s ...'"), 
+				     tmp);
+			g_free (tmp);
 		}
 	}
 	else if (type == GDA_TYPE_BLOB) {



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