diff --git a/CHANGELOG.md b/CHANGELOG.md
index 196a8292b20918926df4a66fb1081651f0ede66e..1a52dbfa8ee747cf8d7400279fa41ab1a487c187 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,8 +7,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
-This is an important security update.
-
 ### Added
 
 ### Changed
@@ -19,6 +17,9 @@ This is an important security update.
 
 ### Fixed
 
+* [caosdb-server#131](https://gitlab.com/caosdb/caosdb-server/-/issues/131)
+  Query: AND does not work with sub-properties
+
 ### Security
 
 
diff --git a/src/main/java/org/caosdb/server/query/CQLParser.g4 b/src/main/java/org/caosdb/server/query/CQLParser.g4
index c4311ac1cbe03f490b79456e091cc0e73b94c506..f8c2a3b5ea4e7c34f3cc8fd07cdc77c912a5cc7b 100644
--- a/src/main/java/org/caosdb/server/query/CQLParser.g4
+++ b/src/main/java/org/caosdb/server/query/CQLParser.g4
@@ -287,15 +287,36 @@ pov returns [POV filter] locals [Query.Pattern p, String o, String v, String a]
 ;
 
 
-subproperty returns [SubProperty subp] locals [String p]
+subproperty returns [SubProperty subp]
 @init{
-    $p = null;
     $subp = null;
 }
 :
-    entity_filter {$subp = new SubProperty($entity_filter.filter);}
+	subproperty_filter {$subp = new SubProperty($subproperty_filter.filter);}
 ;
 
+subproperty_filter returns [EntityFilterInterface filter]
+    @init{
+        $filter = null;
+    }
+:
+    which_exp
+    (
+        (
+            LPAREN WHITE_SPACE?
+            (
+                filter_expression {$filter = $filter_expression.efi;}
+                | conjunction {$filter = $conjunction.c;}
+                | disjunction {$filter = $disjunction.d;}
+            )
+            RPAREN
+        ) | (
+            filter_expression {$filter = $filter_expression.efi;}
+        )
+    )?
+;
+
+
 backreference returns [Backreference ref] locals [Query.Pattern e, Query.Pattern p]
     @init{
         $e = null;
@@ -328,7 +349,7 @@ storedat returns [StoredAt filter] locals [String loc]
     WHITE_SPACE?
 ;
 
-conjunction returns [Conjunction c] locals [Conjunction dummy]
+conjunction returns [Conjunction c]
     @init{
         $c = new Conjunction();
     }
@@ -493,7 +514,7 @@ number_with_unit
 
 unit
 :
-    (~(WHITE_SPACE | WHICH | HAS_A | WITH | WHERE | DOT | AND | OR ))
+    (~(WHITE_SPACE | WHICH | HAS_A | WITH | WHERE | DOT | AND | OR | RPAREN ))
     (~(WHITE_SPACE))*
     |
     NUM SLASH (~(WHITE_SPACE))+
@@ -510,7 +531,7 @@ atom returns [Query.Pattern ep]
 :
     double_quoted {$ep = $double_quoted.ep;}
     | single_quoted {$ep = $single_quoted.ep;}
-    | (~(WHITE_SPACE | DOT ))+  {$ep = new Query.Pattern($text, Query.Pattern.TYPE_NORMAL);}
+    | (~(WHITE_SPACE | DOT | RPAREN | LPAREN ))+ {$ep = new Query.Pattern($text, Query.Pattern.TYPE_NORMAL);}
 ;
 
 single_quoted returns [Query.Pattern ep] locals [StringBuffer sb, int patternType]
diff --git a/src/test/java/org/caosdb/server/query/TestCQL.java b/src/test/java/org/caosdb/server/query/TestCQL.java
index cf54bf71b69ea5f539744bd4bbe30fd1c37edcf4..a721fec389aa7635cab8f12c7801db5a6080e265 100644
--- a/src/test/java/org/caosdb/server/query/TestCQL.java
+++ b/src/test/java/org/caosdb/server/query/TestCQL.java
@@ -264,6 +264,13 @@ public class TestCQL {
   String queryMR56 = "FIND ENTITY WITH ((p0 = v0 OR p1=v1) AND p2=v2)";
 
   String versionedQuery1 = "FIND ANY VERSION OF ENTITY e1";
+  // https://gitlab.com/caosdb/caosdb-server/-/issues/131
+  String issue131a = "FIND ename WITH pname1.x AND pname2";
+  String issue131b = "FIND ename WITH (pname1.x < 10) AND (pname1.x)";
+  String issue131c = "FIND ename WITH pname2 AND pname1.x ";
+  String issue131d = "FIND ename WITH (pname1.x) AND pname2";
+  String issue131e = "FIND ename WITH (pname1.pname2 > 30) AND (pname1.pname2 < 40)";
+  String issue131f = "FIND ename WITH (pname1.pname2 > 30) AND pname1.pname2 < 40";
 
   @Test
   public void testQuery1()
@@ -6740,4 +6747,163 @@ public class TestCQL {
     // must not throw ParsingException
     new Query(this.queryIssue131).parse();
   }
+
+  /** String issue131a = "FIND ename WITH pname1.x AND pname2"; */
+  @Test
+  public void testIssue131a() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.issue131a));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    assertTrue(sfq.filter instanceof Conjunction);
+    LinkedList<EntityFilterInterface> filters = ((Conjunction) sfq.filter).getFilters();
+    assertEquals(filters.size(), 2);
+    assertTrue(filters.get(0) instanceof POV);
+    assertTrue(filters.get(1) instanceof POV);
+    POV pov1 = ((POV) filters.get(0));
+    POV pov2 = ((POV) filters.get(1));
+    assertEquals("POV(pname1,null,null)", pov1.toString());
+    assertEquals("POV(pname2,null,null)", pov2.toString());
+    assertTrue(pov1.hasSubProperty());
+    assertFalse(pov2.hasSubProperty());
+    assertEquals("POV(x,null,null)", pov1.getSubProperty().getFilter().toString());
+  }
+
+  /** String issue131b = "FIND ename WITH (pname1.x < 10) AND (pname1.x)"; */
+  @Test
+  public void testIssue131b() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.issue131b));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    assertTrue(sfq.filter instanceof Conjunction);
+    LinkedList<EntityFilterInterface> filters = ((Conjunction) sfq.filter).getFilters();
+    assertEquals(filters.size(), 2);
+    assertTrue(filters.get(0) instanceof POV);
+    assertTrue(filters.get(1) instanceof POV);
+    POV pov1 = ((POV) filters.get(0));
+    POV pov2 = ((POV) filters.get(1));
+    assertEquals("POV(pname1,null,null)", pov1.toString());
+    assertEquals("POV(pname1,null,null)", pov2.toString());
+    assertTrue(pov1.hasSubProperty());
+    assertTrue(pov2.hasSubProperty());
+    assertEquals("POV(x,<,10)", pov1.getSubProperty().getFilter().toString());
+    assertEquals("POV(x,null,null)", pov2.getSubProperty().getFilter().toString());
+  }
+
+  /** String issue131c = "FIND ename WITH pname2 AND pname1.x "; */
+  @Test
+  public void testIssue131c() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.issue131c));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    assertTrue(sfq.filter instanceof Conjunction);
+    LinkedList<EntityFilterInterface> filters = ((Conjunction) sfq.filter).getFilters();
+    assertEquals(filters.size(), 2);
+    assertTrue(filters.get(0) instanceof POV);
+    assertTrue(filters.get(1) instanceof POV);
+    POV pov1 = ((POV) filters.get(0));
+    POV pov2 = ((POV) filters.get(1));
+    assertEquals("POV(pname2,null,null)", pov1.toString());
+    assertEquals("POV(pname1,null,null)", pov2.toString());
+    assertFalse(pov1.hasSubProperty());
+    assertTrue(pov2.hasSubProperty());
+    assertEquals("POV(x,null,null)", pov2.getSubProperty().getFilter().toString());
+  }
+
+  /** String issue131d = "FIND ename WITH (pname1.x) AND pname2"; */
+  @Test
+  public void testIssue131d() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.issue131d));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    assertTrue(sfq.filter instanceof Conjunction);
+    LinkedList<EntityFilterInterface> filters = ((Conjunction) sfq.filter).getFilters();
+    assertEquals(filters.size(), 2);
+    assertTrue(filters.get(0) instanceof POV);
+    assertTrue(filters.get(1) instanceof POV);
+    POV pov1 = ((POV) filters.get(0));
+    POV pov2 = ((POV) filters.get(1));
+    assertEquals("POV(pname1,null,null)", pov1.toString());
+    assertEquals("POV(pname2,null,null)", pov2.toString());
+    assertTrue(pov1.hasSubProperty());
+    assertFalse(pov2.hasSubProperty());
+    assertEquals("POV(x,null,null)", pov1.getSubProperty().getFilter().toString());
+  }
+
+  /** String issue131e = "FIND ename WITH (pname1.pname2 > 30) AND (pname1.pname2 < 40)"; */
+  @Test
+  public void testIssue131e() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.issue131e));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    assertTrue(sfq.filter instanceof Conjunction);
+    LinkedList<EntityFilterInterface> filters = ((Conjunction) sfq.filter).getFilters();
+    assertEquals(filters.size(), 2);
+    assertTrue(filters.get(0) instanceof POV);
+    assertTrue(filters.get(1) instanceof POV);
+    POV pov1 = ((POV) filters.get(0));
+    POV pov2 = ((POV) filters.get(1));
+    assertEquals("POV(pname1,null,null)", pov1.toString());
+    assertEquals("POV(pname1,null,null)", pov2.toString());
+    assertTrue(pov1.hasSubProperty());
+    assertTrue(pov2.hasSubProperty());
+    assertEquals("POV(pname2,>,30)", pov1.getSubProperty().getFilter().toString());
+    assertEquals("POV(pname2,<,40)", pov2.getSubProperty().getFilter().toString());
+  }
+
+  /** String issue131f = "FIND ename WITH (pname1.pname2 > 30) AND pname1.pname2 < 40"; */
+  @Test
+  public void testIssue131f() {
+    CQLLexer lexer;
+    lexer = new CQLLexer(CharStreams.fromString(this.issue131f));
+    final CommonTokenStream tokens = new CommonTokenStream(lexer);
+
+    final CQLParser parser = new CQLParser(tokens);
+    final CqContext sfq = parser.cq();
+
+    System.out.println(sfq.toStringTree(parser));
+
+    assertTrue(sfq.filter instanceof Conjunction);
+    LinkedList<EntityFilterInterface> filters = ((Conjunction) sfq.filter).getFilters();
+    assertEquals(filters.size(), 2);
+    assertTrue(filters.get(0) instanceof POV);
+    assertTrue(filters.get(1) instanceof POV);
+    POV pov1 = ((POV) filters.get(0));
+    POV pov2 = ((POV) filters.get(1));
+    assertEquals("POV(pname1,null,null)", pov1.toString());
+    assertEquals("POV(pname1,null,null)", pov2.toString());
+    assertTrue(pov1.hasSubProperty());
+    assertTrue(pov2.hasSubProperty());
+    assertEquals("POV(pname2,>,30)", pov1.getSubProperty().getFilter().toString());
+    assertEquals("POV(pname2,<,40)", pov2.getSubProperty().getFilter().toString());
+  }
 }