private void AddOperator(BinaryOperatorToken token)
 {
     while (_operatorStack.Count > 0)
     {
         var currentPrecedence = _operatorStack.Peek().Precedence;
         if (token.Precedence > currentPrecedence || (token.Associativity == BinaryOperatorToken.AssociativityTypes.Right && token.Precedence == currentPrecedence)) break;
         EvaluateOperator();
     }
     _operatorStack.Push(token);
 }
 public void BinaryOperatorQueryTokenDefaultTest()
 {
     LiteralToken left = new LiteralToken(null);
     LiteralToken right = new LiteralToken(null);
     BinaryOperatorToken binary = new BinaryOperatorToken(BinaryOperatorKind.Or, left, right);
     this.Assert.AreEqual(QueryTokenKind.BinaryOperator, binary.Kind, "The InternalKind property has an unexpected value.");
     this.Assert.AreEqual(BinaryOperatorKind.Or, binary.OperatorKind, "The OperatorKind property should be Or.");
     this.Assert.AreEqual(left, binary.Left, "The Left property has an unexpected value.");
     this.Assert.AreEqual(right, binary.Right, "The Right property has an unexpected value.");
 }
예제 #3
0
        /// <summary>
        /// Binds a binary operator token.
        /// </summary>
        /// <param name="binaryOperatorToken">The binary operator token to bind.</param>
        /// <returns>The bound binary operator token.</returns>
        internal QueryNode BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)
        {
            ExceptionUtils.CheckArgumentNotNull(binaryOperatorToken, "binaryOperatorToken");

            SingleValueNode left = this.GetOperandFromToken(binaryOperatorToken.OperatorKind, binaryOperatorToken.Left);
            SingleValueNode right = this.GetOperandFromToken(binaryOperatorToken.OperatorKind, binaryOperatorToken.Right);

            IEdmTypeReference typeReference;
            this.resolver.PromoteBinaryOperandTypes(binaryOperatorToken.OperatorKind, ref left, ref right, out typeReference);

            return new BinaryOperatorNode(binaryOperatorToken.OperatorKind, left, right, typeReference);
        }
        public void OrOperatorShouldResultInBinaryOperatorNode()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(false);
            this.rightParameterSingleValueQueryNode = new ConstantNode(true);
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.Or, new LiteralToken(false), new LiteralToken(true));

            var resultNode = this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            resultNode.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Or).And.TypeReference.PrimitiveKind().Should().Be(EdmPrimitiveTypeKind.Boolean);
            resultNode.As<BinaryOperatorNode>().Left.ShouldBeConstantQueryNode(false);
            resultNode.As<BinaryOperatorNode>().Right.ShouldBeConstantQueryNode(true);
        }
        public void AndOperatorCompatibleTypeShouldResultInBinaryOperatorNode()
        {
            this.leftParameterSingleValueQueryNode = new UnaryOperatorNode(UnaryOperatorKind.Negate, new UnaryOperatorNode(UnaryOperatorKind.Not, new ConstantNode(null)));
            this.rightParameterSingleValueQueryNode = new SingleValueFunctionCallNode("func", null, EdmCoreModel.Instance.GetBoolean(false));
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.And, new LiteralToken("foo"), new LiteralToken("bar"));

            var resultNode = this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            resultNode.ShouldBeBinaryOperatorNode(BinaryOperatorKind.And).And.TypeReference.PrimitiveKind().Should().Be(EdmPrimitiveTypeKind.Boolean);
            resultNode.As<BinaryOperatorNode>().Left.ShouldBeConvertQueryNode(EdmPrimitiveTypeKind.Boolean);
            resultNode.As<BinaryOperatorNode>().Right.ShouldBeConvertQueryNode(EdmPrimitiveTypeKind.Boolean);
        }
        public void GreaterThanOrEqualOperatorShouldResultInBinaryOperatorNode()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(99);
            this.rightParameterSingleValueQueryNode = new ConstantNode(99.1);
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.GreaterThanOrEqual, new LiteralToken("foo"), new LiteralToken("bar"));

            var resultNode = this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            resultNode.ShouldBeBinaryOperatorNode(BinaryOperatorKind.GreaterThanOrEqual).And.TypeReference.PrimitiveKind().Should().Be(EdmPrimitiveTypeKind.Boolean);
            resultNode.As<BinaryOperatorNode>().Left.ShouldBeConstantQueryNode(99d);
            resultNode.As<BinaryOperatorNode>().Right.ShouldBeConstantQueryNode(99.1);
        }
        public void AndOperatorNullAndOpenPropertyShouldResultInBinaryOperatorNodeWithNullType()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(null);
            this.rightParameterSingleValueQueryNode = new SingleValueOpenPropertyAccessNode(new ConstantNode(null), OpenPropertyName);

            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.And, new LiteralToken("foo"), new LiteralToken("bar"));

            var resultNode = this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            var binaryNode = resultNode.ShouldBeBinaryOperatorNode(BinaryOperatorKind.And).And;

            binaryNode.TypeReference.Should().BeNull();
            binaryNode.Left.ShouldBeConstantQueryNode<object>(null);
            binaryNode.Right.ShouldBeSingleValueOpenPropertyAccessQueryNode(OpenPropertyName);
        }
예제 #8
0
 private static void VerifyBinaryOperatorQueryTokensAreEqual(BinaryOperatorToken expected, BinaryOperatorToken actual, AssertionHandler assert)
 {
     assert.AreEqual(expected.OperatorKind, actual.OperatorKind, "The binary operator kind doesn't match the expected one.");
     VerifyQueryTokensAreEqual(expected.Left, actual.Left, assert);
     VerifyQueryTokensAreEqual(expected.Right, actual.Right, assert);
 }
예제 #9
0
        /// <summary>
        /// Parses the or operator.
        /// </summary>
        /// <returns>The lexical token representing the expression.</returns>
        private QueryToken ParseLogicalOr()
        {
            this.RecurseEnter();
            QueryToken left = this.ParseLogicalAnd();
            while (this.TokenIdentifierIs(ExpressionConstants.SearchKeywordOr))
            {
                this.lexer.NextToken();
                QueryToken right = this.ParseLogicalAnd();
                left = new BinaryOperatorToken(BinaryOperatorKind.Or, left, right);
            }

            this.RecurseLeave();
            return left;
        }
예제 #10
0
        /// <summary>
        /// Parses the and operator.
        /// </summary>
        /// <returns>The lexical token representing the expression.</returns>
        private QueryToken ParseLogicalAnd()
        {
            this.RecurseEnter();
            QueryToken left = this.ParseUnary();
            while (this.TokenIdentifierIs(ExpressionConstants.SearchKeywordAnd)
                || this.TokenIdentifierIs(ExpressionConstants.SearchKeywordNot)
                || this.lexer.CurrentToken.Kind == ExpressionTokenKind.StringLiteral
                || this.lexer.CurrentToken.Kind == ExpressionTokenKind.OpenParen)
            {
                // Handle A NOT B, A (B)
                // Bypass only when next token is AND
                if (this.TokenIdentifierIs(ExpressionConstants.SearchKeywordAnd))
                {
                    this.lexer.NextToken();
                }

                QueryToken right = this.ParseUnary();
                left = new BinaryOperatorToken(BinaryOperatorKind.And, left, right);
            }

            this.RecurseLeave();
            return left;
        }
예제 #11
0
        /// <summary>
        /// Binds a binary operator token.
        /// </summary>
        /// <param name="binaryOperatorToken">The binary operator token to bind.</param>
        /// <returns>The bound binary operator token.</returns>
        protected virtual QueryNode BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)
        {
            BinaryOperatorBinder binaryOperatorBinder = new BinaryOperatorBinder(this.Bind, this.BindingState.Configuration.Resolver);

            return(binaryOperatorBinder.BindBinaryOperator(binaryOperatorToken));
        }
예제 #12
0
 /// <summary>
 /// Visits a BinaryOperatorToken
 /// </summary>
 /// <param name="tokenIn">The Binary operator token to visit.</param>
 /// <returns>A BinaryOperatorNode thats bound to this token</returns>
 public virtual T Visit(BinaryOperatorToken tokenIn)
 {
     throw new NotImplementedException();
 }
        public void LeftTokenTypeImcompatibleWithRightTokenShouldFail()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(true);
            this.rightParameterSingleValueQueryNode = new ConstantNode(1);
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.Equal, new LiteralToken("foo"), new LiteralToken("bar"));
            Action bind = () => this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            bind.ShouldThrow<ODataException>().
                WithMessage((Strings.MetadataBinder_IncompatibleOperandsError("Edm.Boolean", "Edm.Int32", BinaryOperatorKind.Equal)));
        }
        public void LeftTokenTypeIncompatibleWithOperatorAndRightTokenOpenPropertyShouldFail()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(DateTimeOffset.Now);
            this.rightParameterSingleValueQueryNode = new SingleValueOpenPropertyAccessNode(new ConstantNode(null), "SomeProperty");
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.And, new LiteralToken("foo"), new LiteralToken("bar"));
            Action bind = () => this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            bind.ShouldThrow<ODataException>().
                WithMessage((Strings.MetadataBinder_IncompatibleOperandsError("Edm.DateTimeOffset", "<null>", BinaryOperatorKind.And)));
        }
예제 #15
0
 /// <summary>
 /// Binds a binary operator token.
 /// </summary>
 /// <param name="binaryOperatorToken">The binary operator token to bind.</param>
 /// <returns>The bound binary operator token.</returns>
 protected virtual QueryNode BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)
 {
     BinaryOperatorBinder binaryOperatorBinder = new BinaryOperatorBinder(this.Bind, this.BindingState.Configuration.Resolver);
     return binaryOperatorBinder.BindBinaryOperator(binaryOperatorToken);
 }
예제 #16
0
 /// <summary>
 /// Write the given binary token as Uri part.
 /// </summary>
 /// <param name="binary">To write as Uri part.</param>
 public void Write(BinaryOperatorToken binary)
 {
     Write(false, binary);
 }
예제 #17
0
        /// <summary>
        /// Binds a binary operator token.
        /// </summary>
        /// <param name="binaryOperatorToken">The binary operator token to bind.</param>
        /// <returns>The bound binary operator token.</returns>
        protected virtual QueryNode BindBinaryOperator(BinaryOperatorToken binaryOperatorToken)
        {
            BinaryOperatorBinder binaryOperatorBinder = new BinaryOperatorBinder(this.Bind);

            return(binaryOperatorBinder.BindBinaryOperator(binaryOperatorToken));
        }
예제 #18
0
        internal static bool TryEvaluateExpression(string text, out TokenBase token, bool requireReturnValue = true)
        {
            string temp = text;

            if (new NullCoalesceOperatorToken().TryGetToken(ref temp, out token))
            {
                return(true);
            }
            temp = text;
            if (new TernaryOperatorToken().TryGetToken(ref temp, out token))
            {
                return(true);
            }

            token = null;
            List <TokenBase> tokens    = new List <TokenBase>();
            List <Operator>  operators = new List <Operator>();

            while (operators.Count == tokens.Count)
            {
                if (tokens.Count != 0 && !requireReturnValue)
                {
                    return(false);
                }
                TokenBase newToken;
                if (!TryGetValueToken(ref text, out newToken, requireReturnValue))
                {
                    return(false);
                }
                tokens.Add(newToken);
                text = text.TrimStart();
                for (int i = (int)Operator.Multiply; i <= (int)Operator.BitwiseXor; ++i)
                {
                    if (text.StartsWith(representations[i]))
                    {
                        operators.Add((Operator)i);
                        text = text.Substring(representations[i].Length).TrimStart();
                        break;
                    }
                }
            }
            if (!String.IsNullOrWhiteSpace(text))
            {
                return(false);
            }
            while (tokens.Count > 1)
            {
                int lastPrecedence = 1000;
                int last           = -1;
                for (int i = 0; i < operators.Count; ++i)
                {
                    int precendence = precedenceLevel[(int)operators[i]];
                    if (precendence < lastPrecedence)
                    {
                        lastPrecedence = precendence;
                        last           = i;
                    }
                    else
                    {
                        break;
                    }
                }
                tokens[last] = new BinaryOperatorToken(tokens[last], tokens[last + 1], operators[last]);
                tokens.RemoveAt(last + 1);
                operators.RemoveAt(last);
            }
            token = tokens[0];
            return(true);
        }
예제 #19
0
        private static void VerifyBinaryOperatorToken <T>(string expectedEndPathIdentifier, BinaryOperatorKind expectedOperator, T expectedLiteralValue, BinaryOperatorToken actual)
        {
            actual.Should().NotBeNull();
            actual.OperatorKind.Should().Be(expectedOperator);

            EndPathToken left = actual.Left as EndPathToken;

            left.Should().NotBeNull();
            left.Identifier.Should().Be(expectedEndPathIdentifier);

            LiteralToken right = actual.Right as LiteralToken;

            right.Should().NotBeNull();
            right.Value.Should().Be(expectedLiteralValue);
        }
        public void ModuloOperatorShouldResultInBinaryOperatorNode()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(-9.9);
            this.rightParameterSingleValueQueryNode = new ConstantNode(-100.9);
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.Modulo, new LiteralToken("foo"), new LiteralToken("bar"));

            var resultNode = this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            resultNode.ShouldBeBinaryOperatorNode(BinaryOperatorKind.Modulo).And.TypeReference.PrimitiveKind().Should().Be(EdmPrimitiveTypeKind.Double);
            resultNode.As<BinaryOperatorNode>().Left.ShouldBeConstantQueryNode(-9.9);
            resultNode.As<BinaryOperatorNode>().Right.ShouldBeConstantQueryNode(-100.9);
        }
        public void CollectionRightTokenShouldFail()
        {
            this.binaryOperatorBinder = new BinaryOperatorBinder(this.BindMethodThatReturnsQueryNode, /*resolver*/ null);
            this.leftQueryNode = new ConstantNode("People");
            this.rightQueryNode = new EntitySetNode(this.model.FindDeclaredEntitySet("People"));
            var binaryOperatorToken = new BinaryOperatorToken(BinaryOperatorKind.Equal, new LiteralToken("foo"), new LiteralToken("bar"));
            Action bind = () => this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorToken);

            bind.ShouldThrow<ODataException>().
                WithMessage((Strings.MetadataBinder_BinaryOperatorOperandNotSingleValue("Equal")));
        }
예제 #22
0
        /// <summary>
        /// Determine whether parentheses are needed around the left subtree base on the current operator.
        /// </summary>
        /// <param name="currentOperator">The current binary node's operator.</param>
        /// <param name="leftSubtree">The left binary subtree.</param>
        /// <returns>True if need parenthese, false if not.</returns>
        private static bool NeedParenthesesLeft(BinaryOperator currentOperator, BinaryOperatorToken leftSubtree)
        {
            BinaryOperator leftOperator = BinaryOperator.GetOperator(leftSubtree.OperatorKind);

            return(leftOperator.Precedence < currentOperator.Precedence);
        }
        public void RightTokenTypeImcompatibleWithOperatorShouldFail()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(999);
            this.rightParameterSingleValueQueryNode = new ConstantNode(string.Empty);
            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.Multiply, new LiteralToken("foo"), new LiteralToken("bar"));
            Action bind = () => this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            bind.ShouldThrow<ODataException>().
                WithMessage((Strings.MetadataBinder_IncompatibleOperandsError("Edm.Int32", "Edm.String", BinaryOperatorKind.Multiply)));
        }
예제 #24
0
        /// <summary>
        /// Parses the eq, ne, lt, gt, le, ge operators.
        /// </summary>
        /// <returns>The lexical token representing the expression.</returns>
        private QueryToken ParseComparison()
        {
            this.RecurseEnter();
            QueryToken left = this.ParseAdditive();
            while (true)
            {
                BinaryOperatorKind binaryOperatorKind;
                if (this.TokenIdentifierIs(ExpressionConstants.KeywordEqual))
                {
                    binaryOperatorKind = BinaryOperatorKind.Equal;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordNotEqual))
                {
                    binaryOperatorKind = BinaryOperatorKind.NotEqual;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordGreaterThan))
                {
                    binaryOperatorKind = BinaryOperatorKind.GreaterThan;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordGreaterThanOrEqual))
                {
                    binaryOperatorKind = BinaryOperatorKind.GreaterThanOrEqual;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordLessThan))
                {
                    binaryOperatorKind = BinaryOperatorKind.LessThan;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordLessThanOrEqual))
                {
                    binaryOperatorKind = BinaryOperatorKind.LessThanOrEqual;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordHas))
                {
                    binaryOperatorKind = BinaryOperatorKind.Has;
                }
                else
                {
                    break;
                }

                this.lexer.NextToken();
                QueryToken right = this.ParseAdditive();
                left = new BinaryOperatorToken(binaryOperatorKind, left, right);
            }

            this.RecurseLeave();
            return left;
        }
예제 #25
0
        /// <summary>
        /// Parses the add, sub operators.
        /// </summary>
        /// <returns>The lexical token representing the expression.</returns>
        private QueryToken ParseAdditive()
        {
            this.RecurseEnter();
            QueryToken left = this.ParseMultiplicative();
            while (this.TokenIdentifierIs(ExpressionConstants.KeywordAdd) ||
                this.TokenIdentifierIs(ExpressionConstants.KeywordSub))
            {
                BinaryOperatorKind binaryOperatorKind;
                if (this.TokenIdentifierIs(ExpressionConstants.KeywordAdd))
                {
                    binaryOperatorKind = BinaryOperatorKind.Add;
                }
                else
                {
                    Debug.Assert(this.TokenIdentifierIs(ExpressionConstants.KeywordSub), "Was a new binary operator added?");
                    binaryOperatorKind = BinaryOperatorKind.Subtract;
                }

                this.lexer.NextToken();
                QueryToken right = this.ParseMultiplicative();
                left = new BinaryOperatorToken(binaryOperatorKind, left, right);
            }

            this.RecurseLeave();
            return left;
        }
예제 #26
0
        /// <summary>
        /// Parses the mul, div, mod operators.
        /// </summary>
        /// <returns>The lexical token representing the expression.</returns>
        private QueryToken ParseMultiplicative()
        {
            this.RecurseEnter();
            QueryToken left = this.ParseUnary();
            while (this.TokenIdentifierIs(ExpressionConstants.KeywordMultiply) ||
                this.TokenIdentifierIs(ExpressionConstants.KeywordDivide) ||
                this.TokenIdentifierIs(ExpressionConstants.KeywordModulo))
            {
                BinaryOperatorKind binaryOperatorKind;
                if (this.TokenIdentifierIs(ExpressionConstants.KeywordMultiply))
                {
                    binaryOperatorKind = BinaryOperatorKind.Multiply;
                }
                else if (this.TokenIdentifierIs(ExpressionConstants.KeywordDivide))
                {
                    binaryOperatorKind = BinaryOperatorKind.Divide;
                }
                else
                {
                    Debug.Assert(this.TokenIdentifierIs(ExpressionConstants.KeywordModulo), "Was a new binary operator added?");
                    binaryOperatorKind = BinaryOperatorKind.Modulo;
                }

                this.lexer.NextToken();
                QueryToken right = this.ParseUnary();
                left = new BinaryOperatorToken(binaryOperatorKind, left, right);
            }

            this.RecurseLeave();
            return left;
        }
        public void AndOperatorNullLiteralShouldResultInBinaryOperatorNodeWithConvert()
        {
            this.leftParameterSingleValueQueryNode = new ConstantNode(null);
            this.rightParameterSingleValueQueryNode =
                new SingleValueFunctionCallNode(FuncName, null, EdmCoreModel.Instance.GetBoolean(false));

            var binaryOperatorQueryToken = new BinaryOperatorToken(BinaryOperatorKind.And, new LiteralToken("foo"), new LiteralToken("bar"));

            var resultNode = this.binaryOperatorBinder.BindBinaryOperator(binaryOperatorQueryToken);

            var binaryNode = resultNode.ShouldBeBinaryOperatorNode(BinaryOperatorKind.And).And;

            binaryNode.TypeReference.IsNullable.Should().BeTrue();

            var left = binaryNode.Left.ShouldBeConvertQueryNode(EdmPrimitiveTypeKind.Boolean).And;
            left.TypeReference.IsNullable.Should().BeTrue();
            left.Source.ShouldBeConstantQueryNode<object>(null);

            var right = binaryNode.Right.ShouldBeConvertQueryNode(EdmPrimitiveTypeKind.Boolean).And;
            right.TypeReference.IsNullable.Should().BeTrue();
            right.Source.ShouldBeSingleValueFunctionCallQueryNode(FuncName);
        }
            public bool Visit(BinaryOperatorToken tokenIn)
            {
                stringBuilder.Append('(');
                tokenIn.Left.Accept(this);
                stringBuilder.Append(' ');
                switch (tokenIn.OperatorKind)
                {
                case BinaryOperatorKind.Or:
                    stringBuilder.Append("OR");
                    break;

                case BinaryOperatorKind.And:
                    stringBuilder.Append("AND");
                    break;

                case BinaryOperatorKind.Equal:
                    stringBuilder.Append("=");
                    break;

                case BinaryOperatorKind.NotEqual:
                    stringBuilder.Append("!=");
                    break;

                case BinaryOperatorKind.GreaterThan:
                    stringBuilder.Append(">");
                    break;

                case BinaryOperatorKind.GreaterThanOrEqual:
                    stringBuilder.Append(">=");
                    break;

                case BinaryOperatorKind.LessThan:
                    stringBuilder.Append("<");
                    break;

                case BinaryOperatorKind.LessThanOrEqual:
                    stringBuilder.Append("<=");
                    break;

                case BinaryOperatorKind.Add:
                    stringBuilder.Append("+");
                    break;

                case BinaryOperatorKind.Subtract:
                    stringBuilder.Append("-");
                    break;

                case BinaryOperatorKind.Multiply:
                    stringBuilder.Append("*");
                    break;

                case BinaryOperatorKind.Divide:
                    stringBuilder.Append("/");
                    break;

                case BinaryOperatorKind.Modulo:
                    stringBuilder.Append("%");
                    break;

                default:
                    throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "QueryToken of type '{0}' is not supported.", tokenIn.OperatorKind));
                }
                stringBuilder.Append(' ');
                EndPathToken endPathToken = tokenIn.Left as EndPathToken;

                if (endPathToken != null && endPathToken.Identifier.Equals("Timestamp") && enableTimestampQuery)
                {
                    LiteralToken literalToken = tokenIn.Right as LiteralToken;
                    stringBuilder.Append(SchemaUtil.GetTimestampEpochSecondString(literalToken.Value));
                }
                else
                {
                    tokenIn.Right.Accept(this);
                }
                stringBuilder.Append(')');
                return(true);
            }