This is an automated email from the ASF dual-hosted git repository.

ramyav pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/olingo-odata4.git


The following commit(s) were added to refs/heads/master by this push:
     new bc6a299  [OLINGO-1526]Allow aggregates in concat to have multiple 
identical aliases
bc6a299 is described below

commit bc6a299a1f940165ca5633a9a805a9b176f2bab2
Author: ramya vasanth <[email protected]>
AuthorDate: Fri Sep 17 13:20:19 2021 +0530

    [OLINGO-1526]Allow aggregates in concat to have multiple identical aliases
---
 .../uri/queryoption/apply/AggregateExpression.java | 13 ++++++
 .../olingo/server/core/uri/parser/ApplyParser.java | 51 ++++++++++++----------
 .../queryoption/apply/AggregateExpressionImpl.java | 13 ++++++
 .../queryoption/apply/DynamicStructuredType.java   |  4 ++
 .../server/core/uri/parser/ApplyParserTest.java    | 13 ++++++
 5 files changed, 72 insertions(+), 22 deletions(-)

diff --git 
a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/apply/AggregateExpression.java
 
b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/apply/AggregateExpression.java
index 9947596..44c3b8d 100644
--- 
a/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/apply/AggregateExpression.java
+++ 
b/lib/server-api/src/main/java/org/apache/olingo/server/api/uri/queryoption/apply/AggregateExpression.java
@@ -19,6 +19,7 @@
 package org.apache.olingo.server.api.uri.queryoption.apply;
 
 import java.util.List;
+import java.util.Set;
 
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.server.api.uri.UriResource;
@@ -77,4 +78,16 @@ public interface AggregateExpression extends Expression {
    * @return a (potentially empty) list of aggregate expressions (but never 
<code>null</code>)
    */
   List<AggregateExpression> getFrom();
+  
+  /**
+   * Gets the dynamic properties for aggregation expression.
+   * @return the set of properties
+   */
+  Set<String> getDynamicProperties();
+
+  /**
+   * Adds the dynamic property for aggregation expression.
+   * @param name an identifier
+   */
+  void addDynamicProperty(String name);
 }
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ApplyParser.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ApplyParser.java
index 6cfe85d..71404d2 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ApplyParser.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/parser/ApplyParser.java
@@ -21,8 +21,10 @@ package org.apache.olingo.server.core.uri.parser;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.olingo.commons.api.edm.Edm;
 import org.apache.olingo.commons.api.edm.EdmElement;
@@ -221,21 +223,33 @@ public class ApplyParser {
   private Aggregate parseAggregateTrafo(EdmStructuredType referencedType)
       throws UriParserException, UriValidationException {
     AggregateImpl aggregate = new AggregateImpl();
+    Set<String> dynamicProps = new HashSet<>();
     do {
-       aggregate.addExpression(parseAggregateExpr(referencedType, 
Requirement.REQUIRED));
+       AggregateExpression aggregateExpr = parseAggregateExpr(referencedType, 
dynamicProps, Requirement.REQUIRED);
+        aggregate.addExpression(aggregateExpr);
+        dynamicProps.addAll(aggregateExpr.getDynamicProperties());
     } while (tokenizer.next(TokenKind.COMMA));
+    dynamicProps.forEach(dp -> addPropertyToRefType(referencedType, dp));
     ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
     return aggregate;
   }
   
+  private void addPropertyToRefType(EdmStructuredType referencedType, String 
alias) {
+      ((DynamicStructuredType) referencedType).addProperty(
+              createDynamicProperty(alias,
+                  // The OData standard mandates Edm.Decimal (with no 
decimals), although counts are always integer.
+                  
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Decimal)));
+  }
+  
   public AggregateExpression parseAggregateMethodCallExpr(UriTokenizer 
tokenizer, EdmStructuredType referringType)
              throws UriParserException, UriValidationException {
            this.tokenizer = tokenizer;
 
-           return parseAggregateExpr(referringType, Requirement.FORBIDDEN);
+           return parseAggregateExpr(referringType, Collections.emptySet(), 
Requirement.FORBIDDEN);
          }
 
-  private AggregateExpression parseAggregateExpr(EdmStructuredType 
referencedType, Requirement aliasRequired)
+  private AggregateExpression parseAggregateExpr(EdmStructuredType 
referencedType, Set<String> dynamicProps,
+                 Requirement aliasRequired)
       throws UriParserException, UriValidationException {
            AggregateExpressionImpl aggregateExpression = new 
AggregateExpressionImpl();
            tokenizer.saveState();
@@ -254,19 +268,16 @@ public class ApplyParser {
              aggregateExpression.setPath(uriInfo);
              DynamicStructuredType inlineType = new 
DynamicStructuredType((EdmStructuredType)
                  ParserHelper.getTypeInformation((UriResourcePartTyped) 
lastResourcePart));
-             
aggregateExpression.setInlineAggregateExpression(parseAggregateExpr(inlineType, 
aliasRequired));
+             
aggregateExpression.setInlineAggregateExpression(parseAggregateExpr(inlineType, 
+                         dynamicProps, aliasRequired));
              ParserHelper.requireNext(tokenizer, TokenKind.CLOSE);
            } else if (tokenizer.next(TokenKind.COUNT)) {
              uriInfo.addResourcePart(new UriResourceCountImpl());
              aggregateExpression.setPath(uriInfo);
-             final String alias = parseAsAlias(referencedType, aliasRequired);
+             final String alias = parseAsAlias(referencedType, dynamicProps, 
aliasRequired);
              if (alias != null) {
                aggregateExpression.setAlias(alias);
-               ((DynamicStructuredType) referencedType).addProperty(
-                   createDynamicProperty(alias,
-                       // The OData standard mandates Edm.Decimal (with no 
decimals), 
-                       // although counts are always integer.
-                       
odata.createPrimitiveTypeInstance(EdmPrimitiveTypeKind.Decimal)));
+               aggregateExpression.addDynamicProperty(alias);
              }
            } else {
              // No legitimate continuation of a path prefix has been found.
@@ -286,14 +297,10 @@ public class ApplyParser {
                                
                                return aggregateExpression;
                      }
-             final String alias = parseAsAlias(referencedType, aliasRequired);
+             final String alias = parseAsAlias(referencedType, dynamicProps, 
aliasRequired);
              if(alias != null) {
                aggregateExpression.setAlias(alias);
-               ((DynamicStructuredType) referencedType).addProperty(
-                   createDynamicProperty(alias,
-                       // Determine the type for standard methods; there is no 
way to do this for custom methods.
-                       
getTypeForAggregateMethod(aggregateExpression.getStandardMethod(),
-                           ExpressionParser.getType(expression))));
+               aggregateExpression.addDynamicProperty(alias);
              }
              parseAggregateFrom(aggregateExpression, referencedType);
            }
@@ -311,10 +318,10 @@ public class ApplyParser {
     // allowed and have no type.
     uriInfo.addResourcePart(new 
UriResourcePrimitivePropertyImpl(createDynamicProperty(customAggregate, null)));
     aggregateExpression.setPath(uriInfo);
-    final String alias = parseAsAlias(referencedType, Requirement.OPTIONAL);
+    final String alias = parseAsAlias(referencedType, 
aggregateExpression.getDynamicProperties(), Requirement.OPTIONAL);
     if (alias != null) {
       aggregateExpression.setAlias(alias);
-      ((DynamicStructuredType) 
referencedType).addProperty(createDynamicProperty(alias, null));
+      aggregateExpression.addDynamicProperty(alias);
     }
     parseAggregateFrom(aggregateExpression, referencedType);
   }
@@ -371,8 +378,8 @@ public class ApplyParser {
            REQUIRED, OPTIONAL, FORBIDDEN
          }
 
-  private String parseAsAlias(final EdmStructuredType referencedType, final 
Requirement requirement)
-      throws UriParserException {
+  private String parseAsAlias(final EdmStructuredType referencedType, 
Set<String> dynamicProps,
+             final Requirement requirement) throws UriParserException {
            if (tokenizer.next(TokenKind.AsOperator)) {
                if(requirement == Requirement.FORBIDDEN) {
                  throw new UriParserSyntaxException("Unexpected as alias 
found.", 
@@ -380,7 +387,7 @@ public class ApplyParser {
                }
                ParserHelper.requireNext(tokenizer, TokenKind.ODataIdentifier);
                final String name = tokenizer.getText();
-               if (referencedType.getProperty(name) != null) {
+               if 
(((DynamicStructuredType)referencedType).hasStaticProperty(name) || 
dynamicProps.contains(name)) {
                  throw new UriParserSemanticException("Alias '" + name + "' is 
already a property.",
                      UriParserSemanticException.MessageKeys.IS_PROPERTY, name);
                }
@@ -417,7 +424,7 @@ public class ApplyParser {
         throw new UriParserSemanticException("Compute expressions must return 
primitive values.",
             UriParserSemanticException.MessageKeys.ONLY_FOR_PRIMITIVE_TYPES, 
"compute");
       }
-      final String alias = parseAsAlias(referencedType, Requirement.REQUIRED);
+      final String alias = parseAsAlias(referencedType, 
Collections.emptySet(), Requirement.REQUIRED);
       ((DynamicStructuredType) 
referencedType).addProperty(createDynamicProperty(alias, expressionType));
       compute.addExpression(new ComputeExpressionImpl()
           .setExpression(expression)
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
index f7f6fd9..63baa1c 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/AggregateExpressionImpl.java
@@ -20,7 +20,9 @@ package org.apache.olingo.server.core.uri.queryoption.apply;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.apache.olingo.commons.api.edm.FullQualifiedName;
 import org.apache.olingo.server.api.ODataApplicationException;
@@ -43,6 +45,7 @@ public class AggregateExpressionImpl implements 
AggregateExpression {
   private String alias;
   private AggregateExpression inlineAggregateExpression;
   private List<AggregateExpression> from = new ArrayList<>();
+  private Set<String> dynamicProperties = new HashSet<>();
 
   @Override
   public List<UriResource> getPath() {
@@ -119,4 +122,14 @@ public class AggregateExpressionImpl implements 
AggregateExpression {
     // TODO Auto-generated method stub
     return null;
   }
+  
+  @Override
+  public Set<String> getDynamicProperties() {
+    return Collections.unmodifiableSet(dynamicProperties);
+  }
+
+  @Override
+  public void addDynamicProperty(String name) {
+    dynamicProperties.add(name);
+  }
 }
diff --git 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
index 37a796a..8678c06 100644
--- 
a/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
+++ 
b/lib/server-core/src/main/java/org/apache/olingo/server/core/uri/queryoption/apply/DynamicStructuredType.java
@@ -59,6 +59,10 @@ public class DynamicStructuredType implements 
EdmStructuredType, Cloneable {
         properties == null ? null : properties.get(name) :
         property;
   }
+  
+  public boolean hasStaticProperty(final String name) {
+         return startType.getProperty(name) != null;
+  }
 
   @Override
   public List<String> getPropertyNames() {
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ApplyParserTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ApplyParserTest.java
index 8307c47..b8c95a9 100644
--- 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ApplyParserTest.java
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/ApplyParserTest.java
@@ -364,6 +364,19 @@ public class ApplyParserTest {
     parseEx("ESTwoKeyNav", "Namespace1_Alias.BFCESTwoKeyNavRTTwoKeyNav()")
         
.isExSemantic(UriParserSemanticException.MessageKeys.FUNCTION_MUST_USE_COLLECTIONS);
   }
+  
+  @Test
+  public void concat2aggregatesSameAlias() throws Exception {
+    parse("ESTwoKeyNav",
+        "concat(aggregate(PropertyInt16 with sum as s),aggregate(PropertyInt16 
with max as s))")
+        
.is(Concat.class).goConcat(0).goAggregate(0).goUp().goUp().goConcat(1).goAggregate(0);
+  }
+
+  @Test
+  public void aggregate2expressionsSameAlias() throws Exception {
+    parseEx("ESTwoKeyNav", "aggregate(PropertyInt16 with sum as 
s,PropertyInt16 with max as s)")
+    .isExSemantic(UriParserSemanticException.MessageKeys.IS_PROPERTY);
+  }
 
   @Test
   public void groupBy() throws Exception {

Reply via email to