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