private def genQuery()

in repository/src/main/scala/org/apache/atlas/query/GremlinQuery.scala [405:631]


    private def genQuery(parent: GroovyExpression, expr: Expression, inClosure: Boolean): GroovyExpression = expr match {
        case ClassExpression(clsName) => typeTestExpression(parent, clsName)
        case TraitExpression(clsName) => typeTestExpression(parent, clsName)
        case fe@FieldExpression(fieldName, fInfo, child)
            if fe.dataType.getTypeCategory == TypeCategory.PRIMITIVE || fe.dataType.getTypeCategory == TypeCategory.ARRAY => {
                val fN = gPersistenceBehavior.fieldNameInVertex(fInfo.dataType, fInfo.attrInfo)
                val childExpr = translateOptChild(parent, child, inClosure);
                return GremlinExpressionFactory.INSTANCE.generateFieldExpression(childExpr, fInfo, fN, inClosure);
            }
        case fe@FieldExpression(fieldName, fInfo, child)
            if fe.dataType.getTypeCategory == TypeCategory.CLASS || fe.dataType.getTypeCategory == TypeCategory.STRUCT => {
            val childExpr = translateOptChild(parent, child, inClosure);
            val direction = if (fInfo.isReverse) AtlasEdgeDirection.IN else AtlasEdgeDirection.OUT
            val edgeLbl = gPersistenceBehavior.edgeLabel(fInfo)
            return GremlinExpressionFactory.INSTANCE.generateAdjacentVerticesExpression(childExpr, direction, edgeLbl)

            }
        case fe@FieldExpression(fieldName, fInfo, child) if fInfo.traitName != null => {
            val childExpr = translateOptChild(parent, child, inClosure);
            val direction = gPersistenceBehavior.instanceToTraitEdgeDirection
            val edgeLbl = gPersistenceBehavior.edgeLabel(fInfo)
            return GremlinExpressionFactory.INSTANCE.generateAdjacentVerticesExpression(childExpr, direction, edgeLbl)

        }
        case c@ComparisonExpression(symb, f@FieldExpression(fieldName, fInfo, ch), l) => {
            val qualifiedPropertyName = s"${gPersistenceBehavior.fieldNameInVertex(fInfo.dataType, fInfo.attrInfo)}"

            val childExpr = translateOptChild(parent, ch, inClosure)
            val persistentExprValue : GroovyExpression = if(l.isInstanceOf[Literal[_]]) {
                translateLiteralValue(fInfo.attrInfo.dataType, l.asInstanceOf[Literal[_]]);
            }
            else {
                genQuery(null, l, inClosure);
            }

            if (symb == "like") {
              return GremlinExpressionFactory.INSTANCE.generateLikeExpressionUsingFilter(childExpr, qualifiedPropertyName, persistentExprValue);
            }

           return GremlinExpressionFactory.INSTANCE.generateHasExpression(gPersistenceBehavior, childExpr, qualifiedPropertyName, c.symbol, persistentExprValue, fInfo);
        }
        case fil@FilterExpression(child, condExpr) => {
            var newParent = genQuery(parent, child, inClosure);
            val alias = "a" + counter.next;
            newParent = GremlinExpressionFactory.INSTANCE.generateAliasExpression(newParent, alias);
            val translated =  genQuery(newParent, condExpr, inClosure);
            //we want the query to return instances of the class whose instances we are filtering out
            //The act of filtering may traverse edges and have other side effects.
            GremlinExpressionFactory.INSTANCE.generateBackReferenceExpression(translated, false, alias);
        }
        case l@LogicalExpression(symb, children) => {
            val translatedChildren : java.util.List[GroovyExpression] = translateList(children, false);
            return GremlinExpressionFactory.INSTANCE.generateLogicalExpression(parent, symb, translatedChildren);
        }
        case sel@SelectExpression(child, selList, forGroupBy) => {
              val m = groupSelectExpressionsBySrc(sel)
              var srcNamesList: java.util.List[LiteralExpression] = new ArrayList()
              var srcExprsList: List[java.util.List[GroovyExpression]] = List()
              val it = m.iterator

              while (it.hasNext) {
                  val (src, selExprs) = it.next
                  srcNamesList.add(new LiteralExpression(src));
                  val translatedSelExprs : java.util.List[GroovyExpression] = translateList(selExprs, true);
                  srcExprsList = srcExprsList :+ translatedSelExprs
               }
               val srcExprsStringList : java.util.List[GroovyExpression] = new ArrayList();
               srcExprsList.foreach { it =>
                    srcExprsStringList.add(new ListExpression(it));
               }

               val childExpr = genQuery(parent, child, inClosure)
               return GremlinExpressionFactory.INSTANCE.generateSelectExpression(childExpr, srcNamesList, srcExprsStringList);

        }
        case loop@LoopExpression(input, loopExpr, t) => {

            val times : Integer = if(t.isDefined) {
                t.get.rawValue.asInstanceOf[Integer]
            }
            else {
                null.asInstanceOf[Integer]
            }
            val alias = input.asInstanceOf[AliasExpression].alias;
            val inputQry = genQuery(parent, input, inClosure)
            val translatedLoopExpr = genQuery(GremlinExpressionFactory.INSTANCE.getLoopExpressionParent(inputQry), loopExpr, inClosure);
            return GremlinExpressionFactory.INSTANCE.generateLoopExpression(inputQry, gPersistenceBehavior, input.dataType, translatedLoopExpr, alias, times);
        }
        case BackReference(alias, _, _) => {

            return GremlinExpressionFactory.INSTANCE.generateBackReferenceExpression(parent, inClosure, alias);
        }
        case AliasExpression(child, alias) => {
            var childExpr = genQuery(parent, child, inClosure);
            return GremlinExpressionFactory.INSTANCE.generateAliasExpression(childExpr, alias);
        }
        case isTraitLeafExpression(traitName, Some(clsExp)) => {
            val label = gPersistenceBehavior.traitLabel(clsExp.dataType, traitName);
            return GremlinExpressionFactory.INSTANCE.generateAdjacentVerticesExpression(parent, AtlasEdgeDirection.OUT, label);
        }
        case isTraitUnaryExpression(traitName, child) => {
            val label = gPersistenceBehavior.traitLabel(child.dataType, traitName);
            return GremlinExpressionFactory.INSTANCE.generateAdjacentVerticesExpression(parent, AtlasEdgeDirection.OUT, label);
        }
        case hasFieldLeafExpression(fieldName, clsExp) => clsExp match {
            case None => GremlinExpressionFactory.INSTANCE.generateUnaryHasExpression(parent, fieldName)
            case Some(x) => {
                val fi = TypeUtils.resolveReference(clsExp.get.dataType, fieldName);
                if(! fi.isDefined) {
                    return GremlinExpressionFactory.INSTANCE.generateUnaryHasExpression(parent, fieldName);
                }
                else {
                    val fName = gPersistenceBehavior.fieldNameInVertex(fi.get.dataType, fi.get.attrInfo)
                    return GremlinExpressionFactory.INSTANCE.generateUnaryHasExpression(parent, fName);
                }
            }
        }
        case hasFieldUnaryExpression(fieldName, child) =>
            val childExpr = genQuery(parent, child, inClosure);
            return GremlinExpressionFactory.INSTANCE.generateUnaryHasExpression(childExpr, fieldName);
        case ArithmeticExpression(symb, left, right) => {
            val leftExpr = genQuery(parent, left, inClosure);
            val rightExpr = genQuery(parent, right, inClosure);
            return GremlinExpressionFactory.INSTANCE.generateArithmeticExpression(leftExpr, symb, rightExpr);
        }
        case l: Literal[_] =>  {

            if(parent != null) {
                return new org.apache.atlas.groovy.FieldExpression(parent, cleanStringLiteral(l));
            }
            return translateLiteralValue(l.dataType, l);
        }
        case list: ListLiteral[_] =>  {
            //Here, we are creating a Groovy list literal expression ([value1, value2, value3]).  Because
            //of this, any gremlin query expressions within the list must start with an anonymous traversal.
            //We set 'inClosure' to true in this case to make that happen.
            val  values : java.util.List[GroovyExpression] = translateList(list.rawValue, true);
            return new ListExpression(values);
        }
        case in@TraitInstanceExpression(child) => {
          val childExpr = genQuery(parent, child, inClosure);
          val direction = gPersistenceBehavior.traitToInstanceEdgeDirection;
          return GremlinExpressionFactory.INSTANCE.generateAdjacentVerticesExpression(childExpr, direction);
        }
        case in@InstanceExpression(child) => {
            return genQuery(parent, child, inClosure);
        }
        case pe@PathExpression(child) => {
            val childExpr = genQuery(parent, child, inClosure)
            return GremlinExpressionFactory.INSTANCE.generatePathExpression(childExpr);
        }
        case order@OrderExpression(child, odr, asc) => {
          var orderExpression = odr
          if(odr.isInstanceOf[BackReference]) {
              orderExpression = odr.asInstanceOf[BackReference].reference
          }
          else if (odr.isInstanceOf[AliasExpression]) {
              orderExpression = odr.asInstanceOf[AliasExpression].child
          }

          val childExpr = genQuery(parent, child, inClosure);
          var orderByParents : java.util.List[GroovyExpression] = GremlinExpressionFactory.INSTANCE.getOrderFieldParents();

          val translatedParents : java.util.List[GroovyExpression] = new ArrayList[GroovyExpression]();
          var translatedOrderParents = orderByParents.foreach { it =>
                 translatedParents.add(genQuery(it, orderExpression, true));
          }
          return GremlinExpressionFactory.INSTANCE.generateOrderByExpression(childExpr, translatedParents,asc);

        }
        case limitOffset@LimitExpression(child, limit, offset) => {
            val childExpr = genQuery(parent, child, inClosure);
            val totalResultRows = limit.value + offset.value;
            return GremlinExpressionFactory.INSTANCE.generateRangeExpression(childExpr, offset.value, totalResultRows);
        }
        case count@CountExpression() => {
          val listExpr = GremlinExpressionFactory.INSTANCE.getClosureArgumentValue();
          GremlinExpressionFactory.INSTANCE.generateCountExpression(listExpr);
        }
        case max@MaxExpression(child) => {
          //use "it" as the parent since the child will become
          //part of a closure.  Its value will be whatever vertex
          //we are looking at in the collection.
          val childExprParent = null;
          val childExpr = genQuery(childExprParent, child, true);
          val listExpr = GremlinExpressionFactory.INSTANCE.getClosureArgumentValue();
          GremlinExpressionFactory.INSTANCE.generateMaxExpression(listExpr, childExpr);
        }
        case min@MinExpression(child) => {
          //use "it" as the parent since the child will become
          //part of a closure.  Its value will be whatever vertex
          //we are looking at in the collection.
          val childExprParent = null;
          val childExpr = genQuery(childExprParent, child, true);
          val listExpr = GremlinExpressionFactory.INSTANCE.getClosureArgumentValue();
          GremlinExpressionFactory.INSTANCE.generateMinExpression(listExpr, childExpr);
        }
        case sum@SumExpression(child) => {
           //use "it" as the parent since the child will become
          //part of a closure.  Its value will be whatever vertex
          //we are looking at in the collection.
          val childExprParent = null;
          val childExpr = genQuery(childExprParent, child, true);
          val listExpr = GremlinExpressionFactory.INSTANCE.getClosureArgumentValue();
          GremlinExpressionFactory.INSTANCE.generateSumExpression(listExpr, childExpr);
        }
        case groupByExpr@GroupByExpression(child, groupBy, selExpr) => {
          //remove aliases
          val groupByExprListToTranslate = (groupBy.asInstanceOf[SelectExpression]).selectListWithAlias.map {
            x => x.child;
          }
          val grpByExprsList = translateList(groupByExprListToTranslate, true);
          val groupByValue = new ListExpression(grpByExprsList);

          //reduction only aggregate methods are supported here as of now.(Max, Min, Count)
          //remove aliases
          val srcExprListToTranslate = selExpr.selectListWithAlias.map {
            x => x.child;
          }
          val srcExprsList = translateList(srcExprListToTranslate, true, true);
          val srcExprsStringList = new ListExpression(srcExprsList)

          val childExpr = genQuery(parent, child, inClosure);
          return GremlinExpressionFactory.INSTANCE.generateGroupByExpression(childExpr, groupByValue, srcExprsStringList);
         }
        case x => throw new GremlinTranslationException(x, "expression not yet supported")
    }