You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@olingo.apache.org by ch...@apache.org on 2015/08/14 16:33:30 UTC

olingo-odata4 git commit: [OLINGO-659] Literals returned by the URI Parser provide an EdmType

Repository: olingo-odata4
Updated Branches:
  refs/heads/master f9c68b8ba -> cd11add7c


[OLINGO-659] Literals returned by the URI Parser provide an EdmType


Project: http://git-wip-us.apache.org/repos/asf/olingo-odata4/repo
Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata4/commit/cd11add7
Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata4/tree/cd11add7
Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata4/diff/cd11add7

Branch: refs/heads/master
Commit: cd11add7c1da3a529947280e0913a926250a306b
Parents: f9c68b8
Author: Christian Holzer <c....@sap.com>
Authored: Fri Aug 14 16:32:56 2015 +0200
Committer: Christian Holzer <c....@sap.com>
Committed: Fri Aug 14 16:33:14 2015 +0200

----------------------------------------------------------------------
 .../api/uri/queryoption/expression/Literal.java |   7 +-
 .../olingo/server/core/uri/antlr/UriParser.g4   |  50 ++++---
 .../core/uri/parser/UriParseTreeVisitor.java    | 135 ++++++++++++++++---
 .../core/uri/antlr/TestFullResourcePath.java    |  93 ++++++++++++-
 .../core/uri/testutil/FilterValidator.java      |  27 +++-
 5 files changed, 271 insertions(+), 41 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cd11add7/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
----------------------------------------------------------------------
diff --git a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
index 524074d..b4bdde2 100644
--- a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
+++ b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/expression/Literal.java
@@ -31,7 +31,12 @@ public interface Literal extends Expression {
   public String getText();
 
   /**
-   * @return Type of the literal if detected
+   * Numeric literals without an dot and without an e return the smallest possible Edm Integer type.
+   * Numeric literals without an dot, without an e and larger than 2^63 - 1 are considered as Edm.Decimal
+   * Numeric literals with an e, are considered to be Edm.Double 
+   * Numeric literals with an dot and without an e, are supposed to be Edm.Decimal
+   * 
+   * @return Type of the literal if detected. The type of the literal is guessed by the parser. 
    */
   public EdmType getType();
 

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cd11add7/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4 b/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
index e7572dc..93a4ee1 100644
--- a/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
+++ b/lib/server-core/src/main/antlr4/org/apache/olingo/server/core/uri/antlr/UriParser.g4
@@ -148,7 +148,7 @@ skip                : SKIP_QO EQ INT;
 top                 : TOP EQ INT;
 //format              : FORMAT EQ ( ATOM | JSON | XML | PCHARS SLASH PCHARS);
 
-inlinecount         : COUNT EQ booleanNonCase;
+inlinecount         : COUNT EQ booleanNonCaseLiteral;
 
 search              : SEARCH searchSpecialToken;
 searchInline        : SEARCH_INLINE searchSpecialToken;
@@ -342,19 +342,19 @@ odataIdentifier         : ODATAIDENTIFIER;
 //;------------------------------------------------------------------------------
 
 
-primitiveLiteral    : nullrule
-                    | booleanNonCase
-                    | DECIMAL   //includes double and single literals
-                    | naninfinity
-                    | INT       //includes int16/int32 and int64 literals
-                    | BINARY  
-                    | DATE
-                    | DATETIMEOFFSET
-                    | DURATION
-                    | GUID
-                    | string
-                    | TIMEOFDAY
-                    | enumLit
+primitiveLiteral    : nullruleLiteral
+                    | booleanNonCaseLiteral
+                    | decimalLiteral   //includes double and single literals
+                    | naninfinityLiteral
+                    | intLiteral       //includes int16/int32 and int64 literals
+                    | binaryLiteral  
+                    | dateLiteral
+                    | datetimeoffsetLiteral
+                    | durationLiteral
+                    | guidLiteral
+                    | stringLiteral
+                    | timeofdayLiteral
+                    | enumLiteral
                     | geographyCollection
                     | geographyLineString
                     | geographyMultilineString
@@ -371,14 +371,22 @@ primitiveLiteral    : nullrule
                     | geometryPolygon
                     ;
 
-naninfinity         : NANINFINITY;
 
-nullrule            : NULLVALUE;
-booleanNonCase      : BOOLEAN | TRUE | FALSE;
-string              : STRING;
-
-enumLit             : vNS=namespace vODI=odataIdentifier vValues=STRING;
-enumValues          : vlODI+=odataIdentifier ( COMMA vlODI+=odataIdentifier )*;
+nullruleLiteral            : NULLVALUE;
+booleanNonCaseLiteral      : BOOLEAN | TRUE | FALSE;
+decimalLiteral             : DECIMAL;
+naninfinityLiteral         : NANINFINITY;
+intLiteral                 : INT;
+binaryLiteral              : BINARY;
+dateLiteral                : DATE;
+datetimeoffsetLiteral      : DATETIMEOFFSET;
+durationLiteral            : DURATION;
+guidLiteral                : GUID;
+stringLiteral              : STRING;
+timeofdayLiteral           : TIMEOFDAY;
+
+enumLiteral                : vNS=namespace vODI=odataIdentifier vValues=STRING;
+enumValues                 : vlODI+=odataIdentifier ( COMMA vlODI+=odataIdentifier )*;
 
 geographyCollection         : GEOGRAPHY  fullCollectionLiteral SQUOTE;
 fullCollectionLiteral       : sridLiteral collectionLiteral;

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cd11add7/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
----------------------------------------------------------------------
diff --git a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
index c853c1a..16816bd 100644
--- a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
+++ b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/UriParseTreeVisitor.java
@@ -18,6 +18,10 @@
  */
 package org.apache.olingo.server.core.uri.parser;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
 import org.antlr.v4.runtime.misc.NotNull;
 import org.antlr.v4.runtime.misc.ParseCancellationException;
 import org.antlr.v4.runtime.tree.ParseTree;
@@ -87,18 +91,23 @@ import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltMultContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.AltOrContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.AnyExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.BatchEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.BooleanNonCaseContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.BinaryLiteralContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.BooleanNonCaseLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.CastExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.CeilingMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ConcatMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ConstSegmentContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ContainsMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.CrossjoinEOFContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.DateLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.DateMethodCallExprContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.DatetimeoffsetLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.DayMethodCallExprContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.DecimalLiteralContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.DurationLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.EndsWithMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.EntityEOFContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.EnumLitContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.EnumLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandCountOptionContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandItemContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ExpandItemsContext;
@@ -113,9 +122,11 @@ import org.apache.olingo.server.core.uri.antlr.UriParserParser.Fractionalseconds
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.GeoDistanceMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.GeoIntersectsMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.GeoLengthMethodCallExprContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.GuidLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.HourMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.IndexOfMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.InlinecountContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.IntLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.IsofExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.LengthMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.LevelsContext;
@@ -128,9 +139,9 @@ import org.apache.olingo.server.core.uri.antlr.UriParserParser.MonthMethodCallEx
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.NameValueOptListContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.NameValuePairContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.NamespaceContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NaninfinityContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.NaninfinityLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.NowMethodCallExprContext;
-import org.apache.olingo.server.core.uri.antlr.UriParserParser.NullruleContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.NullruleLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.OdataIdentifierContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderByContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.OrderByEOFContext;
@@ -151,8 +162,10 @@ import org.apache.olingo.server.core.uri.antlr.UriParserParser.SelectSegmentCont
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.SkipContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.SkiptokenContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.StartsWithMethodCallExprContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.StringLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.SubstringMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.TimeMethodCallExprContext;
+import org.apache.olingo.server.core.uri.antlr.UriParserParser.TimeofdayLiteralContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ToLowerMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.ToUpperMethodCallExprContext;
 import org.apache.olingo.server.core.uri.antlr.UriParserParser.TopContext;
@@ -184,10 +197,6 @@ import org.apache.olingo.server.core.uri.queryoption.expression.MethodImpl;
 import org.apache.olingo.server.core.uri.queryoption.expression.TypeLiteralImpl;
 import org.apache.olingo.server.core.uri.queryoption.expression.UnaryImpl;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * UriVisitor
  *
@@ -954,7 +963,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
   }
 
   @Override
-  public Object visitBooleanNonCase(final BooleanNonCaseContext ctx) {
+  public Object visitBooleanNonCaseLiteral(final BooleanNonCaseLiteralContext ctx) {
     String text = ctx.getText().toLowerCase();
 
     if (text.equals("false")) {
@@ -1148,7 +1157,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
   }
 
   @Override
-  public Object visitEnumLit(final EnumLitContext ctx) {
+  public Object visitEnumLiteral(final EnumLiteralContext ctx) {
     EnumerationImpl enum1 = new EnumerationImpl();
 
     // get type
@@ -1711,7 +1720,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
   }
 
   @Override
-  public Object visitNaninfinity(final NaninfinityContext ctx) {
+  public Object visitNaninfinityLiteral(final NaninfinityLiteralContext ctx) {
     return new LiteralImpl().setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal)).
         setText(ctx.getText());
   }
@@ -1723,7 +1732,7 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
   }
 
   @Override
-  public Object visitNullrule(final NullruleContext ctx) {
+  public Object visitNullruleLiteral(final NullruleLiteralContext ctx) {
     return new LiteralImpl().setText("null");
   }
 
@@ -1823,15 +1832,107 @@ public class UriParseTreeVisitor extends UriParserBaseVisitor<Object> {
   @Override
   public Object visitPrimitiveLiteral(final PrimitiveLiteralContext ctx) {
     ParseTree child1 = ctx.children.get(0);
-
-    if (child1 instanceof EnumLitContext
-        || child1 instanceof BooleanNonCaseContext
-        || child1 instanceof NullruleContext
-        || child1 instanceof NaninfinityContext) {
+    
+    if (child1 instanceof EnumLiteralContext
+        || child1 instanceof BooleanNonCaseLiteralContext
+        || child1 instanceof NullruleLiteralContext
+        || child1 instanceof NaninfinityLiteralContext
+        || child1 instanceof StringLiteralContext
+        || child1 instanceof IntLiteralContext
+        || child1 instanceof BinaryLiteralContext
+        || child1 instanceof DateLiteralContext
+        || child1 instanceof DatetimeoffsetLiteralContext
+        || child1 instanceof DurationLiteralContext
+        || child1 instanceof GuidLiteralContext
+        || child1 instanceof TimeofdayLiteralContext
+        || child1 instanceof DecimalLiteralContext
+        || child1 instanceof BinaryLiteralContext) {
       return child1.accept(this);
     }
+    
+    // TODO Implement geography types and set the proper type
     return new LiteralImpl().setText(ctx.getText());
   }
+  
+  @Override
+  public Object visitBinaryLiteral(BinaryLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+        .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Binary));
+  }
+
+  @Override
+  public Object visitStringLiteral(final StringLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+                            .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.String));
+  }
+  
+  @Override
+  public Object visitDecimalLiteral(final DecimalLiteralContext ctx) {
+    EdmType type = null;
+    
+    if(!ctx.getText().matches(".*[eE].*")) {
+      type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal);
+    } else {
+      type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Double);
+    }
+    
+    return new LiteralImpl().setText(ctx.getText()).setType(type);
+  }
+
+  @Override
+  public Object visitIntLiteral(final IntLiteralContext ctx) {
+    try {
+      final long value = Long.parseLong(ctx.getText());
+      EdmType type = null;
+      
+      if(value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+        type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.SByte);
+      } else if (value >= 0 && value <= 255) {
+        type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Byte);
+      } else if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+        type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int16);
+      } else if(value >= Integer.MIN_VALUE && value <= Integer.MAX_VALUE) {
+        type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int32);
+      } else {
+        type = EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Int64);
+      }
+
+      return new LiteralImpl().setText(ctx.getText()).setType(type);
+    } catch( NumberFormatException e) {
+      return new LiteralImpl().setText(ctx.getText())
+          .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Decimal));
+    }
+  }
+
+  @Override
+  public Object visitDateLiteral(final DateLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+        .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Date));
+  }
+
+  @Override
+  public Object visitDatetimeoffsetLiteral(final  DatetimeoffsetLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+        .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.DateTimeOffset));
+  }
+
+  @Override
+  public Object visitDurationLiteral(final DurationLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+        .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Duration));
+  }
+
+  @Override
+  public Object visitGuidLiteral(final GuidLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+        .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.Guid));
+  }
+
+  @Override
+  public Object visitTimeofdayLiteral(final TimeofdayLiteralContext ctx) {
+    return new LiteralImpl().setText(ctx.getText())
+        .setType(EdmPrimitiveTypeFactory.getInstance(EdmPrimitiveTypeKind.TimeOfDay));
+  }
 
   @Override
   public Object visitQueryOptions(final QueryOptionsContext ctx) {

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cd11add7/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
index fb231f0..11b882e 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/antlr/TestFullResourcePath.java
@@ -25,8 +25,22 @@ import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.http.HttpContentType;
 import org.apache.olingo.commons.core.Encoder;
 import org.apache.olingo.commons.core.edm.EdmProviderImpl;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmBinary;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmBoolean;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmByte;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDateTimeOffset;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDecimal;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDouble;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmDuration;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmGuid;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmInt16;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmInt32;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmInt64;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmSByte;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmString;
+import org.apache.olingo.commons.core.edm.primitivetype.EdmTimeOfDay;
 import org.apache.olingo.server.api.ODataApplicationException;
-import org.apache.olingo.server.api.processor.EntityProcessor;
 import org.apache.olingo.server.api.uri.UriInfoKind;
 import org.apache.olingo.server.api.uri.UriResourceKind;
 import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;
@@ -5300,6 +5314,83 @@ public class TestFullResourcePath {
         + "(PropertyInt=1,PropertyString='2')");
   }
   
+  @Test
+  public void testFilterLiteralTypes() throws Exception {
+    testUri.run("ESAllPrim", "$filter='1' eq 42")
+      .goFilter().isBinary(BinaryOperatorKind.EQ)
+        .left().isLiteral("'1'").isLiteralType(EdmString.getInstance())
+        .root()
+        .right().isLiteral("42").isLiteralType(EdmSByte.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=127 eq 128")
+      .goFilter().isBinary(BinaryOperatorKind.EQ)
+        .left().isLiteral("127").isLiteralType(EdmSByte.getInstance())
+        .root()
+        .right().isLiteral("128").isLiteralType(EdmByte.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=null eq 42.1")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("null").isNullLiteralType()
+      .root()
+      .right().isLiteral("42.1").isLiteralType(EdmDecimal.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=15.6E300 eq 3.4E37")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("15.6E300")
+      .isLiteralType(EdmDouble.getInstance())
+      .root()
+      .right().isLiteral("3.4E37").isLiteralType(EdmDouble.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=15.55555555555555555555555555555555555555555555 eq 3.1")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("15.55555555555555555555555555555555555555555555")
+      .isLiteralType(EdmDecimal.getInstance())
+      .root()
+      .right().isLiteral("3.1").isLiteralType(EdmDecimal.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=duration'PT1H2S' eq 2012-12-03")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("duration'PT1H2S'").isLiteralType(EdmDuration.getInstance())
+      .root()
+      .right().isLiteral("2012-12-03").isLiteralType(EdmDate.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=true eq 2012-12-03T07:16:23Z")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("true").isLiteralType(EdmBoolean.getInstance())
+      .root()
+      .right().isLiteral("2012-12-03T07:16:23Z").isLiteralType(EdmDateTimeOffset.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=07:59:59.999 eq 01234567-89ab-cdef-0123-456789abcdef")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("07:59:59.999").isLiteralType(EdmTimeOfDay.getInstance())
+      .root()
+      .right().isLiteral("01234567-89ab-cdef-0123-456789abcdef").isLiteralType(EdmGuid.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=binary'0FAB7B' eq true")
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("binary'0FAB7B'").isLiteralType(EdmBinary.getInstance())
+      .root()
+      .right().isLiteral("true").isLiteralType(EdmBoolean.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=" + Short.MIN_VALUE + " eq " + Short.MAX_VALUE)
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("" + Short.MIN_VALUE).isLiteralType(EdmInt16.getInstance())
+      .root()
+      .right().isLiteral("" + Short.MAX_VALUE).isLiteralType(EdmInt16.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=" + Integer.MIN_VALUE + " eq " + Integer.MAX_VALUE)
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("" + Integer.MIN_VALUE).isLiteralType(EdmInt32.getInstance())
+      .root()
+      .right().isLiteral("" + Integer.MAX_VALUE).isLiteralType(EdmInt32.getInstance());
+    
+    testUri.run("ESAllPrim", "$filter=" + Long.MIN_VALUE + " eq " + Long.MAX_VALUE)
+    .goFilter().isBinary(BinaryOperatorKind.EQ)
+      .left().isLiteral("" + Long.MIN_VALUE).isLiteralType(EdmInt64.getInstance())
+      .root()
+      .right().isLiteral("" + Long.MAX_VALUE).isLiteralType(EdmInt64.getInstance());
+  }
+  
   public static String encode(final String decoded) throws UnsupportedEncodingException {
     return Encoder.encode(decoded);
   }

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/cd11add7/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
----------------------------------------------------------------------
diff --git a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
index 5752208..02cf29e 100644
--- a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
+++ b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/testutil/FilterValidator.java
@@ -19,6 +19,8 @@
 package org.apache.olingo.server.core.uri.testutil;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
 
 import java.util.List;
@@ -362,7 +364,30 @@ public class FilterValidator implements TestValidator {
 
     return this;
   }
-
+  
+  public FilterValidator isLiteralType(EdmType edmType) {
+    if(!(curExpression instanceof LiteralImpl)) {
+      fail("Current expression is nit a literal");
+    }
+    
+    final EdmType type = ((LiteralImpl) curExpression).getType();
+    assertNotNull(type);
+    assertEquals(edmType.getClass(), type.getClass());
+    
+    return this;
+  }
+  
+  public FilterValidator isNullLiteralType() {
+    if(!(curExpression instanceof LiteralImpl)) {
+      fail("Current expression is nit a literal");
+    }
+    
+    final EdmType type = ((LiteralImpl) curExpression).getType();
+    assertNull(type);
+    
+    return this;
+  }
+  
   public FilterValidator isMethod(final MethodKind methodKind, final int parameterCount) {
     if (!(curExpression instanceof MethodImpl)) {
       fail("Current expression is not a methodCall");