Ejemplo n.º 1
0
        private static void ProcessMaximized(SemqContext context, Predicate predicate, ref Chainer query)
        {
            var ix1 = context.GetNewIndex();
            var ix2 = context.GetNewIndex();

            var self = predicate.Subject;

            context.SetIndex(self);

            var maximizedExpression = predicate.MaximizedExpression;

            var ordered = predicate.MaximizedType == MaximizationType.Min ?
                          new OrderedChainer(maximizedExpression, SortOrder.Asc) :
                          new OrderedChainer(maximizedExpression, SortOrder.Desc);

            var root = new InternalNode(self);

            query = root.GetDesigner()
                    .From(Designer.GetNewDesigner()
                          .From(((ISelect)query).Select(), root).As(ix1)
                          .OrderBy(ordered)
                          .Select().TopWithTies(predicate.MaximizedTop)
                          , root
                          ).As(ix2);

            self.ChangeIndex(ix2);
        }
Ejemplo n.º 2
0
        private static void TranslateGraphSubject(SemqContext context, DbNode node, Designer root,
                                                  Chainer translatedNode, StringBuilder nodeTableVar)
        {
            var ix1 = node.Index;
            var ix2 = context.GetNewIndex();

            var columnArguments = node.Map.GetKeyColumns(node.Index);

            var nodeTableVarName = GetTableVarName(ix1);

            var subjectQuery = ((ISelect)translatedNode)
                               .Select(columnArguments)
                               .Insert(nodeTableVarName)
                               .EndSnipInternal();

            context.TranslatedGraph = root.GetDesigner()
                                      .Inject(nodeTableVar.ToString())
                                      .Inject(subjectQuery)
                                      .From(node.Map.Name).As(ix1)
                                      .InnerJoin(nodeTableVarName).As(ix2).On(node.Map.BuildSelfRelation(ix1, ix2))
                                      .Select(node.Map.GetColumns(ix1))
                                      .End();
        }
Ejemplo n.º 3
0
        private static void ProcessTopQuantified(SemqContext context, Predicate predicate, ref Chainer query)
        {
            // manually create new table indexes
            var ix1 = context.GetNewIndex();
            var ix2 = context.GetNewIndex();
            var ix3 = context.GetNewIndex();
            var ix4 = context.GetNewIndex();

            // get relation between the subject of the predicate and its inner node
            var subject   = predicate.Subject;
            var self      = subject.SynonymOrThis.Map.Name;
            var innerNode = ((ISemantic)predicate).Subject;
            var link      = DbMapping.TryFindPredicateLink(subject, innerNode);

            var foreignKey         = innerNode.GetFK();
            var relation           = link.TryGetRelation(foreignKey);
            var relationExpression = relation.BuildRelation(subject.NodeID, ix1, ix2).E();
            var count = Designer.Identifier(ix4.ToString(), Text.Reserved.CountColumnReserved);

            // get columns of inner table A1
            List <Column> columnsA1 = new List <Column>();

            columnsA1.AddRange(subject.SynonymOrThis.Map.GetRKColumns(ix4));
            columnsA1.Add(count);

            // get columns of inner table A2
            List <Column> columnsA2 = new List <Column>();

            columnsA2.AddRange(subject.SynonymOrThis.Map.GetRKColumns(ix1));
            columnsA2.Add(Designer.CountBig().As(Text.Reserved.CountColumnReserved));

            // build self-relation of a Subject
            var selfRelation = subject.SynonymOrThis.Map.BuildSelfRelation(subject.Index, ix3);

            // translate predicate (without finalization)
            // attention:
            //   Do not move this line upper, before tableB assignment because after the translation
            //   the node chain gets split and tableB is not assigned the correct node if the predicate
            //   is translated before the assignment takes place.
            var translatedPredicate = ((ISelect)TranslatePredicate(context, predicate));

            // get columns of inner table B2 (subject of a predicate)
            List <Column> columnsB2 = new List <Column>();

            if (relation.IsRefTable(innerNode.NodeID))
            {
                columnsB2.AddRange(innerNode.Map.GetRKColumns(innerNode.Index));
            }
            else
            {
                columnsB2.AddRange(relation.GetFK(innerNode.Index));
            }

            // create TopQuantified body
            var body = Designer.GetNewDesigner()
                       .From(Designer.GetNewDesigner()
                             .From(Designer.GetNewDesigner()
                                   .From(self).As(ix1)
                                   .InnerJoin(translatedPredicate.Select(columnsB2.ToArray())).As(ix2) // diff
                                   .On(relationExpression)
                                   .GroupBy(subject.SynonymOrThis.Map.GetGroupBy(ix1))
                                   .Select(columnsA2.ToArray())).As(ix4)
                             .OrderBy(count.AsDesc())
                             .Select(columnsA1.ToArray()).TopWithTies(predicate.Quantifier.Cardinality)
                             , subject).As(ix3)
                       .Where(selfRelation, predicate.Sign, null);

            if (query is IWhere)
            {
                query = ((IWhere)query).WhereExists(body, predicate.Sign, predicate.PredicateGroup);
            }
            else
            {
                query = ((ConditionChainer)query).WhereExists(body, predicate.Sign, predicate);
            }
        }
Ejemplo n.º 4
0
        // translate related table
        private static void TranslateGraphRelated(IGraph graph, SemqContext context, DbNode predecessor, DbNode related,
                                                  Chainer translatedNode, StringBuilder relatedTableVar)
        {
            // try find link
            var link = DbMapping.TryFindPredicateLink(predecessor, related.Root, Text.Method.With);

            if (link.HasIntermediate)
            {
                ThrowWithRelatedNotFound(graph, related.Root);
            }

            // get FK
            var foreignKey = related.GetFK();

            foreignKey = foreignKey.Coalesce(link.DefaultForeignKey);

            // set RX
            var relation = context.AddGraphPair(foreignKey, predecessor, related, link);

            // add comment
            context.TranslatedGraph.Comment(String.Format("{0} {1} of {2} ({3}->{4})",
                                                          Text.Free.GraphComment, related.Name, predecessor.Name, predecessor.RX, related.RX));

            var predecessorTableVarName = GetTableVarName(predecessor.Index);
            var relatedTableVarName     = GetTableVarName(related.Index);
            var keyColumns = related.Map.GetKeyColumns(related.Index);
            var ix1        = context.GetNewIndex();
            var ix2        = context.GetNewIndex();
            var ix3        = context.GetNewIndex();

            // append the predicate
            if (translatedNode is ConditionChainer)
            {
                translatedNode = ((IWhereAnd)translatedNode)
                                 .AndExists(new InternalRoot(related).GetDesigner()
                                            .From(predecessorTableVarName).As(ix1)
                                            .Where(relation.BuildRelation(related.NodeID, related.Index, ix1)));
            }
            else
            {
                translatedNode = ((IWhere)translatedNode)
                                 .WhereExists(new InternalRoot(related).GetDesigner()
                                              .From(predecessorTableVarName).As(ix1)
                                              .Where(relation.BuildRelation(related.NodeID, related.Index, ix1)));
            }

            // inject related table query into the subject query
            if (relatedTableVar != null)
            {
                context.TranslatedGraph
                .Inject(relatedTableVar.ToString())
                .Inject((((ISelect)translatedNode)
                         .Select(keyColumns)
                         .Insert(GetTableVarName(related.Index)))
                        .EndSnipInternal())
                .From(related.Map.Name).As(ix2)
                .InnerJoin(relatedTableVarName).As(ix3).On(related.Map.BuildSelfRelation(ix2, ix3))
                .Select(related.Map.GetColumns(ix2));
            }
            // leaf nodes:
            else
            {
                var allColumns = related.Map.GetColumns(related.Index);
                context.TranslatedGraph
                .Inject((((ISelect)translatedNode).Select(allColumns)).EndSnipInternal());
            }
        }