Skip to content

Commit

Permalink
Merge pull request #28 from ryshoooo/feat/sql_handle_join
Browse files Browse the repository at this point in the history
feat: sql handler join support
  • Loading branch information
ryshoooo authored Sep 28, 2024
2 parents e1237ae + 542e04f commit 34e7568
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 44 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM docker.io/library/golang:1.22-alpine as builder
FROM docker.io/library/golang:1.23-alpine as builder

# Setup
RUN mkdir -p /go/src/github.com/ryshoooo/food-me
Expand Down
16 changes: 8 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/getsentry/raven-go v0.2.0 // indirect
github.com/getsentry/sentry-go v0.28.1 // indirect
github.com/getsentry/sentry-go v0.29.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/go-cmp v0.6.0 // indirect
Expand All @@ -31,17 +31,17 @@ require (
github.com/lib/pq v1.10.9 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/text v0.17.0 // indirect
google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed // indirect
google.golang.org/grpc v1.66.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
google.golang.org/genproto v0.0.0-20240924160255-9d4c2d233b61 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 // indirect
google.golang.org/grpc v1.67.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
)
36 changes: 18 additions & 18 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs=
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k=
github.com/getsentry/sentry-go v0.28.1/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg=
github.com/getsentry/sentry-go v0.29.0 h1:YtWluuCFg9OfcqnaujpY918N/AhCCwarIDWOYSBAjCA=
github.com/getsentry/sentry-go v0.29.0/go.mod h1:jhPesDAL0Q0W2+2YEuVOvdWmVtdsr1+jtBrlDEVWwLY=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
Expand Down Expand Up @@ -199,8 +199,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
Expand Down Expand Up @@ -282,8 +282,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg=
golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -317,8 +317,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -327,8 +327,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
Expand All @@ -354,21 +354,21 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed h1:4C4dbrVFtfIp3GXJdMX1Sj25mahfn5DywOo65/2ISQ8=
google.golang.org/genproto v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:ICjniACoWvcDz8c8bOsHVKuuSGDJy1z5M4G0DM3HzTc=
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed h1:3RgNmBoI9MZhsj3QxC+AP/qQhNwpCLOvYDYYsFrhFt0=
google.golang.org/genproto/googleapis/api v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:OCdP9MfskevB/rbYvHTsXTtKC+3bHWajPdoKgjcYkfo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed h1:J6izYgfBXAI3xTKLgxzTmUltdYaLsuBxFCgDHWJ/eXg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240827150818-7e3bb234dfed/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/genproto v0.0.0-20240924160255-9d4c2d233b61 h1:KipVMxePgXPFBzXOvpKbny3RVdVmJOD64R/Ob7GPWEs=
google.golang.org/genproto v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:HiAZQz/G7n0EywFjmncAwsfnmFm2bjm7qPjwl8hyzjM=
google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61 h1:pAjq8XSSzXoP9ya73v/w+9QEAAJNluLrpmMq5qFJQNY=
google.golang.org/genproto/googleapis/api v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:O6rP0uBq4k0mdi/b4ZEMAZjkhYWhS815kCvaMha4VN8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61 h1:N9BgCIAUvn/M+p4NJccWPWb3BWh88+zyL0ll9HgbEeM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240924160255-9d4c2d233b61/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c=
google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y=
google.golang.org/grpc v1.67.0 h1:IdH9y6PF5MPSdAntIcpjQ+tXO41pcQsfZV2RxtQgVcw=
google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
Expand Down
39 changes: 31 additions & 8 deletions internal/opa.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,27 @@ func (c *CompileResponse) Compile(stringEscapeChar, tableName, tableAlias string

for qidx, query := range c.Result.Queries {
iresp := make([]string, len(query))
allExtraTables := []string{}

for qqidx, iq := range query {
cnd, err := iq.Compile(stringEscapeChar, tableName, tableAlias)
if err != nil {
return "", fmt.Errorf("failed to compile response: %w", err)
}
iresp[qqidx] = fmt.Sprintf("(%s)", cnd)
iresp[qqidx] = fmt.Sprintf("(%s)", cnd.Value)

for _, et := range cnd.ExtraTables {
if !contains(allExtraTables, et) {
allExtraTables = append(allExtraTables, et)
}
}
}

resp[qidx] = fmt.Sprintf("(%s)", strings.Join(iresp, " AND "))
if len(allExtraTables) > 0 {
resp[qidx] = fmt.Sprintf("(exists (select 1 from %s where (%s)))", strings.Join(allExtraTables, ", "), strings.Join(iresp, " AND "))
} else {
resp[qidx] = fmt.Sprintf("(%s)", strings.Join(iresp, " AND "))
}
}

return strings.Join(resp, " OR "), nil
Expand All @@ -69,34 +80,41 @@ type CompileResponseQuery struct {
Terms []CompileResponseTerm `json:"terms"`
}

func (c *CompileResponseQuery) Compile(stringEscapeChart, tableName, tableAlias string) (string, error) {
func (c *CompileResponseQuery) Compile(stringEscapeChart, tableName, tableAlias string) (*CompiledQuery, error) {
if len(c.Terms) != 3 {
return "", fmt.Errorf("unexpected number of terms in query: %d", len(c.Terms))
return nil, fmt.Errorf("unexpected number of terms in query: %d", len(c.Terms))
}

ra := make([]*CompiledTerm, len(c.Terms))
for idx, term := range c.Terms {
ct, err := term.Compile(stringEscapeChart, tableName, tableAlias)
if err != nil {
return "", fmt.Errorf("failed to compile query: %w", err)
return nil, fmt.Errorf("failed to compile query: %w", err)
}
ra[idx] = ct
}

_ = setIndicesForCompiledTerms(ra)
result := make([]string, 3)
extraTables := []string{}
for _, compiledTerm := range ra {
if result[compiledTerm.Index] != "" {
return "", fmt.Errorf("index already used: %d (value %s)", compiledTerm.Index, compiledTerm.Value)
return nil, fmt.Errorf("index already used: %d (value %s)", compiledTerm.Index, compiledTerm.Value)
}
result[compiledTerm.Index] = compiledTerm.Value
if compiledTerm.IsTableReference {
extraTableName := strings.Split(compiledTerm.Value, ".")[0]
if extraTableName != tableName && extraTableName != tableAlias {
extraTables = append(extraTables, extraTableName)
}
}
}

f := strings.Join(result, " ")
if c.Negated {
return fmt.Sprintf("NOT (%s)", f), nil
return &CompiledQuery{Value: fmt.Sprintf("NOT (%s)", f), ExtraTables: extraTables}, nil
} else {
return f, nil
return &CompiledQuery{Value: f, ExtraTables: extraTables}, nil
}
}

Expand Down Expand Up @@ -219,6 +237,11 @@ type CompiledTerm struct {
Index int
}

type CompiledQuery struct {
Value string
ExtraTables []string
}

// Template context
type TemplateContext struct {
TableName string
Expand Down
73 changes: 70 additions & 3 deletions internal/opa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,79 @@ func TestCompileResponseQuery(t *testing.T) {

result, err := rq.Compile("'", "tablename", "")
assert.NilError(t, err)
assert.Equal(t, result, "tablename.columnname = true")
assert.Equal(t, result.Value, "tablename.columnname = true")
assert.Equal(t, len(result.ExtraTables), 0)

result, err = rq.Compile("'", "tablename", "t")
assert.NilError(t, err)
assert.Equal(t, result, "t.columnname = true")
assert.Equal(t, result.Value, "t.columnname = true")
assert.Equal(t, len(result.ExtraTables), 0)

rq.Negated = true
result, err = rq.Compile("'", "tablename", "t")
assert.NilError(t, err)
assert.Equal(t, result, "NOT (t.columnname = true)")
assert.Equal(t, result.Value, "NOT (t.columnname = true)")
assert.Equal(t, len(result.ExtraTables), 0)
}

func TestCompileResponseQueryMultipleTables(t *testing.T) {
rq := CompileResponseQuery{Index: 0, Negated: false, Terms: []CompileResponseTerm{
{Type: "ref", Value: []interface{}{
map[string]interface{}{"type": "var", "value": "data"},
map[string]interface{}{"type": "string", "value": "tables"},
map[string]interface{}{"type": "string", "value": "secondtablename"},
map[string]interface{}{"type": "string", "value": "id"},
}},
{Type: "ref", Value: []interface{}{map[string]interface{}{"type": "var", "value": "eq"}}},
{Type: "ref", Value: []interface{}{
map[string]interface{}{"type": "var", "value": "data"},
map[string]interface{}{"type": "string", "value": "tables"},
map[string]interface{}{"type": "string", "value": "tablename"},
map[string]interface{}{"type": "string", "value": "id"},
}},
}}

result, err := rq.Compile("'", "tablename", "")
assert.NilError(t, err)
assert.Equal(t, result.Value, "tablename.id = secondtablename.id")
assert.Equal(t, len(result.ExtraTables), 1)
assert.Equal(t, result.ExtraTables[0], "secondtablename")

result, err = rq.Compile("'", "tablename", "t")
assert.NilError(t, err)
assert.Equal(t, result.Value, "t.id = secondtablename.id")
assert.Equal(t, len(result.ExtraTables), 1)
assert.Equal(t, result.ExtraTables[0], "secondtablename")

rq.Negated = true
result, err = rq.Compile("'", "tablename", "t")
assert.NilError(t, err)
assert.Equal(t, result.Value, "NOT (t.id = secondtablename.id)")
assert.Equal(t, len(result.ExtraTables), 1)
assert.Equal(t, result.ExtraTables[0], "secondtablename")

rq.Negated = false
result, err = rq.Compile("'", "othertable", "")
assert.NilError(t, err)
assert.Equal(t, result.Value, "tablename.id = secondtablename.id")
assert.Equal(t, len(result.ExtraTables), 2)
assert.Equal(t, result.ExtraTables[0], "secondtablename")
assert.Equal(t, result.ExtraTables[1], "tablename")

result, err = rq.Compile("'", "othertable", "o")
assert.NilError(t, err)
assert.Equal(t, result.Value, "tablename.id = secondtablename.id")
assert.Equal(t, len(result.ExtraTables), 2)
assert.Equal(t, result.ExtraTables[0], "secondtablename")
assert.Equal(t, result.ExtraTables[1], "tablename")

rq.Negated = true
result, err = rq.Compile("'", "othertable", "o")
assert.NilError(t, err)
assert.Equal(t, result.Value, "NOT (tablename.id = secondtablename.id)")
assert.Equal(t, len(result.ExtraTables), 2)
assert.Equal(t, result.ExtraTables[0], "secondtablename")
assert.Equal(t, result.ExtraTables[1], "tablename")
}

func TestCompileResponseQueryEdgeCases(t *testing.T) {
Expand Down Expand Up @@ -301,6 +364,10 @@ func TestCompileResponse(t *testing.T) {
res, err := cr.Compile("'", "tablename", "t")
assert.NilError(t, err)
assert.Equal(t, res, "((t.columnname1 = 'val1') AND (NOT (t.columnname2 = 'val2'))) OR ((t.columnname3 >= 12))")

res, err = cr.Compile("'", "othertable", "o")
assert.NilError(t, err)
assert.Equal(t, res, "(exists (select 1 from tablename where ((tablename.columnname1 = 'val1') AND (NOT (tablename.columnname2 = 'val2'))))) OR (exists (select 1 from tablename where ((tablename.columnname3 >= 12))))")
}

func TestCompileResponseEdge(t *testing.T) {
Expand Down
21 changes: 16 additions & 5 deletions internal/postgres_sql_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func HandleTables(ctx interface{}, node interface{}) (stop bool) {
return true
}
case *tree.SelectClause:
for _, table := range node.From.Tables {
for tableIdx, table := range node.From.Tables {
tbs := getTableNamesAndAliases(table)
for _, tb := range tbs {
if _, ok := h.withTables[tb.TableName]; ok {
Expand Down Expand Up @@ -119,10 +119,21 @@ func HandleTables(ctx interface{}, node interface{}) (stop bool) {

if len(filters.JoinFilters) > 0 {
h.Logger.Debugf("Found join filters for table %s: %v", tb.TableName, filters.JoinFilters)
h.Logger.Error("join filters are not supported yet, sorry!")
h.handleFailed = true
h.handleError = fmt.Errorf("join filters are not supported yet, sorry")
return true
joinSql := fmt.Sprintf("SELECT * FROM %s", tb.TableName)
for _, f := range filters.JoinFilters {
joinSql = fmt.Sprintf("%s INNER JOIN %s ON %s", joinSql, f.TableName, f.Conditions)
}

pst, err := parser.Parse(joinSql)
if err != nil {
h.Logger.Errorf("failed to parse join statement for table %s: %v", tb.TableName, err)
h.handleFailed = true
h.handleError = fmt.Errorf("failed to parse join statement for table %s: %v", tb.TableName, err)
return true
}

newTblExpr := pst[0].AST.(*tree.Select).Select.(*tree.SelectClause).From.Tables[0]
node.From.Tables[tableIdx] = newTblExpr
}
}
}
Expand Down
Loading

0 comments on commit 34e7568

Please sign in to comment.