diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
index 01b5375c94..36379eee85 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/query/xpath/XPathToSQL2Converter.java
@@ -230,9 +230,25 @@ public class XPathToSQL2Converter {
                             read(")");
                         }
                     } else if ("rep:excerpt".equals(identifier)) {
-                        readOpenDotClose(false);
-                        rewindSelector();
-                        Expression.Property p = new Expression.Property(currentSelector, "rep:excerpt", false);
+                        Expression.Property p;
+
+                        if (readIf(".")) {
+                            rewindSelector();
+                            p = new Expression.Property(currentSelector, "rep:excerpt", false);
+                        } else {
+                            // this will also deal with relative properties
+                            Expression e = parseExpression();
+                            if (!(e instanceof Expression.Property)) {
+                                throw getSyntaxError();
+                            }
+                            Expression.Property prop = (Expression.Property) e;
+                            String property = prop.getColumnAliasName();
+                            rewindSelector();
+                            p = new Expression.Property(currentSelector,
+                                    "rep:excerpt(" + property + ")", false);
+                        }
+                        read(")");
+
                         statement.addSelectColumn(p);
                     } else {
                         throw getSyntaxError();
@@ -253,8 +269,24 @@ public class XPathToSQL2Converter {
                         Expression.Property p = readProperty();
                         statement.addSelectColumn(p);
                     } else if (readIf("rep:excerpt")) {
-                        readOpenDotClose(true);
-                        Expression.Property p = new Expression.Property(currentSelector, "rep:excerpt", false);
+                        Expression.Property p;
+
+                        read("(");
+                        if (readIf(".")) {
+                            p = new Expression.Property(currentSelector, "rep:excerpt", false);
+                        } else {
+                            // this will also deal with relative properties
+                            Expression e = parseExpression();
+                            if (!(e instanceof Expression.Property)) {
+                                throw getSyntaxError();
+                            }
+                            Expression.Property prop = (Expression.Property) e;
+                            String property = prop.getColumnAliasName();
+                            p = new Expression.Property(currentSelector,
+                                    "rep:excerpt(" + property + ")", false);
+                        }
+                        read(")");
+
                         statement.addSelectColumn(p);
                     } else if (readIf("rep:spellcheck")) {
                         // only rep:spellcheck() is currently supported
diff --git a/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java b/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
index 1cc3cf4b66..825938fb4d 100644
--- a/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
+++ b/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2ParserTest.java
@@ -17,10 +17,13 @@
 package org.apache.jackrabbit.oak.query;
 
 import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
 import java.text.ParseException;
+import java.util.Map;
 
+import com.google.common.collect.Maps;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
 import org.apache.jackrabbit.oak.query.stats.QueryStatsData;
diff --git a/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt b/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
index fba0f3831b..cee661b3a5 100644
--- a/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
+++ b/oak-core/src/test/resources/org/apache/jackrabbit/oak/query/xpath.txt
@@ -24,6 +24,85 @@
 # * new tests are typically be added on top, after the syntax docs
 # * use ascii character only
 
+# OAK-7151
+xpath2sql //*[@a='b']/rep:excerpt(.)
+select [jcr:path], [jcr:score], [rep:excerpt]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(.))
+select [jcr:path], [jcr:score], [rep:excerpt]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/rep:excerpt(@a)
+select [jcr:path], [jcr:score], [rep:excerpt(a)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(@a))
+select [jcr:path], [jcr:score], [rep:excerpt(a)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/rep:excerpt(a/@b)
+select [jcr:path], [jcr:score], [rep:excerpt(a/b)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(a/@b))
+select [jcr:path], [jcr:score], [rep:excerpt(a/b)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/rep:excerpt(a/b/@c)
+select [jcr:path], [jcr:score], [rep:excerpt(a/b/c)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(a/b/@c))
+select [jcr:path], [jcr:score], [rep:excerpt(a/b/c)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(@a) | rep:excerpt(@b))
+select [jcr:path], [jcr:score], [rep:excerpt(a)], [rep:excerpt(b)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(@a) | rep:excerpt(@b) | rep:excerpt(@c))
+select [jcr:path], [jcr:score], [rep:excerpt(a)], [rep:excerpt(b)], [rep:excerpt(c)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(rel/@a) | rep:excerpt(rel/@b))
+select [jcr:path], [jcr:score], [rep:excerpt(rel/a)], [rep:excerpt(rel/b)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(.) | rep:excerpt(@a))
+select [jcr:path], [jcr:score], [rep:excerpt], [rep:excerpt(a)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
+xpath2sql //*[@a='b']/(rep:excerpt(.) | rep:excerpt(rel/@a) | rep:excerpt(rel/@b))
+select [jcr:path], [jcr:score], [rep:excerpt], [rep:excerpt(rel/a)], [rep:excerpt(rel/b)]
+  from [nt:base] as a
+  where [a] = 'b'
+  /* xpath ... */
+
 # OAK-6792
 
 xpath2sql /jcr:root//*/(rep:facet(jcr:data/jcr:createdBy))
