Hi,

this patch lowers the number of failing tests in DbLinq.PostgreSql_test
from 167 to 141. I hope the kind of checks I did is the right one but
let me know if there is a better way to do them.

Also, I can avoid the checks completely and replace all uses of "<>" and
"=" operators respectively by

IS DISTINCT FROM
IS NOT DISTINCT FROM

but I don't like that because puts gives extra work to the database when
we already _know_ we're sending a NULL literal.

-- 
Federico Di Gregorio                         http://people.initd.org/fog
Debian GNU/Linux Developer                                [email protected]
INIT.D Developer                                           [email protected]
                   Ma chi sei?....-il trafficante di Nutella? -- Giorgia
Index: src/DbLinq.PostgreSql/PgsqlSqlProvider.cs
===================================================================
--- src/DbLinq.PostgreSql/PgsqlSqlProvider.cs	(revisione 1157)
+++ src/DbLinq.PostgreSql/PgsqlSqlProvider.cs	(copia locale)
@@ -58,10 +58,40 @@
         {
             return string.Format("LOWER({0})", a);
         }
+        
         protected override SqlStatement GetLiteralDateDiff(SqlStatement dateA, SqlStatement dateB)
         {
             return string.Format("(DATE_PART('Day',{0}-{1})*86400000+DATE_PART('Hour',{0}-{1})*3600000+DATE_PART('Minute',{0}-{1})*60000+DATE_PART('Second',{0}-{1})*1000+DATE_PART('Millisecond',{0}-{1}))::real", dateA, dateB);
         }
+        
+        protected override SqlStatement GetLiteralEqual(SqlStatement a, SqlStatement b)
+        {
+            // PostgreSQL return NULL (and not a boolean) for every comparaison involving
+            // a NULL value, unless the operator used is "IS" (or "IS NOT"). Also,
+            // using those two operators when the right-hand value is not a literal
+            // NULL is an error. The only possibility is to explicitly check for NULL
+            // literals and even swap the operands to make sure NULL gets to the
+            // right place.
+            
+            if (b.Count == 1 && b[0].Sql == "NULL")
+                return SqlStatement.Format("{0} IS {1}", a, b);
+            else if (a.Count == 1 && a[0].Sql == "NULL")
+                return SqlStatement.Format("{0} IS {1}", b, a);
+            else
+                return SqlStatement.Format("{0} = {1}", a, b);
+        }
+        
+        protected override SqlStatement GetLiteralNotEqual(SqlStatement a, SqlStatement b)
+        {
+            // See comment above, in GetLiteralEqual().
+            
+            if (b.Count == 1 && b[0].Sql == "NULL")
+                return SqlStatement.Format("{0} IS NOT {1}", a, b);
+            else if (a.Count == 1 && a[0].Sql == "NULL")
+                return SqlStatement.Format("{0} IS NOT {1}", b, a);
+            else
+                return SqlStatement.Format("{0} <> {1}", a, b);
+        }        
 
         public static readonly Dictionary<Type, string> typeMapping = new Dictionary<Type, string>
                                                                           {

Attachment: signature.asc
Description: Questa รจ una parte del messaggio firmata digitalmente

Reply via email to