// 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); }
internal static void ProcessExpression(DbNode currentNode, Predicate predicate, ref Chainer query) { bool sign = true; var logicalOperator = LogicalOperator.And; if (predicate != null) { sign = predicate.Sign; logicalOperator = predicate.LogicalOperator; // check predicate type - no quantifiers allowed - ! if (!predicate.HasDefaultQuantifier()) { ThrowInvalidQuantifierException(predicate, currentNode, null, null, null); } } // else subject expression (S.a) with positive sign if (query is ConditionChainer) { if (logicalOperator == LogicalOperator.And) { query = ((ConditionChainer)query) .AndWhere(currentNode.Expression, sign, predicate != null ? predicate.PredicateGroup : null); } else { query = ((ConditionChainer)query) .OrWhere(currentNode.Expression, sign, predicate != null ? predicate.PredicateGroup : null); } } else { query = ((IWhere)query) .Where(currentNode.Expression, sign, predicate != null ? predicate.PredicateGroup : null); } }
internal void SetNext(Chainer next) { _next = next; }
internal void TryTakeAll(Chainer from) { TryTake(from, TakeProperty.Exception, TakeProperty.Build); }
// inliner: procedure, snippet, stored procedure private ExecChainer( Chainer prev, Variable inliner, string returnValueToVariable, params ParameterArgument[] arguments) : base(prev) { Build = (buildContext, buildArgs) => { ParameterArgument inlinerArgument = buildArgs.Executable.GetInlinerArgument(inliner.Name); if (inlinerArgument.Value == null) { buildContext.TryTakeException(new QueryTalkException(this, QueryTalkExceptionType.InlinerArgumentNull, String.Format("{0} = null", inliner.Name))); return(null); } if (inliner.DT == DT.InProcedure) { if (inlinerArgument.DT != DT.InProcedure) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _procInliners)); return(null); } PassChainer cpass; if (inlinerArgument.ArgType == typeof(PassChainer)) { cpass = (PassChainer)inlinerArgument.Original; } // inliner variable else { var proc = (Procedure)inlinerArgument.Original; cpass = new PassChainer(proc, arguments); } BodyMethod(cpass, returnValueToVariable); return(BuildExecProc(buildContext, buildArgs)); } else if (inliner.DT == DT.InStoredProcedure) { if (inlinerArgument.DT != DT.InStoredProcedure) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _sprocInliners)); return(null); } PassChainer cpass; if (inlinerArgument.ArgType == typeof(PassChainer)) { cpass = (PassChainer)inlinerArgument.Original; } else if (inlinerArgument.ArgType == typeof(ExecArgument)) { cpass = PassChainer.Create(new InternalRoot(), (ExecArgument)inlinerArgument.Original); } // inliner variable else { var execArgument = ((string)inlinerArgument.Original).Pass(arguments); cpass = PassChainer.Create(new InternalRoot(), execArgument); } BodyMethod(cpass, returnValueToVariable); return(BuildExecProc(buildContext, buildArgs)); } else { if (inlinerArgument.DT != DT.InSql) { buildContext.TryTakeException(inliner.DT.InvalidInlinerException(GetType().Name, inliner.Name, _sqlInliners)); return(null); } PassChainer cpass; if (inlinerArgument.ArgType == typeof(ExecArgument)) { cpass = PassChainer.Create(new InternalRoot(), (ExecArgument)inlinerArgument.Original); } // inliner variable else { var execArgument = ((string)inlinerArgument.Original).Pass(arguments); cpass = PassChainer.Create(new InternalRoot(), execArgument); } BodyMethod(cpass, null); return(BuildExecProc(buildContext, buildArgs)); } }; }
internal DropTempTableChainer(Chainer prev) : base(prev) { }
internal BeginTableColumnChainer(Chainer prev, NonSelectColumnArgument column, DataType dataTypeDef) : base(prev) { Initialize(column, dataTypeDef); }
// 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()); } }
internal Statement(Chainer firstObject) { First = firstObject; Root.Statements.Add(this); _statementIndex = Root.GetStatementIndex(); }
internal TableChainer(Chainer prev, IOpenView openView) : this(prev) { IOpenView query = null; // SEMQ if (openView is ISemantic) { SetNode(((DbNode)openView).Root); if (((ISemantic)openView).IsQuery) { query = DbMapping.SelectFromSemantic((ISemantic)openView); } else if (openView is IFunction) { ProcessTableArgument(((IFunction)openView).GetUdf()); return; } // table/view identifier: else { if (_node.IsSynonym) { if (_node.SynonymQuery is IOpenView) { query = (IOpenView)_node.SynonymQuery; } else { ProcessTableArgument((View)_node.SynonymQuery); return; } } else { ProcessTableArgument(_node.Map.Name); return; } } } // SQL query: else { query = openView; } Query.AddTableObject(this); var tableArgument = query; CheckNullAndThrow(Arg(() => tableArgument, tableArgument)); TryThrow(((Chainer)query).Exception); var view = new View(query, Query); _table = view; Query.AddArguments(view.Query.Arguments.ToArray()); if (chainException != null) { chainException.Extra = String.Format("Check {0} method.", chainException.Method); TryThrow(); } TableArgument = _table; }
internal TableChainer(Chainer prev, Table table) : this(prev) { ProcessTableArgument(table); }