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()); } }
internal CountQueryResultInfo(string tableAliasName , string columnAliasName , KeyType keyType , bool explicitDecl , bool isComplemented , SqlTable sourceTable , string SourceColumnName , ResultColumn node , ResultInfoList sourceInfoList , int sourceInfoListIndex) { this.TableAliasName = tableAliasName; this.ColumnAliasName = columnAliasName; this.KeyType = keyType; this.ExplicitDecl = explicitDecl; this.IsComplemented = isComplemented; this.SourceTable = sourceTable; this.SourceColumnName = SourceColumnName; this.Node = node; this.SourceInfoList = sourceInfoList; this.SourceInfoListIndex = sourceInfoListIndex; if (sourceInfoList != null && sourceInfoListIndex >= 0) { this.SourceInfo = sourceInfoList[sourceInfoListIndex]; } }
//public SqlPredicate ConvertToExistsExpr(SqlTable correlatedTable // , IEnumerable<Tuple<string, bool>> tableColumnNames) { // if(this.GetStatementType() != StatementType.Select) { // throw new NotSupportedException("相関サブクエリに変形できるのはSELECT文のみです"); // } // // 相関サブクエリにそのテーブル別名が存在しない場合、 // // また、存在した場合でもそのテーブル別名の実テーブル名が、 // // 被相関クエリの実テーブル名に一致しない場合、処理を中断する // string correlatedTableName = null; // foreach(var table in this.GetSrcTables()) { // if(table.AliasName == correlatedTable.AliasName) { // correlatedTableName = table.Name; // break; // } // } // if(string.IsNullOrEmpty(correlatedTableName)) { // throw new ArgumentException( // "相関対象テーブル別名が相関クエリに存在しません", "correlatedTableAliasName"); // } // // (0) 相関クエリのSELECT句を定数値に変更する // this.SetConstant(); // // (1) 相関クエリのOrderBy句を削除する // this.ClearOrderBy(); // // (2) 相関クエリのメインクエリスコープに、相関対象テーブル名(又はテーブル別名)と // // 同じテーブル名(又はテーブル別名)が存在する場合は、相関クエリのテーブル別名を変更する // var tableAliasNameSub = correlatedTable.AliasName + "_"; // this.RenameTableAliasName(correlatedTable.AliasName, tableAliasNameSub); // // (3) 相関クエリのSELECT句リストを取得する // // それと同時に相関対象テーブルの主キーを相関クエリのメインスコープに引き上げる // var resultInfoList = this.GetResultInfoList(correlatedTableName // , tableColumnNames // , ResultInfoAST.PrimaryKeyCompletion.SubQueryOnly); // // (4) 相関クエリのSELECT句リストから、結合条件を作成し付加する // var queryClause = (IQueryClause)((SelectStmt)this.GetStmt()).Query; // this.AddCorrelatedConditions(queryClause, resultInfoList, null, tableAliasNameSub, correlatedTable.ExplicitAliasName); // // (5) Existsで囲んで返す // var query = ((SelectStmt)this.GetStmt()).Query; // return new SqlPredicate(new ExistsPredicate(query)); //} private void AddCorrelatedConditions(IQueryClause subQueryClause , ResultInfoList subResultInfoList , string oldTableAliasNameOfSub , string correlatedTableAliasName) { foreach (var subResultInfo in subResultInfoList) { // キーのみを結合条件にする if (subResultInfo.KeyType == KeyType.None) { continue; } if (subResultInfo.Type == ResultInfoType.Query) { var subQueryInfo = (QueryResultInfo)subResultInfo; if (oldTableAliasNameOfSub == subQueryInfo.SourceTable.AliasName) { var tableAliasNameOfSub = this.GetSourceInfoOfSingleQueryResultInfo(subResultInfo).TableAliasName; this.AddCorrelatedCondition(subQueryClause , subResultInfo , tableAliasNameOfSub , null , correlatedTableAliasName); } } else if (subResultInfo.Type == ResultInfoType.Compound) { } } }
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); } }
private bool GetSourcesOf(Column column, ResultInfoList resultInfoList) { foreach (var resultInfo in resultInfoList) { if (resultInfo.IsDirectSource(column, _ignoreCase)) { return(true); } } return(false); }
private List <TableAndColumn> GetSourcesOf(Column column, ResultInfoList resultInfoList) { foreach (var resultInfo in resultInfoList) { if (resultInfo.IsDirectSource(column, _ignoreCase)) { return(resultInfo.Sources); } } return(null); }
// 結合条件を作成し付加する private void AddCorrelatedConditions(IQueryClause subQueryClause , ResultInfoList subResultInfoList , ResultInfoList mainResultInfoList , string tableAliasNameOfMain , string correlatedTableAliasName) { foreach (var subResultInfo in subResultInfoList) { // キーのみを結合条件にする if (subResultInfo.KeyType == KeyType.None) { continue; } foreach (var mainResultInfo in mainResultInfoList) { // キーのみを結合条件にする if (mainResultInfo.KeyType == KeyType.None) { continue; } if (correlatedTableAliasName == mainResultInfo.SourceTable.AliasName && subResultInfo.SourceColumnName == mainResultInfo.SourceColumnName) { // 相関クエリのメインクエリスコープに、相関対象テーブル名(又はテーブル別名)を // 抽出元にもつSELECT句があればそのSELECT句のテーブル別名を取得する var tableAliasNameOfSub = this.GetSourceInfoOfSingleQueryResultInfo(subResultInfo).TableAliasName; // 結合条件を作成し付加する this.AddCorrelatedCondition(subQueryClause , subResultInfo , tableAliasNameOfSub , mainResultInfo , tableAliasNameOfMain); } } // foreach } // foreach }
virtual public void VisitAfter(ResultInfoList resultInfoList) { }
virtual public void VisitBefore(ResultInfoList resultInfoList) { }
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); }