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());
            }
        }
Пример #2
0
 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];
     }
 }
Пример #3
0
        //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)
                {
                }
            }
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
 private bool GetSourcesOf(Column column, ResultInfoList resultInfoList)
 {
     foreach (var resultInfo in resultInfoList)
     {
         if (resultInfo.IsDirectSource(column, _ignoreCase))
         {
             return(true);
         }
     }
     return(false);
 }
Пример #6
0
 private List <TableAndColumn> GetSourcesOf(Column column, ResultInfoList resultInfoList)
 {
     foreach (var resultInfo in resultInfoList)
     {
         if (resultInfo.IsDirectSource(column, _ignoreCase))
         {
             return(resultInfo.Sources);
         }
     }
     return(null);
 }
Пример #7
0
        // 結合条件を作成し付加する
        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
        }
Пример #8
0
 virtual public void VisitAfter(ResultInfoList resultInfoList)
 {
 }
Пример #9
0
 virtual public void VisitBefore(ResultInfoList resultInfoList)
 {
 }
Пример #10
0
        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);
        }