From 4924685876f7b3336a90337272a7937c380b55af Mon Sep 17 00:00:00 2001
From: Jun-Seok Heo <jun.seok.heo@samsung.com>
Date: Wed, 7 Nov 2018 11:09:43 +0900
Subject: [PATCH] [parser] parser,ast: fix the TiDB issue #8153 (#20)

---
 parser/ast/expressions.go |  9 ++++++++-
 parser/parser.go          | 10 ++++------
 parser/parser.y           | 12 +++++-------
 3 files changed, 17 insertions(+), 14 deletions(-)

diff --git a/parser/ast/expressions.go b/parser/ast/expressions.go
index e81f878760b8d..c3d38dcf7bcef 100644
--- a/parser/ast/expressions.go
+++ b/parser/ast/expressions.go
@@ -699,7 +699,7 @@ func (n *ParenthesesExpr) Accept(v Visitor) (Node, bool) {
 type PositionExpr struct {
 	exprNode
 	// N is the position, started from 1 now.
-	N int
+	N ExprNode
 	// Refer is the result field the position refers to.
 	Refer *ResultField
 }
@@ -716,6 +716,13 @@ func (n *PositionExpr) Accept(v Visitor) (Node, bool) {
 		return v.Leave(newNode)
 	}
 	n = newNode.(*PositionExpr)
+	if n.N != nil {
+		node, ok := n.N.Accept(v)
+		if !ok {
+			return n, false
+		}
+		n.N = node.(ExprNode)
+	}
 	return v.Leave(n)
 }
 
diff --git a/parser/parser.go b/parser/parser.go
index 13277a307628e..5d0bac0dcc94a 100644
--- a/parser/parser.go
+++ b/parser/parser.go
@@ -8399,12 +8399,10 @@ yynewstate:
 	case 606:
 		{
 			expr := yyS[yypt-1].expr
-			valueExpr, ok := expr.(ast.ValueExpr)
-			if ok {
-				position, isPosition := valueExpr.GetValue().(int64)
-				if isPosition {
-					expr = &ast.PositionExpr{N: int(position)}
-				}
+			if valueExpr, ok := expr.(ast.ValueExpr); ok {
+				expr = &ast.PositionExpr{N: valueExpr}
+			} else if paramExpr, ok := expr.(ast.ParamMarkerExpr); ok {
+				expr = &ast.PositionExpr{N: paramExpr}
 			}
 			parser.yyVAL.item = &ast.ByItem{Expr: expr, Desc: yyS[yypt-0].item.(bool)}
 		}
diff --git a/parser/parser.y b/parser/parser.y
index 344d2c5d00f02..04b9b82df3c07 100644
--- a/parser/parser.y
+++ b/parser/parser.y
@@ -3187,13 +3187,11 @@ ByItem:
 	Expression Order
 	{
 		expr := $1
-		valueExpr, ok := expr.(ast.ValueExpr)
-		if ok {
-			position, isPosition := valueExpr.GetValue().(int64)
-			if isPosition {
-				expr = &ast.PositionExpr{N: int(position)}
-			}
-		}
+		if valueExpr, ok := expr.(ast.ValueExpr); ok {
+			expr = &ast.PositionExpr{N: valueExpr}
+		} else if paramExpr, ok := expr.(ast.ParamMarkerExpr); ok {
+			expr = &ast.PositionExpr{N: paramExpr}
+ 		}
 		$$ = &ast.ByItem{Expr: expr, Desc: $2.(bool)}
 	}