Skip to content

Commit

Permalink
Added not reserved keyword. Works for both not in and not like (#68)
Browse files Browse the repository at this point in the history
* Added not reserved keyword. Functions for both not in and not like

* removed all vestiges of T_NOT_OR_T_LIKE

* Deleting IDE files (1)

* Deleting IDE files (2)

* Deleting IDE files (3)

* Deleting IDE files (4)

* Deleting IDE files (5)

* Fixing spaces on tokens.go
  • Loading branch information
frahman5 authored and filhodanuvem committed Oct 15, 2018
1 parent 8804813 commit a3f1a73
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 2 deletions.
1 change: 1 addition & 0 deletions lexical/lexemes.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ const L_IN = "in"
const L_ASC = "asc"
const L_DESC = "desc"
const L_LIKE = "like"
const L_NOT = "not"
2 changes: 2 additions & 0 deletions lexical/lexical.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ func lexemeToToken(lexeme string) uint8 {
return T_DESC
case L_LIKE:
return T_LIKE
case L_NOT:
return T_NOT
}
return T_ID
}
Expand Down
5 changes: 4 additions & 1 deletion lexical/lexical_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ func TestErrorUnrecognizeChar(t *testing.T) {

func TestReservedWords(t *testing.T) {
setUp()
source = "SELECT from WHEre in "
source = "SELECT from WHEre in not"
char = nextChar()

var token uint8
Expand All @@ -144,6 +144,9 @@ func TestReservedWords(t *testing.T) {
token, _ = Token()
assertToken(t, token, T_IN)

token, _ = Token()
assertToken(t, token, T_NOT)

token, _ = Token()
assertToken(t, token, T_EOF)
}
Expand Down
2 changes: 2 additions & 0 deletions lexical/tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const T_PARENTH_R = 23
const T_IN = 24
const T_ASC = 25
const T_LIKE = 26
const T_NOT = 27
const T_EOF = 0
const T_FUCK = 66

Expand Down Expand Up @@ -58,6 +59,7 @@ func allocMapTokenNames() {
T_IN: "T_IN",
T_EOF: "T_EOF",
T_ASC: "T_ASC",
T_NOT: "T_NOT",
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions parser/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type NodeAdapterBinToConst struct {
type NodeIn struct {
leftValue NodeExpr
rightValue NodeExpr
Not bool
}

type NodeEqual struct {
Expand All @@ -73,6 +74,7 @@ type NodeLike struct {
leftValue NodeExpr
rightValue NodeExpr
Pattern *regexp.Regexp
Not bool
}

type NodeGreater struct {
Expand Down Expand Up @@ -129,6 +131,9 @@ func (e *NodeEmpty) Run() {
}

func (n *NodeIn) Assertion(lvalue string, rvalue string) bool {
if n.Not {
return !strings.Contains(rvalue, lvalue)
}
return strings.Contains(rvalue, lvalue)
}

Expand Down Expand Up @@ -210,6 +215,9 @@ func (n *NodeNotEqual) LeftValue() NodeExpr {

// LIKE
func (n *NodeLike) Assertion(lvalue string, rvalue string) bool {
if n.Not {
return !n.Pattern.MatchString(lvalue)
}
return n.Pattern.MatchString(lvalue)
}

Expand Down
17 changes: 16 additions & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ func gWC3(eating bool) (NodeExpr, error) {
return expr, nil
}

// where cond 'equal', 'in', 'like' and 'not equal'
// where cond 'equal', 'in', 'not in', 'like', 'not like' and 'not equal'
func gWC4(eating bool) (NodeExpr, error) {
if eating {
token, err := lexical.Token()
Expand All @@ -355,6 +355,19 @@ func gWC4(eating bool) (NodeExpr, error) {
return nil, err
}

var notBool bool
if look_ahead == lexical.T_NOT {
notBool = true
token, err := lexical.Token()
if err != nil {
return nil, err
}
look_ahead = token
if look_ahead != lexical.T_LIKE && look_ahead != lexical.T_IN {
return nil, throwSyntaxError(lexical.T_NOT, look_ahead)
}
}

switch look_ahead {
case lexical.T_EQUAL:
op := new(NodeEqual)
Expand Down Expand Up @@ -387,6 +400,7 @@ func gWC4(eating bool) (NodeExpr, error) {
// we don't need to compile for every row
rx := strings.Replace(expr2.(*NodeLiteral).Value(), "%", "(.*)", -1)
op.Pattern, err2 = regexp.Compile(rx)
op.Not = notBool
return op, err2
case lexical.T_IN:
op := new(NodeIn)
Expand All @@ -396,6 +410,7 @@ func gWC4(eating bool) (NodeExpr, error) {
return nil, err2
}
op.SetRightValue(expr2)
op.Not = notBool
return op, nil
}

Expand Down
148 changes: 148 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,154 @@ func TestWhereWithNotEqualCompare(t *testing.T) {
}
}

func TestWhereWithIn(t *testing.T) {
New("Select message from commits where 'react' in message")

ast, err := AST()
if err != nil {
t.Errorf(err.Error())
return
}

selectNode := ast.Child.(*NodeSelect)
w := selectNode.Where
if w == nil {
t.Errorf("should have where node")
}

if reflect.TypeOf(w) != reflect.TypeOf(new(NodeIn)) {
t.Errorf("should be a NodeIn")
}

notBool := w.(*NodeIn).Not
if notBool == true {
t.Errorf("Not bool should be set to false")
}

lValue := w.LeftValue().(*NodeLiteral)
rValue := w.RightValue().(*NodeId)
if lValue.Value() != "react" {
t.Errorf("LValue should be 'react'")
}

if rValue.Value() != "message" {
t.Errorf("RValue should be 'message'")
}



}

func TestWhereWithNotIn(t *testing.T) {
New("Select message from commits where 'react' not in message")

ast, err := AST()
if err != nil {
t.Errorf(err.Error())
return
}

selectNode := ast.Child.(*NodeSelect)
w := selectNode.Where
if w == nil {
t.Errorf("should have where node")
}

if reflect.TypeOf(w) != reflect.TypeOf(new(NodeIn)) {
t.Errorf("should be a NodeIn")
}

notBool := w.(*NodeIn).Not
if notBool == false {
t.Errorf("Not bool should be set to true")
}

lValue := w.LeftValue().(*NodeLiteral)
rValue := w.RightValue().(*NodeId)
if lValue.Value() != "react" {
t.Errorf("LValue should be 'react'")
}

if rValue.Value() != "message" {
t.Errorf("RValue should be 'message'")
}

}

func TestWhereWithLike(t *testing.T) {
New("Select author, message from commits where message like '%B'")

ast, err := AST()
if err != nil {
t.Errorf(err.Error())
return
}

selectNode := ast.Child.(*NodeSelect)
w := selectNode.Where
if w == nil {
t.Errorf("should have where node")
}

if reflect.TypeOf(w) != reflect.TypeOf(new(NodeLike)) {
t.Errorf("should be a NodeLike")
}

notBool := w.(*NodeLike).Not
if notBool == true {
t.Errorf("Not bool should be set to false")
}

lValue := w.LeftValue().(*NodeId)
rValue := w.RightValue().(*NodeLiteral)
if lValue.Value() != "message" {
t.Errorf("LValue should be 'message'")
}

es := `Rvalue should be &B`
if rValue.Value() != "%B" {
t.Errorf(es)
}

}

func TestWhereWithNotLike(t *testing.T) {
New("Select author, message from commits where message not like '%B'")

ast, err := AST()
if err != nil {
t.Errorf(err.Error())
return
}

selectNode := ast.Child.(*NodeSelect)
w := selectNode.Where
if w == nil {
t.Errorf("should have where node")
}

if reflect.TypeOf(w) != reflect.TypeOf(new(NodeLike)) {
t.Errorf("should be a NodeLike")
}

notBool := w.(*NodeLike).Not
if notBool == false {
t.Errorf("Not bool should be set to true")
}

lValue := w.LeftValue().(*NodeId)
rValue := w.RightValue().(*NodeLiteral)
if lValue.Value() != "message" {
t.Errorf("LValue should be 'message'")
}

es := `Rvalue should be &B`
if rValue.Value() != "%B" {
t.Errorf(es)
}

}

func TestWhereWithGreater(t *testing.T) {
New("select * from commits where date > '2014-05-12 00:00:00' ")

Expand Down

0 comments on commit a3f1a73

Please sign in to comment.