コード例 #1
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        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);
        }
コード例 #2
0
        internal static IOpenView SelectFromSemantic(ISemantic query)
        {
            var subject = ((ISemantic)query).Subject;
            var context = new SemqContext(subject, subject.QueryRoot);

            return(((ISelect)query.Translate(context, null)).Select());
        }
コード例 #3
0
        Chainer ISemantic.Translate(SemqContext context, DbNode predecessor)
        {
            if (context == null)
            {
                throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException,
                                             "context = null", "InternalNode.ISemantic.Translate");
            }

            if (predecessor == null)
            {
                throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException,
                                             "predecessor = null", "InternalNode.ISemantic.Translate");
            }

            context.SetIndex(this);

            var from = GetDesigner().From(new Table(Map.Name, new AliasAs(Index)));

            if (!((IPredicate)this).HasPredicate)
            {
                return(from);
            }

            var predicate          = ((IPredicate)this).Predicates[0];
            var relation           = DbMapping.GetRelation(predecessor.SynonymOrThis.NodeID, NodeID, DB3.Default);
            var relationExpression = relation.BuildRelation(predecessor.SynonymOrThis.NodeID, predecessor.Index, Index).E();

            if (predicate.PredicateType == PredicateType.Cartesian)
            {
                var innerNode = ((ISemantic)predicate).Subject;
                context.SetIndex(innerNode);
                innerNode.QueryRoot = context.Subject;

                var innerJoinAs = from
                                  .InnerJoin((IOpenView)innerNode)
                                  .As(innerNode.Index);

                var joinRelation   = DbMapping.GetRelation(NodeID, innerNode.SynonymOrThis.NodeID, DB3.Default);
                var joinExpression = joinRelation.BuildRelation(NodeID, Index, innerNode.Index).E();
                var on             = innerJoinAs
                                     .On(joinExpression);

                if (IsFinalizeable)
                {
                    return(on.Where(relationExpression));
                }
                else
                {
                    return(on);
                }
            }
            else
            {
                return((Chainer)from.WhereExists(
                           (INonSelectView)
                           ((ISemantic)predicate).Translate(context, this), true)
                       .AndWhere(relationExpression, true));
            }
        }
コード例 #4
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
 internal static void ProcessSelfPredicate(SemqContext context, DbNode currentNode, Predicate predicate, ref Chainer query)
 {
     if (predicate.PredicateType == PredicateType.Maximized)
     {
         ProcessMaximized(context, predicate, ref query);
     }
     else
     {
         ProcessExpressionSQL(currentNode, predicate, ref query);
     }
 }
コード例 #5
0
        /// <summary>
        /// Sets the inner node of the graph instance.
        /// </summary>
        /// <param name="context">A semantic context.</param>
        /// <param name="innerNode">The inner node.</param>
        protected void SetInnerNode(SemqContext context, DbNode innerNode)
        {
            if (context == null)
            {
                throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException,
                                             "context = null", "DbGraphBase.SetInnerNode");
            }

            _innerNode = innerNode;
            context.SetGraphIndex(_innerNode);
        }
コード例 #6
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        private static void ProcessQuantified(SemqContext context, Predicate predicate, ref Chainer query)
        {
            var body = TranslatePredicate(context, predicate);

            if (query is IWhere)
            {
                query = ((IWhere)query).WhereQuantified(body, predicate.Sign, predicate);
            }
            else
            {
                query = ((ConditionChainer)query).WhereQuantified(body, predicate.Sign, predicate);
            }
        }
コード例 #7
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        private static void ProcessExistential(SemqContext context, Predicate predicate, ref Chainer query)
        {
            var body = TranslatePredicate(context, predicate);

            if (query is IWhere)
            {
                query = ((IWhere)query).WhereExists(body, predicate.Sign, predicate.PredicateGroup);
            }
            else
            {
                query = ((ConditionChainer)query).WhereExists(body, predicate.Sign, predicate);
            }
        }
コード例 #8
0
        internal static void TranslateGraph(IGraph graph, SemqContext context, IGraph predecessor)
        {
            if (predecessor == null)
            {
                Translate.TranslateGraphNode(graph, context, null, context.Subject);
            }

            while (graph != null)
            {
                ((IGraph)graph).Translate(context, predecessor);

                graph = graph.Next;
            }
        }
コード例 #9
0
        /// <summary>
        /// Executes the table-valued function returning a strongly typed result set.
        /// </summary>
        /// <param name="client">A client assembly.</param>
        /// <param name="arguments">Are the arguments to pass.</param>
        protected Result <TNode> GoFunc(System.Reflection.Assembly client, params FunctionArgument[] arguments)
        {
            return(PublicInvoker.Call <Result <TNode> >(() =>
            {
                _arguments = arguments;
                var context = new SemqContext((DbNode)this);
                var query = ((ISelect)((ISemantic)this).Translate(context, null))
                            .Select();

                Mapper.SetSql(((IEndProc)query).EndProcInternal().Sql);

                var connectable = Reader.GetConnectable(client, Mapper);
                return Reader.LoadTable <TNode>(connectable, null, true);
            }));
        }
コード例 #10
0
        /// <summary>
        /// Returns the inner node of the graph instance.
        /// </summary>
        /// <param name="context">A semantic context.</param>
        protected DbNode GetInnerNode(SemqContext context)
        {
            if (context == null)
            {
                throw new QueryTalkException(this, QueryTalkExceptionType.NullArgumentInnerException,
                                             "context = null", "DbGraphBase.GetInnerNode");
            }

            if (_innerNode != null)
            {
                return(_innerNode);
            }
            else
            {
                var innerNode = InnerGraph.Subject;
                context.SetGraphIndex(innerNode);
                return(innerNode);
            }
        }
コード例 #11
0
        internal static void TranslateGraphNode(IGraph graph, SemqContext context, DbNode predecessor, DbNode node, bool isLeafNode = false)
        {
            var isSubject = (predecessor == null);

            node = node.Root;
            context.SetGraphIndex(node);

            Chainer  translatedNode;
            Designer root;

            if (isSubject)
            {
                root = new InternalRoot(node);
            }
            else
            {
                root = context.TranslatedGraph.GetRoot();
                node.IsFinalizeable = false;
            }

            // translate node only
            //   important:
            //     The node should be translated before the graph processing begins in order that to obtain the appropriate index.
            translatedNode = ((ISemantic)node).Translate(context, predecessor);

            StringBuilder nodeTableVar = null;

            // create table variable storage except for the last leaf node which does not need a table variable
            if (!isLeafNode)
            {
                TranslateGraphDeclareTable(node, root, out nodeTableVar);
            }

            // finish the node query translation as part of a graph
            if (isSubject)
            {
                TranslateGraphSubject(context, node, root, translatedNode, nodeTableVar);
            }
            else
            {
                TranslateGraphRelated(graph, context, predecessor, node, translatedNode, nodeTableVar);
            }
        }
コード例 #12
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        internal static void ProcessPredicate(SemqContext context, Predicate predicate, ref Chainer query)
        {
            switch (predicate.PredicateType)
            {
            case PredicateType.Existential:
                ProcessExistential(context, predicate, ref query);
                break;

            case PredicateType.Quantified:
                ProcessQuantified(context, predicate, ref query);
                break;

            case PredicateType.TopQuantified:
                ProcessTopQuantified(context, predicate, ref query);
                break;

            case PredicateType.Maximized:
                ProcessMaximized(context, predicate, ref query);
                break;
            }
        }
コード例 #13
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        internal static DbNode ProcessIntermediate(SemqContext context, Predicate predicate, DbNode innerNode, Link link)
        {
            var intermediate = new InternalNode(link.Intermediate);

            context.AddNode(intermediate);
            intermediate.IsFinalizeable = predicate.IsFinalizeable;

            if (predicate.PredicateType == PredicateType.Quantified ||
                predicate.PredicateType == PredicateType.TopQuantified)
            {
                ((IPredicate)intermediate).AddPredicate(PredicateType.Cartesian, innerNode);
            }
            else
            {
                ((IPredicate)intermediate).AddPredicate(PredicateType.Existential, innerNode);
            }

            predicate.Sentence = (ISemantic)intermediate;

            return(intermediate);
        }
コード例 #14
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();
        }
コード例 #15
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
 private static INonSelectView TranslatePredicate(SemqContext context, Predicate predicate)
 {
     return((INonSelectView)((ISemantic)predicate).Translate(context, predicate.Subject));
 }
コード例 #16
0
 Chainer ISemantic.Translate(SemqContext context, DbNode predecessor)
 {
     return(Translate.TranslateNode(context, predecessor, this));
 }
コード例 #17
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());
            }
        }
コード例 #18
0
        Chainer ISemantic.Translate(SemqContext context, DbNode predecessor)
        {
            var innerNode = ((ISemantic)this).Subject;

            return(((ISemantic)innerNode).Translate(context, predecessor));
        }
コード例 #19
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        // General translation method for the database (table) node.
        internal static Chainer TranslateNode(SemqContext context, DbNode predecessor, DbNode node)
        {
            var currentNode = node.Root;

            if (context == null)
            {
                context = new SemqContext(currentNode);
            }

            context.AddNode(currentNode);
            currentNode.CheckReuseAndThrow();
            context.SetIndex(currentNode);

            Chainer query = Translate.CreateQueryFromSubject(currentNode);

            if (currentNode.HasExpression)
            {
                query.ExpressionGroupType = ExpressionGroupType.BeginEnd;
                Translate.ProcessExpression(currentNode, null, ref query);
            }
            else
            {
                currentNode.SetAsUsed();
            }

            Translate.ConvertChainIntoPredicate(currentNode);

            if (((IPredicate)currentNode).HasPredicate)
            {
                Predicate prevPredicate = null;
                var       predicates    = ((IPredicate)currentNode).Predicates;
                var       pix           = 0;

                foreach (var predicate in predicates)
                {
                    SetExpressionGrouping(query, predicates, predicate, ref pix);

                    CheckHavingPredicateAndThrow(predicate, ref prevPredicate);

                    var innerNode = ((ISemantic)predicate).Subject;
                    if (innerNode != null)
                    {
                        context.AddNode(innerNode);

                        if (CheckSelfPredicate(currentNode, innerNode))
                        {
                            innerNode          = innerNode.BreakChain();
                            predicate.Sentence = (ISemantic)innerNode;
                        }
                        else if (innerNode.Equals(currentNode) && innerNode.HasExpression)
                        {
                            // let the predicate subject have the same level as its caller
                            innerNode.ChangeIndex(currentNode.Index);

                            Translate.ProcessExpression(innerNode, predicate, ref query);

                            continue;
                        }

                        // get link
                        var link = DbMapping.TryFindPredicateLink(currentNode, innerNode);

                        // process intermediate node
                        DbNode intermediate = null;
                        if (link.HasIntermediate)
                        {
                            intermediate = Translate.ProcessIntermediate(context, predicate, innerNode, link);
                        }

                        // process a simple foreign key (if possible)
                        else if (Translate.ProcessSimpleForeignKey(currentNode, innerNode, predicate, link, ref query))
                        {
                            CheckQuantifierAndThrow(currentNode, innerNode, intermediate, predicate);
                            continue;
                        }

                        CheckQuantifierAndThrow(currentNode, innerNode, intermediate, predicate);

                        Translate.ProcessPredicate(context, predicate, ref query);
                    }
                    else
                    {
                        Translate.ProcessSelfPredicate(context, currentNode, predicate, ref query);
                    }
                }
            }

            if (predecessor != null)
            {
                Translate.Finalize(predecessor, currentNode, ref query);
            }

            if (((IPredicate)currentNode).PredicateGroupLevel != 0)
            {
                PredicateGroup.ThrowInvalidPredicateGroupingException((DbNode)currentNode);
            }

            return(query);
        }
コード例 #20
0
ファイル: Translate.cs プロジェクト: amosvoron/querytalk
        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);
            }
        }