public override WTableReference ToTableReference() { WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock(); foreach (var projectProperty in ProjectedProperties) { if (projectProperty == GremlinKeyword.TableDefaultColumnName) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(InputVariable.GetDefaultProjection().ToScalarExpression(), GremlinKeyword.TableDefaultColumnName)); } else if (InputVariable.ProjectedProperties.Contains(projectProperty)) { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr( InputVariable.GetVariableProperty(projectProperty).ToScalarExpression(), projectProperty)); } else { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), projectProperty)); } } WSelectQueryBlock secondQueryExpr = OptionalContext.ToSelectQueryBlock(); bool HasAggregateFunctionAsChildren = false; foreach (var variable in OptionalContext.TableReferences) { if (variable is GremlinFoldVariable || variable is GremlinCountVariable || variable is GremlinMinVariable || variable is GremlinMaxVariable || variable is GremlinSumVariable || variable is GremlinMeanVariable || variable is GremlinTreeVariable) { HasAggregateFunctionAsChildren = true; } var group = variable as GremlinGroupVariable; if (group != null && group.SideEffectKey == null) { HasAggregateFunctionAsChildren = true; } } var WBinaryQueryExpression = SqlUtil.GetBinaryQueryExpr(firstQueryExpr, secondQueryExpr); List <WScalarExpression> parameters = new List <WScalarExpression>(); parameters.Add(SqlUtil.GetScalarSubquery(WBinaryQueryExpression)); var tableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Optional, parameters, GetVariableName()); ((WOptionalTableReference)tableRef).HasAggregateFunctionAsChildren = HasAggregateFunctionAsChildren; return(SqlUtil.GetCrossApplyTableReference(tableRef)); }
public override WTableReference ToTableReference() { List <WSelectQueryBlock> selectQueryBlocks = new List <WSelectQueryBlock>(); selectQueryBlocks.Add(new WSelectQueryBlock()); selectQueryBlocks.Add(this.OptionalContext.ToSelectQueryBlock()); Dictionary <string, WSelectElement> projectionMap = new Dictionary <string, WSelectElement>(); WSelectElement value = selectQueryBlocks[1].SelectElements[0]; foreach (WSelectElement selectElement in selectQueryBlocks[1].SelectElements) { projectionMap[(selectElement as WSelectScalarExpression).ColumnName] = selectElement; } selectQueryBlocks[1].SelectElements.Clear(); selectQueryBlocks[0].SelectElements.Add(SqlUtil.GetSelectScalarExpr(this.InputVariable.DefaultProjection().ToScalarExpression(), this.DefaultProperty())); selectQueryBlocks[1].SelectElements.Add(SqlUtil.GetSelectScalarExpr((value as WSelectScalarExpression).SelectExpr, this.DefaultProperty())); foreach (string property in this.ProjectedProperties) { selectQueryBlocks[0].SelectElements.Add( SqlUtil.GetSelectScalarExpr( this.InputVariable.RealVariable.ProjectedProperties.Contains(property) ? this.InputVariable.RealVariable.GetVariableProperty(property).ToScalarExpression() : SqlUtil.GetValueExpr(null), property)); selectQueryBlocks[1].SelectElements.Add( projectionMap.TryGetValue(property, out value) ? value : SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), property)); } WBinaryQueryExpression binaryQueryExpression = SqlUtil.GetBinaryQueryExpr(selectQueryBlocks[0], selectQueryBlocks[1]); List <WScalarExpression> parameters = new List <WScalarExpression>(); parameters.Add(SqlUtil.GetScalarSubquery(binaryQueryExpression)); var tableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Optional, parameters, GetVariableName()); return(SqlUtil.GetCrossApplyTableReference(tableRef)); }
public override WTableReference ToTableReference() { WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock(); foreach (var projectProperty in ProjectedProperties) { if (projectProperty == GremlinKeyword.TableDefaultColumnName) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(InputVariable.DefaultProjection().ToScalarExpression(), GremlinKeyword.TableDefaultColumnName)); } else if (InputVariable.ProjectedProperties.Contains(projectProperty)) { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr( InputVariable.GetVariableProperty(projectProperty).ToScalarExpression(), projectProperty)); } else { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), projectProperty)); } } if (OptionalContext.IsPopulateGremlinPath) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), GremlinKeyword.Path)); } WSelectQueryBlock secondQueryExpr = OptionalContext.ToSelectQueryBlock(ProjectedProperties); var WBinaryQueryExpression = SqlUtil.GetBinaryQueryExpr(firstQueryExpr, secondQueryExpr); List <WScalarExpression> parameters = new List <WScalarExpression>(); parameters.Add(SqlUtil.GetScalarSubquery(WBinaryQueryExpression)); var tableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Optional, parameters, GetVariableName()); return(SqlUtil.GetCrossApplyTableReference(tableRef)); }
public override WTableReference ToTableReference() { Dictionary <GremlinVariableProperty, string> map = new Dictionary <GremlinVariableProperty, string>(); Dictionary <GremlinVariableProperty, string> map2 = new Dictionary <GremlinVariableProperty, string>(); Dictionary <GremlinVariableProperty, string> map3 = new Dictionary <GremlinVariableProperty, string>(); Dictionary <GremlinVariableProperty, string> map4 = new Dictionary <GremlinVariableProperty, string>(); WRepeatConditionExpression conditionExpr = GetRepeatConditionExpression(); List <WSelectScalarExpression> inputSelectList = GetInputSelectList(ref map); List <WSelectScalarExpression> outerSelectList = GetOuterSelectList(ref map); List <WSelectScalarExpression> terminateSelectList = GetConditionSelectList(ref map2); List <WSelectScalarExpression> repeatPathOuterList = GetRepeatPathOuterVariableList(ref map3); List <WSelectScalarExpression> conditionPathOuterList = GetConditionPathOuterVariableList(ref map4); WSelectQueryBlock selectQueryBlock = RepeatContext.ToSelectQueryBlock(); selectQueryBlock.SelectElements.Clear(); foreach (var selectElement in inputSelectList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in outerSelectList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in terminateSelectList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in repeatPathOuterList) { selectQueryBlock.SelectElements.Add(selectElement); } foreach (var selectElement in conditionPathOuterList) { selectQueryBlock.SelectElements.Add(selectElement); } WSelectQueryBlock firstQueryExpr = new WSelectQueryBlock(); foreach (var item in map) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(item.Key.ToScalarExpression(), item.Value)); } foreach (var item in map2) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), item.Value)); } foreach (var item in map3) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(item.Key.ToScalarExpression(), item.Value)); } foreach (var item in map4) { firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(item.Key.ToScalarExpression(), item.Value)); } //firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(FirstVariable.DefaultProjection().ToScalarExpression(), GremlinKeyword.TableDefaultColumnName)); //selectQueryBlock.SelectElements.Add(SqlUtil.GetSelectScalarExpr(RepeatContext.PivotVariable.DefaultProjection().ToScalarExpression(), GremlinKeyword.TableDefaultColumnName)); foreach (var property in ProjectedProperties) { if (InputVariable.ProjectedProperties.Contains(property)) { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr( InputVariable.GetVariableProperty(property).ToScalarExpression(), property)); } else { firstQueryExpr.SelectElements.Add( SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), property)); } if (RepeatContext.PivotVariable.ProjectedProperties.Contains(property)) { selectQueryBlock.SelectElements.Add( SqlUtil.GetSelectScalarExpr( RepeatContext.PivotVariable.GetVariableProperty(property).ToScalarExpression(), property)); } else { selectQueryBlock.SelectElements.Add( SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), property)); } } if (SelectedVariableList.Count != 0) { foreach (var selectedVariableTuple in SelectedVariableList) { var columnName = selectedVariableTuple.Item1; var selectedVariable = selectedVariableTuple.Item2; firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), columnName)); List <WScalarExpression> compose2Paramters = new List <WScalarExpression>(); compose2Paramters.Add(selectedVariable.RealVariable.ToCompose1()); compose2Paramters.Add(SqlUtil.GetColumnReferenceExpr("R", columnName)); WFunctionCall compose2 = SqlUtil.GetFunctionCall(GremlinKeyword.func.Compose2, compose2Paramters); selectQueryBlock.SelectElements.Add(SqlUtil.GetSelectScalarExpr(compose2, columnName)); } } if (RepeatContext.IsPopulateGremlinPath) { var columnName = GremlinKeyword.Path; var pathVariable = RepeatContext.CurrentContextPath; firstQueryExpr.SelectElements.Add(SqlUtil.GetSelectScalarExpr(SqlUtil.GetValueExpr(null), columnName)); selectQueryBlock.SelectElements.Add(SqlUtil.GetSelectScalarExpr(pathVariable.DefaultProjection().ToScalarExpression(), columnName)); } var WBinaryQueryExpression = SqlUtil.GetBinaryQueryExpr(firstQueryExpr, selectQueryBlock); ModifyColumnNameVisitor newVisitor = new ModifyColumnNameVisitor(); newVisitor.Invoke(selectQueryBlock, map); newVisitor.Invoke(conditionExpr, map2); newVisitor.Invoke(selectQueryBlock, map3); newVisitor.Invoke(conditionExpr, map4); List <WScalarExpression> repeatParameters = new List <WScalarExpression>(); repeatParameters.Add(SqlUtil.GetScalarSubquery(WBinaryQueryExpression)); repeatParameters.Add(conditionExpr); var secondTableRef = SqlUtil.GetFunctionTableReference(GremlinKeyword.func.Repeat, repeatParameters, this, GetVariableName()); return(SqlUtil.GetCrossApplyTableReference(null, secondTableRef)); }
// 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)); }
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)); }