[Mono-dev] IIF Bug in Mono.Data.SqlExpressions/Parser.jay

Joel Reed joelwreed at gmail.com
Mon Sep 24 22:34:45 EDT 2007


The following code works on MS.NET but not mono svn head (as of 9/24/07):

  DataTable dt = new DataTable();
  dt.Columns.Add("SurveyImage", Type.GetType("System.String"), 
	  "IIF(LMSurvey, 'g1.gif', 'g2.gif')");


1) The attached file "Iif.testcase.diff" adds a test case for
this. OK to apply?


2) I first tried fixing this by adding this code to "BoolExpr"

Index: class/System.Data/Mono.Data.SqlExpressions/Parser.jay
===================================================================
--- class/System.Data/Mono.Data.SqlExpressions/Parser.jay	(revision 86284)
+++ class/System.Data/Mono.Data.SqlExpressions/Parser.jay	(working copy)
@@ -118,6 +118,10 @@
 		$$ = new Negation ((IExpression)$2);
 	}
 	| Predicate
+	| SingleColumnValue
+	{
+		$$ = new BoolOperation(Operation.EQ, (IExpression)$1, new Literal (true));
+	}
 	;
 
 Predicate


But this broke alot of test cases (about 8). I think Parser.jay needs more surgery to fix
these test cases. For example, this line in "CalcFunction"

  SUBSTRING PAROPEN Expr COMMA NumberLiteral COMMA NumberLiteral PARCLOSE

Doesn't seem correct. Expr is defined as "BoolExpr | ArithExpr". But SUBSTRING
doesn't work on a BoolOperation or ArithmeticOperation afaik. It works now because
ArithExpr can also be a "Value". Come to think of it, shouldn't NumberLiteral actually
be ArithExpr? I'll have to try that on MS.NET...

Anyway, not wanting to make lots of changes to this file without checking in here first,
I instead made this change:

Index: class/System.Data/Mono.Data.SqlExpressions/Parser.jay
===================================================================
--- class/System.Data/Mono.Data.SqlExpressions/Parser.jay	(revision 86284)
+++ class/System.Data/Mono.Data.SqlExpressions/Parser.jay	(working copy)
@@ -269,11 +269,19 @@
 	| VAR		{ $$ = AggregationFunction.Var; }
 	;
 
-CalcFunction
+IifFunction
 	: IIF PAROPEN BoolExpr COMMA Expr COMMA Expr PARCLOSE
 	{
 		$$ = new IifFunction ((IExpression)$3, (IExpression)$5, (IExpression)$7);
 	}
+	| IIF PAROPEN SingleColumnValue COMMA Expr COMMA Expr PARCLOSE
+	{
+		$$ = new IifFunction (new BoolOperation(Operation.EQ, (IExpression)$3, new Literal (true)), (IExpression)$5, (IExpression)$7);
+	}
+	;
+
+CalcFunction
+	: IifFunction
 	| SUBSTRING PAROPEN Expr COMMA NumberLiteral COMMA NumberLiteral PARCLOSE
 	{
 		long arg1 = (long) $5;


Which does the job - but seems rather ugly to me. Any comments? Anyone interested in 
this quick fix or me taking the first route & fixing up the rest of this file?

jr
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Iif.testcase.diff
Type: text/x-diff
Size: 994 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070924/fba7525b/attachment.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: BoolOper.fix.diff
Type: text/x-diff
Size: 481 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070924/fba7525b/attachment-0001.bin 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: IifFix.diff
Type: text/x-diff
Size: 861 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20070924/fba7525b/attachment-0002.bin 


More information about the Mono-devel-list mailing list