public override void Visit(Table table) { if (this.IsNotInMainResultsSource()) { return; } if (_tableColumns.ContainsKey(table.Name)) { var tableResultInfoList = new ResultInfoList(); foreach (string tableColumnName in _tableColumns[table.Name]) { tableResultInfoList.Add( new ResultInfo(table.GetAliasOrTableName() , tableColumnName , new TableAndColumn(table, tableColumnName)) ); } ; _stack.Push(tableResultInfoList); } else { ; _stack.Push(new ResultInfoList()); } }
public override void Visit(Table table) { if (this.IsNotInMainResultsSource()) { return; } if (_tableColumns.ContainsKey(table.Name)) { var tableResultInfoList = new ResultInfoList(); foreach (string tableColumnName in _tableColumns[table.Name]) { tableResultInfoList.Add( new ResultInfo(table.GetAliasOrTableName() , tableColumnName , new TableAndColumn(table, tableColumnName)) ); } _cnfSet.Add(table); _stack.Push(tableResultInfoList); } else { _cnfSet.Add(table); _stack.Push(new ResultInfoList()); } // EXISTS句内で用いるテーブルへの一致条件はCNFに含めない if (_subQueryStack.Contains(SubQueryType.Exists)) { _cnfSet.AddExistsTable(table); } }
public sealed override void VisitAfter(SingleQueryClause query) { // ReadロックはReadするテーブル行をロックするのが目的なので、その行を抽出するための条件 // (EXISTS, IN, ..)で用いられるサブクエリ内のテーブル行はロックしない if (this.IsNotInMainResultsSource()) { return; } // // このQueryの列情報(ResultInfoList)を作成する // // 作成するこのQueryの列情報 var resultInfoList = new ResultInfoList(); // SELECT句サブクエリ var subQueries = new Stack <ResultInfoList>(); // FROM句の抽出元テーブル列 ResultInfoList sources; while (true) { ResultInfoList subQuery = _stack.Pop(); if (subQuery.IsSubQueryInResults) { subQueries.Push(subQuery); } else if (this.CurrentSubQueryIs(SubQueryType.Exists)) { // Existsサブクエリの場合はSELECT句情報を作成しない return; } else if (this.CurrentSubQueryIs(SubQueryType.OrderBy)) { // OrderByサブクエリの場合はSELECT句情報を作成しない return; } else { sources = subQuery; break; } } if (query.HasWildcard) { foreach (var source in sources) { resultInfoList.Add(new ResultInfo("", source.ColumnAliasName, null, source)); } _stack.Push(resultInfoList); return; } foreach (var resultColumn in query.Results) { if (resultColumn.IsTableWildcard) { var tableWildcard = (TableWildcard)resultColumn; foreach (var source in sources) { if (source.TableAliasName == tableWildcard.TableAliasName) { resultInfoList.Add(new ResultInfo("", source.ColumnAliasName, tableWildcard, source)); } } } else { var resultExpr = (ResultExpr)resultColumn; if (resultExpr.Value.GetType() == typeof(Column)) { // sourcesから参照元のResultInfoを見つける var column = (Column)resultExpr.Value; var columnAliasName = string.IsNullOrEmpty(resultExpr.AliasName) ? column.Name : resultExpr.AliasName; var foundInSources = false; foreach (var source in sources) { if (source.IsDirectSource(column, _ignoreCase)) { resultInfoList.Add(new ResultInfo("", columnAliasName, resultExpr, source)); foundInSources = true; break; } } // 参照元のResultInfoが見つからない場合(抽出元テーブルの列名が不明な場合等) // UNIONでResultInfoをマージするためSELECT句には必ずResultInfoを用意する if (!foundInSources) { resultInfoList.Add(new ResultInfo("", columnAliasName, resultExpr)); } } else if (resultExpr.Value.GetType() == typeof(SubQueryExp)) { var subQueryExp = (SubQueryExp)resultExpr.Value; var subQueryResultInfo = subQueries.Pop(); if (subQueryResultInfo.Count == 0) { resultInfoList.Add(new ResultInfo("", resultExpr.AliasName, resultExpr, null)); } else { resultInfoList.Add(new ResultInfo("", resultExpr.AliasName, resultExpr, subQueryResultInfo[0])); } } else { // UNIONでResultInfoをマージするためSELECT句には必ずResultInfoを用意する resultInfoList.Add(new ResultInfo("", resultExpr.AliasName, resultColumn)); } } // if } // for if (query.HasGroupBy) { // GROUP BY句がある場合は、そのGROUPBY句で指定されていないSELECT句は // 一致条件の被演算子に指定されてもテーブル列への一致条件とは見做さない for (var i = resultInfoList.Count - 1; i >= 0; --i) { if (!this.FindInGroupByItems(query.GroupBy, resultInfoList[i], i)) { resultInfoList[i] = new ResultInfo("" , resultInfoList[i].ColumnAliasName , resultInfoList[i].Node); } } } else { var aggregateFinder = new FindAggregateExprVisitor(); query.Results.Accept(aggregateFinder); if (aggregateFinder.ContainsAggregativeExpr) { // GROUP BY句がなく集約関数がある場合は、全てのSELECT句は // 一致条件の被演算子に指定されてもテーブル列への一致条件とは見做さない for (var i = resultInfoList.Count - 1; i >= 0; --i) { resultInfoList[i] = new ResultInfo("" , resultInfoList[i].ColumnAliasName , resultInfoList[i].Node); } } } // if _stack.Push(resultInfoList); }