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
        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);
        }