예제 #1
0
        static Expression MakeNotNullCheck(ExpressionItem list)
        {
            Expression top = null;

            while (list != null)
            {
                INode term = TailorUtil.GetTerm(list.Expression);
                if (!(term is IntegerValue) && !(term is StringValue))
                {
                    Expression leaf = new Expression();
                    leaf.Left     = term.Clone();
                    leaf.Operator = ExpressionOperator.IsNotNull;

                    if (top == null)
                    {
                        top = leaf;
                    }
                    else
                    {
                        top = new Expression(top, ExpressionOperator.Or, leaf);
                    }
                }

                list = list.Next;
            }

            return(top);
        }
예제 #2
0
        static FunctionCall MakeConvert(LiteralDateTime literalDateTime)
        {
            if (literalDateTime == null)
            {
                throw new ArgumentNullException("literalDateTime");
            }

            DateTime dateTime = literalDateTime.DateTime;
            string   literal  = dateTime.ToString("yyyy-MM-dd HH:mm:ss");

            FunctionCall functionCall = new FunctionCall(
                TailorUtil.CONVERT.ToUpperInvariant());

            // Well, technically it's a type name, not a database ID, but
            // this is what the parser builds from "CONVERT(datetime)"
            // and it should serve just as well...
            functionCall.ExpressionArguments = new ExpressionItem(
                new DbObject(new Identifier("datetime")));

            functionCall.ExpressionArguments.Add(
                TailorUtil.MakeLiteralString(literal));
            functionCall.ExpressionArguments.Add(
                TailorUtil.MakeLiteralInteger(120));

            return(functionCall);
        }
예제 #3
0
        void ReplaceIntervals(Expression done)
        {
            Expression node = GetExpressionParent(done);

            if (node == null)
            {
                return;
            }

            Interval leftInterval  = TailorUtil.GetInterval(node.Left);
            Interval rightInterval = TailorUtil.GetInterval(node.Right);

            if (leftInterval != null)
            {
                if (rightInterval != null)
                {
                    ReplaceBothIntervals(node, leftInterval, rightInterval);
                }
                else
                {
                    ReplaceLeftInterval(node, leftInterval);
                }
            }
            else if (rightInterval != null)
            {
                ReplaceRightInterval(node, rightInterval);
            }
        }
예제 #4
0
        static INode MakeNotNullCheck(ExpressionItem list)
        {
            INode top = null;

            while (list != null)
            {
                INode        term         = TailorUtil.GetTerm(list.Expression);
                IntegerValue integerValue = term as IntegerValue;
                if (integerValue == null)
                {
                    FunctionCall leaf = new FunctionCall("IsNull");
                    leaf.ExpressionArguments = new ExpressionItem(term.Clone());

                    if (top == null)
                    {
                        top = leaf;
                    }
                    else
                    {
                        top = new Expression(top, ExpressionOperator.Or, leaf);
                    }
                }

                list = list.Next;
            }

            return(top);
        }
예제 #5
0
        INode MakeSubstring(FunctionCall substringCall)
        {
            if (substringCall == null)
            {
                throw new ArgumentNullException("substringCall");
            }

            substringCall.Name = TailorUtil.GetCapitalized(TailorUtil.MID);

            ExpressionItem val = substringCall.ExpressionArguments;

            if (val == null)
            {
                throw new InvalidOperationException("No parameters for SUBSTRING.");
            }

            ExpressionItem start = val.Next;

            if (start == null)
            {
                throw new InvalidOperationException("Too few parameters for SUBSTRING.");
            }

            ExpressionItem len = start.Next;

            INode cond = MakeNotNullCheck(start);   // Mid actually handles NULL

            // in the first parameter

            if (len == null)
            {
                // We don't need to add length in the normal case, but it's
                // useful when the start position is too large and the call
                // ought to fail (which Mid doesn't, unless it's called with
                // a negative length).
                IExpression argument = TailorUtil.MakeLenArg(start.Expression,
                                                             val.Expression, "Len");
                start.Add(new ExpressionItem(argument));
            }
            else
            {
                if (len.Next != null)
                {
                    throw new InvalidOperationException("Too many parameters for SUBSTRING.");
                }
            }

            if (cond == null)
            {
                return(substringCall);
            }
            else
            {
                FunctionCall iifCall = new FunctionCall("Iif");
                iifCall.ExpressionArguments = new ExpressionItem(cond);
                iifCall.ExpressionArguments.Add(new ExpressionItem(NullValue.Value));
                iifCall.ExpressionArguments.Add(new ExpressionItem(substringCall));
                return(iifCall);
            }
        }
예제 #6
0
        public override void PerformBefore(DbObject node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (!node.HasNext)
            {
                if (TailorUtil.IsSysdate(node.Identifier))
                {
                    ReplaceTerm(node, new FunctionCall(
                                    TailorUtil.GetCapitalized(TailorUtil.NOW)));
                }

                if (!m_inSelectItems && (m_selectItemAliases != null))
                {
                    string key = Identifier.Canonicalize(node.Identifier.ID);
                    if (m_selectItemAliases.ContainsKey(key))
                    {
                        AliasedItem orig = m_selectItemAliases[key];
                        ReplaceTerm(node, orig.Item.Clone());
                    }
                }
            }

            base.PerformBefore(node);
        }
예제 #7
0
        public override void PerformBefore(DbObject node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (!node.HasNext && TailorUtil.IsSysdate(node.Identifier))
            {
                ReplaceTerm(node, new FunctionCall(TailorUtil.GETDATE.ToUpperInvariant()));
            }

            base.PerformBefore(node);
        }
예제 #8
0
        public override void PerformBefore(DbObject node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (!node.HasNext && TailorUtil.IsSysdate(node.Identifier))
            {
                ReplaceTerm(node, new DbObject(new Identifier(
                                                   TailorUtil.CURRENT_TIMESTAMP.ToUpperInvariant())));
            }

            base.PerformBefore(node);
        }
예제 #9
0
        void CoalesceIntervals(Expression done)
        {
            Expression node = GetExpressionParent(done);

            if (node == null)
            {
                return;
            }

            Interval leftInterval  = TailorUtil.GetInterval(node.Left);
            Interval rightInterval = TailorUtil.GetInterval(node.Right);

            if ((leftInterval != null) && (rightInterval != null))
            {
                ReplaceIntervalOp(node, leftInterval, rightInterval);
            }
        }
예제 #10
0
        public override void PerformBefore(QueryExpression node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            base.PerformBefore(node);

            if (node.Where == null)
            {
                AliasedItem from = node.From;
                if ((from != null) && (from.Alias == null) && !from.HasNext)
                {
                    Table singleTable = from.Item as Table;
                    if ((singleTable != null) && (singleTable.Alias == null) &&
                        (singleTable.JoinCondition == null) &&
                        (singleTable.JoinType == null) && !singleTable.HasNext)
                    {
                        DbObject singleName = TailorUtil.GetTerm(
                            singleTable.Source) as DbObject;
                        if ((singleName != null) && !singleName.HasNext)
                        {
                            Identifier identifier = singleName.Identifier;

                            // Not canonicalizing - we're accepting quoted "dual"
                            // as a regular identifier.
                            if (TailorUtil.DUAL.Equals(
                                    identifier.ID.ToLowerInvariant()))
                            {
                                node.From = null;
                            }
                        }
                    }
                }
            }

            if (node.LimitFormat != ' ')
            {
                node.LimitFormat = 'L';
            }
        }
예제 #11
0
        public override void PerformBefore(FunctionCall node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            base.PerformBefore(node);

            string name = node.Name.ToLowerInvariant();

            if (name.Equals(TailorUtil.GETDATE))
            {
                node.Name = TailorUtil.GetCapitalized(TailorUtil.NOW);
            }
            else if (name.Equals(TailorUtil.COALESCE))
            {
                CoalesceToIif(node);
            }
        }
예제 #12
0
        public override void Perform(Identifier node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            base.Perform(node);

            if (TailorUtil.IsRownum(node))
            {
                int limit = 0;

                QueryExpression query = GetAncestor <QueryExpression>(null, null);
                if (query != null)
                {
                    Expression relational = GetExpressionAncestor(null, query);
                    if (relational != null)
                    {
                        limit = TailorUtil.GetRownumExpressionLimit(relational);
                        if (limit > 0)
                        {
                            bool matched = false;

                            Expression logical = GetExpressionAncestor(relational, query);
                            if (logical == null)
                            {
                                if (query.Where == relational)
                                {
                                    query.Where = null;
                                    matched     = true;
                                }
                            }
                            else
                            {
                                if (logical.Operator == ExpressionOperator.And)
                                {
                                    if (relational == logical.Left)
                                    {
                                        logical.Operator = null;
                                        logical.Left     = null;
                                        matched          = true;
                                    }
                                    else if (relational == logical.Right)
                                    {
                                        logical.Operator = null;
                                        logical.Right    = null;
                                        matched          = true;
                                    }
                                }
                            }

                            if (matched)
                            {
                                SetTop(query, limit);
                            }
                            else
                            {
                                limit = -1;
                            }
                        }
                    }
                }

                if (limit <= 0)
                {
                    throw new InvalidOperationException(
                              "MS engines do not have ROWNUM.");
                }
            }

            node.NormalizeQuotes('`');
        }
예제 #13
0
        INode MakeSubstring(FunctionCall substringCall)
        {
            if (substringCall == null)
            {
                throw new ArgumentNullException("substringCall");
            }

            if (TailorUtil.HasNullArgument(substringCall))
            {
                return(NullValue.Value);
            }

            ExpressionItem val = substringCall.ExpressionArguments;

            if (val == null)
            {
                throw new InvalidOperationException("No parameters for SUBSTRING.");
            }

            ExpressionItem start = val.Next;

            if (start == null)
            {
                throw new InvalidOperationException("Too few parameters for SUBSTRING.");
            }

            ExpressionItem len = start.Next;

            // before adding len to the list
            Expression when = MakeNotNullCheck(substringCall.ExpressionArguments);

            if (len == null)
            {
                IExpression argument = TailorUtil.MakeLenArg(start.Expression,
                                                             val.Expression, "LEN");
                start.Add(new ExpressionItem(argument));
            }
            else
            {
                if (len.Next != null)
                {
                    throw new InvalidOperationException("Too many parameters for SUBSTRING.");
                }
            }

            if (when != null)
            {
                CaseExpression caseExpression = new CaseExpression();
                caseExpression.Alternatives = new CaseAlternative(when, substringCall);

                Expression elseExpr = new Expression();
                elseExpr.Left       = NullValue.Value;
                caseExpression.Else = elseExpr;

                return(caseExpression);
            }
            else
            {
                return(substringCall);
            }
        }