Example #1
0
        public virtual void Visit(CreateTransformationTableNode node)
        {
            foreach (var item in node.Fields)
            {
                item.Accept(this);
            }

            node.Accept(Visitor);
        }
        public void Visit(CreateTransformationTableNode node)
        {
            _walker = _walker.NextChild();
            _visitor.SetScope(_walker.Scope);

            node.Accept(_visitor);

            _walker = _walker.Parent();
        }
Example #3
0
        public void Visit(CreateTransformationTableNode node)
        {
            SetQueryPart(QueryPart.None);
            foreach (var item in node.Fields)
            {
                item.Accept(this);
            }

            node.Accept(_visitor);
        }
Example #4
0
        public virtual void Visit(CreateTransformationTableNode node)
        {
            var items = new FieldNode[node.Fields.Length];

            for (var i = node.Fields.Length - 1; i >= 0; --i)
            {
                items[i] = (FieldNode)Nodes.Pop();
            }

            Nodes.Push(new CreateTransformationTableNode(node.Name, node.Keys, items, node.ForGrouping));
        }
        public void Visit(CreateTransformationTableNode node)
        {
            var fields = CreateFields(node.Fields);

            Nodes.Push(new CreateTransformationTableNode(node.Name, node.Keys, fields, node.ForGrouping));
        }
Example #6
0
        public void Visit(QueryNode node)
        {
            var orderBy = node.OrderBy != null?Nodes.Pop() as OrderByNode : null;

            var groupBy = node.GroupBy != null?Nodes.Pop() as GroupByNode : null;

            var skip = node.Skip != null?Nodes.Pop() as SkipNode : null;

            var take = node.Take != null?Nodes.Pop() as TakeNode : null;

            var select = Nodes.Pop() as SelectNode;

            var where = node.Where != null?Nodes.Pop() as WhereNode : null;

            var from = Nodes.Pop() as ExpressionFromNode;

            var scoreSelect = select;
            var scoreWhere  = where;

            QueryNode query;

            var splittedNodes = new List <Node>();
            var source        = from.Alias.ToRowsSource().WithRowsUsage();

            QueryNode lastJoinQuery = null;

            _scope[MetaAttributes.MethodName] = $"ComputeTable_{from.Alias}_{_queryIndex++}";

            IReadOnlyList <AccessMethodNode> usedRefreshMethods = null;

            if (_scope.ScopeSymbolTable.SymbolIsOfType <RefreshMethodsSymbol>(from.Alias.ToRefreshMethodsSymbolName()))
            {
                usedRefreshMethods = _scope.ScopeSymbolTable
                                     .GetSymbol <RefreshMethodsSymbol>(from.Alias.ToRefreshMethodsSymbolName()).RefreshMethods;
            }

            var aliasIndex             = 0;
            var aliasesPositionsSymbol = new AliasesPositionsSymbol();

            if (from.Expression is JoinsNode)
            {
                var current = _joinedTables[0];
                var left    = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.Source.Alias);
                var right   = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.With.Alias);

                var scopeCreateTable = _scope.AddScope("Table");
                var scopeJoinedQuery = _scope.AddScope("Query");

                var bothForCreateTable = CreateAndConcatFields(left, current.Source.Alias, right, current.With.Alias,
                                                               (name, alias) => NamingHelper.ToColumnName(alias, name));
                var bothForSelect = CreateAndConcatFields(left, current.Source.Alias, right, current.With.Alias,
                                                          (name, alias) => name);

                scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.Source.Alias, left);
                scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.With.Alias, right);

                var targetTableName = $"{current.Source.Alias}{current.With.Alias}";

                aliasesPositionsSymbol.AliasesPositions.Add(current.Source.Alias, aliasIndex++);
                aliasesPositionsSymbol.AliasesPositions.Add(current.With.Alias, aliasIndex++);

                scopeJoinedQuery.ScopeSymbolTable.AddSymbol(targetTableName,
                                                            _scope.ScopeSymbolTable.GetSymbol(targetTableName));

                scopeJoinedQuery[MetaAttributes.SelectIntoVariableName] = targetTableName.ToTransitionTable();
                scopeJoinedQuery[MetaAttributes.OriginAlias]            = targetTableName;
                scopeJoinedQuery[MetaAttributes.Contexts] = $"{current.Source.Alias},{current.With.Alias}";
                scopeCreateTable[MetaAttributes.CreateTableVariableName] = targetTableName.ToTransitionTable();

                var joinedQuery = new InternalQueryNode(
                    new SelectNode(bothForSelect),
                    new ExpressionFromNode(
                        new JoinSourcesTableFromNode(
                            current.Source,
                            current.With,
                            current.Expression,
                            current.JoinType)),
                    null,
                    null,
                    null,
                    null,
                    null,
                    new RefreshNode(new AccessMethodNode[0]));

                var targetTable = new CreateTransformationTableNode(targetTableName, new string[0], bothForCreateTable, false);

                splittedNodes.Add(targetTable);
                splittedNodes.Add(joinedQuery);

                lastJoinQuery = joinedQuery;
                source        = targetTableName.ToTransitionTable().ToTransformedRowsSource();

                var usedTables = new Dictionary <string, string>
                {
                    { current.Source.Alias, targetTableName },
                    { current.With.Alias, targetTableName }
                };

                for (var i = 1; i < _joinedTables.Count; i++)
                {
                    current = _joinedTables[i];
                    left    = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.Source.Alias);
                    right   = _scope.ScopeSymbolTable.GetSymbol <TableSymbol>(current.With.Alias);

                    targetTableName = $"{current.Source.Alias}{current.With.Alias}";

                    aliasesPositionsSymbol.AliasesPositions.Add(current.Source.Alias, aliasIndex++);
                    aliasesPositionsSymbol.AliasesPositions.Add(current.With.Alias, aliasIndex++);

                    scopeCreateTable = _scope.AddScope("Table");
                    scopeJoinedQuery = _scope.AddScope("Query");

                    bothForCreateTable = CreateAndConcatFields(left, current.Source.Alias, right, current.With.Alias,
                                                               (name, alias) => NamingHelper.ToColumnName(alias, name));
                    bothForSelect = CreateAndConcatFields(
                        left,
                        current.Source.Alias,
                        right,
                        current.With.Alias,
                        (name, alias) => NamingHelper.ToColumnName(alias, name),
                        (name, alias) => name,
                        (name, alias) => NamingHelper.ToColumnName(alias, name),
                        (name, alias) => name);

                    scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.Source.Alias, left);
                    scopeJoinedQuery.ScopeSymbolTable.AddSymbol(current.With.Alias, right);

                    scopeJoinedQuery.ScopeSymbolTable.AddSymbol(targetTableName,
                                                                _scope.ScopeSymbolTable.GetSymbol(targetTableName));
                    scopeJoinedQuery[MetaAttributes.SelectIntoVariableName] = targetTableName.ToTransitionTable();
                    scopeJoinedQuery[MetaAttributes.OriginAlias]            = targetTableName;
                    scopeJoinedQuery[MetaAttributes.Contexts] = $"{current.Source.Alias},{current.With.Alias}";
                    scopeCreateTable[MetaAttributes.CreateTableVariableName] = targetTableName.ToTransitionTable();

                    scopeJoinedQuery.ScopeSymbolTable.AddSymbol(
                        MetaAttributes.OuterJoinSelect,
                        new FieldsNamesSymbol(bothForSelect.Select(f => f.FieldName).ToArray()));

                    var expressionUpdater = new RewriteWhereConditionWithUpdatedColumnAccess(usedTables);
                    var traverser         = new CloneTraverseVisitor(expressionUpdater);

                    new WhereNode(current.Expression).Accept(traverser);

                    foreach (var key in usedTables.Keys.ToArray())
                    {
                        usedTables[key] = targetTableName;
                    }

                    usedTables[current.Source.Alias] = targetTableName;
                    usedTables.Add(current.With.Alias, targetTableName);

                    joinedQuery = new InternalQueryNode(
                        new SelectNode(bothForSelect),
                        new ExpressionFromNode(
                            new JoinInMemoryWithSourceTableFromNode(
                                current.Source.Alias,
                                current.With,
                                expressionUpdater.Where.Expression,
                                current.JoinType)),
                        null,
                        null,
                        null,
                        null,
                        null,
                        new RefreshNode(new AccessMethodNode[0]));

                    targetTable = new CreateTransformationTableNode(targetTableName, new string[0], bothForCreateTable, false);

                    splittedNodes.Add(targetTable);
                    splittedNodes.Add(joinedQuery);

                    lastJoinQuery = joinedQuery;
                    source        = targetTableName.ToTransitionTable().ToTransformedRowsSource();
                }

                var rewriter       = new RewritePartsToUseJoinTransitionTable();
                var partsTraverser = new CloneTraverseVisitor(rewriter);

                select.Accept(partsTraverser);
                where?.Accept(partsTraverser);

                scoreSelect = rewriter.ChangedSelect;
                scoreWhere  = rewriter.ChangedWhere;
            }

            if (groupBy != null)
            {
                var nestedFrom = splittedNodes.Count > 0
                    ? new ExpressionFromNode(new InMemoryGroupedFromNode(lastJoinQuery.From.Alias))
                    : from;

                var splitted       = SplitBetweenAggreateAndNonAggreagate(select.Fields, groupBy.Fields, true);
                var refreshMethods = CreateRefreshMethods(usedRefreshMethods);
                var aggSelect      = new SelectNode(ConcatAggregateFieldsWithGroupByFields(splitted[0], groupBy.Fields)
                                                    .Reverse().ToArray());
                var outSelect = new SelectNode(splitted[1]);

                var scopeCreateTranformingTable = _scope.AddScope("Table");
                var scopeTransformedQuery       = _scope.AddScope("Query");
                var scopeCreateResultTable      = _scope.AddScope("Table");
                var scopeResultQuery            = _scope.AddScope("Query");

                scopeCreateTranformingTable[MetaAttributes.CreateTableVariableName] = nestedFrom.Alias.ToGroupingTable();
                scopeCreateResultTable[MetaAttributes.CreateTableVariableName]      = nestedFrom.Alias.ToScoreTable();

                var destination = nestedFrom.Alias.ToGroupingTable().ToTransformedRowsSource();
                scopeTransformedQuery[MetaAttributes.SelectIntoVariableName] = destination;
                scopeTransformedQuery[MetaAttributes.SourceName]             = splittedNodes.Count > 0
                    ? nestedFrom.Alias.ToTransitionTable().ToTransformedRowsSource()
                    : nestedFrom.Alias.ToRowsSource().WithRowsUsage();
                scopeTransformedQuery[MetaAttributes.OriginAlias] = nestedFrom.Alias;
                scopeTransformedQuery.ScopeSymbolTable.AddSymbol(nestedFrom.Alias,
                                                                 _scope.ScopeSymbolTable.GetSymbol(nestedFrom.Alias));
                scopeTransformedQuery[MetaAttributes.Contexts] = $"{nestedFrom.Alias}";

                if (splittedNodes.Count > 0)
                {
                    var selectRewriter  = new RewritePartsToUseJoinTransitionTable(nestedFrom.Alias);
                    var selectTraverser = new CloneTraverseVisitor(selectRewriter);

                    groupBy.Accept(selectTraverser);
                    groupBy = selectRewriter.ChangedGroupBy;

                    scopeTransformedQuery.ScopeSymbolTable.AddSymbol("groupFields",
                                                                     new FieldsNamesSymbol(groupBy.Fields.Select(f => f.FieldName).ToArray()));

                    var newRefreshMethods = new List <AccessMethodNode>();
                    foreach (var method in refreshMethods.Nodes)
                    {
                        var newNodes = new List <Node>();
                        foreach (var arg in method.Arguments.Args)
                        {
                            arg.Accept(selectTraverser);
                            newNodes.Add(selectRewriter.RewrittenNode);
                        }

                        var newArgs = new ArgsListNode(newNodes.ToArray());
                        newRefreshMethods.Add(new AccessMethodNode(method.FToken, newArgs,
                                                                   method.ExtraAggregateArguments, method.CanSkipInjectSource, method.Method));
                    }

                    refreshMethods = new RefreshNode(newRefreshMethods.ToArray());
                }
                else
                {
                    scopeTransformedQuery.ScopeSymbolTable.AddSymbol("groupFields",
                                                                     new FieldsNamesSymbol(groupBy.Fields.Select(f => f.Expression.ToString()).ToArray()));
                }

                var transformingQuery = new InternalQueryNode(aggSelect, nestedFrom, where, groupBy, null, null, null,
                                                              refreshMethods);

                var returnScore = nestedFrom.Alias.ToScoreTable();
                scopeResultQuery[MetaAttributes.SelectIntoVariableName] = returnScore;
                scopeResultQuery[MetaAttributes.SourceName]             = destination;
                scopeResultQuery[MetaAttributes.Contexts] = $"{nestedFrom.Alias}";

                aliasesPositionsSymbol.AliasesPositions.Add(nestedFrom.Alias, aliasIndex++);
                aliasesPositionsSymbol.AliasesPositions.Add(returnScore, aliasIndex++);

                query = new DetailedQueryNode(
                    outSelect,
                    new ExpressionFromNode(
                        new InMemoryGroupedFromNode(returnScore)),
                    null,
                    null,
                    null,
                    skip,
                    take,
                    returnScore);

                splittedNodes.Add(new CreateTransformationTableNode(destination, new string[0], transformingQuery.Select.Fields, true));
                splittedNodes.Add(transformingQuery);
                splittedNodes.Add(new CreateTransformationTableNode(query.From.Alias, new string[0], query.Select.Fields, false));
                splittedNodes.Add(query);

                Nodes.Push(
                    new MultiStatementNode(
                        splittedNodes.ToArray(),
                        null));
            }
            else
            {
                var splitted = SplitBetweenAggreateAndNonAggreagate(select.Fields, new FieldNode[0], true);

                if (IsQueryWithMixedAggregateAndNonAggregateMethods(splitted))
                {
                    query = new InternalQueryNode(select, from, where, null, null, skip, take,
                                                  CreateRefreshMethods(usedRefreshMethods));
                }
                else
                {
                    var scopeCreateResultTable = _scope.AddScope("Table");
                    var scopeResultQuery       = _scope.AddScope("Query");

                    scopeCreateResultTable[MetaAttributes.CreateTableVariableName] = from.Alias.ToScoreTable();
                    scopeCreateResultTable[MetaAttributes.OriginAlias]             = from.Alias;
                    scopeResultQuery[MetaAttributes.SelectIntoVariableName]        = from.Alias.ToScoreTable();
                    scopeResultQuery[MetaAttributes.Contexts]   = from.Alias;
                    scopeResultQuery[MetaAttributes.SourceName] = source;

                    var newFrom = lastJoinQuery != null
                        ? new ExpressionFromNode(
                        new InMemoryGroupedFromNode(lastJoinQuery.From.Alias))
                        : from;

                    aliasesPositionsSymbol.AliasesPositions.Add(newFrom.Alias, aliasIndex++);

                    splittedNodes.Add(new CreateTransformationTableNode(scopeResultQuery[MetaAttributes.SelectIntoVariableName], new string[0], select.Fields, false));
                    splittedNodes.Add(new DetailedQueryNode(scoreSelect, newFrom, scoreWhere, null, null, skip, take,
                                                            scopeResultQuery[MetaAttributes.SelectIntoVariableName]));

                    Nodes.Push(
                        new MultiStatementNode(
                            splittedNodes.ToArray(),
                            null));
                }
            }

            _scope.ScopeSymbolTable.AddSymbol(MetaAttributes.AllQueryContexts, aliasesPositionsSymbol);

            _joinedTables.Clear();
        }
 public void Visit(CreateTransformationTableNode node)
 {
 }