示例#1
0
        internal void DropEdge(GremlinVariable dropEdgeVariable)
        {
            var sourceProperty = dropEdgeVariable.GetVariableProperty(GremlinKeyword.EdgeSourceV);
            var edgeProperty   = dropEdgeVariable.GetVariableProperty(GremlinKeyword.EdgeID);
            GremlinDropVariable dropVariable = new GremlinDropEdgeVariable(sourceProperty, edgeProperty);

            VariableList.Add(dropVariable);
            TableReferences.Add(dropVariable);
            SetPivotVariable(dropVariable);
        }
示例#2
0
        internal void BothV(GremlinVariable lastVariable)
        {
            GremlinVariableProperty    sourceProperty = lastVariable.GetVariableProperty(GremlinKeyword.EdgeSourceV);
            GremlinVariableProperty    sinkProperty   = lastVariable.GetVariableProperty(GremlinKeyword.EdgeSinkV);
            GremlinBoundVertexVariable bothVertex     = new GremlinBoundVertexVariable(lastVariable.GetEdgeType(), sourceProperty, sinkProperty);

            VariableList.Add(bothVertex);
            TableReferences.Add(bothVertex);
            SetPivotVariable(bothVertex);
        }
示例#3
0
        internal void OutE(GremlinVariable lastVariable, List <string> edgeLabels)
        {
            GremlinVariableProperty       sourceProperty = lastVariable.GetVariableProperty(GremlinKeyword.NodeID);
            GremlinVariableProperty       adjEdge        = lastVariable.GetVariableProperty(GremlinKeyword.EdgeAdj);
            GremlinVariableProperty       labelProperty  = lastVariable.GetVariableProperty(GremlinKeyword.Label);
            GremlinBoundEdgeTableVariable outEdgeTable   = new GremlinBoundEdgeTableVariable(sourceProperty, adjEdge, labelProperty, WEdgeType.OutEdge);

            VariableList.Add(outEdgeTable);
            TableReferences.Add(outEdgeTable);
            AddLabelPredicateForEdge(outEdgeTable, edgeLabels);

            AddPath(new GremlinMatchPath(lastVariable, outEdgeTable, null));
            SetPivotVariable(outEdgeTable);
        }
示例#4
0
        internal void BothE(GremlinVariable lastVariable, List <string> edgeLabels)
        {
            GremlinVariableProperty       sourceProperty = lastVariable.GetVariableProperty(GremlinKeyword.NodeID);
            GremlinVariableProperty       adjReverseEdge = lastVariable.GetVariableProperty(GremlinKeyword.ReverseEdgeAdj);
            GremlinVariableProperty       adjEdge        = lastVariable.GetVariableProperty(GremlinKeyword.EdgeAdj);
            GremlinVariableProperty       labelProperty  = lastVariable.GetVariableProperty(GremlinKeyword.Label);
            GremlinBoundEdgeTableVariable bothEdgeTable  = new GremlinBoundEdgeTableVariable(sourceProperty, adjEdge, adjReverseEdge, labelProperty,
                                                                                             WEdgeType.BothEdge);

            VariableList.Add(bothEdgeTable);
            TableReferences.Add(bothEdgeTable);
            AddLabelPredicateForEdge(bothEdgeTable, edgeLabels);

            SetPivotVariable(bothEdgeTable);
        }
示例#5
0
        internal void HasId(GremlinVariable lastVariable, Predicate predicate)
        {
            WScalarExpression firstExpr  = lastVariable.GetVariableProperty(lastVariable.GetPrimaryKey()).ToScalarExpression();
            WScalarExpression secondExpr = SqlUtil.GetValueExpr(predicate.Value);

            AddPredicate(SqlUtil.GetBooleanComparisonExpr(firstExpr, secondExpr, BooleanComparisonType.Equals));
        }
示例#6
0
        internal void Has(GremlinVariable lastVariable, string propertyKey, Predicate predicate)
        {
            WScalarExpression firstExpr  = lastVariable.GetVariableProperty(propertyKey).ToScalarExpression();
            WScalarExpression secondExpr = SqlUtil.GetValueExpr(predicate.Value);

            AddPredicate(SqlUtil.GetBooleanComparisonExpr(firstExpr, secondExpr, predicate));
        }
示例#7
0
        internal void DropVertex(GremlinVariable dropVertexVariable)
        {
            GremlinVariableProperty variableProperty = dropVertexVariable.GetVariableProperty(GremlinKeyword.NodeID);
            GremlinDropVariable     dropVariable     = new GremlinDropVertexVariable(variableProperty);

            VariableList.Add(dropVariable);
            TableReferences.Add(dropVariable);
            SetPivotVariable(dropVariable);
        }
示例#8
0
        internal void OutV(GremlinVariable lastVariable)
        {
            if (lastVariable is GremlinFreeEdgeTableVariable)
            {
                var path = GetPathFromPathList(lastVariable);

                if (path != null && path.SourceVariable != null)
                {
                    if (IsVariableInCurrentContext(path.SourceVariable))
                    {
                        SetPivotVariable(path.SourceVariable);
                    }
                    else
                    {
                        GremlinContextVariable newContextVariable = GremlinContextVariable.Create(path.SourceVariable);
                        VariableList.Add(newContextVariable);
                        SetPivotVariable(newContextVariable);
                    }
                }
                else
                {
                    GremlinVariableProperty sourceProperty = lastVariable.GetVariableProperty(GremlinKeyword.EdgeSourceV);
                    GremlinTableVariable    outVertex      = lastVariable.CreateAdjVertex(sourceProperty);
                    if (path != null)
                    {
                        path.SetSourceVariable(outVertex);
                    }

                    VariableList.Add(outVertex);
                    TableReferences.Add(outVertex);
                    SetPivotVariable(outVertex);
                }
            }
            else
            {
                GremlinVariableProperty sourceProperty = lastVariable.GetVariableProperty(GremlinKeyword.EdgeSourceV);
                GremlinTableVariable    outVertex      = new GremlinBoundVertexVariable(lastVariable.GetEdgeType(), sourceProperty);
                VariableList.Add(outVertex);
                TableReferences.Add(outVertex);
                SetPivotVariable(outVertex);
            }
        }
示例#9
0
        internal void In(GremlinVariable lastVariable, List <string> edgeLabels)
        {
            GremlinVariableProperty       sourceProperty = lastVariable.GetVariableProperty(GremlinKeyword.NodeID);
            GremlinVariableProperty       adjReverseEdge = lastVariable.GetVariableProperty(GremlinKeyword.ReverseEdgeAdj);
            GremlinVariableProperty       labelProperty  = lastVariable.GetVariableProperty(GremlinKeyword.Label);
            GremlinBoundEdgeTableVariable inEdgeTable    = new GremlinBoundEdgeTableVariable(sourceProperty, adjReverseEdge,
                                                                                             labelProperty, WEdgeType.InEdge);

            VariableList.Add(inEdgeTable);
            TableReferences.Add(inEdgeTable);
            AddLabelPredicateForEdge(inEdgeTable, edgeLabels);

            GremlinVariableProperty    edgeProperty = inEdgeTable.GetVariableProperty(GremlinKeyword.EdgeSourceV);
            GremlinBoundVertexVariable outVertex    = new GremlinBoundVertexVariable(inEdgeTable.GetEdgeType(), edgeProperty);

            VariableList.Add(outVertex);
            TableReferences.Add(outVertex);

            AddPath(new GremlinMatchPath(outVertex, inEdgeTable, lastVariable));

            SetPivotVariable(outVertex);
        }
示例#10
0
        internal void HasLabel(GremlinVariable lastVariable, List <object> values)
        {
            List <WBooleanExpression> booleanExprList = new List <WBooleanExpression>();

            foreach (var value in values)
            {
                WScalarExpression firstExpr  = lastVariable.GetVariableProperty(GremlinKeyword.Label).ToScalarExpression();
                WScalarExpression secondExpr = SqlUtil.GetValueExpr(value);
                booleanExprList.Add(SqlUtil.GetEqualBooleanComparisonExpr(firstExpr, secondExpr));
            }
            WBooleanExpression concatSql = SqlUtil.ConcatBooleanExprWithOr(booleanExprList);

            AddPredicate(SqlUtil.GetBooleanParenthesisExpr(concatSql));
        }
示例#11
0
        public List <WSelectScalarExpression> GetOuterSelectList(ref Dictionary <GremlinVariableProperty, string> map)
        {
            List <WSelectScalarExpression> outerSelectList = new List <WSelectScalarExpression>();
            var allVariablesInRepeatContext = RepeatContext.FetchVarsFromCurrAndChildContext();

            foreach (var variable in allVariablesInRepeatContext)
            {
                if (variable is GremlinSelectedVariable)
                {
                    var repeatInnerVar = (variable as GremlinSelectedVariable);
                    if (repeatInnerVar.IsFromSelect &&
                        !allVariablesInRepeatContext.Contains(repeatInnerVar.RealVariable))
                    {
                        List <GremlinVariable> outerVarList = RepeatContext.Select(repeatInnerVar.SelectKey);
                        GremlinVariable        outerVar     = null;
                        switch (repeatInnerVar.Pop)
                        {
                        case GremlinKeyword.Pop.last:
                            outerVar = outerVarList.Last();
                            break;

                        case GremlinKeyword.Pop.first:
                            outerVar = outerVarList.First();
                            break;
                        }
                        if (repeatInnerVar != outerVar)
                        {
                            foreach (var property in repeatInnerVar.ProjectedProperties)
                            {
                                var aliasName = GenerateKey();
                                outerSelectList.Add(
                                    SqlUtil.GetSelectScalarExpr(
                                        outerVar.GetVariableProperty(property).ToScalarExpression(), aliasName));
                                map[repeatInnerVar.GetVariableProperty(property)] = aliasName;
                            }
                        }
                    }
                }
            }
            return(outerSelectList);
        }
示例#12
0
        internal void OtherV(GremlinVariable lastVariable)
        {
            switch (lastVariable.GetEdgeType())
            {
            case WEdgeType.Undefined:
            case WEdgeType.BothEdge:
                GremlinVariableProperty    otherProperty = lastVariable.GetVariableProperty(GremlinKeyword.EdgeOtherV);
                GremlinBoundVertexVariable otherVertex   = new GremlinBoundVertexVariable(lastVariable.GetEdgeType(), otherProperty);
                VariableList.Add(otherVertex);
                TableReferences.Add(otherVertex);
                SetPivotVariable(otherVertex);
                break;

            case WEdgeType.InEdge:
                OutV(lastVariable);
                break;

            case WEdgeType.OutEdge:
                InV(lastVariable);
                break;
            }
        }
示例#13
0
        // Repeat algorithm
        // Firstly, we generate the repeatQueryBlock in order that we can get the initial query
        // Secondly, we generate the inputVariableVistorMap via repeatInputVariable.ProjectedProperties,
        // untilInputVariable.ProjectedProperties, emitInputVariable.ProjectedProperties and ProjectedProperties.
        // Generally, these properties are related to the input every time, but in repeatQueryBlock, these are
        // just related to the input of the first time. Therefore, we need to replace these after.
        // Thirdly, we need to generate the firstQueryExpr and the selectColumnExpr of repeatQueryBlock. Pay
        // attention, we need to repeatQueryBlock again because we need more properties about the output of
        // the last step in repeat-step. These properties are populated in the second step.
        // Fourthly, we use the inputVariableVistorMap to replace the columns in the repeatQueryBlock. But we
        // should not change the columns in path-step. Because if we generate the path in the repeat-step, the
        // path consists of
        //  1. the previous steps before the repeat-step
        //  2. the local path(_path) in the repeat-step
        // Keep in mind that the initial _path is null, the _path includes all steps as long as they are in
        // the repeat-step except for the first input. And the _path after the first pass includes the last step
        // in the repeat-step. So the path must include the two part. That means all columns in path-step should
        // not be replaced. Here, we use the ModifyRepeatInputVariablesVisitor to finish this work. If it visits
        // WPathTableReference, it does nothing, otherwise, it will replace the columns according to the
        // inputVariableVistorMap.
        public override WTableReference ToTableReference()
        {
            //The following two variables are used for manually creating SelectScalarExpression of repeat
            List <WSelectScalarExpression> firstSelectList = new List <WSelectScalarExpression>();
            List <WSelectScalarExpression> secondSelectList = new List <WSelectScalarExpression>();
            WScalarExpression firstSelectColumn, secondSelectColumn, firstExpr, secondExpr;

            // The following map is used to replace columns of the first input to columns of the repeat input
            // such as N_0.id -> R.key_0
            string aliasName;
            Tuple <string, string> key, value;
            Dictionary <Tuple <string, string>, Tuple <string, string> > inputVariableVistorMap =
                new Dictionary <Tuple <string, string>, Tuple <string, string> >();

            // We should generate the syntax tree firstly
            // Some variables will populate ProjectProperty only when we call the ToTableReference function where they appear.
            WRepeatConditionExpression repeatConditionExpr = this.GetRepeatConditionExpression();
            WSelectQueryBlock          repeatQueryBlock    = this.RepeatContext.ToSelectQueryBlock();

            GremlinVariable repeatInputVariable  = this.RepeatContext.VariableList.First();
            GremlinVariable repeatOutputVariable = this.RepeatContext.PivotVariable;
            GremlinVariable realInputVariable    = this.InputVariable.RealVariable;
            GremlinVariable repeatPivotVariable  = this.RepeatContext.PivotVariable;

            // this.DefaultProperty
            key   = new Tuple <string, string>(this.GetVariableName(), this.DefaultProperty());
            value = key;
            inputVariableVistorMap[key] = value;

            key   = new Tuple <string, string>(realInputVariable.GetVariableName(), realInputVariable.DefaultProperty());
            value = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, this.DefaultProperty());
            inputVariableVistorMap[key] = value;

            firstExpr  = realInputVariable.DefaultProjection().ToScalarExpression();
            secondExpr = repeatOutputVariable.DefaultProjection().ToScalarExpression();
            firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstExpr, this.DefaultProperty()));
            secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondExpr, this.DefaultProperty()));

            foreach (string property in this.ProjectedProperties)
            {
                if (property == GremlinKeyword.Path)
                {
                    firstSelectList.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), GremlinKeyword.Path));
                    secondSelectList.Add(
                        SqlUtil.GetSelectScalarExpr(
                            this.RepeatContext.ContextLocalPath.DefaultProjection().ToScalarExpression(),
                            GremlinKeyword.Path));
                }
                else
                {
                    key   = new Tuple <string, string>(this.GetVariableName(), property);
                    value = key;
                    inputVariableVistorMap[key] = value;

                    key   = new Tuple <string, string>(realInputVariable.GetVariableName(), property);
                    value = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, property);
                    inputVariableVistorMap[key] = value;

                    firstExpr = realInputVariable.ProjectedProperties.Contains(property)
                        ? realInputVariable.GetVariableProperty(property).ToScalarExpression()
                        : SqlUtil.GetValueExpr(null);
                    secondExpr = repeatOutputVariable.ProjectedProperties.Contains(property)
                        ? this.RepeatContext.PivotVariable.GetVariableProperty(property).ToScalarExpression()
                        : SqlUtil.GetValueExpr(null);

                    firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstExpr, property));
                    secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondExpr, property));
                }
            }

            // repeatInputVariable.DefaultProperty()
            key = new Tuple <string, string>(repeatInputVariable.GetVariableName(), repeatInputVariable.DefaultProperty());
            if (!inputVariableVistorMap.Keys.Contains(key))
            {
                aliasName = this.GenerateKey();
                value     = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, aliasName);
                inputVariableVistorMap[key] = value;

                firstSelectColumn  = repeatInputVariable.DefaultProjection().ToScalarExpression() as WColumnReferenceExpression;
                secondSelectColumn = repeatPivotVariable.DefaultProjection().ToScalarExpression() as WColumnReferenceExpression;
                firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
            }
            foreach (string property in repeatInputVariable.ProjectedProperties)
            {
                key = new Tuple <string, string>(repeatInputVariable.GetVariableName(), property);
                if (!inputVariableVistorMap.Keys.Contains(key))
                {
                    aliasName = this.GenerateKey();
                    value     = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, aliasName);
                    inputVariableVistorMap[key] = value;

                    firstSelectColumn  = repeatInputVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                    secondSelectColumn = repeatPivotVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                    firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                    secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
                }
            }

            if (this.RepeatCondition.TerminationContext != null && this.RepeatCondition.TerminationContext.VariableList.Count > 0)
            {
                GremlinVariable untilInputVariable = this.RepeatCondition.TerminationContext.VariableList.First();

                // untilInputVariable.DefaultProperty()
                key = new Tuple <string, string>(untilInputVariable.GetVariableName(), untilInputVariable.DefaultProperty());
                if (!inputVariableVistorMap.Keys.Contains(key))
                {
                    aliasName = this.GenerateKey();
                    value     = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, aliasName);
                    inputVariableVistorMap[key] = value;

                    firstSelectColumn =
                        untilInputVariable.DefaultProjection().ToScalarExpression() as WColumnReferenceExpression;
                    secondSelectColumn =
                        repeatPivotVariable.DefaultProjection().ToScalarExpression() as WColumnReferenceExpression;
                    firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                    secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
                }

                foreach (string property in untilInputVariable.ProjectedProperties)
                {
                    key = new Tuple <string, string>(untilInputVariable.GetVariableName(), property);
                    if (!inputVariableVistorMap.Keys.Contains(key))
                    {
                        aliasName = this.GenerateKey();
                        value     = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, aliasName);
                        inputVariableVistorMap[key] = value;

                        firstSelectColumn  = untilInputVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                        secondSelectColumn = repeatPivotVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                        firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                        secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
                    }
                }
            }

            if (this.RepeatCondition.EmitContext != null && this.RepeatCondition.EmitContext.VariableList.Count > 0)
            {
                GremlinVariable emitInputVariable = this.RepeatCondition.EmitContext.VariableList.First();

                // emitInputVariable.DefaultProperty()
                key = new Tuple <string, string>(emitInputVariable.GetVariableName(), emitInputVariable.DefaultProperty());
                if (!inputVariableVistorMap.Keys.Contains(key))
                {
                    aliasName = this.GenerateKey();
                    value     = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, aliasName);
                    inputVariableVistorMap[key] = value;

                    firstSelectColumn =
                        emitInputVariable.DefaultProjection().ToScalarExpression() as WColumnReferenceExpression;
                    secondSelectColumn =
                        repeatPivotVariable.DefaultProjection().ToScalarExpression() as WColumnReferenceExpression;
                    firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                    secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
                }

                foreach (string property in emitInputVariable.ProjectedProperties)
                {
                    key = new Tuple <string, string>(emitInputVariable.GetVariableName(), property);
                    if (!inputVariableVistorMap.Keys.Contains(key))
                    {
                        aliasName = this.GenerateKey();
                        value     = new Tuple <string, string>(GremlinKeyword.RepeatInitalTableName, aliasName);
                        inputVariableVistorMap[key] = value;

                        firstSelectColumn =
                            emitInputVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                        secondSelectColumn =
                            repeatPivotVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                        firstSelectList.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                        secondSelectList.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
                    }
                }
            }

            WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock();

            foreach (WSelectScalarExpression selectColumnExpr in firstSelectList)
            {
                firstQueryExpr.SelectElements.Add(selectColumnExpr);
            }

            repeatQueryBlock = this.RepeatContext.ToSelectQueryBlock();
            repeatQueryBlock.SelectElements.Clear();
            foreach (WSelectScalarExpression selectColumnExpr in secondSelectList)
            {
                repeatQueryBlock.SelectElements.Add(selectColumnExpr);
            }

            //Then we will use the inputVariableVistorMap to replace ColumnRefernceExpression in the syntax tree
            //which matchs n_0.id to R_0.key_0 except for WPathTableReference
            new ModifyRepeatInputVariablesVisitor().Invoke(repeatQueryBlock, inputVariableVistorMap);
            new ModifyRepeatInputVariablesVisitor().Invoke(repeatConditionExpr, inputVariableVistorMap);

            List <WScalarExpression> repeatParameters = new List <WScalarExpression>()
            {
                SqlUtil.GetScalarSubquery(SqlUtil.GetBinaryQueryExpr(firstQueryExpr, repeatQueryBlock)),
                repeatConditionExpr
            };
            WSchemaObjectFunctionTableReference tableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Repeat, repeatParameters, this.GetVariableName());

            return(SqlUtil.GetCrossApplyTableReference(tableRef));
        }
示例#14
0
        public override WTableReference ToTableReference()
        {
            if (RepeatContext.ContextLocalPath != null)
            {
                RepeatContext.ContextLocalPath.PathList.Insert(0, null);
                RepeatContext.ContextLocalPath.IsInRepeatContext = true;
            }

            //The following two variables are used for manually creating SelectScalarExpression of repeat
            List <WSelectScalarExpression> repeatFirstSelect  = new List <WSelectScalarExpression>();
            List <WSelectScalarExpression> repeatSecondSelect = new List <WSelectScalarExpression>();

            // The following two variables are used for Generating a Map
            // such as N_0.id -> key_0
            // Then we will use this map to replace ColumnRefernceExpression in the syntax tree which matchs n_0.id to R_0.key_0
            Dictionary <WColumnReferenceExpression, string> repeatVistorMap    = new Dictionary <WColumnReferenceExpression, string>();
            Dictionary <WColumnReferenceExpression, string> conditionVistorMap = new Dictionary <WColumnReferenceExpression, string>();

            //We should generate the syntax tree firstly
            //Some variables will populate ProjectProperty only when we call the ToTableReference function where they appear.
            WRepeatConditionExpression repeatConditionExpr = GetRepeatConditionExpression();
            WSelectQueryBlock          repeatQueryBlock    = RepeatContext.ToSelectQueryBlock();

            // TODO: explain this step in detail
            var repeatNewToOldSelectedVarMap = GetNewToOldSelectedVarMap(RepeatContext);

            if (!repeatNewToOldSelectedVarMap.ContainsKey(RepeatContext.PivotVariable))
            {
                repeatNewToOldSelectedVarMap[RepeatContext.PivotVariable] = RepeatContext.VariableList.First();
            }
            foreach (var pair in repeatNewToOldSelectedVarMap)
            {
                GremlinVariable newVariable = pair.Key;
                GremlinVariable oldVariable = pair.Value;
                foreach (var property in pair.Value.ProjectedProperties)
                {
                    var aliasName          = GenerateKey();
                    var firstSelectColumn  = oldVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;
                    var secondSelectColumn = newVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;

                    repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                    repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));
                    repeatVistorMap[firstSelectColumn.Copy()] = aliasName;
                }
            }

            if (RepeatCondition.TerminationContext != null && RepeatCondition.TerminationContext.VariableList.Count > 0)
            {
                var terminatedNewToOldSelectedVarMap = GetNewToOldSelectedVarMap(RepeatCondition.TerminationContext);
                if (!terminatedNewToOldSelectedVarMap.ContainsKey(RepeatContext.PivotVariable))
                {
                    terminatedNewToOldSelectedVarMap[RepeatContext.PivotVariable] = RepeatCondition.TerminationContext.VariableList.First();
                }
                foreach (var pair in terminatedNewToOldSelectedVarMap)
                {
                    GremlinVariable newVariable = pair.Key;
                    GremlinVariable oldVariable = pair.Value;
                    foreach (var property in oldVariable.ProjectedProperties)
                    {
                        var aliasName         = GenerateKey();
                        var firstSelectColumn = RepeatCondition.StartFromContext
                            ? oldVariable.GetVariableProperty(property).ToScalarExpression()
                            : SqlUtil.GetValueExpr(null);
                        var secondSelectColumn = newVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;

                        repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                        repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));

                        if (RepeatCondition.StartFromContext)
                        {
                            conditionVistorMap[(firstSelectColumn as WColumnReferenceExpression).Copy()] = aliasName;
                        }
                        else
                        {
                            conditionVistorMap[secondSelectColumn.Copy()] = aliasName;
                        }
                    }
                }
            }

            if (RepeatCondition.EmitContext != null && RepeatCondition.EmitContext.VariableList.Count > 0)
            {
                var terminatedNewToOldSelectedVarMap = GetNewToOldSelectedVarMap(RepeatCondition.EmitContext);
                if (!terminatedNewToOldSelectedVarMap.ContainsKey(RepeatContext.PivotVariable))
                {
                    terminatedNewToOldSelectedVarMap[RepeatContext.PivotVariable] = RepeatCondition.EmitContext.VariableList.First();
                }
                foreach (var pair in terminatedNewToOldSelectedVarMap)
                {
                    GremlinVariable newVariable = pair.Key;
                    GremlinVariable oldVariable = pair.Value;
                    foreach (var property in pair.Value.ProjectedProperties)
                    {
                        var aliasName         = GenerateKey();
                        var firstSelectColumn = RepeatCondition.IsEmitContext
                            ? oldVariable.GetVariableProperty(property).ToScalarExpression()
                            : SqlUtil.GetValueExpr(null);
                        var secondSelectColumn = newVariable.GetVariableProperty(property).ToScalarExpression() as WColumnReferenceExpression;

                        repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstSelectColumn, aliasName));
                        repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondSelectColumn, aliasName));

                        if (RepeatCondition.IsEmitContext)
                        {
                            conditionVistorMap[(firstSelectColumn as WColumnReferenceExpression).Copy()] = aliasName;
                        }
                        else
                        {
                            conditionVistorMap[secondSelectColumn.Copy()] = aliasName;
                        }
                    }
                }
            }

            foreach (var property in ProjectedProperties)
            {
                if (property == GremlinKeyword.Path)
                {
                    repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), GremlinKeyword.Path));
                    repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(RepeatContext.ContextLocalPath.GetDefaultProjection().ToScalarExpression(), GremlinKeyword.Path));
                    continue;
                }
                WScalarExpression firstExpr = InputVariable.ProjectedProperties.Contains(property)
                    ? InputVariable.GetVariableProperty(property).ToScalarExpression()
                    : SqlUtil.GetValueExpr(null);

                WScalarExpression secondExpr = RepeatContext.PivotVariable.ProjectedProperties.Contains(property)
                    ? RepeatContext.PivotVariable.GetVariableProperty(property).ToScalarExpression()
                    : SqlUtil.GetValueExpr(null);

                repeatFirstSelect.Add(SqlUtil.GetSelectScalarExpr(firstExpr, property));
                repeatSecondSelect.Add(SqlUtil.GetSelectScalarExpr(secondExpr, property));
            }

            WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock();

            foreach (var selectColumnExpr in repeatFirstSelect)
            {
                firstQueryExpr.SelectElements.Add(selectColumnExpr);
            }

            repeatQueryBlock = RepeatContext.ToSelectQueryBlock();
            repeatQueryBlock.SelectElements.Clear();
            foreach (var selectColumnExpr in repeatSecondSelect)
            {
                repeatQueryBlock.SelectElements.Add(selectColumnExpr);
            }

            //Replace N_0.id -> R_0.key_0, when N_0 is a outer variable
            new ModifyColumnNameVisitor().Invoke(repeatQueryBlock, repeatVistorMap);
            new ModifyColumnNameVisitor().Invoke(repeatConditionExpr, conditionVistorMap);

            List <WScalarExpression> repeatParameters = new List <WScalarExpression>()
            {
                SqlUtil.GetScalarSubquery(SqlUtil.GetBinaryQueryExpr(firstQueryExpr, repeatQueryBlock)),
                repeatConditionExpr
            };
            var tableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Repeat, repeatParameters, GetVariableName());

            return(SqlUtil.GetCrossApplyTableReference(tableRef));
        }