diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 727ec9f6..6ea09eb3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,5 @@ # global code owners * @TimSatke -internal/parser @SUMUKHA-PK \ No newline at end of file +internal/parser @SUMUKHA-PK +internal/raft @SUMUKHA-PK \ No newline at end of file diff --git a/.gitignore b/.gitignore index cee72eee..99325c9b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ *.log /xdb /xdb-fuzz.zip -.idea/ \ No newline at end of file +.idea/ diff --git a/SECURITY.md b/SECURITY.md index 627adbdf..7287816f 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -18,4 +18,3 @@ When building from source, please always use the latest version of Go that is av If you detect a vulnerability, please open a common issue. As there is no release intended for production use, vulnerabilities are not required to be handled critically yet. This will change as soon as we have our first production release. -See issue [#92](https://github.com/xqueries/xdb/issues/92) for more info. diff --git a/driver/driver_test.go b/driver/driver_test.go index 42be110f..9d09a971 100644 --- a/driver/driver_test.go +++ b/driver/driver_test.go @@ -33,7 +33,7 @@ func TestStatement(t *testing.T) { assert := assert.New(t) - pool, err := sql.Open("add", LocalDatabaseAddress) + pool, err := sql.Open("xdb", LocalDatabaseAddress) assert.NoError(err) assert.NoError(pool.Ping()) defer func() { diff --git a/go.mod b/go.mod index bd0763f3..8adc45bc 100644 --- a/go.mod +++ b/go.mod @@ -3,12 +3,23 @@ module github.com/xqueries/xdb go 1.13 require ( + github.com/golang/protobuf v1.5.2 + github.com/google/go-cmp v0.5.5 + github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/google/go-cmp v0.5.6 github.com/oklog/ulid v1.3.1 github.com/rs/zerolog v1.21.0 github.com/spf13/afero v1.6.0 github.com/spf13/cobra v1.1.3 github.com/stretchr/testify v1.7.0 + golang.org/x/mod v0.4.2 // indirect + golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 + golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 + golang.org/x/sys v0.0.0-20210415045647-66c3f260301c // indirect + golang.org/x/text v0.3.6 + golang.org/x/tools v0.1.0 + google.golang.org/protobuf v1.26.0 + gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/text v0.3.6 diff --git a/go.sum b/go.sum index 87533d08..aa078ae3 100644 --- a/go.sum +++ b/go.sum @@ -54,10 +54,14 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -103,7 +107,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -124,6 +127,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -133,8 +138,6 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -172,6 +175,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -205,11 +209,9 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -235,6 +237,8 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -265,6 +269,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210415045647-66c3f260301c h1:6L+uOeS3OQt/f4eFHXZcTxeZrGCuz+CLElgEBjbcTA4= +golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -323,10 +329,14 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/internal/network/errors.go b/internal/network/error.go similarity index 100% rename from internal/network/errors.go rename to internal/network/error.go diff --git a/internal/network/example_test.go b/internal/network/example_test.go index 13b413cb..19fae7bf 100644 --- a/internal/network/example_test.go +++ b/internal/network/example_test.go @@ -6,6 +6,7 @@ import ( "log" "github.com/rs/zerolog" + "github.com/xqueries/xdb/internal/id" "github.com/xqueries/xdb/internal/network" ) @@ -26,7 +27,8 @@ func ExampleServer() { <-srv.Listening() // wait for the server to come up - client, _ := network.DialTCP(ctx, ":59513") + clientID := id.Create() + client, _ := network.DialTCP(ctx, clientID, ":59513") defer func() { _ = client.Close() }() diff --git a/internal/network/mocks/conn.go b/internal/network/mocks/conn.go new file mode 100644 index 00000000..cb41ddfa --- /dev/null +++ b/internal/network/mocks/conn.go @@ -0,0 +1,82 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + id "github.com/xqueries/xdb/internal/id" +) + +// Conn is an autogenerated mock type for the Conn type +type Conn struct { + mock.Mock +} + +// Close provides a mock function with given fields: +func (_m *Conn) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Receive provides a mock function with given fields: _a0 +func (_m *Conn) Receive(ctx context.Context) ([]byte, error) { + ret := _m.Called(ctx) + + var r0 []byte + if rf, ok := ret.Get(0).(func(context.Context) []byte); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RemoteID provides a mock function with given fields: +func (_m *Conn) RemoteID() id.ID { + ret := _m.Called() + + var r0 id.ID + if rf, ok := ret.Get(0).(func() id.ID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(id.ID) + } + } + + return r0 +} + +// Send provides a mock function with given fields: _a0, _a1 +func (_m *Conn) Send(ctx context.Context, _a1 []byte) error { + ret := _m.Called(ctx, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []byte) error); ok { + r0 = rf(ctx, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/internal/network/mocks/doc.go b/internal/network/mocks/doc.go new file mode 100644 index 00000000..35abed3d --- /dev/null +++ b/internal/network/mocks/doc.go @@ -0,0 +1,2 @@ +// Package mocks provides generated mock implementations for easy testing. +package mocks diff --git a/internal/network/server.go b/internal/network/server.go index 99b659b2..f5421b6e 100644 --- a/internal/network/server.go +++ b/internal/network/server.go @@ -2,9 +2,10 @@ package network import ( "context" - "fmt" "io" "net" + + "github.com/xqueries/xdb/internal/id" ) // ConnHandler is a handler function for handling new connections. It will be @@ -29,11 +30,16 @@ type Server interface { // Addr returns the address that this server is listening to. Addr() net.Addr + // OwnID returns the ID of this server. The remote ID of any connection is + // the own ID of another server. + OwnID() id.ID // OnConnect sets a callback that will be executed whenever a new connection // connects to this server. OnConnect(ConnHandler) } +//go:generate mockery -case=snake -name=Conn + // Conn describes a network connection. One can send a message with Conn.Send, // and receive one with Conn.Receive. Unlike an io.Writer, the data that is // passed into Send is guaranteed to be returned in a single Receive call on the @@ -42,9 +48,8 @@ type Server interface { type Conn interface { io.Closer - // ID returns the ID of this connection. It can be used to uniquely identify - // this connection globally. - ID() ID + // RemoteID returns the own ID of the server that this connection points to. + RemoteID() id.ID // Send sends the given payload to the remote part of this connection. The // message will not be chunked, and can be read with a single call to // Conn.Receive. @@ -53,10 +58,3 @@ type Conn interface { // is a byte slice that was sent with a single call to Conn.Send. Receive(context.Context) ([]byte, error) } - -// ID describes an identifier that is used for connections. An ID has to be -// unique application-wide. IDs must not be re-used. -type ID interface { - fmt.Stringer - Bytes() []byte -} diff --git a/internal/network/tcp_conn.go b/internal/network/tcp_conn.go index daa77006..ac82a742 100644 --- a/internal/network/tcp_conn.go +++ b/internal/network/tcp_conn.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "sync" + "sync/atomic" "time" "github.com/xqueries/xdb/internal/id" @@ -23,8 +24,8 @@ var ( var _ Conn = (*tcpConn)(nil) type tcpConn struct { - id ID - closed bool + remoteID id.ID + closed int32 readLock sync.Mutex writeLock sync.Mutex @@ -33,7 +34,7 @@ type tcpConn struct { // DialTCP dials to the given address, assuming a TCP network. The returned Conn // is ready to use. -func DialTCP(ctx context.Context, addr string) (Conn, error) { +func DialTCP(ctx context.Context, ownID id.ID, addr string) (Conn, error) { // dial the remote endpoint var d net.Dialer conn, err := d.DialContext(ctx, "tcp", addr) @@ -44,38 +45,50 @@ func DialTCP(ctx context.Context, addr string) (Conn, error) { // create a new connection object tcpConn := newTCPConn(conn) - // receive the connection ID from the remote endpoint and apply it - myID, err := tcpConn.Receive(ctx) + // receive the remote ID from the remote endpoint and apply it + remoteID, err := tcpConn.Receive(ctx) if err != nil { _ = tcpConn.Close() - return nil, fmt.Errorf("receive ID: %w", err) + return nil, fmt.Errorf("receive remote ID: %w", err) } - parsedID, err := id.Parse(myID) + parsedID, err := id.Parse(remoteID) if err != nil { _ = tcpConn.Close() - return nil, fmt.Errorf("parse ID: %w", err) + return nil, fmt.Errorf("parse remote ID: %w", err) + } + tcpConn.remoteID = parsedID + + // send own ID to remote endpoint + err = tcpConn.Send(ctx, ownID.Bytes()) + if err != nil { + _ = tcpConn.Close() + return nil, fmt.Errorf("send own ID: %w", err) } - tcpConn.id = parsedID // return the connection object return tcpConn, nil } +// NewTCPConn wraps the underlying connection into a tcpConn. +func NewTCPConn(underlying net.Conn) Conn { + return newTCPConn(underlying) +} + func newTCPConn(underlying net.Conn) *tcpConn { id := id.Create() conn := &tcpConn{ - id: id, + remoteID: id, underlying: underlying, } return conn } -func (c *tcpConn) ID() ID { - return c.id +func (c *tcpConn) RemoteID() id.ID { + return c.remoteID } func (c *tcpConn) Send(ctx context.Context, payload []byte) error { - if c.closed { + if atomic.LoadInt32(&c.closed) == 1 { return ErrClosed } @@ -138,7 +151,7 @@ func (c *tcpConn) sendAsync(payload []byte) chan error { } func (c *tcpConn) Receive(ctx context.Context) ([]byte, error) { - if c.closed { + if atomic.LoadInt32(&c.closed) == 1 { return nil, ErrClosed } @@ -203,7 +216,11 @@ func (c *tcpConn) receiveAsync() chan interface{} { } func (c *tcpConn) Close() error { - c.closed = true + if atomic.LoadInt32(&c.closed) == 1 { + return nil + } + + atomic.StoreInt32(&c.closed, 1) // release all resources ctx := context.Background() diff --git a/internal/network/tcp_conn_test.go b/internal/network/tcp_conn_test.go index 19a74b5c..52d37778 100644 --- a/internal/network/tcp_conn_test.go +++ b/internal/network/tcp_conn_test.go @@ -9,6 +9,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/xqueries/xdb/internal/id" ) func TestTCPConnSendReceive(t *testing.T) { @@ -17,7 +18,7 @@ func TestTCPConnSendReceive(t *testing.T) { defer cancel() conn1, conn2 := net.Pipe() - tcpConn1, tcpConn2 := newTCPConn(conn1), newTCPConn(conn2) + tcpConn1, tcpConn2 := NewTCPConn(conn1), NewTCPConn(conn2) payload := []byte("Hello, World!") recv := make([]byte, len(payload)) @@ -47,16 +48,23 @@ func TestDialTCP(t *testing.T) { lis, err := net.Listen("tcp", ":0") assert.NoError(err) + clientID := id.Create() + srvID := id.Create() var wg sync.WaitGroup wg.Add(1) - var srvConnID string go func() { conn, err := lis.Accept() assert.NoError(err) - tcpConn := newTCPConn(conn) - srvConnID = tcpConn.ID().String() - assert.NoError(tcpConn.Send(ctx, tcpConn.ID().Bytes())) + // default handshake + tcpConn := NewTCPConn(conn) + assert.NoError(tcpConn.Send(ctx, srvID.Bytes())) // send server ID + recvID, err := tcpConn.Receive(ctx) // receive client ID + assert.NoError(err) // + parsedID, err := id.Parse(recvID) // parse client ID + assert.NoError(err) // + assert.Equal(clientID.String(), parsedID.String()) // parsed ID must be equal to actual client ID + assert.NoError(tcpConn.Send(ctx, payload)) wg.Done() @@ -64,10 +72,10 @@ func TestDialTCP(t *testing.T) { port := lis.Addr().(*net.TCPAddr).Port - conn, err := DialTCP(ctx, ":"+strconv.Itoa(port)) + conn, err := DialTCP(ctx, clientID, ":"+strconv.Itoa(port)) assert.NoError(err) defer func() { assert.NoError(conn.Close()) }() - assert.Equal(srvConnID, conn.ID().String()) + assert.Equal(srvID.String(), conn.RemoteID().String()) recv, err := conn.Receive(ctx) assert.NoError(err) @@ -82,7 +90,7 @@ func TestTCPConnWriteContext(t *testing.T) { defer cancel() conn1, conn2 := net.Pipe() - tcpConn1, _ := newTCPConn(conn1), newTCPConn(conn2) + tcpConn1, _ := NewTCPConn(conn1), NewTCPConn(conn2) err := tcpConn1.Send(ctx, []byte("Hello")) // will not be able to write within 10ms, because noone is reading assert.Equal(ErrTimeout, err) @@ -94,7 +102,7 @@ func TestTCPConnReadContext(t *testing.T) { defer cancel() conn1, conn2 := net.Pipe() - tcpConn1, _ := newTCPConn(conn1), newTCPConn(conn2) + tcpConn1, _ := NewTCPConn(conn1), NewTCPConn(conn2) data, err := tcpConn1.Receive(ctx) // will not be able to receive within 10ms, because noone is writing assert.Equal(ErrTimeout, err) diff --git a/internal/network/tcp_server.go b/internal/network/tcp_server.go index 097c0974..52500509 100644 --- a/internal/network/tcp_server.go +++ b/internal/network/tcp_server.go @@ -5,7 +5,10 @@ import ( "net" "time" + "sync" + "github.com/rs/zerolog" + "github.com/xqueries/xdb/internal/id" "golang.org/x/net/context" "golang.org/x/sync/errgroup" ) @@ -19,18 +22,27 @@ type tcpServer struct { listening chan struct{} lis net.Listener + ownID id.ID + onConnect ConnHandler + // lock needed for atomic write on onConnect. + mu sync.Mutex } // NewTCPServer creates a new ready to use TCP server that uses the given // logger. func NewTCPServer(log zerolog.Logger) Server { return &tcpServer{ - log: log, + log: log.With().Str("server", "tcp").Logger(), listening: make(chan struct{}), + ownID: id.Create(), } } +func (s *tcpServer) OwnID() id.ID { + return s.ownID +} + func (s *tcpServer) Open(addr string) error { if s.open { return ErrOpen @@ -64,6 +76,8 @@ func (s *tcpServer) Addr() net.Addr { } func (s *tcpServer) OnConnect(h ConnHandler) { + s.mu.Lock() + defer s.mu.Unlock() s.onConnect = h } @@ -73,7 +87,12 @@ func (s *tcpServer) Close() error { // release all resources ctx := context.Background() errs, _ := errgroup.WithContext(ctx) - errs.Go(s.lis.Close) + errs.Go(func() error { + if s.lis == nil { + return nil + } + return s.lis.Close() + }) return errs.Wait() } @@ -108,7 +127,8 @@ func (s *tcpServer) handleIncomingNetConn(conn net.Conn) { ctx, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() - err := tcpConn.Send(ctx, tcpConn.id.Bytes()) + // send own ID to client + err := tcpConn.Send(ctx, s.ownID.Bytes()) if err != nil { s.log.Error(). Err(err). @@ -117,6 +137,27 @@ func (s *tcpServer) handleIncomingNetConn(conn net.Conn) { return } + // receive the client ID from the remote endpoint and apply it + remoteID, err := tcpConn.Receive(ctx) + if err != nil { + s.log.Error(). + Err(err). + Msg("receive remote ID") + _ = tcpConn.Close() + return + } + parsedID, err := id.Parse(remoteID) + if err != nil { + s.log.Error(). + Err(err). + Msg("parse remote ID") + _ = tcpConn.Close() + return + } + tcpConn.remoteID = parsedID + + s.mu.Lock() + defer s.mu.Unlock() if s.onConnect != nil { s.onConnect(tcpConn) } diff --git a/internal/network/tcp_server_test.go b/internal/network/tcp_server_test.go new file mode 100644 index 00000000..cc05a593 --- /dev/null +++ b/internal/network/tcp_server_test.go @@ -0,0 +1,68 @@ +package network_test + +import ( + "context" + "testing" + "time" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" +) + +// TestTCPServerHandshake ensures that the server logon handshake with DialTCP +// works correctly. The handshake is responsible for sending the client the +// server ID, and then receive the client ID and remember it in its connection. +// After the handshake, the ID of the connection on the server side must be +// equal to the client ID, and the remote ID of the connection created with +// DialTCP must be equal to the server ID. +func TestTCPServerHandshake(t *testing.T) { + assert := assert.New(t) + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) + defer cancel() + + // create the server + server := network.NewTCPServer(zerolog.Nop()) + defer func() { _ = server.Close() }() + + serverID := server.OwnID() + assert.NotNil(serverID) + serverConns := make(chan network.Conn) + server.OnConnect(func(conn network.Conn) { + serverConns <- conn + }) + + // open the server in separate goroutine + go func() { + err := server.Open(":0") + assert.NoError(err) + }() + + // enforce timeout for server open + select { + case <-ctx.Done(): + _ = server.Close() + t.Error("timeout") + case <-server.Listening(): + } + + t.Logf("server address: %v", server.Addr()) + + // dial the server + conn1ID := id.Create() // create a connection ID + conn1, err := network.DialTCP(ctx, conn1ID, server.Addr().String()) + assert.NoError(err) + + // check the client side connection + assert.Equal(serverID, conn1.RemoteID()) // ensure that the remote ID of this connection is equal to the own ID of the server + + // check the server side connections + select { + case conn := <-serverConns: + assert.Equal(conn1ID, conn.RemoteID()) + case <-ctx.Done(): + assert.Fail("timeout") + } +} diff --git a/internal/network/test_framework.go b/internal/network/test_framework.go new file mode 100644 index 00000000..557f5362 --- /dev/null +++ b/internal/network/test_framework.go @@ -0,0 +1,28 @@ +package network + +import ( + "github.com/rs/zerolog" +) + +// TestNode describes a single node and all its connections. +type TestNode struct { + Node Server + Conns []Conn +} + +// NewTestNode returns a ready to use node with no connections associated. +func NewTestNode(IP, port string, log zerolog.Logger) (tNode *TestNode, err error) { + node := NewTCPServer(log) + go func() { + err = node.Open(IP + ":" + port) + }() + + if err != nil { + return + } + + <-node.Listening() + return &TestNode{ + Node: node, + }, nil +} diff --git a/internal/node/error.go b/internal/node/error.go new file mode 100644 index 00000000..75abb92a --- /dev/null +++ b/internal/node/error.go @@ -0,0 +1,18 @@ +package node + +// Error is a helper type for creating constant errors. +type Error string + +func (e Error) Error() string { return string(e) } + +const ( + // ErrOpen indicates, that the component was already opened, and it is + // unable to be opened another time. + ErrOpen Error = "already open" + // ErrClosed indicates, that the component is already closed, and it cannot + // be used anymore. + ErrClosed Error = "already closed" + // ErrTimeout indicates, that a the operation took longer than allowed. + // Maybe there was a deadline from a context. + ErrTimeout Error = "timeout" +) diff --git a/internal/node/node.go b/internal/node/node.go index f92a3a86..86f7ea54 100644 --- a/internal/node/node.go +++ b/internal/node/node.go @@ -5,14 +5,22 @@ import ( "fmt" "github.com/rs/zerolog" + "github.com/xqueries/xdb/internal/engine" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft" + "github.com/xqueries/xdb/internal/raft/cluster" + "github.com/xqueries/xdb/internal/raft/message" + "golang.org/x/sync/errgroup" ) -// Node is a database node. -// -// m := node.New(log) -// err := m.ListenAndServe(ctx, ":34213") +// Node is a database node. It uses an underlying raft.Server to communicate +// with other nodes, if any. type Node struct { - log zerolog.Logger + log zerolog.Logger + engine engine.Engine + + raft raft.Server + cluster cluster.Cluster } // New creates a new node that is executing commands on the given executor. @@ -26,9 +34,87 @@ func New(log zerolog.Logger) *Node { // be used to stop the server, since there is no stop function. Canceling the // context or a context timeout will cause the server to attempt a graceful // shutdown. -func (m *Node) ListenAndServe(ctx context.Context, addr string) error { - m.log.Info(). +func (n *Node) ListenAndServe(ctx context.Context, addr string) error { + n.log.Info(). Str("addr", addr). Msg("listen and serve") return fmt.Errorf("unimplemented") } + +// Open opens a new cluster, making this node the only node in the cluster. +// Other clusters can connect to the given address and perform the implemented +// handshake, in order to become nodes in the cluster. +func (n *Node) Open(ctx context.Context, addr string) error { + n.log.Info(). + Str("addr", addr). + Msg("open") + + if err := n.openCluster(ctx, addr); err != nil { + return fmt.Errorf("open cluster: %w", err) + } + + return n.startNode(ctx) +} + +// Close closes the node, starting with the underlying raft server, then the +// cluster, then the executor. +func (n *Node) Close() error { + ctx := context.TODO() + errs, _ := errgroup.WithContext(ctx) + errs.Go(n.raft.Close) + errs.Go(n.cluster.Close) + errs.Go(n.engine.Close) + return errs.Wait() +} + +func (n *Node) openCluster(ctx context.Context, addr string) error { + if n.cluster != nil { + return ErrOpen + } + + cluster := cluster.NewTCPCluster(n.log) + cluster.OnConnect(n.performLogonHandshake) + if err := cluster.Open(ctx, addr); err != nil { + return fmt.Errorf("open cluster: %w", err) + } + return nil +} + +func (n *Node) performLogonHandshake(cluster cluster.Cluster, conn network.Conn) { + n.log.Debug(). + Str("conn-id", conn.RemoteID().String()). + Msg("perform handshake") + + n.log.Info(). + Str("conn-id", conn.RemoteID().String()). + Msg("connected") + + cluster.AddConnection(conn) +} + +func (n *Node) startNode(ctx context.Context) error { + n.raft = raft.NewServer(n.log, n.cluster) + // The replication function is set to allow command + // execution on replication of messages in the nodes. + n.raft.OnReplication(n.replicate) + + return n.raft.Start(ctx) +} + +// replicate returns the number of commands that were executed from the +// given slice of commands. -1 is returned if no commands were executed. +func (n *Node) replicate(input []*message.Command) int { + for i := range input { + cmd := message.ConvertMessageToCommand(input[i]) + + // Link to the engine's executor must be added here. + _, err := n.engine.Evaluate(cmd) + if err != nil { + n.log.Error(). + Err(err). + Msg("failed to replicate input: execute") + return i - 1 + } + } + return len(input) +} diff --git a/internal/parser/scanner/ruleset/ruleset_default_keyword_trie.go b/internal/parser/scanner/ruleset/ruleset_default_keyword_trie.go index 5a930cdc..54737693 100644 --- a/internal/parser/scanner/ruleset/ruleset_default_keyword_trie.go +++ b/internal/parser/scanner/ruleset/ruleset_default_keyword_trie.go @@ -9,8 +9,8 @@ func defaultKeywordsRule(s RuneScanner) (token.Type, bool) { if !ok { return token.Unknown, false } - peek, noEof := s.Lookahead() - if noEof && defaultLiteral.Matches(peek) { // keywords must be terminated with a whitespace + peek, noEOF := s.Lookahead() + if noEOF && defaultLiteral.Matches(peek) { // keywords must be terminated with a whitespace return token.Unknown, false } return tok, ok @@ -22,95 +22,72 @@ func scanKeyword(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordA(s) - case 'B', 'b': s.ConsumeRune() return scanKeywordB(s) - case 'C', 'c': s.ConsumeRune() return scanKeywordC(s) - case 'D', 'd': s.ConsumeRune() return scanKeywordD(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordE(s) - case 'F', 'f': s.ConsumeRune() return scanKeywordF(s) - case 'G', 'g': s.ConsumeRune() return scanKeywordG(s) - case 'H', 'h': s.ConsumeRune() return scanKeywordH(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordI(s) - case 'J', 'j': s.ConsumeRune() return scanKeywordJ(s) - case 'K', 'k': s.ConsumeRune() return scanKeywordK(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordL(s) - case 'M', 'm': s.ConsumeRune() return scanKeywordM(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordN(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordO(s) - case 'P', 'p': s.ConsumeRune() return scanKeywordP(s) - case 'Q', 'q': s.ConsumeRune() return scanKeywordQ(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordR(s) - case 'S', 's': s.ConsumeRune() return scanKeywordS(s) - case 'T', 't': s.ConsumeRune() return scanKeywordT(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordU(s) - case 'V', 'v': s.ConsumeRune() return scanKeywordV(s) - case 'W', 'w': s.ConsumeRune() return scanKeywordW(s) @@ -124,39 +101,30 @@ func scanKeywordA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordAB(s) - case 'C', 'c': s.ConsumeRune() return scanKeywordAC(s) - case 'D', 'd': s.ConsumeRune() return scanKeywordAD(s) - case 'F', 'f': s.ConsumeRune() return scanKeywordAF(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordAL(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordAN(s) - case 'S', 's': s.ConsumeRune() return scanKeywordAS(s) - case 'T', 't': s.ConsumeRune() return scanKeywordAT(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordAU(s) @@ -170,7 +138,6 @@ func scanKeywordAB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordABO(s) @@ -184,7 +151,6 @@ func scanKeywordABO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordABOR(s) @@ -198,7 +164,6 @@ func scanKeywordABOR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordABORT(s) @@ -216,7 +181,6 @@ func scanKeywordAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordACT(s) @@ -230,7 +194,6 @@ func scanKeywordACT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordACTI(s) @@ -244,7 +207,6 @@ func scanKeywordACTI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordACTIO(s) @@ -258,7 +220,6 @@ func scanKeywordACTIO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordACTION(s) @@ -276,7 +237,6 @@ func scanKeywordAD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordADD(s) @@ -294,7 +254,6 @@ func scanKeywordAF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordAFT(s) @@ -308,7 +267,6 @@ func scanKeywordAFT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordAFTE(s) @@ -322,7 +280,6 @@ func scanKeywordAFTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordAFTER(s) @@ -340,15 +297,12 @@ func scanKeywordAL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordALL(s) - case 'T', 't': s.ConsumeRune() return scanKeywordALT(s) - case 'W', 'w': s.ConsumeRune() return scanKeywordALW(s) @@ -366,7 +320,6 @@ func scanKeywordALT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordALTE(s) @@ -380,7 +333,6 @@ func scanKeywordALTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordALTER(s) @@ -398,7 +350,6 @@ func scanKeywordALW(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordALWA(s) @@ -412,7 +363,6 @@ func scanKeywordALWA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordALWAY(s) @@ -426,7 +376,6 @@ func scanKeywordALWAY(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordALWAYS(s) @@ -444,11 +393,9 @@ func scanKeywordAN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordANA(s) - case 'D', 'd': s.ConsumeRune() return scanKeywordAND(s) @@ -462,7 +409,6 @@ func scanKeywordANA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordANAL(s) @@ -476,7 +422,6 @@ func scanKeywordANAL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordANALY(s) @@ -490,7 +435,6 @@ func scanKeywordANALY(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Z', 'z': s.ConsumeRune() return scanKeywordANALYZ(s) @@ -504,7 +448,6 @@ func scanKeywordANALYZ(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordANALYZE(s) @@ -526,7 +469,6 @@ func scanKeywordAS(s RuneScanner) (token.Type, bool) { return token.KeywordAs, true } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordASC(s) @@ -544,7 +486,6 @@ func scanKeywordAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordATT(s) @@ -558,7 +499,6 @@ func scanKeywordATT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordATTA(s) @@ -572,7 +512,6 @@ func scanKeywordATTA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordATTAC(s) @@ -586,7 +525,6 @@ func scanKeywordATTAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordATTACH(s) @@ -604,7 +542,6 @@ func scanKeywordAU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordAUT(s) @@ -618,7 +555,6 @@ func scanKeywordAUT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordAUTO(s) @@ -632,7 +568,6 @@ func scanKeywordAUTO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordAUTOI(s) @@ -646,7 +581,6 @@ func scanKeywordAUTOI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordAUTOIN(s) @@ -660,7 +594,6 @@ func scanKeywordAUTOIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordAUTOINC(s) @@ -674,7 +607,6 @@ func scanKeywordAUTOINC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordAUTOINCR(s) @@ -688,7 +620,6 @@ func scanKeywordAUTOINCR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordAUTOINCRE(s) @@ -702,7 +633,6 @@ func scanKeywordAUTOINCRE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordAUTOINCREM(s) @@ -716,7 +646,6 @@ func scanKeywordAUTOINCREM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordAUTOINCREME(s) @@ -730,7 +659,6 @@ func scanKeywordAUTOINCREME(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordAUTOINCREMEN(s) @@ -744,7 +672,6 @@ func scanKeywordAUTOINCREMEN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordAUTOINCREMENT(s) @@ -762,11 +689,9 @@ func scanKeywordB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordBE(s) - case 'Y', 'y': s.ConsumeRune() return scanKeywordBY(s) @@ -780,15 +705,12 @@ func scanKeywordBE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordBEF(s) - case 'G', 'g': s.ConsumeRune() return scanKeywordBEG(s) - case 'T', 't': s.ConsumeRune() return scanKeywordBET(s) @@ -802,7 +724,6 @@ func scanKeywordBEF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordBEFO(s) @@ -816,7 +737,6 @@ func scanKeywordBEFO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordBEFOR(s) @@ -830,7 +750,6 @@ func scanKeywordBEFOR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordBEFORE(s) @@ -848,7 +767,6 @@ func scanKeywordBEG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordBEGI(s) @@ -862,7 +780,6 @@ func scanKeywordBEGI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordBEGIN(s) @@ -880,7 +797,6 @@ func scanKeywordBET(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'W', 'w': s.ConsumeRune() return scanKeywordBETW(s) @@ -894,7 +810,6 @@ func scanKeywordBETW(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordBETWE(s) @@ -908,7 +823,6 @@ func scanKeywordBETWE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordBETWEE(s) @@ -922,7 +836,6 @@ func scanKeywordBETWEE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordBETWEEN(s) @@ -944,23 +857,18 @@ func scanKeywordC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCA(s) - case 'H', 'h': s.ConsumeRune() return scanKeywordCH(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordCO(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordCR(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordCU(s) @@ -974,7 +882,6 @@ func scanKeywordCA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordCAS(s) @@ -988,15 +895,12 @@ func scanKeywordCAS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordCASC(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordCASE(s) - case 'T', 't': s.ConsumeRune() return scanKeywordCAST(s) @@ -1010,7 +914,6 @@ func scanKeywordCASC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCASCA(s) @@ -1024,7 +927,6 @@ func scanKeywordCASCA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordCASCAD(s) @@ -1038,7 +940,6 @@ func scanKeywordCASCAD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCASCADE(s) @@ -1064,7 +965,6 @@ func scanKeywordCH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCHE(s) @@ -1078,7 +978,6 @@ func scanKeywordCHE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordCHEC(s) @@ -1092,7 +991,6 @@ func scanKeywordCHEC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'K', 'k': s.ConsumeRune() return scanKeywordCHECK(s) @@ -1110,15 +1008,12 @@ func scanKeywordCO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordCOL(s) - case 'M', 'm': s.ConsumeRune() return scanKeywordCOM(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordCON(s) @@ -1132,11 +1027,9 @@ func scanKeywordCOL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordCOLL(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordCOLU(s) @@ -1150,7 +1043,6 @@ func scanKeywordCOLL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCOLLA(s) @@ -1164,7 +1056,6 @@ func scanKeywordCOLLA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCOLLAT(s) @@ -1178,7 +1069,6 @@ func scanKeywordCOLLAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCOLLATE(s) @@ -1196,7 +1086,6 @@ func scanKeywordCOLU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordCOLUM(s) @@ -1210,7 +1099,6 @@ func scanKeywordCOLUM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordCOLUMN(s) @@ -1228,7 +1116,6 @@ func scanKeywordCOM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordCOMM(s) @@ -1242,7 +1129,6 @@ func scanKeywordCOMM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordCOMMI(s) @@ -1256,7 +1142,6 @@ func scanKeywordCOMMI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCOMMIT(s) @@ -1274,11 +1159,9 @@ func scanKeywordCON(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordCONF(s) - case 'S', 's': s.ConsumeRune() return scanKeywordCONS(s) @@ -1292,7 +1175,6 @@ func scanKeywordCONF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordCONFL(s) @@ -1306,7 +1188,6 @@ func scanKeywordCONFL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordCONFLI(s) @@ -1320,7 +1201,6 @@ func scanKeywordCONFLI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordCONFLIC(s) @@ -1334,7 +1214,6 @@ func scanKeywordCONFLIC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCONFLICT(s) @@ -1352,7 +1231,6 @@ func scanKeywordCONS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCONST(s) @@ -1366,7 +1244,6 @@ func scanKeywordCONST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordCONSTR(s) @@ -1380,7 +1257,6 @@ func scanKeywordCONSTR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCONSTRA(s) @@ -1394,7 +1270,6 @@ func scanKeywordCONSTRA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordCONSTRAI(s) @@ -1408,7 +1283,6 @@ func scanKeywordCONSTRAI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordCONSTRAIN(s) @@ -1422,7 +1296,6 @@ func scanKeywordCONSTRAIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCONSTRAINT(s) @@ -1440,11 +1313,9 @@ func scanKeywordCR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCRE(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordCRO(s) @@ -1458,7 +1329,6 @@ func scanKeywordCRE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCREA(s) @@ -1472,7 +1342,6 @@ func scanKeywordCREA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCREAT(s) @@ -1486,7 +1355,6 @@ func scanKeywordCREAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCREATE(s) @@ -1504,7 +1372,6 @@ func scanKeywordCRO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordCROS(s) @@ -1518,7 +1385,6 @@ func scanKeywordCROS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordCROSS(s) @@ -1536,7 +1402,6 @@ func scanKeywordCU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordCUR(s) @@ -1550,7 +1415,6 @@ func scanKeywordCUR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordCURR(s) @@ -1564,7 +1428,6 @@ func scanKeywordCURR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCURRE(s) @@ -1578,7 +1441,6 @@ func scanKeywordCURRE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordCURREN(s) @@ -1592,7 +1454,6 @@ func scanKeywordCURREN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCURRENT(s) @@ -1606,7 +1467,6 @@ func scanKeywordCURRENT(s RuneScanner) (token.Type, bool) { return token.KeywordCurrent, true } switch next { - case '_': s.ConsumeRune() return scanKeywordCURRENTx(s) @@ -1620,11 +1480,9 @@ func scanKeywordCURRENTx(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordCURRENTxD(s) - case 'T', 't': s.ConsumeRune() return scanKeywordCURRENTxT(s) @@ -1638,7 +1496,6 @@ func scanKeywordCURRENTxD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCURRENTxDA(s) @@ -1652,7 +1509,6 @@ func scanKeywordCURRENTxDA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCURRENTxDAT(s) @@ -1666,7 +1522,6 @@ func scanKeywordCURRENTxDAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCURRENTxDATE(s) @@ -1684,7 +1539,6 @@ func scanKeywordCURRENTxT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordCURRENTxTI(s) @@ -1698,7 +1552,6 @@ func scanKeywordCURRENTxTI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordCURRENTxTIM(s) @@ -1712,7 +1565,6 @@ func scanKeywordCURRENTxTIM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordCURRENTxTIME(s) @@ -1726,7 +1578,6 @@ func scanKeywordCURRENTxTIME(s RuneScanner) (token.Type, bool) { return token.KeywordCurrentTime, true } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordCURRENTxTIMES(s) @@ -1740,7 +1591,6 @@ func scanKeywordCURRENTxTIMES(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordCURRENTxTIMEST(s) @@ -1754,7 +1604,6 @@ func scanKeywordCURRENTxTIMEST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordCURRENTxTIMESTA(s) @@ -1768,7 +1617,6 @@ func scanKeywordCURRENTxTIMESTA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordCURRENTxTIMESTAM(s) @@ -1782,7 +1630,6 @@ func scanKeywordCURRENTxTIMESTAM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordCURRENTxTIMESTAMP(s) @@ -1800,23 +1647,18 @@ func scanKeywordD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordDA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordDE(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordDI(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordDO(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordDR(s) @@ -1830,7 +1672,6 @@ func scanKeywordDA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordDAT(s) @@ -1844,7 +1685,6 @@ func scanKeywordDAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordDATA(s) @@ -1858,7 +1698,6 @@ func scanKeywordDATA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordDATAB(s) @@ -1872,7 +1711,6 @@ func scanKeywordDATAB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordDATABA(s) @@ -1886,7 +1724,6 @@ func scanKeywordDATABA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordDATABAS(s) @@ -1900,7 +1737,6 @@ func scanKeywordDATABAS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordDATABASE(s) @@ -1918,19 +1754,15 @@ func scanKeywordDE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordDEF(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordDEL(s) - case 'S', 's': s.ConsumeRune() return scanKeywordDES(s) - case 'T', 't': s.ConsumeRune() return scanKeywordDET(s) @@ -1944,11 +1776,9 @@ func scanKeywordDEF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordDEFA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordDEFE(s) @@ -1962,7 +1792,6 @@ func scanKeywordDEFA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordDEFAU(s) @@ -1976,7 +1805,6 @@ func scanKeywordDEFAU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordDEFAUL(s) @@ -1990,7 +1818,6 @@ func scanKeywordDEFAUL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordDEFAULT(s) @@ -2008,7 +1835,6 @@ func scanKeywordDEFE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordDEFER(s) @@ -2022,7 +1848,6 @@ func scanKeywordDEFER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordDEFERR(s) @@ -2036,11 +1861,9 @@ func scanKeywordDEFERR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordDEFERRA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordDEFERRE(s) @@ -2054,7 +1877,6 @@ func scanKeywordDEFERRA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordDEFERRAB(s) @@ -2068,7 +1890,6 @@ func scanKeywordDEFERRAB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordDEFERRABL(s) @@ -2082,7 +1903,6 @@ func scanKeywordDEFERRABL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordDEFERRABLE(s) @@ -2100,7 +1920,6 @@ func scanKeywordDEFERRE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordDEFERRED(s) @@ -2118,7 +1937,6 @@ func scanKeywordDEL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordDELE(s) @@ -2132,7 +1950,6 @@ func scanKeywordDELE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordDELET(s) @@ -2146,7 +1963,6 @@ func scanKeywordDELET(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordDELETE(s) @@ -2164,7 +1980,6 @@ func scanKeywordDES(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordDESC(s) @@ -2182,7 +1997,6 @@ func scanKeywordDET(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordDETA(s) @@ -2196,7 +2010,6 @@ func scanKeywordDETA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordDETAC(s) @@ -2210,7 +2023,6 @@ func scanKeywordDETAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordDETACH(s) @@ -2228,7 +2040,6 @@ func scanKeywordDI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordDIS(s) @@ -2242,7 +2053,6 @@ func scanKeywordDIS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordDIST(s) @@ -2256,7 +2066,6 @@ func scanKeywordDIST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordDISTI(s) @@ -2270,7 +2079,6 @@ func scanKeywordDISTI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordDISTIN(s) @@ -2284,7 +2092,6 @@ func scanKeywordDISTIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordDISTINC(s) @@ -2298,7 +2105,6 @@ func scanKeywordDISTINC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordDISTINCT(s) @@ -2320,7 +2126,6 @@ func scanKeywordDR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordDRO(s) @@ -2334,7 +2139,6 @@ func scanKeywordDRO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordDROP(s) @@ -2352,23 +2156,18 @@ func scanKeywordE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordEA(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordEL(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordEN(s) - case 'S', 's': s.ConsumeRune() return scanKeywordES(s) - case 'X', 'x': s.ConsumeRune() return scanKeywordEX(s) @@ -2382,7 +2181,6 @@ func scanKeywordEA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordEAC(s) @@ -2396,7 +2194,6 @@ func scanKeywordEAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordEACH(s) @@ -2414,7 +2211,6 @@ func scanKeywordEL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordELS(s) @@ -2428,7 +2224,6 @@ func scanKeywordELS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordELSE(s) @@ -2446,7 +2241,6 @@ func scanKeywordEN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordEND(s) @@ -2464,7 +2258,6 @@ func scanKeywordES(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordESC(s) @@ -2478,7 +2271,6 @@ func scanKeywordESC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordESCA(s) @@ -2492,7 +2284,6 @@ func scanKeywordESCA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordESCAP(s) @@ -2506,7 +2297,6 @@ func scanKeywordESCAP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordESCAPE(s) @@ -2524,15 +2314,12 @@ func scanKeywordEX(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordEXC(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordEXI(s) - case 'P', 'p': s.ConsumeRune() return scanKeywordEXP(s) @@ -2546,11 +2333,9 @@ func scanKeywordEXC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordEXCE(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordEXCL(s) @@ -2564,7 +2349,6 @@ func scanKeywordEXCE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordEXCEP(s) @@ -2578,7 +2362,6 @@ func scanKeywordEXCEP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordEXCEPT(s) @@ -2596,7 +2379,6 @@ func scanKeywordEXCL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordEXCLU(s) @@ -2610,11 +2392,9 @@ func scanKeywordEXCLU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordEXCLUD(s) - case 'S', 's': s.ConsumeRune() return scanKeywordEXCLUS(s) @@ -2628,7 +2408,6 @@ func scanKeywordEXCLUD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordEXCLUDE(s) @@ -2646,7 +2425,6 @@ func scanKeywordEXCLUS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordEXCLUSI(s) @@ -2660,7 +2438,6 @@ func scanKeywordEXCLUSI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'V', 'v': s.ConsumeRune() return scanKeywordEXCLUSIV(s) @@ -2674,7 +2451,6 @@ func scanKeywordEXCLUSIV(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordEXCLUSIVE(s) @@ -2692,7 +2468,6 @@ func scanKeywordEXI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordEXIS(s) @@ -2706,7 +2481,6 @@ func scanKeywordEXIS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordEXIST(s) @@ -2720,7 +2494,6 @@ func scanKeywordEXIST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordEXISTS(s) @@ -2738,7 +2511,6 @@ func scanKeywordEXP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordEXPL(s) @@ -2752,7 +2524,6 @@ func scanKeywordEXPL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordEXPLA(s) @@ -2766,7 +2537,6 @@ func scanKeywordEXPLA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordEXPLAI(s) @@ -2780,7 +2550,6 @@ func scanKeywordEXPLAI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordEXPLAIN(s) @@ -2798,23 +2567,18 @@ func scanKeywordF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordFA(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordFI(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordFO(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordFR(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordFU(s) @@ -2828,7 +2592,6 @@ func scanKeywordFA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordFAI(s) @@ -2842,7 +2605,6 @@ func scanKeywordFAI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordFAIL(s) @@ -2860,11 +2622,9 @@ func scanKeywordFI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordFIL(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordFIR(s) @@ -2878,7 +2638,6 @@ func scanKeywordFIL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordFILT(s) @@ -2892,7 +2651,6 @@ func scanKeywordFILT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordFILTE(s) @@ -2906,7 +2664,6 @@ func scanKeywordFILTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordFILTER(s) @@ -2924,7 +2681,6 @@ func scanKeywordFIR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordFIRS(s) @@ -2938,7 +2694,6 @@ func scanKeywordFIRS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordFIRST(s) @@ -2956,11 +2711,9 @@ func scanKeywordFO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordFOL(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordFOR(s) @@ -2974,7 +2727,6 @@ func scanKeywordFOL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordFOLL(s) @@ -2988,7 +2740,6 @@ func scanKeywordFOLL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordFOLLO(s) @@ -3002,7 +2753,6 @@ func scanKeywordFOLLO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'W', 'w': s.ConsumeRune() return scanKeywordFOLLOW(s) @@ -3016,7 +2766,6 @@ func scanKeywordFOLLOW(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordFOLLOWI(s) @@ -3030,7 +2779,6 @@ func scanKeywordFOLLOWI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordFOLLOWIN(s) @@ -3044,7 +2792,6 @@ func scanKeywordFOLLOWIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordFOLLOWING(s) @@ -3062,7 +2809,6 @@ func scanKeywordFOR(s RuneScanner) (token.Type, bool) { return token.KeywordFor, true } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordFORE(s) @@ -3076,7 +2822,6 @@ func scanKeywordFORE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordFOREI(s) @@ -3090,7 +2835,6 @@ func scanKeywordFOREI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordFOREIG(s) @@ -3104,7 +2848,6 @@ func scanKeywordFOREIG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordFOREIGN(s) @@ -3122,7 +2865,6 @@ func scanKeywordFR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordFRO(s) @@ -3136,7 +2878,6 @@ func scanKeywordFRO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordFROM(s) @@ -3154,7 +2895,6 @@ func scanKeywordFU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordFUL(s) @@ -3168,7 +2908,6 @@ func scanKeywordFUL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordFULL(s) @@ -3186,15 +2925,12 @@ func scanKeywordG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordGE(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordGL(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordGR(s) @@ -3208,7 +2944,6 @@ func scanKeywordGE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordGEN(s) @@ -3222,7 +2957,6 @@ func scanKeywordGEN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordGENE(s) @@ -3236,7 +2970,6 @@ func scanKeywordGENE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordGENER(s) @@ -3250,7 +2983,6 @@ func scanKeywordGENER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordGENERA(s) @@ -3264,7 +2996,6 @@ func scanKeywordGENERA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordGENERAT(s) @@ -3278,7 +3009,6 @@ func scanKeywordGENERAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordGENERATE(s) @@ -3292,7 +3022,6 @@ func scanKeywordGENERATE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordGENERATED(s) @@ -3310,7 +3039,6 @@ func scanKeywordGL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordGLO(s) @@ -3324,7 +3052,6 @@ func scanKeywordGLO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordGLOB(s) @@ -3342,7 +3069,6 @@ func scanKeywordGR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordGRO(s) @@ -3356,7 +3082,6 @@ func scanKeywordGRO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordGROU(s) @@ -3370,7 +3095,6 @@ func scanKeywordGROU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordGROUP(s) @@ -3384,7 +3108,6 @@ func scanKeywordGROUP(s RuneScanner) (token.Type, bool) { return token.KeywordGroup, true } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordGROUPS(s) @@ -3402,7 +3125,6 @@ func scanKeywordH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordHA(s) @@ -3416,7 +3138,6 @@ func scanKeywordHA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'V', 'v': s.ConsumeRune() return scanKeywordHAV(s) @@ -3430,7 +3151,6 @@ func scanKeywordHAV(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordHAVI(s) @@ -3444,7 +3164,6 @@ func scanKeywordHAVI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordHAVIN(s) @@ -3458,7 +3177,6 @@ func scanKeywordHAVIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordHAVING(s) @@ -3476,23 +3194,18 @@ func scanKeywordI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordIF(s) - case 'G', 'g': s.ConsumeRune() return scanKeywordIG(s) - case 'M', 'm': s.ConsumeRune() return scanKeywordIM(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordIN(s) - case 'S', 's': s.ConsumeRune() return scanKeywordIS(s) @@ -3510,7 +3223,6 @@ func scanKeywordIG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordIGN(s) @@ -3524,7 +3236,6 @@ func scanKeywordIGN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordIGNO(s) @@ -3538,7 +3249,6 @@ func scanKeywordIGNO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordIGNOR(s) @@ -3552,7 +3262,6 @@ func scanKeywordIGNOR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordIGNORE(s) @@ -3570,7 +3279,6 @@ func scanKeywordIM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordIMM(s) @@ -3584,7 +3292,6 @@ func scanKeywordIMM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordIMME(s) @@ -3598,7 +3305,6 @@ func scanKeywordIMME(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordIMMED(s) @@ -3612,7 +3318,6 @@ func scanKeywordIMMED(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordIMMEDI(s) @@ -3626,7 +3331,6 @@ func scanKeywordIMMEDI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordIMMEDIA(s) @@ -3640,7 +3344,6 @@ func scanKeywordIMMEDIA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordIMMEDIAT(s) @@ -3654,7 +3357,6 @@ func scanKeywordIMMEDIAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordIMMEDIATE(s) @@ -3672,23 +3374,18 @@ func scanKeywordIN(s RuneScanner) (token.Type, bool) { return token.KeywordIn, true } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordIND(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordINI(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordINN(s) - case 'S', 's': s.ConsumeRune() return scanKeywordINS(s) - case 'T', 't': s.ConsumeRune() return scanKeywordINT(s) @@ -3702,7 +3399,6 @@ func scanKeywordIND(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINDE(s) @@ -3716,7 +3412,6 @@ func scanKeywordINDE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'X', 'x': s.ConsumeRune() return scanKeywordINDEX(s) @@ -3730,7 +3425,6 @@ func scanKeywordINDEX(s RuneScanner) (token.Type, bool) { return token.KeywordIndex, true } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINDEXE(s) @@ -3744,7 +3438,6 @@ func scanKeywordINDEXE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordINDEXED(s) @@ -3762,7 +3455,6 @@ func scanKeywordINI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordINIT(s) @@ -3776,7 +3468,6 @@ func scanKeywordINIT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordINITI(s) @@ -3790,7 +3481,6 @@ func scanKeywordINITI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordINITIA(s) @@ -3804,7 +3494,6 @@ func scanKeywordINITIA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordINITIAL(s) @@ -3818,7 +3507,6 @@ func scanKeywordINITIAL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordINITIALL(s) @@ -3832,7 +3520,6 @@ func scanKeywordINITIALL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordINITIALLY(s) @@ -3850,7 +3537,6 @@ func scanKeywordINN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINNE(s) @@ -3864,7 +3550,6 @@ func scanKeywordINNE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordINNER(s) @@ -3882,11 +3567,9 @@ func scanKeywordINS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINSE(s) - case 'T', 't': s.ConsumeRune() return scanKeywordINST(s) @@ -3900,7 +3583,6 @@ func scanKeywordINSE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordINSER(s) @@ -3914,7 +3596,6 @@ func scanKeywordINSER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordINSERT(s) @@ -3932,7 +3613,6 @@ func scanKeywordINST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINSTE(s) @@ -3946,7 +3626,6 @@ func scanKeywordINSTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordINSTEA(s) @@ -3960,7 +3639,6 @@ func scanKeywordINSTEA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordINSTEAD(s) @@ -3978,11 +3656,9 @@ func scanKeywordINT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINTE(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordINTO(s) @@ -3996,7 +3672,6 @@ func scanKeywordINTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordINTER(s) @@ -4010,7 +3685,6 @@ func scanKeywordINTER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordINTERS(s) @@ -4024,7 +3698,6 @@ func scanKeywordINTERS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordINTERSE(s) @@ -4038,7 +3711,6 @@ func scanKeywordINTERSE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordINTERSEC(s) @@ -4052,7 +3724,6 @@ func scanKeywordINTERSEC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordINTERSECT(s) @@ -4074,7 +3745,6 @@ func scanKeywordIS(s RuneScanner) (token.Type, bool) { return token.KeywordIs, true } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordISN(s) @@ -4088,7 +3758,6 @@ func scanKeywordISN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordISNU(s) @@ -4102,7 +3771,6 @@ func scanKeywordISNU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordISNUL(s) @@ -4116,7 +3784,6 @@ func scanKeywordISNUL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordISNULL(s) @@ -4134,7 +3801,6 @@ func scanKeywordJ(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordJO(s) @@ -4148,7 +3814,6 @@ func scanKeywordJO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordJOI(s) @@ -4162,7 +3827,6 @@ func scanKeywordJOI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordJOIN(s) @@ -4180,7 +3844,6 @@ func scanKeywordK(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordKE(s) @@ -4194,7 +3857,6 @@ func scanKeywordKE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordKEY(s) @@ -4212,15 +3874,12 @@ func scanKeywordL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordLA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordLE(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordLI(s) @@ -4234,7 +3893,6 @@ func scanKeywordLA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordLAS(s) @@ -4248,7 +3906,6 @@ func scanKeywordLAS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordLAST(s) @@ -4266,7 +3923,6 @@ func scanKeywordLE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordLEF(s) @@ -4280,7 +3936,6 @@ func scanKeywordLEF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordLEFT(s) @@ -4298,11 +3953,9 @@ func scanKeywordLI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'K', 'k': s.ConsumeRune() return scanKeywordLIK(s) - case 'M', 'm': s.ConsumeRune() return scanKeywordLIM(s) @@ -4316,7 +3969,6 @@ func scanKeywordLIK(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordLIKE(s) @@ -4334,7 +3986,6 @@ func scanKeywordLIM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordLIMI(s) @@ -4348,7 +3999,6 @@ func scanKeywordLIMI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordLIMIT(s) @@ -4366,7 +4016,6 @@ func scanKeywordM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordMA(s) @@ -4380,7 +4029,6 @@ func scanKeywordMA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordMAT(s) @@ -4394,7 +4042,6 @@ func scanKeywordMAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordMATC(s) @@ -4408,7 +4055,6 @@ func scanKeywordMATC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordMATCH(s) @@ -4426,15 +4072,12 @@ func scanKeywordN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordNA(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordNO(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordNU(s) @@ -4448,7 +4091,6 @@ func scanKeywordNA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordNAT(s) @@ -4462,7 +4104,6 @@ func scanKeywordNAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordNATU(s) @@ -4476,7 +4117,6 @@ func scanKeywordNATU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordNATUR(s) @@ -4490,7 +4130,6 @@ func scanKeywordNATUR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordNATURA(s) @@ -4504,7 +4143,6 @@ func scanKeywordNATURA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordNATURAL(s) @@ -4522,7 +4160,6 @@ func scanKeywordNO(s RuneScanner) (token.Type, bool) { return token.KeywordNo, true } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordNOT(s) @@ -4536,11 +4173,9 @@ func scanKeywordNOT(s RuneScanner) (token.Type, bool) { return token.KeywordNot, true } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordNOTH(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordNOTN(s) @@ -4554,7 +4189,6 @@ func scanKeywordNOTH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordNOTHI(s) @@ -4568,7 +4202,6 @@ func scanKeywordNOTHI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordNOTHIN(s) @@ -4582,7 +4215,6 @@ func scanKeywordNOTHIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordNOTHING(s) @@ -4600,7 +4232,6 @@ func scanKeywordNOTN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordNOTNU(s) @@ -4614,7 +4245,6 @@ func scanKeywordNOTNU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordNOTNUL(s) @@ -4628,7 +4258,6 @@ func scanKeywordNOTNUL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordNOTNULL(s) @@ -4646,7 +4275,6 @@ func scanKeywordNU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordNUL(s) @@ -4660,7 +4288,6 @@ func scanKeywordNUL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordNULL(s) @@ -4674,7 +4301,6 @@ func scanKeywordNULL(s RuneScanner) (token.Type, bool) { return token.KeywordNull, true } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordNULLS(s) @@ -4692,27 +4318,21 @@ func scanKeywordO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordOF(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordON(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordOR(s) - case 'T', 't': s.ConsumeRune() return scanKeywordOT(s) - case 'U', 'u': s.ConsumeRune() return scanKeywordOU(s) - case 'V', 'v': s.ConsumeRune() return scanKeywordOV(s) @@ -4726,7 +4346,6 @@ func scanKeywordOF(s RuneScanner) (token.Type, bool) { return token.KeywordOf, true } switch next { - case 'F', 'f': s.ConsumeRune() return scanKeywordOFF(s) @@ -4740,7 +4359,6 @@ func scanKeywordOFF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordOFFS(s) @@ -4754,7 +4372,6 @@ func scanKeywordOFFS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordOFFSE(s) @@ -4768,7 +4385,6 @@ func scanKeywordOFFSE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordOFFSET(s) @@ -4790,7 +4406,6 @@ func scanKeywordOR(s RuneScanner) (token.Type, bool) { return token.KeywordOr, true } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordORD(s) @@ -4804,7 +4419,6 @@ func scanKeywordORD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordORDE(s) @@ -4818,7 +4432,6 @@ func scanKeywordORDE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordORDER(s) @@ -4836,7 +4449,6 @@ func scanKeywordOT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordOTH(s) @@ -4850,7 +4462,6 @@ func scanKeywordOTH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordOTHE(s) @@ -4864,7 +4475,6 @@ func scanKeywordOTHE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordOTHER(s) @@ -4878,7 +4488,6 @@ func scanKeywordOTHER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordOTHERS(s) @@ -4896,7 +4505,6 @@ func scanKeywordOU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordOUT(s) @@ -4910,7 +4518,6 @@ func scanKeywordOUT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordOUTE(s) @@ -4924,7 +4531,6 @@ func scanKeywordOUTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordOUTER(s) @@ -4942,7 +4548,6 @@ func scanKeywordOV(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordOVE(s) @@ -4956,7 +4561,6 @@ func scanKeywordOVE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordOVER(s) @@ -4974,15 +4578,12 @@ func scanKeywordP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordPA(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordPL(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordPR(s) @@ -4996,7 +4597,6 @@ func scanKeywordPA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordPAR(s) @@ -5010,7 +4610,6 @@ func scanKeywordPAR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordPART(s) @@ -5024,7 +4623,6 @@ func scanKeywordPART(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordPARTI(s) @@ -5038,7 +4636,6 @@ func scanKeywordPARTI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordPARTIT(s) @@ -5052,7 +4649,6 @@ func scanKeywordPARTIT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordPARTITI(s) @@ -5066,7 +4662,6 @@ func scanKeywordPARTITI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordPARTITIO(s) @@ -5080,7 +4675,6 @@ func scanKeywordPARTITIO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordPARTITION(s) @@ -5098,7 +4692,6 @@ func scanKeywordPL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordPLA(s) @@ -5112,7 +4705,6 @@ func scanKeywordPLA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordPLAN(s) @@ -5130,15 +4722,12 @@ func scanKeywordPR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordPRA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordPRE(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordPRI(s) @@ -5152,7 +4741,6 @@ func scanKeywordPRA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordPRAG(s) @@ -5166,7 +4754,6 @@ func scanKeywordPRAG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordPRAGM(s) @@ -5180,7 +4767,6 @@ func scanKeywordPRAGM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordPRAGMA(s) @@ -5198,7 +4784,6 @@ func scanKeywordPRE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordPREC(s) @@ -5212,7 +4797,6 @@ func scanKeywordPREC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordPRECE(s) @@ -5226,7 +4810,6 @@ func scanKeywordPRECE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordPRECED(s) @@ -5240,7 +4823,6 @@ func scanKeywordPRECED(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordPRECEDI(s) @@ -5254,7 +4836,6 @@ func scanKeywordPRECEDI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordPRECEDIN(s) @@ -5268,7 +4849,6 @@ func scanKeywordPRECEDIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordPRECEDING(s) @@ -5286,7 +4866,6 @@ func scanKeywordPRI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordPRIM(s) @@ -5300,7 +4879,6 @@ func scanKeywordPRIM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordPRIMA(s) @@ -5314,7 +4892,6 @@ func scanKeywordPRIMA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordPRIMAR(s) @@ -5328,7 +4905,6 @@ func scanKeywordPRIMAR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordPRIMARY(s) @@ -5346,7 +4922,6 @@ func scanKeywordQ(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordQU(s) @@ -5360,7 +4935,6 @@ func scanKeywordQU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordQUE(s) @@ -5374,7 +4948,6 @@ func scanKeywordQUE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordQUER(s) @@ -5388,7 +4961,6 @@ func scanKeywordQUER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordQUERY(s) @@ -5406,19 +4978,15 @@ func scanKeywordR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordRA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordRE(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordRI(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordRO(s) @@ -5432,11 +5000,9 @@ func scanKeywordRA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordRAI(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordRAN(s) @@ -5450,7 +5016,6 @@ func scanKeywordRAI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordRAIS(s) @@ -5464,7 +5029,6 @@ func scanKeywordRAIS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordRAISE(s) @@ -5482,7 +5046,6 @@ func scanKeywordRAN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordRANG(s) @@ -5496,7 +5059,6 @@ func scanKeywordRANG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordRANGE(s) @@ -5514,35 +5076,27 @@ func scanKeywordRE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordREC(s) - case 'F', 'f': s.ConsumeRune() return scanKeywordREF(s) - case 'G', 'g': s.ConsumeRune() return scanKeywordREG(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordREI(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordREL(s) - case 'N', 'n': s.ConsumeRune() return scanKeywordREN(s) - case 'P', 'p': s.ConsumeRune() return scanKeywordREP(s) - case 'S', 's': s.ConsumeRune() return scanKeywordRES(s) @@ -5556,7 +5110,6 @@ func scanKeywordREC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordRECU(s) @@ -5570,7 +5123,6 @@ func scanKeywordRECU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordRECUR(s) @@ -5584,7 +5136,6 @@ func scanKeywordRECUR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordRECURS(s) @@ -5598,7 +5149,6 @@ func scanKeywordRECURS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordRECURSI(s) @@ -5612,7 +5162,6 @@ func scanKeywordRECURSI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'V', 'v': s.ConsumeRune() return scanKeywordRECURSIV(s) @@ -5626,7 +5175,6 @@ func scanKeywordRECURSIV(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordRECURSIVE(s) @@ -5644,7 +5192,6 @@ func scanKeywordREF(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordREFE(s) @@ -5658,7 +5205,6 @@ func scanKeywordREFE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordREFER(s) @@ -5672,7 +5218,6 @@ func scanKeywordREFER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordREFERE(s) @@ -5686,7 +5231,6 @@ func scanKeywordREFERE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordREFEREN(s) @@ -5700,7 +5244,6 @@ func scanKeywordREFEREN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordREFERENC(s) @@ -5714,7 +5257,6 @@ func scanKeywordREFERENC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordREFERENCE(s) @@ -5728,7 +5270,6 @@ func scanKeywordREFERENCE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordREFERENCES(s) @@ -5746,7 +5287,6 @@ func scanKeywordREG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordREGE(s) @@ -5760,7 +5300,6 @@ func scanKeywordREGE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'X', 'x': s.ConsumeRune() return scanKeywordREGEX(s) @@ -5774,7 +5313,6 @@ func scanKeywordREGEX(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordREGEXP(s) @@ -5792,7 +5330,6 @@ func scanKeywordREI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordREIN(s) @@ -5806,7 +5343,6 @@ func scanKeywordREIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordREIND(s) @@ -5820,7 +5356,6 @@ func scanKeywordREIND(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordREINDE(s) @@ -5834,7 +5369,6 @@ func scanKeywordREINDE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'X', 'x': s.ConsumeRune() return scanKeywordREINDEX(s) @@ -5852,7 +5386,6 @@ func scanKeywordREL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordRELE(s) @@ -5866,7 +5399,6 @@ func scanKeywordRELE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordRELEA(s) @@ -5880,7 +5412,6 @@ func scanKeywordRELEA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordRELEAS(s) @@ -5894,7 +5425,6 @@ func scanKeywordRELEAS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordRELEASE(s) @@ -5912,7 +5442,6 @@ func scanKeywordREN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordRENA(s) @@ -5926,7 +5455,6 @@ func scanKeywordRENA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordRENAM(s) @@ -5940,7 +5468,6 @@ func scanKeywordRENAM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordRENAME(s) @@ -5958,7 +5485,6 @@ func scanKeywordREP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordREPL(s) @@ -5972,7 +5498,6 @@ func scanKeywordREPL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordREPLA(s) @@ -5986,7 +5511,6 @@ func scanKeywordREPLA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordREPLAC(s) @@ -6000,7 +5524,6 @@ func scanKeywordREPLAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordREPLACE(s) @@ -6018,7 +5541,6 @@ func scanKeywordRES(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordREST(s) @@ -6032,7 +5554,6 @@ func scanKeywordREST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordRESTR(s) @@ -6046,7 +5567,6 @@ func scanKeywordRESTR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordRESTRI(s) @@ -6060,7 +5580,6 @@ func scanKeywordRESTRI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordRESTRIC(s) @@ -6074,7 +5593,6 @@ func scanKeywordRESTRIC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordRESTRICT(s) @@ -6092,7 +5610,6 @@ func scanKeywordRI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordRIG(s) @@ -6106,7 +5623,6 @@ func scanKeywordRIG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordRIGH(s) @@ -6120,7 +5636,6 @@ func scanKeywordRIGH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordRIGHT(s) @@ -6138,11 +5653,9 @@ func scanKeywordRO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordROL(s) - case 'W', 'w': s.ConsumeRune() return scanKeywordROW(s) @@ -6156,7 +5669,6 @@ func scanKeywordROL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordROLL(s) @@ -6170,7 +5682,6 @@ func scanKeywordROLL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordROLLB(s) @@ -6184,7 +5695,6 @@ func scanKeywordROLLB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordROLLBA(s) @@ -6198,7 +5708,6 @@ func scanKeywordROLLBA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordROLLBAC(s) @@ -6212,7 +5721,6 @@ func scanKeywordROLLBAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'K', 'k': s.ConsumeRune() return scanKeywordROLLBACK(s) @@ -6230,7 +5738,6 @@ func scanKeywordROW(s RuneScanner) (token.Type, bool) { return token.KeywordRow, true } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordROWS(s) @@ -6248,15 +5755,12 @@ func scanKeywordS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordSA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordSE(s) - case 'T', 't': s.ConsumeRune() return scanKeywordST(s) @@ -6270,7 +5774,6 @@ func scanKeywordSA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'V', 'v': s.ConsumeRune() return scanKeywordSAV(s) @@ -6284,7 +5787,6 @@ func scanKeywordSAV(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordSAVE(s) @@ -6298,7 +5800,6 @@ func scanKeywordSAVE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordSAVEP(s) @@ -6312,7 +5813,6 @@ func scanKeywordSAVEP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordSAVEPO(s) @@ -6326,7 +5826,6 @@ func scanKeywordSAVEPO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordSAVEPOI(s) @@ -6340,7 +5839,6 @@ func scanKeywordSAVEPOI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordSAVEPOIN(s) @@ -6354,7 +5852,6 @@ func scanKeywordSAVEPOIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordSAVEPOINT(s) @@ -6372,11 +5869,9 @@ func scanKeywordSE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordSEL(s) - case 'T', 't': s.ConsumeRune() return scanKeywordSET(s) @@ -6390,7 +5885,6 @@ func scanKeywordSEL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordSELE(s) @@ -6404,7 +5898,6 @@ func scanKeywordSELE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordSELEC(s) @@ -6418,7 +5911,6 @@ func scanKeywordSELEC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordSELECT(s) @@ -6440,7 +5932,6 @@ func scanKeywordST(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordSTO(s) @@ -6454,7 +5945,6 @@ func scanKeywordSTO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordSTOR(s) @@ -6468,7 +5958,6 @@ func scanKeywordSTOR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordSTORE(s) @@ -6482,7 +5971,6 @@ func scanKeywordSTORE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordSTORED(s) @@ -6500,27 +5988,21 @@ func scanKeywordT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordTA(s) - case 'E', 'e': s.ConsumeRune() return scanKeywordTE(s) - case 'H', 'h': s.ConsumeRune() return scanKeywordTH(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordTI(s) - case 'O', 'o': s.ConsumeRune() return scanKeywordTO(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordTR(s) @@ -6534,7 +6016,6 @@ func scanKeywordTA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordTAB(s) @@ -6548,7 +6029,6 @@ func scanKeywordTAB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordTABL(s) @@ -6562,7 +6042,6 @@ func scanKeywordTABL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordTABLE(s) @@ -6580,7 +6059,6 @@ func scanKeywordTE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordTEM(s) @@ -6594,7 +6072,6 @@ func scanKeywordTEM(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'P', 'p': s.ConsumeRune() return scanKeywordTEMP(s) @@ -6608,7 +6085,6 @@ func scanKeywordTEMP(s RuneScanner) (token.Type, bool) { return token.KeywordTemp, true } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordTEMPO(s) @@ -6622,7 +6098,6 @@ func scanKeywordTEMPO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordTEMPOR(s) @@ -6636,7 +6111,6 @@ func scanKeywordTEMPOR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordTEMPORA(s) @@ -6650,7 +6124,6 @@ func scanKeywordTEMPORA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordTEMPORAR(s) @@ -6664,7 +6137,6 @@ func scanKeywordTEMPORAR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'Y', 'y': s.ConsumeRune() return scanKeywordTEMPORARY(s) @@ -6682,7 +6154,6 @@ func scanKeywordTH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordTHE(s) @@ -6696,7 +6167,6 @@ func scanKeywordTHE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordTHEN(s) @@ -6714,7 +6184,6 @@ func scanKeywordTI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordTIE(s) @@ -6728,7 +6197,6 @@ func scanKeywordTIE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordTIES(s) @@ -6750,11 +6218,9 @@ func scanKeywordTR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordTRA(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordTRI(s) @@ -6768,7 +6234,6 @@ func scanKeywordTRA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordTRAN(s) @@ -6782,7 +6247,6 @@ func scanKeywordTRAN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordTRANS(s) @@ -6796,7 +6260,6 @@ func scanKeywordTRANS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordTRANSA(s) @@ -6810,7 +6273,6 @@ func scanKeywordTRANSA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordTRANSAC(s) @@ -6824,7 +6286,6 @@ func scanKeywordTRANSAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordTRANSACT(s) @@ -6838,7 +6299,6 @@ func scanKeywordTRANSACT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordTRANSACTI(s) @@ -6852,7 +6312,6 @@ func scanKeywordTRANSACTI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordTRANSACTIO(s) @@ -6866,7 +6325,6 @@ func scanKeywordTRANSACTIO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordTRANSACTION(s) @@ -6884,7 +6342,6 @@ func scanKeywordTRI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordTRIG(s) @@ -6898,7 +6355,6 @@ func scanKeywordTRIG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordTRIGG(s) @@ -6912,7 +6368,6 @@ func scanKeywordTRIGG(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordTRIGGE(s) @@ -6926,7 +6381,6 @@ func scanKeywordTRIGGE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'R', 'r': s.ConsumeRune() return scanKeywordTRIGGER(s) @@ -6944,15 +6398,12 @@ func scanKeywordU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordUN(s) - case 'P', 'p': s.ConsumeRune() return scanKeywordUP(s) - case 'S', 's': s.ConsumeRune() return scanKeywordUS(s) @@ -6966,11 +6417,9 @@ func scanKeywordUN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'B', 'b': s.ConsumeRune() return scanKeywordUNB(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordUNI(s) @@ -6984,7 +6433,6 @@ func scanKeywordUNB(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordUNBO(s) @@ -6998,7 +6446,6 @@ func scanKeywordUNBO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordUNBOU(s) @@ -7012,7 +6459,6 @@ func scanKeywordUNBOU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordUNBOUN(s) @@ -7026,7 +6472,6 @@ func scanKeywordUNBOUN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordUNBOUND(s) @@ -7040,7 +6485,6 @@ func scanKeywordUNBOUND(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordUNBOUNDE(s) @@ -7054,7 +6498,6 @@ func scanKeywordUNBOUNDE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordUNBOUNDED(s) @@ -7072,11 +6515,9 @@ func scanKeywordUNI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordUNIO(s) - case 'Q', 'q': s.ConsumeRune() return scanKeywordUNIQ(s) @@ -7090,7 +6531,6 @@ func scanKeywordUNIO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordUNION(s) @@ -7108,7 +6548,6 @@ func scanKeywordUNIQ(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordUNIQU(s) @@ -7122,7 +6561,6 @@ func scanKeywordUNIQU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordUNIQUE(s) @@ -7140,7 +6578,6 @@ func scanKeywordUP(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordUPD(s) @@ -7154,7 +6591,6 @@ func scanKeywordUPD(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordUPDA(s) @@ -7168,7 +6604,6 @@ func scanKeywordUPDA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordUPDAT(s) @@ -7182,7 +6617,6 @@ func scanKeywordUPDAT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordUPDATE(s) @@ -7200,7 +6634,6 @@ func scanKeywordUS(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'I', 'i': s.ConsumeRune() return scanKeywordUSI(s) @@ -7214,7 +6647,6 @@ func scanKeywordUSI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordUSIN(s) @@ -7228,7 +6660,6 @@ func scanKeywordUSIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'G', 'g': s.ConsumeRune() return scanKeywordUSING(s) @@ -7246,11 +6677,9 @@ func scanKeywordV(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordVA(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordVI(s) @@ -7264,11 +6693,9 @@ func scanKeywordVA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'C', 'c': s.ConsumeRune() return scanKeywordVAC(s) - case 'L', 'l': s.ConsumeRune() return scanKeywordVAL(s) @@ -7282,7 +6709,6 @@ func scanKeywordVAC(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordVACU(s) @@ -7296,7 +6722,6 @@ func scanKeywordVACU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordVACUU(s) @@ -7310,7 +6735,6 @@ func scanKeywordVACUU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'M', 'm': s.ConsumeRune() return scanKeywordVACUUM(s) @@ -7328,7 +6752,6 @@ func scanKeywordVAL(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordVALU(s) @@ -7342,7 +6765,6 @@ func scanKeywordVALU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordVALUE(s) @@ -7356,7 +6778,6 @@ func scanKeywordVALUE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'S', 's': s.ConsumeRune() return scanKeywordVALUES(s) @@ -7374,11 +6795,9 @@ func scanKeywordVI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordVIE(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordVIR(s) @@ -7392,7 +6811,6 @@ func scanKeywordVIE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'W', 'w': s.ConsumeRune() return scanKeywordVIEW(s) @@ -7410,7 +6828,6 @@ func scanKeywordVIR(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordVIRT(s) @@ -7424,7 +6841,6 @@ func scanKeywordVIRT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordVIRTU(s) @@ -7438,7 +6854,6 @@ func scanKeywordVIRTU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'A', 'a': s.ConsumeRune() return scanKeywordVIRTUA(s) @@ -7452,7 +6867,6 @@ func scanKeywordVIRTUA(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'L', 'l': s.ConsumeRune() return scanKeywordVIRTUAL(s) @@ -7470,11 +6884,9 @@ func scanKeywordW(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordWH(s) - case 'I', 'i': s.ConsumeRune() return scanKeywordWI(s) @@ -7488,7 +6900,6 @@ func scanKeywordWH(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordWHE(s) @@ -7502,11 +6913,9 @@ func scanKeywordWHE(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordWHEN(s) - case 'R', 'r': s.ConsumeRune() return scanKeywordWHER(s) @@ -7524,7 +6933,6 @@ func scanKeywordWHER(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'E', 'e': s.ConsumeRune() return scanKeywordWHERE(s) @@ -7542,11 +6950,9 @@ func scanKeywordWI(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'N', 'n': s.ConsumeRune() return scanKeywordWIN(s) - case 'T', 't': s.ConsumeRune() return scanKeywordWIT(s) @@ -7560,7 +6966,6 @@ func scanKeywordWIN(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'D', 'd': s.ConsumeRune() return scanKeywordWIND(s) @@ -7574,7 +6979,6 @@ func scanKeywordWIND(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordWINDO(s) @@ -7588,7 +6992,6 @@ func scanKeywordWINDO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'W', 'w': s.ConsumeRune() return scanKeywordWINDOW(s) @@ -7606,7 +7009,6 @@ func scanKeywordWIT(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'H', 'h': s.ConsumeRune() return scanKeywordWITH(s) @@ -7620,7 +7022,6 @@ func scanKeywordWITH(s RuneScanner) (token.Type, bool) { return token.KeywordWith, true } switch next { - case 'O', 'o': s.ConsumeRune() return scanKeywordWITHO(s) @@ -7634,7 +7035,6 @@ func scanKeywordWITHO(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'U', 'u': s.ConsumeRune() return scanKeywordWITHOU(s) @@ -7648,7 +7048,6 @@ func scanKeywordWITHOU(s RuneScanner) (token.Type, bool) { return token.Unknown, false } switch next { - case 'T', 't': s.ConsumeRune() return scanKeywordWITHOUT(s) diff --git a/internal/raft/append_entries.go b/internal/raft/append_entries.go new file mode 100644 index 00000000..4540d7d7 --- /dev/null +++ b/internal/raft/append_entries.go @@ -0,0 +1,196 @@ +package raft + +import ( + "fmt" + "log" + + "github.com/xqueries/xdb/internal/raft/message" +) + +// AppendEntriesResponse function is called by a follower on a request from the +// leader to append log data to the follower node. This function generates the +// response to be sent to the leader node. This is the response to the request +// from the leader to assert it's leadership. +func (s *SimpleServer) AppendEntriesResponse(req *message.AppendEntriesRequest) *message.AppendEntriesResponse { + // leader term is just "term" in the paper, but since + // they mean the leader's term, we choose to use this. + leaderTerm := req.GetTerm() + s.lock.Lock() + if s.node.Closed { + s.lock.Unlock() + log.Println("node was closed, returning") + return nil + } + s.lock.Unlock() + + s.node.PersistentState.mu.Lock() + nodePersistentState := s.node.PersistentState + currentTerm := nodePersistentState.CurrentTerm + selfID := s.node.PersistentState.SelfID.String() + s.node.PersistentState.mu.Unlock() + + s.node.VolatileState.mu.Lock() + commitIndex := s.node.VolatileState.CommitIndex + s.node.VolatileState.mu.Unlock() + + // Return false if the leader's term is lesser than currentTerm, + // because it means that the leader is in a stale state. + isLeaderStale := leaderTerm < currentTerm + + // Bound check variable for future operations on the logs. + s.node.PersistentState.mu.Lock() + logsToExecuteExist := len(s.node.PersistentState.Log) > 0 + s.node.PersistentState.mu.Unlock() + + // Return false if term of leader in PrevLogIndex doesn't atleast + // match or exceed the previous Log Term stored by Leader. Essentially + // this is to check whether the leader is not running behind the + // follower. This case means that "leader" is not the real leader + // and is behind on the logs. + // + // In these cases, a true leader would be elected and followed but this + // "leader" for any possible reason (network issues, lag) hasn't caught + // up with it yet. + isLeaderAheadInLogs := req.GetPrevLogIndex() >= commitIndex + + // Reply false if the current node's log doesn't contain an entry + // at prevLogIndex whose term matches prevLogTerm (of the incoming node's). + isPreviousTermMatchingInLeaderAndFollower := + logsToExecuteExist && (nodePersistentState.Log[req.GetPrevLogIndex()].Term != req.GetPrevLogTerm()) + + /* Criterion for a failed append entries request: + 1. Checking whether there are logs to execute - bounds check for + future operations on the nature of the logs. + 2. Checking whether the leader is updated and not stale. + 3. Checking whether the leader is not a phantom leader. + 4. Checking whether the last committed logs in leader and + follower match. + */ + isFailedAppendEntriesResponse := isLeaderStale || !isLeaderAheadInLogs || + isPreviousTermMatchingInLeaderAndFollower + + if isFailedAppendEntriesResponse { + var msg string + if isLeaderStale { + msg = fmt.Sprintf("leader stale, leader term: %d, current term: %d", leaderTerm, currentTerm) + } + if !isLeaderAheadInLogs { + if msg != "" { + msg+="\n" + } + msg = fmt.Sprintf("leader %v is not ahead in logs ", req.LeaderID) + } + s.node.log. + Debug(). + Str("self-id", selfID). + Str("returning failure to append entries to", string(req.GetLeaderID())). + Str("reason",msg). + Msg("append entries failure") + return &message.AppendEntriesResponse{ + Term: currentTerm, + Success: false, + EntriesLength: 0, + } + } + + entries := req.GetEntries() + // Checking for entries in the log. + // + // At this point, only failed AppendEntriesRequest's are cleared, + // we still have to check whether there are entries to be processed, + // because this can still be a heartbeat. + if len(entries) > 0 { + s.node.PersistentState.mu.Lock() + + // If an existing entry conflicts with a new one (same index + // but different terms), delete the existing entry and all that + // follow it. + // + // This is done in order to remove phantom logs or uncommitted + // logs from the follower. Phantom logs can appear when a leader + // which appended to the follower crashed before updating the + // commit index of the follower. Now, the new leader might not + // have these logs in it and since all followers must behave to + // the leader, this truncating operation happens. + /** + Example: + Follower.PersistentState.Log -> [1,1,2,2,3,3,3,4,5,6] + Leader.Entries -> [7,7,7] + Leader.prevLogIndex -> 6 (this indicates that, 7 entries were committed + according to this leader) + Leader.prevLogTerm -> 3 (this matches the term existing in the follower log) + Now, at index i = 7 of follower log and index j = 0 of the entries, + there is a mismatch. Thus, all logs starting from this index is removed. + + Follower.PersistentState.Log -> [1,1,2,2,3,3,3] + After appending new entries -> [1,1,2,2,3,3,3,7,7,7] + */ + prevLogIndex := req.GetPrevLogIndex() + for i := prevLogIndex + 1; + i < int32(len(s.node.PersistentState.Log)); + i++ { + if i - prevLogIndex < int32(len(req.GetEntries())) && + s.node.PersistentState.Log[i].GetTerm() != req.GetEntries()[i-prevLogIndex].GetTerm() { + s.node.PersistentState.Log = s.node.PersistentState.Log[i:] + break + } + } + + // Append any new entries not already in the log, entries that came in the request. + s.node.PersistentState.Log = append(s.node.PersistentState.Log, entries...) + s.node.PersistentState.mu.Unlock() + + // If leaderCommit > commitIndex, set commitIndex = + // min(leaderCommit, index of last new entry in follower) + // + // This happens post appending entries, this operation is + // basically catching up the follower with the newly committed + // indexes. (This probably isn't from this txn - TODO: Check) + leaderCommitIndex := req.GetLeaderCommit() + if leaderCommitIndex > commitIndex { + s.node.VolatileState.mu.Lock() + if int(leaderCommitIndex) > len(nodePersistentState.Log) { + s.node.VolatileState.CommitIndex = int32(len(nodePersistentState.Log)) + } else { + s.node.VolatileState.CommitIndex = leaderCommitIndex + } + s.node.VolatileState.mu.Unlock() + + + // What I believe is left here is, letting the parent caller functions + // from the DB that, replication was successful and we can proceed with + // the operations. + /* FIX ISSUE #152 from this + commandEntries := getCommandFromLogs(entries) + succeeded := s.onReplication(commandEntries) + _ = succeeded + // succeeded returns the number of applied entries. + */ + } + } + + s.node.log. + Debug(). + Str("self-id", s.node.PersistentState.SelfID.String()). + Str("returning success to append entries to", string(req.GetLeaderID())). + Msg("append entries success") + + if s.onAppendEntriesResponse != nil { + s.onAppendEntriesResponse() + } + + return &message.AppendEntriesResponse{ + Term: currentTerm, + Success: true, + EntriesLength: int32(len(req.Entries)), + } + +} + +// func getCommandFromLogs(entries []*message.LogData) []*message.Command { +// var commandEntries []*message.Command +// for i := range entries { +// commandEntries = append(commandEntries, entries[i].Entry) +// } +// return commandEntries +// } diff --git a/internal/raft/append_entries_test.go b/internal/raft/append_entries_test.go new file mode 100644 index 00000000..c57679ad --- /dev/null +++ b/internal/raft/append_entries_test.go @@ -0,0 +1,235 @@ +package raft + +import ( + "github.com/xqueries/xdb/internal/id" + networkmocks "github.com/xqueries/xdb/internal/network/mocks" + raftmocks "github.com/xqueries/xdb/internal/raft/mocks" + "os" + "testing" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/message" +) + +// Test_FailureAppendEntriesResponse1 tests for failure of append entries +// due to leader term being lesser than the term of the operating node i.e +// the node who was requested the append entries. +func Test_FailureAppendEntriesResponse1(t *testing.T) { + + node,cluster,log := prepareBaseSystem() + node.PersistentState.CurrentTerm = 3 + node.PersistentState.Log = []*message.LogData{ + {Term: 1, Entry: nil}, + {Term: 1, Entry: nil}, + } + server := SimpleServer{ + node: node, + log: log, + cluster: cluster, + timeoutProvider: timeoutProvider, + + } + + msg := message.NewAppendEntriesRequest(2,id.Create(),1,1,nil,1) + res := server.AppendEntriesResponse(msg) + assert.Equal(t, int32(3),res.GetTerm()) + assert.False(t, res.GetSuccess()) + assert.Equal(t, int32(0), res.GetEntriesLength()) +} + +// Test_FailureAppendEntriesResponse2 tests for failure of append entries +// due to the committed logs not having the same term. +func Test_FailureAppendEntriesResponse2(t *testing.T) { + node, cluster, log := prepareBaseSystem() + + node.PersistentState.CurrentTerm = 1 + node.PersistentState.Log = []*message.LogData{ + {Term: 1, Entry: nil}, + {Term: 1, Entry: nil}, + } + node.VolatileState.CommitIndex = 2 + server := SimpleServer{ + node: node, + log: log, + cluster: cluster, + timeoutProvider: timeoutProvider, + + } + + msg := message.NewAppendEntriesRequest(3,id.Create(),1,1,nil,1) + res := server.AppendEntriesResponse(msg) + assert.Equal(t, int32(1),res.GetTerm()) + assert.False(t, res.GetSuccess()) + assert.Equal(t, int32(0), res.GetEntriesLength()) +} + +// Test_FailureAppendEntriesResponse3 tests for failures of append +// entries due to mismatch of the terms of the last committed logs +// in both interacting machines. +func Test_FailureAppendEntriesResponse3(t *testing.T) { + node, cluster, log := prepareBaseSystem() + node.PersistentState.CurrentTerm = 3 + node.PersistentState.Log = []*message.LogData{ + {Term: 1, Entry: nil}, + {Term: 2, Entry: nil}, + } + node.VolatileState.CommitIndex = -1 + server := SimpleServer{ + node: node, + log: log, + cluster: cluster, + timeoutProvider: timeoutProvider, + + } + + msg := message.NewAppendEntriesRequest(3,id.Create(),1,1,nil,1) + res := server.AppendEntriesResponse(msg) + assert.Equal(t, int32(3),res.GetTerm()) + assert.False(t, res.GetSuccess()) + assert.Equal(t, int32(0), res.GetEntriesLength()) +} + +// Test_PassAppendEntries1 tests append entries where it returns +// a success status. This test doesn't append any entries to the +// approaching node's logs and can be considered a heartbeat type +// method call. +func Test_PassAppendEntries1(t *testing.T) { + node, cluster, log := prepareBaseSystem() + + node.PersistentState.CurrentTerm = 3 + node.PersistentState.Log = []*message.LogData{ + {Term: 1, Entry: nil}, + {Term: 1, Entry: nil}, + } + node.VolatileState.CommitIndex = -1 + server := SimpleServer{ + node: node, + log: log, + cluster: cluster, + timeoutProvider: timeoutProvider, + + } + + msg := message.NewAppendEntriesRequest(3,id.Create(),1,1,nil,1) + res := server.AppendEntriesResponse(msg) + assert.Equal(t, int32(3),res.GetTerm()) + assert.True(t, res.GetSuccess()) + assert.Equal(t, int32(0), res.GetEntriesLength()) +} + +// Test_PassAppendEntries2 tests a successful append entries call +// with a couple of entries to be added to the approaching node's +// logs. This tests whether the logs were appended and the acknowledgement +// of the function for the number of entries appended. +func Test_PassAppendEntries2(t *testing.T) { + node, cluster, log := prepareBaseSystem() + + node.PersistentState.CurrentTerm = 3 + node.PersistentState.Log = []*message.LogData{ + {Term: 1, Entry: nil}, + {Term: 1, Entry: nil}, + } + node.VolatileState.CommitIndex = -1 + server := SimpleServer{ + node: node, + log: log, + cluster: cluster, + timeoutProvider: timeoutProvider, + + } + + msg := message.NewAppendEntriesRequest(3, + id.Create(), + 1, + 1, + []*message.LogData{ + {Term: 2, Entry: nil}, + {Term: 2, Entry: nil}, + }, + 1) + + assert.Equal(t, 2, len(server.node.PersistentState.Log)) + + res := server.AppendEntriesResponse(msg) + assert.Equal(t, int32(3),res.GetTerm()) + assert.True(t, res.GetSuccess()) + assert.Equal(t, int32(2), res.GetEntriesLength()) + + assert.Equal(t,4, len(server.node.PersistentState.Log)) +} + +// Test_PassAppendEntries3 tests removing of conflicting logs in +// the node's logs and then updating them up to the leader's logs. +func Test_PassAppendEntries3(t *testing.T) { + node, cluster, log := prepareBaseSystem() + + node.PersistentState.CurrentTerm = 3 + node.PersistentState.Log = []*message.LogData{ + {Term: 1, Entry: nil}, + {Term: 1, Entry: nil}, + {Term: 3, Entry: nil}, + {Term: 3, Entry: nil}, + } + node.VolatileState.CommitIndex = 1 + server := SimpleServer{ + node: node, + log: log, + cluster: cluster, + timeoutProvider: timeoutProvider, + + } + + msg := message.NewAppendEntriesRequest(5, + id.Create(), + 1, + 1, + []*message.LogData{ + {Term: 4, Entry: nil}, + {Term: 4, Entry: nil}, + }, + 1) + + // Pre check on the log length. + assert.Equal(t, 4, len(server.node.PersistentState.Log)) + + res := server.AppendEntriesResponse(msg) + // TODO: Check term is 3, I suspect it should be changed to 4. + assert.Equal(t, int32(3),res.GetTerm()) + assert.True(t, res.GetSuccess()) + assert.Equal(t, int32(2), res.GetEntriesLength()) + // Newly appended logs must have removed conflicting logs. + assert.Equal(t,4, len(server.node.PersistentState.Log)) + // New entry's term. + assert.Equal(t, int32(4),server.node.PersistentState.Log[2].GetTerm()) +} + +// prepareBaseSystem prepares the basis of all the tests on which Append Entries +// functionality is being tested. +// This involves creating a mock cluster with 3 nodes, which is created by adding +// 2 mocked connections to the mock cluster. +func prepareBaseSystem() (*Node,*raftmocks.Cluster,zerolog.Logger){ + log := zerolog.New(os.Stdout).With().Logger().Level(zerolog.GlobalLevel()) + + cluster := new(raftmocks.Cluster) + clusterID := id.Create() + + conn1 := new(networkmocks.Conn) + conn2 := new(networkmocks.Conn) + + conn1 = addRemoteID(conn1) + conn2 = addRemoteID(conn2) + + connSlice := []network.Conn{ + conn1, + conn2, + } + + cluster.On("Nodes").Return(connSlice) + cluster.On("OwnID").Return(clusterID) + + node := NewRaftNode(cluster) + + return node, cluster, log +} \ No newline at end of file diff --git a/internal/raft/cluster.go b/internal/raft/cluster.go new file mode 100644 index 00000000..5ba3c510 --- /dev/null +++ b/internal/raft/cluster.go @@ -0,0 +1,21 @@ +package raft + +import ( + "context" + "io" + + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/message" +) + +//go:generate mockery -case=snake -name=Cluster + +// Cluster is a description of a cluster of servers. +type Cluster interface { + OwnID() id.ID + Nodes() []network.Conn + Receive(context.Context) (network.Conn, message.Message, error) + Broadcast(context.Context, message.Message) error + io.Closer +} diff --git a/internal/raft/cluster/cluster.go b/internal/raft/cluster/cluster.go new file mode 100644 index 00000000..2d6a6680 --- /dev/null +++ b/internal/raft/cluster/cluster.go @@ -0,0 +1,53 @@ +package cluster + +import ( + "context" + "io" + + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/message" +) + +// ConnHandler is a function that handles a connection and performs a +// handshake. If an error occurs, considering closing the connection. If you +// want the connection to be remembered by the cluster as node, you must add it +// with (cluster.Cluster).AddConnection(network.Conn). +type ConnHandler func(Cluster, network.Conn) + +// Cluster describes a raft cluster. It sometimes has a leader and consists of +// nodes. +type Cluster interface { + // Nodes returns all nodes in the cluster (except this one), including the + // leader node. + Nodes() []network.Conn + // Receive blocks until any connection in the cluster has sent a message to + // this node. It will return the connection and the message, with respect to + // the given context. + Receive(context.Context) (network.Conn, message.Message, error) + // Broadcast sends the given message to all other nodes in this cluster, + // with respect to the given context. + Broadcast(context.Context, message.Message) error + + // OwnID returns the global ID of this node. + OwnID() id.ID + // Join joins the cluster at the given address. The given address may be the + // address and port of any of the nodes in the existing cluster. + Join(context.Context, string) error + // Open creates a new cluster and opens it on the given address. This + // creates a server that will listen for incoming connections. + Open(context.Context, string) error + // AddConnection adds the connection to the cluster. It is considered + // another node in the cluster. + AddConnection(network.Conn) + // RemoveConnection closes the connection and removes it from the cluster. + RemoveConnection(network.Conn) + // OnConnect allows to set a connection hook. This is useful when + // implementing a custom handshake for connecting to the cluster. By default + // on connect will just remember the connection as cluster node. When this + // is set explicitely, (cluster.Cluster).AddConnection(network.Conn) must be + // called, otherwise the connection will not be added to the cluster. + OnConnect(ConnHandler) + + io.Closer +} diff --git a/internal/raft/cluster/doc.go b/internal/raft/cluster/doc.go new file mode 100644 index 00000000..d7994404 --- /dev/null +++ b/internal/raft/cluster/doc.go @@ -0,0 +1,3 @@ +// Package cluster provides easily usable functionality for interacting with +// other nodes in a raft cluster. +package cluster diff --git a/internal/raft/cluster/error.go b/internal/raft/cluster/error.go new file mode 100644 index 00000000..633f0916 --- /dev/null +++ b/internal/raft/cluster/error.go @@ -0,0 +1,12 @@ +package cluster + +// Error is a helper type for creating constant errors. +type Error string + +func (e Error) Error() string { return string(e) } + +const ( + // ErrTimeout indicates, that a the operation took longer than allowed. + // Maybe there was a deadline from a context. + ErrTimeout Error = "timeout" +) diff --git a/internal/raft/cluster/tcp_cluster.go b/internal/raft/cluster/tcp_cluster.go new file mode 100644 index 00000000..4ce252d2 --- /dev/null +++ b/internal/raft/cluster/tcp_cluster.go @@ -0,0 +1,281 @@ +package cluster + +import ( + "context" + "fmt" + "sync" + "sync/atomic" + + "github.com/rs/zerolog" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/message" + "golang.org/x/sync/errgroup" +) + +const ( + tcpClusterMessageQueueBufferSize = 5 +) + +var _ Cluster = (*tcpCluster)(nil) + +type tcpCluster struct { + log zerolog.Logger + + connLock sync.Mutex + conns []network.Conn + + onConnect ConnHandler + + server network.Server + messages chan incomingPayload + started chan struct{} + startedClosed bool + closed int32 + closeChan chan struct{} + // lock needed for atomic write on startedClosed. + mu sync.Mutex +} + +type incomingPayload struct { + origin network.Conn + payload []byte +} + +// NewTCPCluster creates a new cluster that uses TCP connections to communicate +// with other nodes. +func NewTCPCluster(log zerolog.Logger) Cluster { + return newTCPCluster(log) +} + +func newTCPCluster(log zerolog.Logger) *tcpCluster { + return &tcpCluster{ + log: log.With().Str("cluster", "tcp").Logger(), + onConnect: func(c Cluster, conn network.Conn) { c.AddConnection(conn) }, + server: network.NewTCPServer(log), + messages: make(chan incomingPayload, tcpClusterMessageQueueBufferSize), + started: make(chan struct{}), + startedClosed: false, + closeChan: make(chan struct{}, 1), + } +} + +// OnConnect sets a connect hook that will be executed after a cluster-join +// handshake has been performed. +func (c *tcpCluster) OnConnect(handler ConnHandler) { + c.onConnect = handler +} + +func (c *tcpCluster) Join(ctx context.Context, addr string) error { + // connect to the given address + conn, err := network.DialTCP(ctx, c.server.OwnID(), addr) + if err != nil { + return fmt.Errorf("dial tcp: %w", err) + } + c.AddConnection(conn) + + // We have now joined the cluster, start the common procedure for network + // operations, like listening to incoming connections, messages etc. + go c.start() + + return nil +} + +func (c *tcpCluster) Open(ctx context.Context, addr string) error { + go func() { + _ = c.server.Open(addr) + }() + + select { + case <-ctx.Done(): + _ = c.Close() // will also close the server that we just tried to open + return ErrTimeout + case <-c.server.Listening(): + } + go c.start() + return nil +} + +// Nodes returns a copy of the connections that the cluster currently holds. +func (c *tcpCluster) Nodes() []network.Conn { + c.connLock.Lock() + defer c.connLock.Unlock() + + nodes := make([]network.Conn, len(c.conns)) + copy(nodes, c.conns) + return nodes +} + +func (c *tcpCluster) OwnID() id.ID { + return c.server.OwnID() +} + +func (c *tcpCluster) Receive(ctx context.Context) (network.Conn, message.Message, error) { + incoming, ok := <-c.messages + if !ok { + return nil, nil, fmt.Errorf("channel closed") + } + msg, err := message.Unmarshal(incoming.payload) + if err != nil { + return nil, nil, fmt.Errorf("unmarshal: %w", err) + } + return incoming.origin, msg, nil +} + +func (c *tcpCluster) Broadcast(ctx context.Context, msg message.Message) error { + c.connLock.Lock() + defer c.connLock.Unlock() + + errs, _ := errgroup.WithContext(ctx) + for _, conn := range c.conns { + execFunc := func() error { + if err := c.sendMessage(ctx, conn, msg); err != nil { + return fmt.Errorf("send message: %w", err) + } + return nil + } + errs.Go(execFunc) + } + return errs.Wait() +} + +// Close will shut down the cluster. This means: +// +// * the cluster's status is set to closed +// * all connections in the cluster's connection list are closed (not removed) +// * the underlying network server is closed +// * the cluster's message queue is closed +// +// After Close is called on this cluster, it is no longer usable. +func (c *tcpCluster) Close() error { + if atomic.LoadInt32(&c.closed) == 1 { + return nil + } + atomic.StoreInt32(&c.closed, 1) + + // close all connections + var errs errgroup.Group + c.connLock.Lock() + for _, conn := range c.conns { + errs.Go(conn.Close) + } + c.connLock.Unlock() + + errs.Go(c.server.Close) + + // close the message queue + c.closeChan <- struct{}{} + + return errs.Wait() +} + +// addConnection will add the connection to the list of connections of this +// cluster. It will also start a goroutine that reads from the connection. That +// goroutine will push back read data. +func (c *tcpCluster) AddConnection(conn network.Conn) { + c.connLock.Lock() + defer c.connLock.Unlock() + + c.conns = append(c.conns, conn) + go c.receiveMessages(conn) +} + +// RemoveConnection will attempt to remove the given connection from the list of +// connections in this cluster. If the connection was found, it will be removed +// AND CLOSED. If the connection was NOT found, it will NOT be closed. +func (c *tcpCluster) RemoveConnection(conn network.Conn) { + c.connLock.Lock() + defer c.connLock.Unlock() + + for i, node := range c.conns { + if node.RemoteID() == conn.RemoteID() { + c.conns[i] = c.conns[len(c.conns)-1] + c.conns[len(c.conns)-1] = nil + c.conns = c.conns[:len(c.conns)-1] + + _ = conn.Close() + return + } + } +} + +func (c *tcpCluster) handshake(conn network.Conn) { + // TODO: implement + //c.AddConnection(conn) +} + +func (c *tcpCluster) sendMessage(ctx context.Context, conn network.Conn, msg message.Message) error { + msgData, err := message.Marshal(msg) + if err != nil { + return fmt.Errorf("marshal: %w", err) + } + + if err := conn.Send(ctx, msgData); err != nil { + return fmt.Errorf("send: %w", err) + } + return nil +} + +func (c *tcpCluster) start() { + // On connect, execute the on-connect hook. + c.server.OnConnect(func(conn network.Conn) { + c.handshake(conn) + if c.onConnect != nil { + c.onConnect(c, conn) + } + }) + + // signal all waiting receive message goroutines that the server is now + // started and they can start pushing messages onto the queue + c.mu.Lock() + defer c.mu.Unlock() + if !c.startedClosed { + close(c.started) + c.startedClosed = true + } +} + +// receiveMessages will wait for the cluster to be started, and then, while the +// cluster is not closed, attempt to read data from the connection. If the read +// times out, it tries again indefinitely. If an error occurs during the read, +// and the server is already closed, nothing happens, but this method returns. +// If an error occurs during the read, and the server is NOT closed, the +// connection will be removed with (*tcpCluster).RemoveConnection, and the error +// will be logged with error level. After that, this method will return. +func (c *tcpCluster) receiveMessages(conn network.Conn) { + <-c.started // wait for the server to be started + + for atomic.LoadInt32(&c.closed) == 0 { + // receive data from the connection + data, err := conn.Receive(context.TODO()) + if err != nil { + if err == network.ErrTimeout { + // didn't receive a message within the timeout, try again + continue + } + if atomic.LoadInt32(&c.closed) == 1 { + // server is closed, no reason to log errors from connections + // that we failed to read from, but break the read loop and + // terminate this goroutine + return + } + c.RemoveConnection(conn) // also closes the connection + c.log.Error(). + Err(err). + Str("fromID", conn.RemoteID().String()). + Msg("receive failed, removing connection") + return // abort this goroutine + } + + select { + case <-c.closeChan: + close(c.messages) + default: + // push payload and connection onto the message queue + c.messages <- incomingPayload{ + origin: conn, + payload: data, + } + } + } +} diff --git a/internal/raft/cluster/tcp_cluster_test.go b/internal/raft/cluster/tcp_cluster_test.go new file mode 100644 index 00000000..764dc358 --- /dev/null +++ b/internal/raft/cluster/tcp_cluster_test.go @@ -0,0 +1,94 @@ +package cluster_test + +import ( + "context" + "net" + "sync" + "testing" + "time" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/cluster" + "github.com/xqueries/xdb/internal/raft/message" +) + +func TestTCPClusterCommunication(t *testing.T) { + assert := assert.New(t) + + ctx := context.Background() + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + + cluster := cluster.NewTCPCluster(zerolog.Nop()) + defer func() { + _ = cluster.Close() + }() + assert.Empty(cluster.Nodes()) + + err := cluster.Open(ctx, ":0") + assert.NoError(err) + + conn1, conn2 := net.Pipe() + tcp1, tcp2 := network.NewTCPConn(conn1), network.NewTCPConn(conn2) + defer func() { + _ = tcp1.Close() + _ = tcp2.Close() + }() + + cluster.AddConnection(tcp1) + assert.Len(cluster.Nodes(), 1) + + t.Run("Broadcast", _TestTCPClusterBroadcast(ctx, cluster, tcp2)) + t.Run("Receive", _TestTCPClusterReceive(ctx, cluster, tcp1, tcp2)) +} + +func _TestTCPClusterBroadcast(ctx context.Context, cluster cluster.Cluster, externalConn network.Conn) func(*testing.T) { + return func(t *testing.T) { + assert := assert.New(t) + + var wg sync.WaitGroup + wg.Add(1) + go func() { + err := cluster.Broadcast(ctx, message.NewTestMessage("Hello, World!")) + assert.NoError(err) + wg.Done() + }() + + data, err := externalConn.Receive(ctx) + assert.NoError(err) + + wg.Wait() + msg, err := message.Unmarshal(data) + assert.NoError(err) + assert.Equal(message.KindTestMessage, msg.Kind()) + assert.IsType(&message.TestMessage{}, msg) + assert.Equal("Hello, World!", msg.(*message.TestMessage).GetData()) + } +} + +func _TestTCPClusterReceive(ctx context.Context, cluster cluster.Cluster, internalConn, externalConn network.Conn) func(*testing.T) { + return func(t *testing.T) { + assert := assert.New(t) + + data, err := message.Marshal(message.NewTestMessage("Hello, World!")) + assert.NoError(err) + + // This should not block, since the cluster uses a buffered message + // queue. If it blocks however, it will run into a timeout. + err = externalConn.Send(ctx, data) + assert.NoError(err) + + conn, msg, err := cluster.Receive(ctx) + assert.NoError(err) + // The external conn ID is not equal to the conn.ID(), because it did + // not connect to a network.Server with network.DialTCP, and thus had no + // chance of exchanging the ID. When connecting to the cluster with + // cluster.Join or network.DialTCP however, this ID will be the same. + assert.Equal(internalConn.RemoteID(), conn.RemoteID()) + assert.Equal(message.KindTestMessage, msg.Kind()) + assert.IsType(&message.TestMessage{}, msg) + assert.Equal("Hello, World!", msg.(*message.TestMessage).GetData()) + } +} diff --git a/internal/raft/cluster/test_framework.go b/internal/raft/cluster/test_framework.go new file mode 100644 index 00000000..ffc0d9ca --- /dev/null +++ b/internal/raft/cluster/test_framework.go @@ -0,0 +1,54 @@ +package cluster + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/xqueries/xdb/internal/network" +) + +// TCPTestNetwork encompasses the entire network on which +// the tests will be performed. +type TCPTestNetwork struct { + Clusters []*tcpCluster +} + +// NewTCPTestNetwork starts a ready to use network of +// "num" number of nodes. +func NewTCPTestNetwork(t *testing.T, num int) *TCPTestNetwork { + assert := assert.New(t) + + var clusters []*tcpCluster + + for i := 0; i < num; i++ { + ctx := context.TODO() + + c := newTCPCluster(zerolog.Nop()) + assert.NoError(c.Open(ctx, ":0")) + + select { + case <-c.server.Listening(): + case <-time.After(1 * time.Second): + assert.FailNow("timeout") + } + + for _, otherCluster := range clusters { + conn, err := network.DialTCP(ctx, c.OwnID(), otherCluster.server.Addr().String()) + assert.NoError(err) + c.AddConnection(conn) + } + clusters = append(clusters, c) + } + + for _, c := range clusters { + fmt.Println(c.Nodes()) + } + + return &TCPTestNetwork{ + Clusters: clusters, + } +} diff --git a/internal/raft/doc.go b/internal/raft/doc.go new file mode 100644 index 00000000..9a9b577f --- /dev/null +++ b/internal/raft/doc.go @@ -0,0 +1,3 @@ +// Package raft implements the raft consensus protocol. +// This package provides API to run a raft cluster. +package raft diff --git a/internal/raft/error.go b/internal/raft/error.go new file mode 100644 index 00000000..a508ed1b --- /dev/null +++ b/internal/raft/error.go @@ -0,0 +1,11 @@ +package raft + +import "fmt" + +type multiError []error + +var _ error = (*multiError)(nil) + +func (e multiError) Error() string { + return fmt.Sprintf("multiple errors: %v", []error(e)) +} diff --git a/internal/raft/example_test.go b/internal/raft/example_test.go new file mode 100644 index 00000000..7f64bcd9 --- /dev/null +++ b/internal/raft/example_test.go @@ -0,0 +1,28 @@ +package raft + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + networkmocks "github.com/xqueries/xdb/internal/network/mocks" + "github.com/xqueries/xdb/internal/raft/mocks" +) + +func TestExample(t *testing.T) { + conn := new(networkmocks.Conn) + // mock call to RemoteID + id := id.Create() + conn. + On("RemoteID"). + Return(id) + + c := new(mocks.Cluster) + // mock call to Nodes + c. + On("Nodes"). + Return([]network.Conn{conn}) + + assert.Equal(t, conn.RemoteID().String(), c.Nodes()[0].RemoteID().String()) +} diff --git a/internal/raft/follower.go b/internal/raft/follower.go new file mode 100644 index 00000000..bee83654 --- /dev/null +++ b/internal/raft/follower.go @@ -0,0 +1,19 @@ +package raft + +import "github.com/xqueries/xdb/internal/id" + +// becomeFollower converts a leader to a follower. +// After this function is executed, the node goes back to the loop in raft.go, +// thus resuming normal operations. +func (node *Node) becomeFollower(leaderTerm int32, leaderID id.ID) { + node.log. + Debug(). + Str("self-id", node.PersistentState.SelfID.String()). + Msg("becoming follower") + node.PersistentState.mu.Lock() + node.PersistentState.CurrentTerm = leaderTerm + node.PersistentState.LeaderID = leaderID + node.PersistentState.VotedFor = leaderID + node.State = StateFollower.String() + node.PersistentState.mu.Unlock() +} diff --git a/internal/raft/leader.go b/internal/raft/leader.go new file mode 100644 index 00000000..aeede501 --- /dev/null +++ b/internal/raft/leader.go @@ -0,0 +1,160 @@ +package raft + +import ( + "context" + "time" + + "github.com/xqueries/xdb/internal/raft/message" +) + +// startLeader begins the leaders operations. Once a leader is confirmed +// to be elected, this function is executed. +// +// The leader is responsible to do two things; one, ensure that all other +// nodes know that there is a leader alive in this term and two, to send +// logs that were received by the client and maintain consensus. Part one +// is achieved by sending heartbeats when there are no logs that are to +// be appended and two is achieved by sending the AppendEntriesRequest. +// +// The leader begins by sending append entries RPC to the nodes parallelly. +// The leader sends periodic append entries request to the +// followers to keep them alive. +// +// The selfID is passed as an argument for two reasons, +// one it acts as a double check that this node is actually the leader, +// and second, it reduces locks to find out the selfID in the future. +// +// Empty append entries request are also called heartbeats. +// The data that goes in the append entries request is determined by +// existence of data in the LogChannel channel. +// +// This function doesn't bother with obtaining the response for the sent +// requests. This is handled by the raft-core functions. +func (s *SimpleServer) startLeader(ctx context.Context, selfID string) { + + s.node.log. + Debug(). + Str("self-id", selfID). + Msg("starting leader election proceedings") + + stopLeaderOps := make(chan struct{}) + go func() { + // The loop that the leader stays in until it's functioning properly. + // The goal of this loop is to maintain raft in it's working phase; + // periodically sending heartbeats/appendEntries. + // This loop goes on until this node is the leader. + for { + select { + case <-ctx.Done(): + s.node.log. + Debug(). + Str("self-id", selfID). + Msg("leader stopping operation, stop signal encountered") + stopLeaderOps <- struct{}{} + return + default: + // Send heartbeats every 50ms. + <-time.NewTimer(50 * time.Millisecond).C + + // Before continuing the operations, check whether + // the server is not closed. + s.lock.Lock() + if s.node.Closed { + s.lock.Unlock() + return + } + s.node.PersistentState.mu.Lock() + if s.node.State != StateLeader.String() { + s.node.PersistentState.mu.Unlock() + stopLeaderOps <- struct{}{} + return + } + s.node.PersistentState.mu.Unlock() + + s.sendHeartBeats(ctx, selfID, stopLeaderOps) + s.lock.Unlock() + } + } + }() +} + +func (s *SimpleServer) sendHeartBeats(ctx context.Context, selfIDString string, stopLeaderOps chan struct{}) { + + s.node.PersistentState.mu.Lock() + savedCurrentTerm := s.node.PersistentState.CurrentTerm + s.node.PersistentState.mu.Unlock() + + // Parallelly send AppendEntriesRPC to all followers. + for i := range s.node.PersistentState.peerIPs { + select { + case <-stopLeaderOps: + s.node.log. + Debug(). + Str("self-id", selfIDString). + Msg("leader stopping operation mid-heartbeat, stop signal encountered") + return + default: + s.node.log. + Debug(). + Str("self-id", selfIDString). + Msg("sending heartbeats") + go func(i int) { + s.node.PersistentState.mu.Lock() + + nextIndex := s.node.VolatileStateLeader.NextIndex[i] + prevLogIndex := nextIndex - 1 + prevLogTerm := -1 + if prevLogIndex >= 0 { + prevLogTerm = int(s.node.PersistentState.Log[prevLogIndex].Term) + } + commitIndex := s.node.VolatileState.CommitIndex + conn := s.node.PersistentState.peerIPs[i] + selfID := s.node.PersistentState.SelfID + // Logs are included from the nextIndex value to the current appended values + // in the leader node. If there are none, no logs will be appended. + var entries []*message.LogData + if nextIndex >= 0 { + entries = s.node.PersistentState.Log[nextIndex:] + } + s.node.PersistentState.mu.Unlock() + + appendEntriesRequest := message.NewAppendEntriesRequest( + savedCurrentTerm, + selfID, + int32(prevLogIndex), + int32(prevLogTerm), + entries, + commitIndex, + ) + + payload, err := message.Marshal(appendEntriesRequest) + if err != nil { + s.node.log. + Err(err). + Str("Node", selfIDString). + Msg("Error marshalling append entries request in leader") + return + } + + err = conn.Send(ctx, payload) + if err != nil { + s.node.log. + Err(err). + Str("Node", selfIDString). + Msg("Error sending append entries request over network") + return + } + + s.node.log. + Debug(). + Str("self-id", selfIDString). + Str("sent to", conn.RemoteID().String()). + Msg("sent heartbeat to peer") + + if s.onAppendEntriesRequest != nil { + s.onAppendEntriesRequest(conn) + } + }(i) + } + } +} diff --git a/internal/raft/leader_election.go b/internal/raft/leader_election.go new file mode 100644 index 00000000..2e935656 --- /dev/null +++ b/internal/raft/leader_election.go @@ -0,0 +1,65 @@ +package raft + +import ( + "context" + "fmt" + + "github.com/xqueries/xdb/internal/raft/message" +) + +// StartElection enables a node in the cluster to start the election. +// The function caller doesn't need to wait for a voting response from this function, +// the function triggers the necessary functions responsible to continue the raft cluster +// into it's working stage if the node won the election. +func (s *SimpleServer) StartElection(ctx context.Context) { + + s.lock.Lock() + s.node.PersistentState.mu.Lock() + s.node.PersistentState.CurrentTerm++ + s.node.VolatileState.Votes = 0 + s.node.State = StateCandidate.String() + var lastLogTerm, lastLogIndex int32 + savedCurrentTerm := s.node.PersistentState.CurrentTerm + if len(s.node.PersistentState.Log) == 0 { + lastLogTerm = 0 + } else { + lastLogTerm = s.node.PersistentState.Log[len(s.node.PersistentState.Log)].Term + } + lastLogIndex = int32(len(s.node.PersistentState.Log)) + selfID := s.node.PersistentState.SelfID + numNodes := s.node.PersistentState.peerIPs + s.node.log. + Debug(). + Str("self-id", selfID.String()). + Int32("term", s.node.PersistentState.CurrentTerm). + Msg("starting election") + s.node.PersistentState.mu.Unlock() + s.lock.Unlock() + + for i := range numNodes { + // Parallelly request votes from the peers. + go func(i int) { + req := message.NewRequestVoteRequest( + savedCurrentTerm, + selfID, + lastLogIndex, + lastLogTerm, + ) + s.lock.Lock() + if s.node.Closed { + return + } + nodeConn := s.node.PersistentState.peerIPs[i] + s.lock.Unlock() + + err := s.RequestVote(ctx, nodeConn, req) + if err != nil { + fmt.Println(err) + } + // If there's an error, the vote is considered to be not casted by the node. + // Worst case, there will be a re-election; the errors might be from network or + // data consistency errors, which will be sorted by a re-election. + // This decision was taken because, StartElection returning an error is not feasible. + }(i) + } +} diff --git a/internal/raft/leader_election_test.go b/internal/raft/leader_election_test.go new file mode 100644 index 00000000..5ed409d7 --- /dev/null +++ b/internal/raft/leader_election_test.go @@ -0,0 +1,54 @@ +package raft + +import ( + "context" + "github.com/rs/zerolog" + "github.com/stretchr/testify/mock" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + networkmocks "github.com/xqueries/xdb/internal/network/mocks" + raftmocks "github.com/xqueries/xdb/internal/raft/mocks" + "os" + "testing" + "time" +) + +// Test_StartElection tests the StartElection function whose sole +// responsibility is to eventually call Send on the connections +// that are in the SimpleServer's cluster, which is being tested here. +func Test_StartElection(t *testing.T) { + ctx := context.Background() + log := zerolog.New(os.Stdout).With().Logger().Level(zerolog.GlobalLevel()) + + cluster := new(raftmocks.Cluster) + clusterID := id.Create() + + conn1 := new(networkmocks.Conn) + conn2 := new(networkmocks.Conn) + + connSlice := []network.Conn{ + conn1, + conn2, + } + + conn1 = addRemoteID(conn1) + conn2 = addRemoteID(conn2) + + cluster.On("Nodes").Return(connSlice) + cluster.On("OwnID").Return(clusterID) + + conn1.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn2.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + + node := NewRaftNode(cluster) + + server := newServer( + log, + cluster, + timeoutProvider, + ) + server.node = node + server.StartElection(ctx) + + time.Sleep(5* time.Second) +} \ No newline at end of file diff --git a/internal/raft/leader_test.go b/internal/raft/leader_test.go new file mode 100644 index 00000000..2fe17d53 --- /dev/null +++ b/internal/raft/leader_test.go @@ -0,0 +1,12 @@ +package raft + +import "testing" + +func TestStartLeader(t *testing.T) { + +} + + +func TestSendHeartbeats(t *testing.T) { + +} diff --git a/internal/raft/log b/internal/raft/log new file mode 100644 index 00000000..aee2ed31 --- /dev/null +++ b/internal/raft/log @@ -0,0 +1,917 @@ +[0xc000098e40 0xc000232080] +[0xc000232040 0xc000232140] +[0xc000098e80 0xc000232100] +{"level":"debug","message":"beginning execution goroutine"} +{"level":"debug","message":"initiating operation injection"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":281,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":237,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":197,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","term":1,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":209,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","request-vote sent to":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"request vote"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindRequestVoteRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","received":"KindRequestVoteRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","vote granted to":"01F0B6VE1MT139V4VBQHGH609S","message":"voting a peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","vote granted to":"01F0B6VE1MT139V4VBQHGH609S","message":"voting a peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":181,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindRequestVoteResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":168,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":175,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindRequestVoteResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":290,"message":"heart beat timer"} +{"level":"debug","component":"raft","received vote from":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"voting from peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"node voting for itself"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"node elected leader"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"starting leader election proceedings"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":256,"message":"heart beat timer"} +{"level":"debug","component":"raft","received vote from":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"voting from peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":150,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"self term out of date, returning to follower state"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"self term out of date, returning to follower state"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"becoming follower"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"becoming follower"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":194,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":211,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":162,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":239,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":178,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":224,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":261,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":245,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":287,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":206,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":245,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":216,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":278,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":208,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":297,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":247,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":187,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":238,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":240,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":165,"message":"heart beat timer"} +{"level":"debug","executing":"2","message":"beginning execution"} +{"level":"debug","message":"operation moved to execution channel"} +{"level":"debug","message":"executing operation"} +{"level":"debug","node ID":1,"message":"stopping the node"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"closing node"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":241,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":258,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":287,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":281,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":279,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":206,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":237,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":181,"message":"heart beat timer"} +2021/03/09 15:29:53 node was closed, exiting +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":285,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":276,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":163,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":190,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":244,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":213,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":283,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":297,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":178,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":274,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":259,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":153,"message":"heart beat timer"} +{"level":"debug","executing":"4","message":"beginning execution"} +{"level":"debug","message":"operation moved to execution channel"} +{"level":"debug","message":"executing operation"} +{"level":"debug","node ID":1,"message":"restarting the node"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":207,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":271,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":189,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":249,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":250,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":205,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":188,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":288,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":253,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":1,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":155,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":251,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":210,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":255,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":156,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":2,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":166,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":278,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":161,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":152,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":233,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":296,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":163,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":276,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":152,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":3,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":218,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":297,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":294,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":277,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":163,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":196,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":170,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":273,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":153,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":4,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":187,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":283,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":191,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":259,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":233,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":293,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":191,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":202,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":5,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":278,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":286,"message":"heart beat timer"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":246,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":157,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":240,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":253,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":252,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":243,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":205,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":248,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":225,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":151,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":6,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":165,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":257,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":287,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":260,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":160,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":235,"message":"heart beat timer"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":240,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":7,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":232,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":198,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":253,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":241,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":182,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":234,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":247,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":167,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":187,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":8,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":171,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":294,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":176,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":202,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":231,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":279,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":166,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":270,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":293,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":9,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":286,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":169,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":231,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":252,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":225,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":235,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":260,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":237,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":199,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":278,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":218,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":10,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":234,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":153,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":174,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":197,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":262,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":232,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":266,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":239,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":290,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":236,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":251,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":11,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":176,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":190,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":151,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":244,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":214,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":155,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":283,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":12,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":201,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":240,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":202,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":158,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":217,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":231,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":178,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":204,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":222,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":13,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":273,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":192,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":258,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":243,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":268,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":216,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":210,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":185,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":240,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":254,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":262,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":14,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":157,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":165,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":171,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":239,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":280,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","returning success to append entries to":"01F0B6VE1MT139V4VBQHGH609S","message":"append entries success"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","random timer set to":213,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","received":"KindAppendEntriesResponse","message":"received request"} +{"level":"debug","component":"raft","node-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"received append entries response"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","random timer set to":250,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"sending heartbeats"} +{"level":"error","component":"raft","error":"already closed","Node":"01F0B6VE1MT139V4VBQHGH609S","message":"error"} +{"level":"debug","message":"shutting down - reached round limit"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"sent heartbeat to peer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","received":"KindAppendEntriesRequest","message":"received request"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"closing node"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","term":15,"message":"starting election"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","random timer set to":159,"message":"heart beat timer"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1HJM50QS5TB8SPHV6D","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","request-vote sent to":"01F0B6VE1MT139V4VBQHGH609S","message":"request vote"} +already closed +{"level":"debug","component":"raft","self-id":"01F0B6VE1KR0R2XQT0WWB8KHJA","message":"closing node"} +{"level":"debug","component":"raft","self-id":"01F0B6VE1MT139V4VBQHGH609S","message":"closing node"} +{"level":"debug","message":"gracefully shutting down"} +{"level":"debug","message":"execution shutting down"} +PASS +ok github.com/xqueries/xdb/internal/raft 4.585s diff --git a/internal/raft/message/append_entries.go b/internal/raft/message/append_entries.go new file mode 100644 index 00000000..f1a8d7ee --- /dev/null +++ b/internal/raft/message/append_entries.go @@ -0,0 +1,54 @@ +package message + +import ( + "github.com/xqueries/xdb/internal/compiler/command" + "github.com/xqueries/xdb/internal/id" +) + +//go:generate protoc --go_out=. append_entries.proto + +var _ Message = (*AppendEntriesRequest)(nil) + +// NewAppendEntriesRequest creates a new append-entries-request message with the +// given parameters. +func NewAppendEntriesRequest(term int32, leaderID id.ID, prevLogIndex int32, prevLogTerm int32, entries []*LogData, leaderCommit int32) *AppendEntriesRequest { + return &AppendEntriesRequest{ + Term: term, + LeaderID: leaderID.Bytes(), + PrevLogIndex: prevLogIndex, + PrevLogTerm: prevLogTerm, + Entries: entries, + LeaderCommit: leaderCommit, + } +} + +// Kind returns KindAppendEntriesRequest. +func (*AppendEntriesRequest) Kind() Kind { + return KindAppendEntriesRequest +} + +// NewLogData creates a new log-data object, which can be used for an +// append-entries-request message. +func NewLogData(term int32, data command.Command) *LogData { + msg, _ := ConvertCommandToMessage(data) + + return &LogData{ + Term: term, + Entry: msg.(*Command), + } +} + +// NewAppendEntriesResponse creates a new append-entries-response message with +// the given parameters. +func NewAppendEntriesResponse(term int32, success bool, entriesLength int32) *AppendEntriesResponse { + return &AppendEntriesResponse{ + Term: term, + Success: success, + EntriesLength: entriesLength, + } +} + +// Kind returns KindAppendEntriesResponse. +func (*AppendEntriesResponse) Kind() Kind { + return KindAppendEntriesResponse +} diff --git a/internal/raft/message/append_entries.pb.go b/internal/raft/message/append_entries.pb.go new file mode 100644 index 00000000..dcbf8156 --- /dev/null +++ b/internal/raft/message/append_entries.pb.go @@ -0,0 +1,361 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.25.0 +// protoc v3.13.0 +// source: append_entries.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type AppendEntriesRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Term int32 `protobuf:"varint,1,opt,name=term,proto3" json:"term,omitempty"` + LeaderID []byte `protobuf:"bytes,2,opt,name=leaderID,proto3" json:"leaderID,omitempty"` + PrevLogIndex int32 `protobuf:"varint,3,opt,name=prevLogIndex,proto3" json:"prevLogIndex,omitempty"` + PrevLogTerm int32 `protobuf:"varint,4,opt,name=prevLogTerm,proto3" json:"prevLogTerm,omitempty"` + Entries []*LogData `protobuf:"bytes,5,rep,name=Entries,proto3" json:"Entries,omitempty"` // Entries are the log entries in the node. + LeaderCommit int32 `protobuf:"varint,6,opt,name=leaderCommit,proto3" json:"leaderCommit,omitempty"` // LeaderCommit is the Leader's commit index. +} + +func (x *AppendEntriesRequest) Reset() { + *x = AppendEntriesRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_append_entries_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppendEntriesRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppendEntriesRequest) ProtoMessage() {} + +func (x *AppendEntriesRequest) ProtoReflect() protoreflect.Message { + mi := &file_append_entries_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppendEntriesRequest.ProtoReflect.Descriptor instead. +func (*AppendEntriesRequest) Descriptor() ([]byte, []int) { + return file_append_entries_proto_rawDescGZIP(), []int{0} +} + +func (x *AppendEntriesRequest) GetTerm() int32 { + if x != nil { + return x.Term + } + return 0 +} + +func (x *AppendEntriesRequest) GetLeaderID() []byte { + if x != nil { + return x.LeaderID + } + return nil +} + +func (x *AppendEntriesRequest) GetPrevLogIndex() int32 { + if x != nil { + return x.PrevLogIndex + } + return 0 +} + +func (x *AppendEntriesRequest) GetPrevLogTerm() int32 { + if x != nil { + return x.PrevLogTerm + } + return 0 +} + +func (x *AppendEntriesRequest) GetEntries() []*LogData { + if x != nil { + return x.Entries + } + return nil +} + +func (x *AppendEntriesRequest) GetLeaderCommit() int32 { + if x != nil { + return x.LeaderCommit + } + return 0 +} + +type LogData struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Term int32 `protobuf:"varint,1,opt,name=term,proto3" json:"term,omitempty"` + Entry *Command `protobuf:"bytes,2,opt,name=Entry,proto3" json:"Entry,omitempty"` // Each is a compiled sql stmt +} + +func (x *LogData) Reset() { + *x = LogData{} + if protoimpl.UnsafeEnabled { + mi := &file_append_entries_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogData) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogData) ProtoMessage() {} + +func (x *LogData) ProtoReflect() protoreflect.Message { + mi := &file_append_entries_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogData.ProtoReflect.Descriptor instead. +func (*LogData) Descriptor() ([]byte, []int) { + return file_append_entries_proto_rawDescGZIP(), []int{1} +} + +func (x *LogData) GetTerm() int32 { + if x != nil { + return x.Term + } + return 0 +} + +func (x *LogData) GetEntry() *Command { + if x != nil { + return x.Entry + } + return nil +} + +type AppendEntriesResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Term int32 `protobuf:"varint,1,opt,name=term,proto3" json:"term,omitempty"` // Term is the responder node's current term. + Success bool `protobuf:"varint,2,opt,name=success,proto3" json:"success,omitempty"` // Success returns true if the log matching property holds good. + EntriesLength int32 `protobuf:"varint,3,opt,name=entriesLength,proto3" json:"entriesLength,omitempty"` // The length of the entries that was appended by the node. +} + +func (x *AppendEntriesResponse) Reset() { + *x = AppendEntriesResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_append_entries_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *AppendEntriesResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AppendEntriesResponse) ProtoMessage() {} + +func (x *AppendEntriesResponse) ProtoReflect() protoreflect.Message { + mi := &file_append_entries_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AppendEntriesResponse.ProtoReflect.Descriptor instead. +func (*AppendEntriesResponse) Descriptor() ([]byte, []int) { + return file_append_entries_proto_rawDescGZIP(), []int{2} +} + +func (x *AppendEntriesResponse) GetTerm() int32 { + if x != nil { + return x.Term + } + return 0 +} + +func (x *AppendEntriesResponse) GetSuccess() bool { + if x != nil { + return x.Success + } + return false +} + +func (x *AppendEntriesResponse) GetEntriesLength() int32 { + if x != nil { + return x.EntriesLength + } + return 0 +} + +var File_append_entries_proto protoreflect.FileDescriptor + +var file_append_entries_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, + 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xdc, + 0x01, 0x0a, 0x14, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x12, 0x1a, 0x0a, 0x08, 0x6c, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x6c, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x70, 0x72, 0x65, 0x76, 0x4c, + 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0c, 0x70, + 0x72, 0x65, 0x76, 0x4c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, 0x0a, 0x0b, 0x70, + 0x72, 0x65, 0x76, 0x4c, 0x6f, 0x67, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0b, 0x70, 0x72, 0x65, 0x76, 0x4c, 0x6f, 0x67, 0x54, 0x65, 0x72, 0x6d, 0x12, 0x2a, 0x0a, + 0x07, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, + 0x52, 0x07, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x0c, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x43, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x22, 0x45, 0x0a, + 0x07, 0x4c, 0x6f, 0x67, 0x44, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x72, 0x6d, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x12, 0x26, 0x0a, 0x05, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x05, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x22, 0x6b, 0x0a, 0x15, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x45, 0x6e, + 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x65, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x65, 0x72, + 0x6d, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x07, 0x73, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x0d, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x4c, 0x65, 0x6e, 0x67, 0x74, + 0x68, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_append_entries_proto_rawDescOnce sync.Once + file_append_entries_proto_rawDescData = file_append_entries_proto_rawDesc +) + +func file_append_entries_proto_rawDescGZIP() []byte { + file_append_entries_proto_rawDescOnce.Do(func() { + file_append_entries_proto_rawDescData = protoimpl.X.CompressGZIP(file_append_entries_proto_rawDescData) + }) + return file_append_entries_proto_rawDescData +} + +var file_append_entries_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_append_entries_proto_goTypes = []interface{}{ + (*AppendEntriesRequest)(nil), // 0: message.AppendEntriesRequest + (*LogData)(nil), // 1: message.LogData + (*AppendEntriesResponse)(nil), // 2: message.AppendEntriesResponse + (*Command)(nil), // 3: message.Command +} +var file_append_entries_proto_depIdxs = []int32{ + 1, // 0: message.AppendEntriesRequest.Entries:type_name -> message.LogData + 3, // 1: message.LogData.Entry:type_name -> message.Command + 2, // [2:2] is the sub-list for method output_type + 2, // [2:2] is the sub-list for method input_type + 2, // [2:2] is the sub-list for extension type_name + 2, // [2:2] is the sub-list for extension extendee + 0, // [0:2] is the sub-list for field type_name +} + +func init() { file_append_entries_proto_init() } +func file_append_entries_proto_init() { + if File_append_entries_proto != nil { + return + } + file_command_proto_init() + if !protoimpl.UnsafeEnabled { + file_append_entries_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppendEntriesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_append_entries_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogData); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_append_entries_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AppendEntriesResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_append_entries_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_append_entries_proto_goTypes, + DependencyIndexes: file_append_entries_proto_depIdxs, + MessageInfos: file_append_entries_proto_msgTypes, + }.Build() + File_append_entries_proto = out.File + file_append_entries_proto_rawDesc = nil + file_append_entries_proto_goTypes = nil + file_append_entries_proto_depIdxs = nil +} diff --git a/internal/raft/message/append_entries.proto b/internal/raft/message/append_entries.proto new file mode 100644 index 00000000..2db1305a --- /dev/null +++ b/internal/raft/message/append_entries.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; +import "command.proto"; + +message AppendEntriesRequest { + int32 term = 1; + bytes leaderID = 2; + int32 prevLogIndex = 3; // index of log entry immediately preceding new ones. + int32 prevLogTerm = 4; // term of prevLogIndex entry. + repeated LogData Entries = 5; // Entries are the log entries in the node. + int32 leaderCommit = 6; // LeaderCommit is the Leader's commit index. +} + +message LogData { + int32 term = 1; + Command Entry = 2; // Each is a compiled sql stmt +} + +message AppendEntriesResponse { + int32 term = 1; // Term is the responder node's current term. + bool success = 2; // Success returns true if the log matching property holds good. + int32 entriesLength = 3; // The length of the entries that was appended by the node. +} \ No newline at end of file diff --git a/internal/raft/message/command.go b/internal/raft/message/command.go new file mode 100644 index 00000000..0231b7eb --- /dev/null +++ b/internal/raft/message/command.go @@ -0,0 +1,66 @@ +package message + +import "github.com/xqueries/xdb/internal/compiler/command" + +var _ Message = (*Command)(nil) +var _ command.Command = (*Command)(nil) + +// NewCommand creates a new Command variable. +func NewCommand() *Command { + return &Command{} +} + +// Kind returns KindCommand. +func (*Command) Kind() Kind { + return KindCommand +} + +// Kind returns KindExpr +func (*Expr) Kind() Kind { + return KindExpr +} + +// Kind returns KindCommandScan. +func (*Command_Scan) Kind() Kind { + return KindCommandScan +} + +// Kind returns KindCommandSelect. +func (*Command_Select) Kind() Kind { + return KindCommandSelect +} + +// Kind returns KindCommandProject. +func (*Command_Project) Kind() Kind { + return KindCommandProject +} + +// Kind returns KindCommandDelete. +func (*Command_Delete) Kind() Kind { + return KindCommandDelete +} + +// Kind returns KindCommandUpdate. +func (*Command_Update) Kind() Kind { + return KindCommandUpdate +} + +// Kind returns KindCommandDrop. +func (*CommandDrop) Kind() Kind { + return KindCommandDrop +} + +// Kind returns KindCommandLimit. +func (*Command_Limit) Kind() Kind { + return KindCommandLimit +} + +// Kind returns KindCommandJoin. +func (*Command_Join) Kind() Kind { + return KindCommandJoin +} + +// Kind returns KindCommandInsert. +func (*Command_Insert) Kind() Kind { + return KindCommandInsert +} diff --git a/internal/raft/message/command.pb.go b/internal/raft/message/command.pb.go new file mode 100644 index 00000000..d22edb83 --- /dev/null +++ b/internal/raft/message/command.pb.go @@ -0,0 +1,2866 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.11.4 +// source: command.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type JoinType int32 + +const ( + JoinType_JoinUnknown JoinType = 0 + JoinType_JoinLeft JoinType = 1 + JoinType_JoinLeftOuter JoinType = 2 + JoinType_JoinInner JoinType = 3 + JoinType_JoinCross JoinType = 4 +) + +// Enum value maps for JoinType. +var ( + JoinType_name = map[int32]string{ + 0: "JoinUnknown", + 1: "JoinLeft", + 2: "JoinLeftOuter", + 3: "JoinInner", + 4: "JoinCross", + } + JoinType_value = map[string]int32{ + "JoinUnknown": 0, + "JoinLeft": 1, + "JoinLeftOuter": 2, + "JoinInner": 3, + "JoinCross": 4, + } +) + +func (x JoinType) Enum() *JoinType { + p := new(JoinType) + *p = x + return p +} + +func (x JoinType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (JoinType) Descriptor() protoreflect.EnumDescriptor { + return file_command_proto_enumTypes[0].Descriptor() +} + +func (JoinType) Type() protoreflect.EnumType { + return &file_command_proto_enumTypes[0] +} + +func (x JoinType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use JoinType.Descriptor instead. +func (JoinType) EnumDescriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{0} +} + +type UpdateOr int32 + +const ( + UpdateOr_UpdateOrUnknown UpdateOr = 0 + UpdateOr_UpdateOrRollback UpdateOr = 1 + UpdateOr_UpdateOrAbort UpdateOr = 2 + UpdateOr_UpdateOrReplace UpdateOr = 3 + UpdateOr_UpdateOrFail UpdateOr = 4 + UpdateOr_UpdateOrIgnore UpdateOr = 5 +) + +// Enum value maps for UpdateOr. +var ( + UpdateOr_name = map[int32]string{ + 0: "UpdateOrUnknown", + 1: "UpdateOrRollback", + 2: "UpdateOrAbort", + 3: "UpdateOrReplace", + 4: "UpdateOrFail", + 5: "UpdateOrIgnore", + } + UpdateOr_value = map[string]int32{ + "UpdateOrUnknown": 0, + "UpdateOrRollback": 1, + "UpdateOrAbort": 2, + "UpdateOrReplace": 3, + "UpdateOrFail": 4, + "UpdateOrIgnore": 5, + } +) + +func (x UpdateOr) Enum() *UpdateOr { + p := new(UpdateOr) + *p = x + return p +} + +func (x UpdateOr) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (UpdateOr) Descriptor() protoreflect.EnumDescriptor { + return file_command_proto_enumTypes[1].Descriptor() +} + +func (UpdateOr) Type() protoreflect.EnumType { + return &file_command_proto_enumTypes[1] +} + +func (x UpdateOr) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use UpdateOr.Descriptor instead. +func (UpdateOr) EnumDescriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{1} +} + +type InsertOr int32 + +const ( + InsertOr_InsertOrUnknown InsertOr = 0 + InsertOr_InsertOrReplace InsertOr = 1 + InsertOr_InsertOrRollback InsertOr = 2 + InsertOr_InsertOrAbort InsertOr = 3 + InsertOr_InsertOrFail InsertOr = 4 + InsertOr_InsertOrIgnore InsertOr = 5 +) + +// Enum value maps for InsertOr. +var ( + InsertOr_name = map[int32]string{ + 0: "InsertOrUnknown", + 1: "InsertOrReplace", + 2: "InsertOrRollback", + 3: "InsertOrAbort", + 4: "InsertOrFail", + 5: "InsertOrIgnore", + } + InsertOr_value = map[string]int32{ + "InsertOrUnknown": 0, + "InsertOrReplace": 1, + "InsertOrRollback": 2, + "InsertOrAbort": 3, + "InsertOrFail": 4, + "InsertOrIgnore": 5, + } +) + +func (x InsertOr) Enum() *InsertOr { + p := new(InsertOr) + *p = x + return p +} + +func (x InsertOr) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (InsertOr) Descriptor() protoreflect.EnumDescriptor { + return file_command_proto_enumTypes[2].Descriptor() +} + +func (InsertOr) Type() protoreflect.EnumType { + return &file_command_proto_enumTypes[2] +} + +func (x InsertOr) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use InsertOr.Descriptor instead. +func (InsertOr) EnumDescriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{2} +} + +type DropTarget int32 + +const ( + DropTarget_Table DropTarget = 0 + DropTarget_View DropTarget = 1 + DropTarget_Index DropTarget = 2 + DropTarget_Trigger DropTarget = 3 +) + +// Enum value maps for DropTarget. +var ( + DropTarget_name = map[int32]string{ + 0: "Table", + 1: "View", + 2: "Index", + 3: "Trigger", + } + DropTarget_value = map[string]int32{ + "Table": 0, + "View": 1, + "Index": 2, + "Trigger": 3, + } +) + +func (x DropTarget) Enum() *DropTarget { + p := new(DropTarget) + *p = x + return p +} + +func (x DropTarget) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (DropTarget) Descriptor() protoreflect.EnumDescriptor { + return file_command_proto_enumTypes[3].Descriptor() +} + +func (DropTarget) Type() protoreflect.EnumType { + return &file_command_proto_enumTypes[3] +} + +func (x DropTarget) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use DropTarget.Descriptor instead. +func (DropTarget) EnumDescriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{3} +} + +type SimpleTable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Schema string `protobuf:"bytes,1,opt,name=Schema,proto3" json:"Schema,omitempty"` + Table string `protobuf:"bytes,2,opt,name=Table,proto3" json:"Table,omitempty"` + Alias string `protobuf:"bytes,3,opt,name=Alias,proto3" json:"Alias,omitempty"` + Indexed bool `protobuf:"varint,4,opt,name=Indexed,proto3" json:"Indexed,omitempty"` + Index string `protobuf:"bytes,5,opt,name=Index,proto3" json:"Index,omitempty"` +} + +func (x *SimpleTable) Reset() { + *x = SimpleTable{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SimpleTable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SimpleTable) ProtoMessage() {} + +func (x *SimpleTable) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SimpleTable.ProtoReflect.Descriptor instead. +func (*SimpleTable) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{0} +} + +func (x *SimpleTable) GetSchema() string { + if x != nil { + return x.Schema + } + return "" +} + +func (x *SimpleTable) GetTable() string { + if x != nil { + return x.Table + } + return "" +} + +func (x *SimpleTable) GetAlias() string { + if x != nil { + return x.Alias + } + return "" +} + +func (x *SimpleTable) GetIndexed() bool { + if x != nil { + return x.Indexed + } + return false +} + +func (x *SimpleTable) GetIndex() string { + if x != nil { + return x.Index + } + return "" +} + +type UpdateSetter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cols []string `protobuf:"bytes,1,rep,name=Cols,proto3" json:"Cols,omitempty"` + // Types that are assignable to Value: + // *UpdateSetter_Literal + // *UpdateSetter_Constant + // *UpdateSetter_Unary + // *UpdateSetter_Binary + // *UpdateSetter_Func + // *UpdateSetter_Equality + // *UpdateSetter_Range + Value isUpdateSetter_Value `protobuf_oneof:"Value"` +} + +func (x *UpdateSetter) Reset() { + *x = UpdateSetter{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateSetter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateSetter) ProtoMessage() {} + +func (x *UpdateSetter) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateSetter.ProtoReflect.Descriptor instead. +func (*UpdateSetter) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{1} +} + +func (x *UpdateSetter) GetCols() []string { + if x != nil { + return x.Cols + } + return nil +} + +func (m *UpdateSetter) GetValue() isUpdateSetter_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *UpdateSetter) GetLiteral() *LiteralExpr { + if x, ok := x.GetValue().(*UpdateSetter_Literal); ok { + return x.Literal + } + return nil +} + +func (x *UpdateSetter) GetConstant() *ConstantBooleanExpr { + if x, ok := x.GetValue().(*UpdateSetter_Constant); ok { + return x.Constant + } + return nil +} + +func (x *UpdateSetter) GetUnary() *UnaryExpr { + if x, ok := x.GetValue().(*UpdateSetter_Unary); ok { + return x.Unary + } + return nil +} + +func (x *UpdateSetter) GetBinary() *BinaryExpr { + if x, ok := x.GetValue().(*UpdateSetter_Binary); ok { + return x.Binary + } + return nil +} + +func (x *UpdateSetter) GetFunc() *FunctionExpr { + if x, ok := x.GetValue().(*UpdateSetter_Func); ok { + return x.Func + } + return nil +} + +func (x *UpdateSetter) GetEquality() *EqualityExpr { + if x, ok := x.GetValue().(*UpdateSetter_Equality); ok { + return x.Equality + } + return nil +} + +func (x *UpdateSetter) GetRange() *RangeExpr { + if x, ok := x.GetValue().(*UpdateSetter_Range); ok { + return x.Range + } + return nil +} + +type isUpdateSetter_Value interface { + isUpdateSetter_Value() +} + +type UpdateSetter_Literal struct { + Literal *LiteralExpr `protobuf:"bytes,2,opt,name=literal,proto3,oneof"` +} + +type UpdateSetter_Constant struct { + Constant *ConstantBooleanExpr `protobuf:"bytes,3,opt,name=constant,proto3,oneof"` +} + +type UpdateSetter_Unary struct { + Unary *UnaryExpr `protobuf:"bytes,4,opt,name=unary,proto3,oneof"` +} + +type UpdateSetter_Binary struct { + Binary *BinaryExpr `protobuf:"bytes,5,opt,name=binary,proto3,oneof"` +} + +type UpdateSetter_Func struct { + Func *FunctionExpr `protobuf:"bytes,6,opt,name=func,proto3,oneof"` +} + +type UpdateSetter_Equality struct { + Equality *EqualityExpr `protobuf:"bytes,7,opt,name=equality,proto3,oneof"` +} + +type UpdateSetter_Range struct { + Range *RangeExpr `protobuf:"bytes,8,opt,name=range,proto3,oneof"` +} + +func (*UpdateSetter_Literal) isUpdateSetter_Value() {} + +func (*UpdateSetter_Constant) isUpdateSetter_Value() {} + +func (*UpdateSetter_Unary) isUpdateSetter_Value() {} + +func (*UpdateSetter_Binary) isUpdateSetter_Value() {} + +func (*UpdateSetter_Func) isUpdateSetter_Value() {} + +func (*UpdateSetter_Equality) isUpdateSetter_Value() {} + +func (*UpdateSetter_Range) isUpdateSetter_Value() {} + +type Column struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Table string `protobuf:"bytes,1,opt,name=Table,proto3" json:"Table,omitempty"` + Column *Expr `protobuf:"bytes,2,opt,name=Column,proto3" json:"Column,omitempty"` + Alias string `protobuf:"bytes,3,opt,name=Alias,proto3" json:"Alias,omitempty"` +} + +func (x *Column) Reset() { + *x = Column{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Column) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Column) ProtoMessage() {} + +func (x *Column) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Column.ProtoReflect.Descriptor instead. +func (*Column) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{2} +} + +func (x *Column) GetTable() string { + if x != nil { + return x.Table + } + return "" +} + +func (x *Column) GetColumn() *Expr { + if x != nil { + return x.Column + } + return nil +} + +func (x *Column) GetAlias() string { + if x != nil { + return x.Alias + } + return "" +} + +type List struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to List: + // *List_Scan + // *List_Select + // *List_Project + // *List_Join + // *List_Limit + // *List_Offset + // *List_Distinct + // *List_Values + List isList_List `protobuf_oneof:"list"` +} + +func (x *List) Reset() { + *x = List{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *List) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*List) ProtoMessage() {} + +func (x *List) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use List.ProtoReflect.Descriptor instead. +func (*List) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{3} +} + +func (m *List) GetList() isList_List { + if m != nil { + return m.List + } + return nil +} + +func (x *List) GetScan() *Command_Scan { + if x, ok := x.GetList().(*List_Scan); ok { + return x.Scan + } + return nil +} + +func (x *List) GetSelect() *Command_Select { + if x, ok := x.GetList().(*List_Select); ok { + return x.Select + } + return nil +} + +func (x *List) GetProject() *Command_Project { + if x, ok := x.GetList().(*List_Project); ok { + return x.Project + } + return nil +} + +func (x *List) GetJoin() *Command_Join { + if x, ok := x.GetList().(*List_Join); ok { + return x.Join + } + return nil +} + +func (x *List) GetLimit() *Command_Limit { + if x, ok := x.GetList().(*List_Limit); ok { + return x.Limit + } + return nil +} + +func (x *List) GetOffset() *Command_Offset { + if x, ok := x.GetList().(*List_Offset); ok { + return x.Offset + } + return nil +} + +func (x *List) GetDistinct() *Command_Distinct { + if x, ok := x.GetList().(*List_Distinct); ok { + return x.Distinct + } + return nil +} + +func (x *List) GetValues() *Command_Values { + if x, ok := x.GetList().(*List_Values); ok { + return x.Values + } + return nil +} + +type isList_List interface { + isList_List() +} + +type List_Scan struct { + Scan *Command_Scan `protobuf:"bytes,1,opt,name=scan,proto3,oneof"` +} + +type List_Select struct { + Select *Command_Select `protobuf:"bytes,2,opt,name=select,proto3,oneof"` +} + +type List_Project struct { + Project *Command_Project `protobuf:"bytes,3,opt,name=project,proto3,oneof"` +} + +type List_Join struct { + Join *Command_Join `protobuf:"bytes,4,opt,name=join,proto3,oneof"` +} + +type List_Limit struct { + Limit *Command_Limit `protobuf:"bytes,5,opt,name=limit,proto3,oneof"` +} + +type List_Offset struct { + Offset *Command_Offset `protobuf:"bytes,6,opt,name=offset,proto3,oneof"` +} + +type List_Distinct struct { + Distinct *Command_Distinct `protobuf:"bytes,7,opt,name=distinct,proto3,oneof"` +} + +type List_Values struct { + Values *Command_Values `protobuf:"bytes,8,opt,name=values,proto3,oneof"` +} + +func (*List_Scan) isList_List() {} + +func (*List_Select) isList_List() {} + +func (*List_Project) isList_List() {} + +func (*List_Join) isList_List() {} + +func (*List_Limit) isList_List() {} + +func (*List_Offset) isList_List() {} + +func (*List_Distinct) isList_List() {} + +func (*List_Values) isList_List() {} + +type Command struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Command) Reset() { + *x = Command{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command) ProtoMessage() {} + +func (x *Command) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command.ProtoReflect.Descriptor instead. +func (*Command) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4} +} + +type Expr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Expr: + // *Expr_Literal + // *Expr_Constant + // *Expr_Unary + // *Expr_Binary + // *Expr_Func + // *Expr_Equality + // *Expr_Range + Expr isExpr_Expr `protobuf_oneof:"expr"` +} + +func (x *Expr) Reset() { + *x = Expr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Expr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Expr) ProtoMessage() {} + +func (x *Expr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Expr.ProtoReflect.Descriptor instead. +func (*Expr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{5} +} + +func (m *Expr) GetExpr() isExpr_Expr { + if m != nil { + return m.Expr + } + return nil +} + +func (x *Expr) GetLiteral() *LiteralExpr { + if x, ok := x.GetExpr().(*Expr_Literal); ok { + return x.Literal + } + return nil +} + +func (x *Expr) GetConstant() *ConstantBooleanExpr { + if x, ok := x.GetExpr().(*Expr_Constant); ok { + return x.Constant + } + return nil +} + +func (x *Expr) GetUnary() *UnaryExpr { + if x, ok := x.GetExpr().(*Expr_Unary); ok { + return x.Unary + } + return nil +} + +func (x *Expr) GetBinary() *BinaryExpr { + if x, ok := x.GetExpr().(*Expr_Binary); ok { + return x.Binary + } + return nil +} + +func (x *Expr) GetFunc() *FunctionExpr { + if x, ok := x.GetExpr().(*Expr_Func); ok { + return x.Func + } + return nil +} + +func (x *Expr) GetEquality() *EqualityExpr { + if x, ok := x.GetExpr().(*Expr_Equality); ok { + return x.Equality + } + return nil +} + +func (x *Expr) GetRange() *RangeExpr { + if x, ok := x.GetExpr().(*Expr_Range); ok { + return x.Range + } + return nil +} + +type isExpr_Expr interface { + isExpr_Expr() +} + +type Expr_Literal struct { + Literal *LiteralExpr `protobuf:"bytes,1,opt,name=literal,proto3,oneof"` +} + +type Expr_Constant struct { + Constant *ConstantBooleanExpr `protobuf:"bytes,2,opt,name=constant,proto3,oneof"` +} + +type Expr_Unary struct { + Unary *UnaryExpr `protobuf:"bytes,3,opt,name=unary,proto3,oneof"` +} + +type Expr_Binary struct { + Binary *BinaryExpr `protobuf:"bytes,4,opt,name=binary,proto3,oneof"` +} + +type Expr_Func struct { + Func *FunctionExpr `protobuf:"bytes,5,opt,name=func,proto3,oneof"` +} + +type Expr_Equality struct { + Equality *EqualityExpr `protobuf:"bytes,6,opt,name=equality,proto3,oneof"` +} + +type Expr_Range struct { + Range *RangeExpr `protobuf:"bytes,7,opt,name=range,proto3,oneof"` +} + +func (*Expr_Literal) isExpr_Expr() {} + +func (*Expr_Constant) isExpr_Expr() {} + +func (*Expr_Unary) isExpr_Expr() {} + +func (*Expr_Binary) isExpr_Expr() {} + +func (*Expr_Func) isExpr_Expr() {} + +func (*Expr_Equality) isExpr_Expr() {} + +func (*Expr_Range) isExpr_Expr() {} + +type RepeatedExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Expr []*Expr `protobuf:"bytes,1,rep,name=expr,proto3" json:"expr,omitempty"` +} + +func (x *RepeatedExpr) Reset() { + *x = RepeatedExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RepeatedExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RepeatedExpr) ProtoMessage() {} + +func (x *RepeatedExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RepeatedExpr.ProtoReflect.Descriptor instead. +func (*RepeatedExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{6} +} + +func (x *RepeatedExpr) GetExpr() []*Expr { + if x != nil { + return x.Expr + } + return nil +} + +type LiteralExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value string `protobuf:"bytes,1,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *LiteralExpr) Reset() { + *x = LiteralExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LiteralExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LiteralExpr) ProtoMessage() {} + +func (x *LiteralExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LiteralExpr.ProtoReflect.Descriptor instead. +func (*LiteralExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{7} +} + +func (x *LiteralExpr) GetValue() string { + if x != nil { + return x.Value + } + return "" +} + +type ConstantBooleanExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Value bool `protobuf:"varint,1,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *ConstantBooleanExpr) Reset() { + *x = ConstantBooleanExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConstantBooleanExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConstantBooleanExpr) ProtoMessage() {} + +func (x *ConstantBooleanExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConstantBooleanExpr.ProtoReflect.Descriptor instead. +func (*ConstantBooleanExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{8} +} + +func (x *ConstantBooleanExpr) GetValue() bool { + if x != nil { + return x.Value + } + return false +} + +type UnaryExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Operator string `protobuf:"bytes,1,opt,name=Operator,proto3" json:"Operator,omitempty"` + Value *Expr `protobuf:"bytes,2,opt,name=Value,proto3" json:"Value,omitempty"` +} + +func (x *UnaryExpr) Reset() { + *x = UnaryExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnaryExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnaryExpr) ProtoMessage() {} + +func (x *UnaryExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnaryExpr.ProtoReflect.Descriptor instead. +func (*UnaryExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{9} +} + +func (x *UnaryExpr) GetOperator() string { + if x != nil { + return x.Operator + } + return "" +} + +func (x *UnaryExpr) GetValue() *Expr { + if x != nil { + return x.Value + } + return nil +} + +type BinaryExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Operator string `protobuf:"bytes,1,opt,name=Operator,proto3" json:"Operator,omitempty"` + Left *Expr `protobuf:"bytes,2,opt,name=Left,proto3" json:"Left,omitempty"` + Right *Expr `protobuf:"bytes,3,opt,name=Right,proto3" json:"Right,omitempty"` +} + +func (x *BinaryExpr) Reset() { + *x = BinaryExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BinaryExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BinaryExpr) ProtoMessage() {} + +func (x *BinaryExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BinaryExpr.ProtoReflect.Descriptor instead. +func (*BinaryExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{10} +} + +func (x *BinaryExpr) GetOperator() string { + if x != nil { + return x.Operator + } + return "" +} + +func (x *BinaryExpr) GetLeft() *Expr { + if x != nil { + return x.Left + } + return nil +} + +func (x *BinaryExpr) GetRight() *Expr { + if x != nil { + return x.Right + } + return nil +} + +type FunctionExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=Name,proto3" json:"Name,omitempty"` + Distinct bool `protobuf:"varint,2,opt,name=Distinct,proto3" json:"Distinct,omitempty"` + Args []*Expr `protobuf:"bytes,3,rep,name=Args,proto3" json:"Args,omitempty"` +} + +func (x *FunctionExpr) Reset() { + *x = FunctionExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FunctionExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FunctionExpr) ProtoMessage() {} + +func (x *FunctionExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FunctionExpr.ProtoReflect.Descriptor instead. +func (*FunctionExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{11} +} + +func (x *FunctionExpr) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *FunctionExpr) GetDistinct() bool { + if x != nil { + return x.Distinct + } + return false +} + +func (x *FunctionExpr) GetArgs() []*Expr { + if x != nil { + return x.Args + } + return nil +} + +type EqualityExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Left *Expr `protobuf:"bytes,1,opt,name=Left,proto3" json:"Left,omitempty"` + Right *Expr `protobuf:"bytes,2,opt,name=Right,proto3" json:"Right,omitempty"` + Invert bool `protobuf:"varint,3,opt,name=Invert,proto3" json:"Invert,omitempty"` +} + +func (x *EqualityExpr) Reset() { + *x = EqualityExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EqualityExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EqualityExpr) ProtoMessage() {} + +func (x *EqualityExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EqualityExpr.ProtoReflect.Descriptor instead. +func (*EqualityExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{12} +} + +func (x *EqualityExpr) GetLeft() *Expr { + if x != nil { + return x.Left + } + return nil +} + +func (x *EqualityExpr) GetRight() *Expr { + if x != nil { + return x.Right + } + return nil +} + +func (x *EqualityExpr) GetInvert() bool { + if x != nil { + return x.Invert + } + return false +} + +type RangeExpr struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Needle *Expr `protobuf:"bytes,1,opt,name=Needle,proto3" json:"Needle,omitempty"` + Lo *Expr `protobuf:"bytes,2,opt,name=Lo,proto3" json:"Lo,omitempty"` + Hi *Expr `protobuf:"bytes,3,opt,name=Hi,proto3" json:"Hi,omitempty"` + Invert bool `protobuf:"varint,4,opt,name=Invert,proto3" json:"Invert,omitempty"` +} + +func (x *RangeExpr) Reset() { + *x = RangeExpr{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RangeExpr) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RangeExpr) ProtoMessage() {} + +func (x *RangeExpr) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RangeExpr.ProtoReflect.Descriptor instead. +func (*RangeExpr) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{13} +} + +func (x *RangeExpr) GetNeedle() *Expr { + if x != nil { + return x.Needle + } + return nil +} + +func (x *RangeExpr) GetLo() *Expr { + if x != nil { + return x.Lo + } + return nil +} + +func (x *RangeExpr) GetHi() *Expr { + if x != nil { + return x.Hi + } + return nil +} + +func (x *RangeExpr) GetInvert() bool { + if x != nil { + return x.Invert + } + return false +} + +type Command_Scan struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Table *SimpleTable `protobuf:"bytes,1,opt,name=Table,proto3" json:"Table,omitempty"` +} + +func (x *Command_Scan) Reset() { + *x = Command_Scan{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Scan) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Scan) ProtoMessage() {} + +func (x *Command_Scan) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Scan.ProtoReflect.Descriptor instead. +func (*Command_Scan) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 0} +} + +func (x *Command_Scan) GetTable() *SimpleTable { + if x != nil { + return x.Table + } + return nil +} + +type Command_Select struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Filter *Expr `protobuf:"bytes,1,opt,name=Filter,proto3" json:"Filter,omitempty"` + Input *List `protobuf:"bytes,2,opt,name=Input,proto3" json:"Input,omitempty"` +} + +func (x *Command_Select) Reset() { + *x = Command_Select{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Select) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Select) ProtoMessage() {} + +func (x *Command_Select) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Select.ProtoReflect.Descriptor instead. +func (*Command_Select) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 1} +} + +func (x *Command_Select) GetFilter() *Expr { + if x != nil { + return x.Filter + } + return nil +} + +func (x *Command_Select) GetInput() *List { + if x != nil { + return x.Input + } + return nil +} + +type Command_Project struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cols []*Column `protobuf:"bytes,1,rep,name=Cols,proto3" json:"Cols,omitempty"` + Input *List `protobuf:"bytes,2,opt,name=Input,proto3" json:"Input,omitempty"` +} + +func (x *Command_Project) Reset() { + *x = Command_Project{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Project) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Project) ProtoMessage() {} + +func (x *Command_Project) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Project.ProtoReflect.Descriptor instead. +func (*Command_Project) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 2} +} + +func (x *Command_Project) GetCols() []*Column { + if x != nil { + return x.Cols + } + return nil +} + +func (x *Command_Project) GetInput() *List { + if x != nil { + return x.Input + } + return nil +} + +type Command_Delete struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Table *SimpleTable `protobuf:"bytes,1,opt,name=Table,proto3" json:"Table,omitempty"` + Filter *Expr `protobuf:"bytes,2,opt,name=Filter,proto3" json:"Filter,omitempty"` +} + +func (x *Command_Delete) Reset() { + *x = Command_Delete{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Delete) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Delete) ProtoMessage() {} + +func (x *Command_Delete) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Delete.ProtoReflect.Descriptor instead. +func (*Command_Delete) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 3} +} + +func (x *Command_Delete) GetTable() *SimpleTable { + if x != nil { + return x.Table + } + return nil +} + +func (x *Command_Delete) GetFilter() *Expr { + if x != nil { + return x.Filter + } + return nil +} + +type CommandDrop struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Target DropTarget `protobuf:"varint,1,opt,name=target,proto3,enum=message.DropTarget" json:"target,omitempty"` + IfExists bool `protobuf:"varint,2,opt,name=IfExists,proto3" json:"IfExists,omitempty"` + Schema string `protobuf:"bytes,3,opt,name=Schema,proto3" json:"Schema,omitempty"` + Name string `protobuf:"bytes,4,opt,name=Name,proto3" json:"Name,omitempty"` +} + +func (x *CommandDrop) Reset() { + *x = CommandDrop{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CommandDrop) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CommandDrop) ProtoMessage() {} + +func (x *CommandDrop) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CommandDrop.ProtoReflect.Descriptor instead. +func (*CommandDrop) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 4} +} + +func (x *CommandDrop) GetTarget() DropTarget { + if x != nil { + return x.Target + } + return DropTarget_Table +} + +func (x *CommandDrop) GetIfExists() bool { + if x != nil { + return x.IfExists + } + return false +} + +func (x *CommandDrop) GetSchema() string { + if x != nil { + return x.Schema + } + return "" +} + +func (x *CommandDrop) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +type Command_Update struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + UpdateOr UpdateOr `protobuf:"varint,1,opt,name=UpdateOr,proto3,enum=message.UpdateOr" json:"UpdateOr,omitempty"` + Table *SimpleTable `protobuf:"bytes,2,opt,name=Table,proto3" json:"Table,omitempty"` + Updates []*UpdateSetter `protobuf:"bytes,3,rep,name=Updates,proto3" json:"Updates,omitempty"` + Filter *Expr `protobuf:"bytes,4,opt,name=Filter,proto3" json:"Filter,omitempty"` +} + +func (x *Command_Update) Reset() { + *x = Command_Update{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Update) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Update) ProtoMessage() {} + +func (x *Command_Update) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Update.ProtoReflect.Descriptor instead. +func (*Command_Update) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 5} +} + +func (x *Command_Update) GetUpdateOr() UpdateOr { + if x != nil { + return x.UpdateOr + } + return UpdateOr_UpdateOrUnknown +} + +func (x *Command_Update) GetTable() *SimpleTable { + if x != nil { + return x.Table + } + return nil +} + +func (x *Command_Update) GetUpdates() []*UpdateSetter { + if x != nil { + return x.Updates + } + return nil +} + +func (x *Command_Update) GetFilter() *Expr { + if x != nil { + return x.Filter + } + return nil +} + +type Command_Join struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Natural bool `protobuf:"varint,1,opt,name=Natural,proto3" json:"Natural,omitempty"` + Type JoinType `protobuf:"varint,2,opt,name=Type,proto3,enum=message.JoinType" json:"Type,omitempty"` + Filter *Expr `protobuf:"bytes,3,opt,name=Filter,proto3" json:"Filter,omitempty"` + Left *List `protobuf:"bytes,4,opt,name=Left,proto3" json:"Left,omitempty"` + Right *List `protobuf:"bytes,5,opt,name=Right,proto3" json:"Right,omitempty"` +} + +func (x *Command_Join) Reset() { + *x = Command_Join{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Join) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Join) ProtoMessage() {} + +func (x *Command_Join) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Join.ProtoReflect.Descriptor instead. +func (*Command_Join) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 6} +} + +func (x *Command_Join) GetNatural() bool { + if x != nil { + return x.Natural + } + return false +} + +func (x *Command_Join) GetType() JoinType { + if x != nil { + return x.Type + } + return JoinType_JoinUnknown +} + +func (x *Command_Join) GetFilter() *Expr { + if x != nil { + return x.Filter + } + return nil +} + +func (x *Command_Join) GetLeft() *List { + if x != nil { + return x.Left + } + return nil +} + +func (x *Command_Join) GetRight() *List { + if x != nil { + return x.Right + } + return nil +} + +type Command_Limit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Limit *Expr `protobuf:"bytes,1,opt,name=Limit,proto3" json:"Limit,omitempty"` + Input *List `protobuf:"bytes,2,opt,name=Input,proto3" json:"Input,omitempty"` +} + +func (x *Command_Limit) Reset() { + *x = Command_Limit{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Limit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Limit) ProtoMessage() {} + +func (x *Command_Limit) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Limit.ProtoReflect.Descriptor instead. +func (*Command_Limit) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 7} +} + +func (x *Command_Limit) GetLimit() *Expr { + if x != nil { + return x.Limit + } + return nil +} + +func (x *Command_Limit) GetInput() *List { + if x != nil { + return x.Input + } + return nil +} + +type Command_Offset struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Offset *Expr `protobuf:"bytes,1,opt,name=Offset,proto3" json:"Offset,omitempty"` + Input *List `protobuf:"bytes,2,opt,name=Input,proto3" json:"Input,omitempty"` +} + +func (x *Command_Offset) Reset() { + *x = Command_Offset{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Offset) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Offset) ProtoMessage() {} + +func (x *Command_Offset) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Offset.ProtoReflect.Descriptor instead. +func (*Command_Offset) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 8} +} + +func (x *Command_Offset) GetOffset() *Expr { + if x != nil { + return x.Offset + } + return nil +} + +func (x *Command_Offset) GetInput() *List { + if x != nil { + return x.Input + } + return nil +} + +type Command_Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Cols []*Column `protobuf:"bytes,1,rep,name=Cols,proto3" json:"Cols,omitempty"` +} + +func (x *Command_Empty) Reset() { + *x = Command_Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Empty) ProtoMessage() {} + +func (x *Command_Empty) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Empty.ProtoReflect.Descriptor instead. +func (*Command_Empty) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 9} +} + +func (x *Command_Empty) GetCols() []*Column { + if x != nil { + return x.Cols + } + return nil +} + +type Command_Distinct struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Input *List `protobuf:"bytes,1,opt,name=Input,proto3" json:"Input,omitempty"` +} + +func (x *Command_Distinct) Reset() { + *x = Command_Distinct{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Distinct) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Distinct) ProtoMessage() {} + +func (x *Command_Distinct) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Distinct.ProtoReflect.Descriptor instead. +func (*Command_Distinct) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 10} +} + +func (x *Command_Distinct) GetInput() *List { + if x != nil { + return x.Input + } + return nil +} + +type Command_Values struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Expr []*RepeatedExpr `protobuf:"bytes,1,rep,name=expr,proto3" json:"expr,omitempty"` +} + +func (x *Command_Values) Reset() { + *x = Command_Values{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Values) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Values) ProtoMessage() {} + +func (x *Command_Values) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Values.ProtoReflect.Descriptor instead. +func (*Command_Values) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 11} +} + +func (x *Command_Values) GetExpr() []*RepeatedExpr { + if x != nil { + return x.Expr + } + return nil +} + +type Command_Insert struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InsertOr InsertOr `protobuf:"varint,1,opt,name=InsertOr,proto3,enum=message.InsertOr" json:"InsertOr,omitempty"` + Table *SimpleTable `protobuf:"bytes,2,opt,name=Table,proto3" json:"Table,omitempty"` + Cols []*Column `protobuf:"bytes,3,rep,name=Cols,proto3" json:"Cols,omitempty"` + DefaultValues bool `protobuf:"varint,4,opt,name=DefaultValues,proto3" json:"DefaultValues,omitempty"` + Input *List `protobuf:"bytes,5,opt,name=Input,proto3" json:"Input,omitempty"` +} + +func (x *Command_Insert) Reset() { + *x = Command_Insert{} + if protoimpl.UnsafeEnabled { + mi := &file_command_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command_Insert) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command_Insert) ProtoMessage() {} + +func (x *Command_Insert) ProtoReflect() protoreflect.Message { + mi := &file_command_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command_Insert.ProtoReflect.Descriptor instead. +func (*Command_Insert) Descriptor() ([]byte, []int) { + return file_command_proto_rawDescGZIP(), []int{4, 12} +} + +func (x *Command_Insert) GetInsertOr() InsertOr { + if x != nil { + return x.InsertOr + } + return InsertOr_InsertOrUnknown +} + +func (x *Command_Insert) GetTable() *SimpleTable { + if x != nil { + return x.Table + } + return nil +} + +func (x *Command_Insert) GetCols() []*Column { + if x != nil { + return x.Cols + } + return nil +} + +func (x *Command_Insert) GetDefaultValues() bool { + if x != nil { + return x.DefaultValues + } + return false +} + +func (x *Command_Insert) GetInput() *List { + if x != nil { + return x.Input + } + return nil +} + +var File_command_proto protoreflect.FileDescriptor + +var file_command_proto_rawDesc = []byte{ + 0x0a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x0b, 0x53, 0x69, 0x6d, + 0x70, 0x6c, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, + 0x12, 0x14, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x18, 0x0a, 0x07, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x82, 0x03, 0x0a, + 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x74, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x43, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x43, 0x6f, 0x6c, + 0x73, 0x12, 0x30, 0x0a, 0x07, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x74, + 0x65, 0x72, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x07, 0x6c, 0x69, 0x74, 0x65, + 0x72, 0x61, 0x6c, 0x12, 0x3a, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, + 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x12, + 0x2a, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, + 0x70, 0x72, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x62, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, + 0x48, 0x00, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x2b, 0x0a, 0x04, 0x66, 0x75, + 0x6e, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x48, + 0x00, 0x52, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x12, 0x33, 0x0a, 0x08, 0x65, 0x71, 0x75, 0x61, 0x6c, + 0x69, 0x74, 0x79, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2e, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x72, + 0x48, 0x00, 0x52, 0x08, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x05, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, + 0x00, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x42, 0x07, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x22, 0x5b, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x54, + 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x12, 0x25, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, + 0x52, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x41, 0x6c, 0x69, 0x61, + 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0xa0, + 0x03, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x04, 0x73, 0x63, 0x61, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x63, 0x61, 0x6e, 0x48, 0x00, 0x52, 0x04, + 0x73, 0x63, 0x61, 0x6e, 0x12, 0x31, 0x0a, 0x06, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x48, 0x00, 0x52, + 0x06, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x34, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x48, 0x00, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x2b, 0x0a, + 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4a, 0x6f, + 0x69, 0x6e, 0x48, 0x00, 0x52, 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x12, 0x2e, 0x0a, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4c, 0x69, 0x6d, 0x69, + 0x74, 0x48, 0x00, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x4f, 0x66, 0x66, + 0x73, 0x65, 0x74, 0x48, 0x00, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x37, 0x0a, + 0x08, 0x64, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x2e, 0x44, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x48, 0x00, 0x52, 0x08, 0x64, 0x69, + 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x48, + 0x00, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04, 0x6c, 0x69, 0x73, + 0x74, 0x22, 0xcc, 0x0a, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x1a, 0x32, 0x0a, + 0x04, 0x53, 0x63, 0x61, 0x6e, 0x12, 0x2a, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, + 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x1a, 0x54, 0x0a, 0x06, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x46, 0x69, 0x6c, 0x74, + 0x65, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x53, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x6a, 0x65, + 0x63, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x43, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, + 0x6e, 0x52, 0x04, 0x43, 0x6f, 0x6c, 0x73, 0x12, 0x23, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x5b, 0x0a, 0x06, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x54, 0x61, 0x62, + 0x6c, 0x65, 0x12, 0x25, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, + 0x72, 0x52, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x7b, 0x0a, 0x04, 0x64, 0x72, 0x6f, + 0x70, 0x12, 0x2b, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x44, 0x72, 0x6f, 0x70, + 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x52, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x1a, + 0x0a, 0x08, 0x49, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x08, 0x49, 0x66, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x53, 0x63, + 0x68, 0x65, 0x6d, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x1a, 0xbb, 0x01, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x12, 0x2d, 0x0a, 0x08, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x52, 0x08, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x72, + 0x12, 0x2a, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x2f, 0x0a, 0x07, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, + 0x74, 0x74, 0x65, 0x72, 0x52, 0x07, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x12, 0x25, 0x0a, + 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x1a, 0xb6, 0x01, 0x0a, 0x04, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x4e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x4e, 0x61, 0x74, 0x75, 0x72, 0x61, 0x6c, 0x12, 0x25, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x4a, 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x25, + 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x52, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x1a, 0x51, 0x0a, + 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x1a, 0x54, 0x0a, 0x06, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x25, 0x0a, 0x06, 0x4f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x12, 0x23, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x2c, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x23, 0x0a, 0x04, 0x43, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x04, + 0x43, 0x6f, 0x6c, 0x73, 0x1a, 0x2f, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, + 0x12, 0x23, 0x0a, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, + 0x49, 0x6e, 0x70, 0x75, 0x74, 0x1a, 0x33, 0x0a, 0x06, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, + 0x29, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x65, 0x64, + 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x1a, 0xd3, 0x01, 0x0a, 0x06, 0x49, + 0x6e, 0x73, 0x65, 0x72, 0x74, 0x12, 0x2d, 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x52, 0x08, 0x49, 0x6e, 0x73, 0x65, + 0x72, 0x74, 0x4f, 0x72, 0x12, 0x2a, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x53, 0x69, + 0x6d, 0x70, 0x6c, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, + 0x12, 0x23, 0x0a, 0x04, 0x43, 0x6f, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, + 0x04, 0x43, 0x6f, 0x6c, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x44, 0x65, + 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x05, 0x49, + 0x6e, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x05, 0x49, 0x6e, 0x70, 0x75, 0x74, + 0x22, 0xe5, 0x02, 0x0a, 0x04, 0x45, 0x78, 0x70, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x6c, 0x69, 0x74, + 0x65, 0x72, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x2e, 0x4c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x72, + 0x48, 0x00, 0x52, 0x07, 0x6c, 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x12, 0x3a, 0x0a, 0x08, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, + 0x42, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x08, 0x63, + 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x12, 0x2a, 0x0a, 0x05, 0x75, 0x6e, 0x61, 0x72, 0x79, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x05, 0x75, 0x6e, + 0x61, 0x72, 0x79, 0x12, 0x2d, 0x0a, 0x06, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x42, 0x69, + 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x06, 0x62, 0x69, 0x6e, 0x61, + 0x72, 0x79, 0x12, 0x2b, 0x0a, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x46, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x04, 0x66, 0x75, 0x6e, 0x63, 0x12, + 0x33, 0x0a, 0x08, 0x65, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x15, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x71, 0x75, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x08, 0x65, 0x71, 0x75, 0x61, + 0x6c, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x52, 0x61, + 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x48, 0x00, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, + 0x42, 0x06, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x31, 0x0a, 0x0c, 0x72, 0x65, 0x70, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x45, 0x78, 0x70, 0x72, 0x12, 0x21, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x22, 0x23, 0x0a, 0x0b, 0x4c, + 0x69, 0x74, 0x65, 0x72, 0x61, 0x6c, 0x45, 0x78, 0x70, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x22, 0x2b, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x74, 0x42, 0x6f, 0x6f, 0x6c, + 0x65, 0x61, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x4c, 0x0a, + 0x09, 0x55, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4f, 0x70, + 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x23, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, + 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x70, 0x0a, 0x0a, 0x42, + 0x69, 0x6e, 0x61, 0x72, 0x79, 0x45, 0x78, 0x70, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x4f, 0x70, 0x65, + 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x21, 0x0a, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, + 0x70, 0x72, 0x52, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x22, 0x61, 0x0a, + 0x0c, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x78, 0x70, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x44, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x44, 0x69, 0x73, 0x74, 0x69, 0x6e, 0x63, 0x74, 0x12, 0x21, 0x0a, + 0x04, 0x41, 0x72, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x41, 0x72, 0x67, 0x73, + 0x22, 0x6e, 0x0a, 0x0c, 0x45, 0x71, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x45, 0x78, 0x70, 0x72, + 0x12, 0x21, 0x0a, 0x04, 0x4c, 0x65, 0x66, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x04, 0x4c, + 0x65, 0x66, 0x74, 0x12, 0x23, 0x0a, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, + 0x72, 0x52, 0x05, 0x52, 0x69, 0x67, 0x68, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x6e, 0x76, 0x65, + 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, + 0x22, 0x88, 0x01, 0x0a, 0x09, 0x52, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x78, 0x70, 0x72, 0x12, 0x25, + 0x0a, 0x06, 0x4e, 0x65, 0x65, 0x64, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, + 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, 0x06, 0x4e, + 0x65, 0x65, 0x64, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x02, 0x4c, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, + 0x52, 0x02, 0x4c, 0x6f, 0x12, 0x1d, 0x0a, 0x02, 0x48, 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0d, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x52, + 0x02, 0x48, 0x69, 0x12, 0x16, 0x0a, 0x06, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x49, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x2a, 0x5a, 0x0a, 0x08, 0x4a, + 0x6f, 0x69, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x4a, 0x6f, 0x69, 0x6e, 0x55, + 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x4a, 0x6f, 0x69, 0x6e, + 0x4c, 0x65, 0x66, 0x74, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x4a, 0x6f, 0x69, 0x6e, 0x4c, 0x65, + 0x66, 0x74, 0x4f, 0x75, 0x74, 0x65, 0x72, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x6f, 0x69, + 0x6e, 0x49, 0x6e, 0x6e, 0x65, 0x72, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x4a, 0x6f, 0x69, 0x6e, + 0x43, 0x72, 0x6f, 0x73, 0x73, 0x10, 0x04, 0x2a, 0x83, 0x01, 0x0a, 0x08, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x4f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x72, + 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4f, 0x72, 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x10, 0x01, 0x12, + 0x11, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x41, 0x62, 0x6f, 0x72, 0x74, + 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x72, 0x52, 0x65, + 0x70, 0x6c, 0x61, 0x63, 0x65, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x4f, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x12, 0x12, 0x0a, 0x0e, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x4f, 0x72, 0x49, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x10, 0x05, 0x2a, 0x83, 0x01, + 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x12, 0x13, 0x0a, 0x0f, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, + 0x13, 0x0a, 0x0f, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x61, + 0x63, 0x65, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, + 0x52, 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x10, 0x03, 0x12, 0x10, 0x0a, + 0x0c, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x46, 0x61, 0x69, 0x6c, 0x10, 0x04, 0x12, + 0x12, 0x0a, 0x0e, 0x49, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x4f, 0x72, 0x49, 0x67, 0x6e, 0x6f, 0x72, + 0x65, 0x10, 0x05, 0x2a, 0x39, 0x0a, 0x0a, 0x44, 0x72, 0x6f, 0x70, 0x54, 0x61, 0x72, 0x67, 0x65, + 0x74, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, + 0x56, 0x69, 0x65, 0x77, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, + 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x10, 0x03, 0x42, 0x0b, + 0x5a, 0x09, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, +} + +var ( + file_command_proto_rawDescOnce sync.Once + file_command_proto_rawDescData = file_command_proto_rawDesc +) + +func file_command_proto_rawDescGZIP() []byte { + file_command_proto_rawDescOnce.Do(func() { + file_command_proto_rawDescData = protoimpl.X.CompressGZIP(file_command_proto_rawDescData) + }) + return file_command_proto_rawDescData +} + +var file_command_proto_enumTypes = make([]protoimpl.EnumInfo, 4) +var file_command_proto_msgTypes = make([]protoimpl.MessageInfo, 27) +var file_command_proto_goTypes = []interface{}{ + (JoinType)(0), // 0: message.JoinType + (UpdateOr)(0), // 1: message.UpdateOr + (InsertOr)(0), // 2: message.InsertOr + (DropTarget)(0), // 3: message.DropTarget + (*SimpleTable)(nil), // 4: message.SimpleTable + (*UpdateSetter)(nil), // 5: message.UpdateSetter + (*Column)(nil), // 6: message.Column + (*List)(nil), // 7: message.List + (*Command)(nil), // 8: message.Command + (*Expr)(nil), // 9: message.Expr + (*RepeatedExpr)(nil), // 10: message.repeatedExpr + (*LiteralExpr)(nil), // 11: message.LiteralExpr + (*ConstantBooleanExpr)(nil), // 12: message.ConstantBooleanExpr + (*UnaryExpr)(nil), // 13: message.UnaryExpr + (*BinaryExpr)(nil), // 14: message.BinaryExpr + (*FunctionExpr)(nil), // 15: message.FunctionExpr + (*EqualityExpr)(nil), // 16: message.EqualityExpr + (*RangeExpr)(nil), // 17: message.RangeExpr + (*Command_Scan)(nil), // 18: message.Command.Scan + (*Command_Select)(nil), // 19: message.Command.Select + (*Command_Project)(nil), // 20: message.Command.Project + (*Command_Delete)(nil), // 21: message.Command.Delete + (*CommandDrop)(nil), // 22: message.Command.drop + (*Command_Update)(nil), // 23: message.Command.Update + (*Command_Join)(nil), // 24: message.Command.Join + (*Command_Limit)(nil), // 25: message.Command.Limit + (*Command_Offset)(nil), // 26: message.Command.Offset + (*Command_Empty)(nil), // 27: message.Command.Empty + (*Command_Distinct)(nil), // 28: message.Command.Distinct + (*Command_Values)(nil), // 29: message.Command.Values + (*Command_Insert)(nil), // 30: message.Command.Insert +} +var file_command_proto_depIdxs = []int32{ + 11, // 0: message.UpdateSetter.literal:type_name -> message.LiteralExpr + 12, // 1: message.UpdateSetter.constant:type_name -> message.ConstantBooleanExpr + 13, // 2: message.UpdateSetter.unary:type_name -> message.UnaryExpr + 14, // 3: message.UpdateSetter.binary:type_name -> message.BinaryExpr + 15, // 4: message.UpdateSetter.func:type_name -> message.FunctionExpr + 16, // 5: message.UpdateSetter.equality:type_name -> message.EqualityExpr + 17, // 6: message.UpdateSetter.range:type_name -> message.RangeExpr + 9, // 7: message.Column.Column:type_name -> message.Expr + 18, // 8: message.List.scan:type_name -> message.Command.Scan + 19, // 9: message.List.select:type_name -> message.Command.Select + 20, // 10: message.List.project:type_name -> message.Command.Project + 24, // 11: message.List.join:type_name -> message.Command.Join + 25, // 12: message.List.limit:type_name -> message.Command.Limit + 26, // 13: message.List.offset:type_name -> message.Command.Offset + 28, // 14: message.List.distinct:type_name -> message.Command.Distinct + 29, // 15: message.List.values:type_name -> message.Command.Values + 11, // 16: message.Expr.literal:type_name -> message.LiteralExpr + 12, // 17: message.Expr.constant:type_name -> message.ConstantBooleanExpr + 13, // 18: message.Expr.unary:type_name -> message.UnaryExpr + 14, // 19: message.Expr.binary:type_name -> message.BinaryExpr + 15, // 20: message.Expr.func:type_name -> message.FunctionExpr + 16, // 21: message.Expr.equality:type_name -> message.EqualityExpr + 17, // 22: message.Expr.range:type_name -> message.RangeExpr + 9, // 23: message.repeatedExpr.expr:type_name -> message.Expr + 9, // 24: message.UnaryExpr.Value:type_name -> message.Expr + 9, // 25: message.BinaryExpr.Left:type_name -> message.Expr + 9, // 26: message.BinaryExpr.Right:type_name -> message.Expr + 9, // 27: message.FunctionExpr.Args:type_name -> message.Expr + 9, // 28: message.EqualityExpr.Left:type_name -> message.Expr + 9, // 29: message.EqualityExpr.Right:type_name -> message.Expr + 9, // 30: message.RangeExpr.Needle:type_name -> message.Expr + 9, // 31: message.RangeExpr.Lo:type_name -> message.Expr + 9, // 32: message.RangeExpr.Hi:type_name -> message.Expr + 4, // 33: message.Command.Scan.Table:type_name -> message.SimpleTable + 9, // 34: message.Command.Select.Filter:type_name -> message.Expr + 7, // 35: message.Command.Select.Input:type_name -> message.List + 6, // 36: message.Command.Project.Cols:type_name -> message.Column + 7, // 37: message.Command.Project.Input:type_name -> message.List + 4, // 38: message.Command.Delete.Table:type_name -> message.SimpleTable + 9, // 39: message.Command.Delete.Filter:type_name -> message.Expr + 3, // 40: message.Command.drop.target:type_name -> message.DropTarget + 1, // 41: message.Command.Update.UpdateOr:type_name -> message.UpdateOr + 4, // 42: message.Command.Update.Table:type_name -> message.SimpleTable + 5, // 43: message.Command.Update.Updates:type_name -> message.UpdateSetter + 9, // 44: message.Command.Update.Filter:type_name -> message.Expr + 0, // 45: message.Command.Join.Type:type_name -> message.JoinType + 9, // 46: message.Command.Join.Filter:type_name -> message.Expr + 7, // 47: message.Command.Join.Left:type_name -> message.List + 7, // 48: message.Command.Join.Right:type_name -> message.List + 9, // 49: message.Command.Limit.Limit:type_name -> message.Expr + 7, // 50: message.Command.Limit.Input:type_name -> message.List + 9, // 51: message.Command.Offset.Offset:type_name -> message.Expr + 7, // 52: message.Command.Offset.Input:type_name -> message.List + 6, // 53: message.Command.Empty.Cols:type_name -> message.Column + 7, // 54: message.Command.Distinct.Input:type_name -> message.List + 10, // 55: message.Command.Values.expr:type_name -> message.repeatedExpr + 2, // 56: message.Command.Insert.InsertOr:type_name -> message.InsertOr + 4, // 57: message.Command.Insert.Table:type_name -> message.SimpleTable + 6, // 58: message.Command.Insert.Cols:type_name -> message.Column + 7, // 59: message.Command.Insert.Input:type_name -> message.List + 60, // [60:60] is the sub-list for method output_type + 60, // [60:60] is the sub-list for method input_type + 60, // [60:60] is the sub-list for extension type_name + 60, // [60:60] is the sub-list for extension extendee + 0, // [0:60] is the sub-list for field type_name +} + +func init() { file_command_proto_init() } +func file_command_proto_init() { + if File_command_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_command_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SimpleTable); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateSetter); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Column); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*List); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Expr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RepeatedExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LiteralExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConstantBooleanExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnaryExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BinaryExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FunctionExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EqualityExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RangeExpr); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Scan); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Select); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Project); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Delete); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CommandDrop); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Update); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Join); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Limit); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Offset); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Distinct); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Values); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_command_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command_Insert); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_command_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*UpdateSetter_Literal)(nil), + (*UpdateSetter_Constant)(nil), + (*UpdateSetter_Unary)(nil), + (*UpdateSetter_Binary)(nil), + (*UpdateSetter_Func)(nil), + (*UpdateSetter_Equality)(nil), + (*UpdateSetter_Range)(nil), + } + file_command_proto_msgTypes[3].OneofWrappers = []interface{}{ + (*List_Scan)(nil), + (*List_Select)(nil), + (*List_Project)(nil), + (*List_Join)(nil), + (*List_Limit)(nil), + (*List_Offset)(nil), + (*List_Distinct)(nil), + (*List_Values)(nil), + } + file_command_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*Expr_Literal)(nil), + (*Expr_Constant)(nil), + (*Expr_Unary)(nil), + (*Expr_Binary)(nil), + (*Expr_Func)(nil), + (*Expr_Equality)(nil), + (*Expr_Range)(nil), + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_command_proto_rawDesc, + NumEnums: 4, + NumMessages: 27, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_command_proto_goTypes, + DependencyIndexes: file_command_proto_depIdxs, + EnumInfos: file_command_proto_enumTypes, + MessageInfos: file_command_proto_msgTypes, + }.Build() + File_command_proto = out.File + file_command_proto_rawDesc = nil + file_command_proto_goTypes = nil + file_command_proto_depIdxs = nil +} diff --git a/internal/raft/message/command.proto b/internal/raft/message/command.proto new file mode 100644 index 00000000..9ff2e2b8 --- /dev/null +++ b/internal/raft/message/command.proto @@ -0,0 +1,218 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; + +message SimpleTable { + string Schema = 1; + string Table = 2; + string Alias = 3; + bool Indexed = 4; + string Index = 5; +} + +message UpdateSetter { + repeated string Cols = 1; + oneof Value { + LiteralExpr literal = 2; + ConstantBooleanExpr constant = 3; + BinaryExpr binary = 4; + FunctionExpr func = 5; + EqualityExpr equality = 6; + RangeExpr range = 7; + } +} + +enum JoinType { + JoinUnknown = 0; + JoinLeft = 1; + JoinLeftOuter = 2; + JoinInner = 3; + JoinCross = 4; +} + +enum UpdateOr { + UpdateOrUnknown = 0; + UpdateOrRollback = 1; + UpdateOrAbort = 2; + UpdateOrReplace = 3; + UpdateOrFail = 4; + UpdateOrIgnore = 5; +} + +enum InsertOr { + InsertOrUnknown = 0; + InsertOrReplace = 1; + InsertOrRollback = 2; + InsertOrAbort = 3; + InsertOrFail = 4; + InsertOrIgnore = 5; +} + +message Column { + string Table = 1; + Expr Column = 2; + string Alias = 3; +} + + message List { + oneof list { + Command.Scan scan = 1; + Command.Select select = 2; + Command.Project project = 3; + Command.Join join = 4; + Command.Limit limit = 5; + Command.Offset offset = 6; + Command.Distinct distinct = 7; + Command.Values values = 8; + } +} + +enum DropTarget { + Table = 0; + View = 1; + Index = 2; + Trigger = 3; +} + +message Command { + + message Scan { + SimpleTable Table = 1; + } + + message Select { + Expr Filter = 1; + List Input = 2; + } + + message Project { + repeated Column Cols = 1; + List Input = 2; + } + + message Delete { + SimpleTable Table = 1; + Expr Filter = 2; + } + + message drop { + DropTarget target = 1; + bool IfExists = 2; + string Schema = 3; + string Name = 4; + } + + message Update { + UpdateOr UpdateOr = 1; + SimpleTable Table = 2; + repeated UpdateSetter Updates = 3; + Expr Filter = 4; + } + + message Join { + bool Natural = 1; + JoinType Type = 2; + Expr Filter = 3; + List Left = 4; + List Right = 5; + } + + message Limit { + Expr Limit = 1; + List Input = 2; + } + + message Offset { + Expr Offset = 1; + List Input = 2; + } + + message Empty { + repeated Column Cols = 1; + } + + message Distinct { + List Input = 1; + } + + message Values { + repeated repeatedExpr expr = 1; + } + + message Insert { + InsertOr InsertOr = 1; + SimpleTable Table = 2; + repeated Column Cols = 3; + bool DefaultValues = 4; + List Input = 5; + } +} + +// Expression + +message Expr { + oneof expr { + LiteralExpr literal = 1; + ConstantBooleanExpr constant = 2; + BinaryExpr binary = 3; + FunctionExpr func = 4; + EqualityExpr equality = 5; + RangeExpr range = 6; + } +} + +message repeatedExpr { + repeated Expr expr = 1; +} + +message LiteralExpr { + string Value = 1; +} + +message ConstantBooleanExpr { + bool Value = 1; +} + +message UnaryBase { + Expr Value = 1; +} + +message UnaryNegativeExpr { + UnaryBase Value = 1; +} + +message UnaryBitwiseNegationExpr { + UnaryBase Value = 1; +} + +message UnaryNegationExpr { + UnaryBase Value = 1; +} + +message BinaryExpr { + string Operator = 1; + Expr Left = 2; + Expr Right = 3; +} + +message FunctionExpr { + string Name = 1; + bool Distinct = 2; + repeated Expr Args = 3; +} + +message EqualityExpr { + Expr Left = 1; + Expr Right = 2; + bool Invert = 3; +} + +message RangeExpr { + Expr Needle = 1; + Expr Lo = 2; + Expr Hi = 3; + bool Invert = 4; +} \ No newline at end of file diff --git a/internal/raft/message/convert.go b/internal/raft/message/convert.go new file mode 100644 index 00000000..226209b3 --- /dev/null +++ b/internal/raft/message/convert.go @@ -0,0 +1,1380 @@ +package message + +import "github.com/xqueries/xdb/internal/compiler/command" + +// import ( +// "github.com/xqueries/xdb/internal/compiler/command" +// ) + +// ConvertCommandToMessage converts a command.Command to a message.Message. +func ConvertCommandToMessage(cmd command.Command) (Message, error) { + // if cmd == nil { + // return nil, ErrNilCommand + // } + // switch c := cmd.(type) { + // case command.Scan: + // return ConvertCommandScanToMessageScan(c) + // case command.Select: + // return ConvertCommandSelectToMessageSelect(c) + // case command.Project: + // return ConvertCommandProjectToMessageProject(c) + // case command.Delete: + // return ConvertCommandDeleteToMessageDelete(c) + // case *command.DropIndex: + // return ConvertCommandDropToMessageDrop(c) + // case *command.DropTable: + // return ConvertCommandDropToMessageDrop(c) + // case *command.DropTrigger: + // return ConvertCommandDropToMessageDrop(c) + // case *command.DropView: + // return ConvertCommandDropToMessageDrop(c) + // case command.Update: + // return ConvertCommandUpdateToMessageUpdate(c) + // case command.Join: + // return ConvertCommandJoinToMessageJoin(c) + // case command.Limit: + // return ConvertCommandLimitToMessageLimit(c) + // case command.Insert: + // return ConvertCommandInsertToMessageInsert(c) + // } + return nil, ErrUnknownCommandKind +} + +// // ConvertCommandTableToMessageTable converts a command.Table to a SimpleTable. +// func ConvertCommandTableToMessageTable(cmd command.Table) (*SimpleTable, error) { +// if cmd == nil { +// return nil, ErrNilCommand +// } +// return &SimpleTable{ +// Schema: cmd.(*command.SimpleTable).Schema, +// Table: cmd.(*command.SimpleTable).Table, +// Alias: cmd.(*command.SimpleTable).Alias, +// Indexed: cmd.(*command.SimpleTable).Indexed, +// Index: cmd.(*command.SimpleTable).Index, +// }, nil +// } + +// // ConvertCommandScanToMessageScan converts a Command type to a Command_Scan type. +// func ConvertCommandScanToMessageScan(cmd command.Scan) (*Command_Scan, error) { +// table, err := ConvertCommandTableToMessageTable(cmd.Table) +// if err != nil { +// return nil, err +// } +// return &Command_Scan{ +// Table: table, +// }, nil +// } + +// // ConvertCommandLiteralExprToMessageLiteralExpr converts a command.Expr to a message.Expr_Literal. +// func ConvertCommandLiteralExprToMessageLiteralExpr(cmd command.LiteralExpr) (*Expr_Literal, error) { +// return &Expr_Literal{ +// &LiteralExpr{ +// Value: cmd.Value, +// }, +// }, nil +// } + +// // ConvertCommandConstantBooleanExprToMessageConstantBooleanExpr converts a command.Expr to a message.Expr_Constant. +// func ConvertCommandConstantBooleanExprToMessageConstantBooleanExpr(cmd command.ConstantBooleanExpr) (*Expr_Constant, error) { +// return &Expr_Constant{ +// &ConstantBooleanExpr{ +// Value: cmd.Value, +// }, +// }, nil +// } + +// // ConvertCommandUnaryExprToMessageUnaryExpr converts a command.Expr to a message.Expr_Unary. +// func ConvertCommandUnaryExprToMessageUnaryExpr(cmd command.UnaryExpr) (*Expr_Unary, error) { +// val, err := ConvertCommandExprToMessageExpr(cmd.Value) +// if err != nil { +// return nil, err +// } +// return &Expr_Unary{ +// &UnaryExpr{ +// Operator: cmd.Operator, +// Value: val, +// }, +// }, nil +// } + +// // ConvertCommandBinaryExprToMessageBinaryExpr converts a command.Expr to a message.Expr_Binary. +// func ConvertCommandBinaryExprToMessageBinaryExpr(cmd command.BinaryExpr) (*Expr_Binary, error) { +// left, err := ConvertCommandExprToMessageExpr(cmd.Left) +// if err != nil { +// return nil, err +// } +// right, err := ConvertCommandExprToMessageExpr(cmd.Right) +// if err != nil { +// return nil, err +// } +// return &Expr_Binary{ +// &BinaryExpr{ +// Operator: cmd.Operator, +// Left: left, +// Right: right, +// }, +// }, nil +// } + +// // ConvertCommandRepeatedExprToMessageRepeatedExpr converts a []command.Expr to a message.Expr. +// func ConvertCommandRepeatedExprToMessageRepeatedExpr(cmd []command.Expr) ([]*Expr, error) { +// msgRepeatedExpr := []*Expr{} +// for i := range cmd { +// expr, err := ConvertCommandExprToMessageExpr(cmd[i]) +// if err != nil { +// return nil, err +// } +// msgRepeatedExpr = append(msgRepeatedExpr, expr) +// } +// return msgRepeatedExpr, nil +// } + +// // ConvertCommandFunctionalExprToMessageFunctionalExpr converts a command.Expr to a message.Expr_Func. +// func ConvertCommandFunctionalExprToMessageFunctionalExpr(cmd command.FunctionExpr) (*Expr_Func, error) { +// args, err := ConvertCommandRepeatedExprToMessageRepeatedExpr(cmd.Args) +// if err != nil { +// return nil, err +// } +// return &Expr_Func{ +// &FunctionExpr{ +// Name: cmd.Name, +// Distinct: cmd.Distinct, +// Args: args, +// }, +// }, nil +// } + +// // ConvertCommandEqualityExprToMessageEqualityExpr converts a command.Expr to a message.Expr_Equality. +// func ConvertCommandEqualityExprToMessageEqualityExpr(cmd command.EqualityExpr) (*Expr_Equality, error) { +// left, err := ConvertCommandExprToMessageExpr(cmd.Left) +// if err != nil { +// return nil, err +// } +// right, err := ConvertCommandExprToMessageExpr(cmd.Right) +// if err != nil { +// return nil, err +// } +// return &Expr_Equality{ +// &EqualityExpr{ +// Left: left, +// Right: right, +// Invert: cmd.Invert, +// }, +// }, nil +// } + +// // ConvertCommandRangeExprToMessageRangeExpr converts a command.Expr to a message.Expr_Range. +// func ConvertCommandRangeExprToMessageRangeExpr(cmd command.RangeExpr) (*Expr_Range, error) { +// needle, err := ConvertCommandExprToMessageExpr(cmd.Needle) +// if err != nil { +// return nil, err +// } +// lo, err := ConvertCommandExprToMessageExpr(cmd.Lo) +// if err != nil { +// return nil, err +// } +// hi, err := ConvertCommandExprToMessageExpr(cmd.Hi) +// if err != nil { +// return nil, err +// } +// return &Expr_Range{ +// &RangeExpr{ +// Needle: needle, +// Lo: lo, +// Hi: hi, +// Invert: cmd.Invert, +// }, +// }, nil +// } + +// // ConvertCommandExprToMessageExpr converts command.Expr to a message.Expr. +// func ConvertCommandExprToMessageExpr(cmd command.Expr) (*Expr, error) { +// var err error +// msgExpr := &Expr{} +// switch c := cmd.(type) { +// case command.LiteralExpr: +// msgExpr.Expr, err = ConvertCommandLiteralExprToMessageLiteralExpr(c) +// if err != nil { +// return nil, err +// } +// case command.ConstantBooleanExpr: +// msgExpr.Expr, err = ConvertCommandConstantBooleanExprToMessageConstantBooleanExpr(c) +// if err != nil { +// return nil, err +// } +// case command.UnaryExpr: +// msgExpr.Expr, err = ConvertCommandUnaryExprToMessageUnaryExpr(c) +// if err != nil { +// return nil, err +// } +// case command.BinaryExpr: +// msgExpr.Expr, err = ConvertCommandBinaryExprToMessageBinaryExpr(c) +// if err != nil { +// return nil, err +// } +// case command.FunctionExpr: +// msgExpr.Expr, err = ConvertCommandFunctionalExprToMessageFunctionalExpr(c) +// if err != nil { +// return nil, err +// } +// case command.EqualityExpr: +// msgExpr.Expr, err = ConvertCommandEqualityExprToMessageEqualityExpr(c) +// if err != nil { +// return nil, err +// } +// case command.RangeExpr: +// msgExpr.Expr, err = ConvertCommandRangeExprToMessageRangeExpr(c) +// if err != nil { +// return nil, err +// } +// default: +// return nil, ErrUnknownCommandKind +// } +// return msgExpr, nil +// } + +// // ConvertCommandListScanToMessageListScan converts a command.Scan to a message.List_Scan. +// func ConvertCommandListScanToMessageListScan(cmd command.Scan) (*List_Scan, error) { +// table, err := ConvertCommandTableToMessageTable(cmd.Table) +// if err != nil { +// return nil, err +// } +// return &List_Scan{ +// &Command_Scan{ +// Table: table, +// }, +// }, nil +// } + +// // ConvertCommandListSelectToMessageListSelect converts a command.Select to a message.List_Select. +// func ConvertCommandListSelectToMessageListSelect(cmd command.Select) (*List_Select, error) { +// filter, err := ConvertCommandExprToMessageExpr(cmd.Filter) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &List_Select{ +// &Command_Select{ +// Filter: filter, +// Input: input, +// }, +// }, nil +// } + +// // ConvertCommandListProjectToMessageListProject converts a command.Project to a message.List_Project. +// func ConvertCommandListProjectToMessageListProject(cmd command.Project) (*List_Project, error) { +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// cols, err := ConvertCommandColSliceToMessageColSlice(cmd.Cols) +// if err != nil { +// return nil, err +// } +// return &List_Project{ +// &Command_Project{ +// Cols: cols, +// Input: input, +// }, +// }, nil +// } + +// // ConvertCommandListJoinToMessageListJoin converts a command.Join to a message.List_Join. +// func ConvertCommandListJoinToMessageListJoin(cmd command.Join) (*List_Join, error) { +// filter, err := ConvertCommandExprToMessageExpr(cmd.Filter) +// if err != nil { +// return nil, err +// } +// left, err := ConvertCommandListToMessageList(cmd.Left) +// if err != nil { +// return nil, err +// } +// right, err := ConvertCommandListToMessageList(cmd.Right) +// if err != nil { +// return nil, err +// } +// return &List_Join{ +// &Command_Join{ +// Natural: cmd.Natural, +// Type: ConvertCommandJoinTypeToMessageJoinType(cmd.Type), +// Filter: filter, +// Left: left, +// Right: right, +// }, +// }, nil +// } + +// // ConvertCommandListLimitToMessageListLimit converts a command.Limit to a message.List_Limit. +// func ConvertCommandListLimitToMessageListLimit(cmd command.Limit) (*List_Limit, error) { +// limit, err := ConvertCommandExprToMessageExpr(cmd.Limit) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &List_Limit{ +// &Command_Limit{ +// Limit: limit, +// Input: input, +// }, +// }, nil +// } + +// // ConvertCommandListOffsetToMessageListOffset converts a command.Offset to a message.List_Offset. +// func ConvertCommandListOffsetToMessageListOffset(cmd command.Offset) (*List_Offset, error) { +// offset, err := ConvertCommandExprToMessageExpr(cmd.Offset) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &List_Offset{ +// &Command_Offset{ +// Offset: offset, +// Input: input, +// }, +// }, nil +// } + +// // ConvertCommandListDistinctToMessageListDistinct converts a command.Distinct to a message.List_Distinct. +// func ConvertCommandListDistinctToMessageListDistinct(cmd command.Distinct) (*List_Distinct, error) { +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &List_Distinct{ +// &Command_Distinct{ +// Input: input, +// }, +// }, nil +// } + +// // ConvertCommandRepeatedExprToMessageRepeatedExprSlice converts a [][]command.Expr to a [][]message.Expr. +// func ConvertCommandRepeatedExprToMessageRepeatedExprSlice(cmd [][]command.Expr) ([]*RepeatedExpr, error) { +// msgRepeatedExprSlice := []*RepeatedExpr{} +// for i := range cmd { +// msgRepeatedExpr := &RepeatedExpr{} +// for j := range cmd[i] { +// expr, err := ConvertCommandExprToMessageExpr(cmd[i][j]) +// if err != nil { +// return nil, err +// } +// msgRepeatedExpr.Expr = append(msgRepeatedExpr.Expr, expr) +// } +// msgRepeatedExprSlice = append(msgRepeatedExprSlice, msgRepeatedExpr) +// } +// return msgRepeatedExprSlice, nil +// } + +// // ConvertCommandListValuesToMessageListValues converts a command.Values to a message.List_Values. +// func ConvertCommandListValuesToMessageListValues(cmd command.Values) (*List_Values, error) { +// exprSlice, err := ConvertCommandRepeatedExprToMessageRepeatedExprSlice(cmd.Values) +// if err != nil { +// return nil, err +// } +// return &List_Values{ +// &Command_Values{ +// Expr: exprSlice, +// }, +// }, nil +// } + +// // ConvertCommandListToMessageList converts a command.List to a message.List. +// func ConvertCommandListToMessageList(cmd command.List) (*List, error) { +// var err error +// msgList := &List{} +// switch c := cmd.(type) { +// case command.Scan: +// msgList.List, err = ConvertCommandListScanToMessageListScan(c) +// if err != nil { +// return nil, err +// } +// case command.Select: +// msgList.List, err = ConvertCommandListSelectToMessageListSelect(c) +// if err != nil { +// return nil, err +// } +// case command.Project: +// msgList.List, err = ConvertCommandListProjectToMessageListProject(c) +// if err != nil { +// return nil, err +// } +// case command.Join: +// msgList.List, err = ConvertCommandListJoinToMessageListJoin(c) +// if err != nil { +// return nil, err +// } +// case command.Limit: +// msgList.List, err = ConvertCommandListLimitToMessageListLimit(c) +// if err != nil { +// return nil, err +// } +// case command.Offset: +// msgList.List, err = ConvertCommandListOffsetToMessageListOffset(c) +// if err != nil { +// return nil, err +// } +// case command.Distinct: +// msgList.List, err = ConvertCommandListDistinctToMessageListDistinct(c) +// if err != nil { +// return nil, err +// } +// case command.Values: +// msgList.List, err = ConvertCommandListValuesToMessageListValues(c) +// if err != nil { +// return nil, err +// } +// default: +// return nil, ErrUnknownCommandKind +// } +// return msgList, nil +// } + +// // ConvertCommandSelectToMessageSelect converts a Command type to a Command_Select type. +// func ConvertCommandSelectToMessageSelect(cmd command.Select) (*Command_Select, error) { +// filter, err := ConvertCommandExprToMessageExpr(cmd.Filter) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &Command_Select{ +// Filter: filter, +// Input: input, +// }, nil +// } + +// // ConvertCommandColToMessageCol converts command.Column to a message.Column. +// func ConvertCommandColToMessageCol(cmd command.Column) (*Column, error) { +// column, err := ConvertCommandExprToMessageExpr(cmd.Column) +// if err != nil { +// return nil, err +// } +// return &Column{ +// Table: cmd.Table, +// Column: column, +// Alias: cmd.Alias, +// }, nil +// } + +// // ConvertCommandColSliceToMessageColSlice converts []command.Column to a []message.Column. +// func ConvertCommandColSliceToMessageColSlice(cmd []command.Column) ([]*Column, error) { +// msgCols := []*Column{} +// for i := range cmd { +// col, err := ConvertCommandColToMessageCol(cmd[i]) +// if err != nil { +// return nil, err +// } +// msgCols = append(msgCols, col) +// } +// return msgCols, nil +// } + +// // ConvertCommandProjectToMessageProject converts a Command type to a Command_Project type. +// func ConvertCommandProjectToMessageProject(cmd command.Project) (*Command_Project, error) { +// cols, err := ConvertCommandColSliceToMessageColSlice(cmd.Cols) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &Command_Project{ +// Cols: cols, +// Input: input, +// }, nil +// } + +// // ConvertCommandDeleteToMessageDelete converts a Command type to a Command_Delete type. +// func ConvertCommandDeleteToMessageDelete(cmd command.Delete) (*Command_Delete, error) { +// table, err := ConvertCommandTableToMessageTable(cmd.Table) +// if err != nil { +// return nil, err +// } +// filter, err := ConvertCommandExprToMessageExpr(cmd.Filter) +// if err != nil { +// return nil, err +// } +// return &Command_Delete{ +// Table: table, +// Filter: filter, +// }, nil +// } + +// // ConvertCommandDropToMessageDrop converts a Command type to a CommandDrop type. +// func ConvertCommandDropToMessageDrop(cmd command.Command) (*CommandDrop, error) { +// if cmd == nil { +// return nil, ErrNilCommand +// } +// msgCmdDrop := &CommandDrop{} +// switch c := cmd.(type) { +// case *command.DropTable: +// msgCmdDrop.Target = DropTarget_Table +// msgCmdDrop.IfExists = c.IfExists +// msgCmdDrop.Schema = c.Schema +// msgCmdDrop.Name = c.Name +// case *command.DropView: +// msgCmdDrop.Target = DropTarget_View +// msgCmdDrop.IfExists = c.IfExists +// msgCmdDrop.Schema = c.Schema +// msgCmdDrop.Name = c.Name +// case *command.DropIndex: +// msgCmdDrop.Target = DropTarget_Index +// msgCmdDrop.IfExists = c.IfExists +// msgCmdDrop.Schema = c.Schema +// msgCmdDrop.Name = c.Name +// case *command.DropTrigger: +// msgCmdDrop.Target = DropTarget_Trigger +// msgCmdDrop.IfExists = c.IfExists +// msgCmdDrop.Schema = c.Schema +// msgCmdDrop.Name = c.Name +// } +// return msgCmdDrop, nil +// } + +// // ConvertCommandUpdateOrToMessageUpdateOr converts a command.Update or to a message.UpdateOr. +// // Returns -1 if the UpdateOr type doesn't match. +// func ConvertCommandUpdateOrToMessageUpdateOr(cmd command.UpdateOr) (UpdateOr, error) { +// switch cmd { +// case command.UpdateOrUnknown: +// return UpdateOr_UpdateOrUnknown, nil +// case command.UpdateOrRollback: +// return UpdateOr_UpdateOrRollback, nil +// case command.UpdateOrAbort: +// return UpdateOr_UpdateOrAbort, nil +// case command.UpdateOrReplace: +// return UpdateOr_UpdateOrReplace, nil +// case command.UpdateOrFail: +// return UpdateOr_UpdateOrFail, nil +// case command.UpdateOrIgnore: +// return UpdateOr_UpdateOrIgnore, nil +// } +// return -1, ErrUnknownCommandKind +// } + +// // ConvertCommandUpdateSetterLiteralToMessageUpdateSetterLiteral converts +// // a command.Literal to a message.UpdateSetter_Literal. +// func ConvertCommandUpdateSetterLiteralToMessageUpdateSetterLiteral( +// cmd command.LiteralExpr, +// ) (*UpdateSetter_Literal, error) { +// return &UpdateSetter_Literal{ +// &LiteralExpr{ +// Value: cmd.Value, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterConstantToMessageUpdateSetterConstant converts +// // a command.Constant to a message.UpdateSetter_Constant. +// func ConvertCommandUpdateSetterConstantToMessageUpdateSetterConstant( +// cmd command.ConstantBooleanExpr, +// ) (*UpdateSetter_Constant, error) { + +// return &UpdateSetter_Constant{ +// &ConstantBooleanExpr{ +// Value: cmd.Value, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterUnaryToMessageUpdateSetterUnary converts +// // a command.Unary to a message.UpdateSetter_Unary. +// func ConvertCommandUpdateSetterUnaryToMessageUpdateSetterUnary( +// cmd command.UnaryExpr, +// ) (*UpdateSetter_Unary, error) { +// val, err := ConvertCommandExprToMessageExpr(cmd.Value) +// if err != nil { +// return nil, err +// } +// return &UpdateSetter_Unary{ +// &UnaryExpr{ +// Operator: cmd.Operator, +// Value: val, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterBinaryToMessageUpdateSetterBinary converts +// // a command.Binary to a message.UpdateSetter_Binary. +// func ConvertCommandUpdateSetterBinaryToMessageUpdateSetterBinary( +// cmd command.BinaryExpr, +// ) (*UpdateSetter_Binary, error) { +// left, err := ConvertCommandExprToMessageExpr(cmd.Left) +// if err != nil { +// return nil, err +// } +// right, err := ConvertCommandExprToMessageExpr(cmd.Right) +// if err != nil { +// return nil, err +// } +// return &UpdateSetter_Binary{ +// &BinaryExpr{ +// Operator: cmd.Operator, +// Left: left, +// Right: right, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterFuncToMessageUpdateSetterFunc converts +// // a command.Func to a message.UpdateSetter_Func. +// func ConvertCommandUpdateSetterFuncToMessageUpdateSetterFunc( +// cmd command.FunctionExpr, +// ) (*UpdateSetter_Func, error) { +// repExpr, err := ConvertCommandRepeatedExprToMessageRepeatedExpr(cmd.Args) +// if err != nil { +// return nil, err +// } +// return &UpdateSetter_Func{ +// &FunctionExpr{ +// Name: cmd.Name, +// Distinct: cmd.Distinct, +// Args: repExpr, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterEqualityToMessageUpdateSetterEquality converts +// // a command.Equality to a message.UpdateSetter_Equality. +// func ConvertCommandUpdateSetterEqualityToMessageUpdateSetterEquality( +// cmd command.EqualityExpr, +// ) (*UpdateSetter_Equality, error) { +// left, err := ConvertCommandExprToMessageExpr(cmd.Left) +// if err != nil { +// return nil, err +// } +// right, err := ConvertCommandExprToMessageExpr(cmd.Right) +// if err != nil { +// return nil, err +// } +// return &UpdateSetter_Equality{ +// &EqualityExpr{ +// Left: left, +// Right: right, +// Invert: cmd.Invert, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterRangeToMessageUpdateSetterRange converts +// // a command.Range to a message.UpdateSetter_Range. +// func ConvertCommandUpdateSetterRangeToMessageUpdateSetterRange( +// cmd command.RangeExpr, +// ) (*UpdateSetter_Range, error) { +// needle, err := ConvertCommandExprToMessageExpr(cmd.Needle) +// if err != nil { +// return nil, err +// } +// lo, err := ConvertCommandExprToMessageExpr(cmd.Lo) +// if err != nil { +// return nil, err +// } +// hi, err := ConvertCommandExprToMessageExpr(cmd.Hi) +// if err != nil { +// return nil, err +// } +// return &UpdateSetter_Range{ +// &RangeExpr{ +// Needle: needle, +// Lo: lo, +// Hi: hi, +// Invert: cmd.Invert, +// }, +// }, nil +// } + +// // ConvertCommandUpdateSetterToMessageUpdateSetter converts +// // a command.UpdateSetter to a message.UpdateSetter. +// func ConvertCommandUpdateSetterToMessageUpdateSetter( +// cmd command.UpdateSetter, +// ) (*UpdateSetter, error) { +// var err error +// msgUpdateSetter := &UpdateSetter{} +// msgUpdateSetter.Cols = cmd.Cols +// switch val := cmd.Value.(type) { +// case command.LiteralExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterLiteralToMessageUpdateSetterLiteral(val) +// if err != nil { +// return nil, err +// } +// case command.ConstantBooleanExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterConstantToMessageUpdateSetterConstant(val) +// if err != nil { +// return nil, err +// } +// case command.UnaryExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterUnaryToMessageUpdateSetterUnary(val) +// if err != nil { +// return nil, err +// } +// case command.BinaryExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterBinaryToMessageUpdateSetterBinary(val) +// if err != nil { +// return nil, err +// } +// case command.FunctionExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterFuncToMessageUpdateSetterFunc(val) +// if err != nil { +// return nil, err +// } +// case command.EqualityExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterEqualityToMessageUpdateSetterEquality(val) +// if err != nil { +// return nil, err +// } +// case command.RangeExpr: +// msgUpdateSetter.Value, err = ConvertCommandUpdateSetterRangeToMessageUpdateSetterRange(val) +// if err != nil { +// return nil, err +// } +// } +// return msgUpdateSetter, nil +// } + +// // ConvertCommandUpdateSetterSliceToMessageUpdateSetterSlice converts +// // a []command.UpdateSetter to a []message.UpdateSetter. +// func ConvertCommandUpdateSetterSliceToMessageUpdateSetterSlice( +// cmd []command.UpdateSetter, +// ) ([]*UpdateSetter, error) { +// msgUpdateSetterSlice := []*UpdateSetter{} +// for i := range cmd { +// updateSetter, err := ConvertCommandUpdateSetterToMessageUpdateSetter(cmd[i]) +// if err != nil { +// return nil, err +// } +// msgUpdateSetterSlice = append(msgUpdateSetterSlice, updateSetter) +// } +// return msgUpdateSetterSlice, nil +// } + +// // ConvertCommandUpdateToMessageUpdate converts a Command type to a Command_Update type. +// func ConvertCommandUpdateToMessageUpdate(cmd command.Update) (*Command_Update, error) { +// updateOr, err := ConvertCommandUpdateOrToMessageUpdateOr(cmd.UpdateOr) +// if err != nil { +// return nil, err +// } +// table, err := ConvertCommandTableToMessageTable(cmd.Table) +// if err != nil { +// return nil, err +// } +// updates, err := ConvertCommandUpdateSetterSliceToMessageUpdateSetterSlice(cmd.Updates) +// if err != nil { +// return nil, err +// } +// filter, err := ConvertCommandExprToMessageExpr(cmd.Filter) +// if err != nil { +// return nil, err +// } +// return &Command_Update{ +// UpdateOr: updateOr, +// Table: table, +// Updates: updates, +// Filter: filter, +// }, nil +// } + +// // ConvertCommandJoinTypeToMessageJoinType converts command.JoinType to message.JoinType. +// // It returns -1 on not finding a valid JoinType. +// func ConvertCommandJoinTypeToMessageJoinType(cmd command.JoinType) JoinType { +// switch cmd { +// case command.JoinUnknown: +// return JoinType_JoinUnknown +// case command.JoinLeft: +// return JoinType_JoinLeft +// case command.JoinLeftOuter: +// return JoinType_JoinLeftOuter +// case command.JoinInner: +// return JoinType_JoinInner +// case command.JoinCross: +// return JoinType_JoinCross +// } +// return -1 +// } + +// // ConvertCommandJoinToMessageJoin converts a Command type to a Command_Join type. +// func ConvertCommandJoinToMessageJoin(cmd command.Join) (*Command_Join, error) { +// filter, err := ConvertCommandExprToMessageExpr(cmd.Filter) +// if err != nil { +// return nil, err +// } +// left, err := ConvertCommandListToMessageList(cmd.Left) +// if err != nil { +// return nil, err +// } +// right, err := ConvertCommandListToMessageList(cmd.Right) +// if err != nil { +// return nil, err +// } + +// return &Command_Join{ +// Natural: cmd.Natural, +// Type: ConvertCommandJoinTypeToMessageJoinType(cmd.Type), +// Filter: filter, +// Left: left, +// Right: right, +// }, nil +// } + +// // ConvertCommandLimitToMessageLimit converts a Command type to a Command_Limit type. +// func ConvertCommandLimitToMessageLimit(cmd command.Limit) (*Command_Limit, error) { +// limit, err := ConvertCommandExprToMessageExpr(cmd.Limit) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &Command_Limit{ +// Limit: limit, +// Input: input, +// }, nil +// } + +// // ConvertCommandInsertOrToMessageInsertOr converts command.InsertOr to a message.InsertOr. +// // It returns -1 on not finding the right InsertOr type. +// func ConvertCommandInsertOrToMessageInsertOr(cmd command.InsertOr) InsertOr { +// switch cmd { +// case command.InsertOrUnknown: +// return InsertOr_InsertOrUnknown +// case command.InsertOrReplace: +// return InsertOr_InsertOrReplace +// case command.InsertOrRollback: +// return InsertOr_InsertOrRollback +// case command.InsertOrAbort: +// return InsertOr_InsertOrAbort +// case command.InsertOrFail: +// return InsertOr_InsertOrFail +// case command.InsertOrIgnore: +// return InsertOr_InsertOrIgnore +// } +// return -1 +// } + +// // ConvertCommandInsertToMessageInsert converts a Command type to a Command_Insert type. +// func ConvertCommandInsertToMessageInsert(cmd command.Insert) (*Command_Insert, error) { +// table, err := ConvertCommandTableToMessageTable(cmd.Table) +// if err != nil { +// return nil, err +// } +// colSlice, err := ConvertCommandColSliceToMessageColSlice(cmd.Cols) +// if err != nil { +// return nil, err +// } +// input, err := ConvertCommandListToMessageList(cmd.Input) +// if err != nil { +// return nil, err +// } +// return &Command_Insert{ +// InsertOr: ConvertCommandInsertOrToMessageInsertOr(cmd.InsertOr), +// Table: table, +// Cols: colSlice, +// DefaultValues: cmd.DefaultValues, +// Input: input, +// }, nil +// } + +// ConvertMessageToCommand converts a message.Command to a command.Command. +func ConvertMessageToCommand(msg Message) command.Command { + // switch m := msg.(type) { + // case *Command_Scan: + // return ConvertMessageScanToCommandScan(m) + // case *Command_Select: + // return ConvertMessageSelectToCommandSelect(m) + // case *Command_Project: + // return ConvertMessageProjectToCommandProject(m) + // case *Command_Delete: + // return ConvertMessageDeleteToCommandDelete(m) + // case *CommandDrop: + // switch m.Target { + // case 0: + // return ConvertMessageDropToCommandDropTable(m) + // case 1: + // return ConvertMessageDropToCommandDropView(m) + // case 2: + // return ConvertMessageDropToCommandDropIndex(m) + // case 3: + // return ConvertMessageDropToCommandDropTrigger(m) + // } + // case *Command_Update: + // return ConvertMessageUpdateToCommandUpdate(m) + // case *Command_Join: + // return ConvertMessageJoinToCommandJoin(m) + // case *Command_Limit: + // return ConvertMessageLimitToCommandLimit(m) + // case *Command_Insert: + // return ConvertMessageInsertToCommandInsert(m) + // } + return nil +} + +// // ConvertMessageTableToCommandTable converts a message.SimpleTable to a command.Table. +// func ConvertMessageTableToCommandTable(msg *SimpleTable) command.Table { +// return &command.SimpleTable{ +// Schema: msg.Schema, +// Table: msg.Table, +// Alias: msg.Alias, +// Indexed: msg.Indexed, +// Index: msg.Index, +// } +// } + +// // ConvertMessageScanToCommandScan converts a message.Command_Scan to a command.Scan. +// func ConvertMessageScanToCommandScan(msg *Command_Scan) command.Scan { +// return command.Scan{ +// Table: ConvertMessageTableToCommandTable(msg.Table), +// } +// } + +// // ConvertMessageLiteralExprToCommandLiteralExpr converts a message.Expr to a command.LiteralExpr. +// func ConvertMessageLiteralExprToCommandLiteralExpr(msg *Expr) command.LiteralExpr { +// return command.LiteralExpr{ +// Value: msg.GetLiteral().GetValue(), +// } +// } + +// // ConvertMessageBooleanExprToCommandConstantBooleanExpr converts a message.Expr to a command.ConstantBooleanExpr. +// func ConvertMessageBooleanExprToCommandConstantBooleanExpr(msg *Expr) command.ConstantBooleanExpr { +// return command.ConstantBooleanExpr{ +// Value: msg.GetConstant().GetValue(), +// } +// } + +// // ConvertMessageUnaryExprToCommandUnaryExpr converts a message.Expr to a command.UnaryExpr. +// func ConvertMessageUnaryExprToCommandUnaryExpr(msg *Expr) command.UnaryExpr { +// return command.UnaryExpr{ +// Operator: msg.GetUnary().GetOperator(), +// Value: ConvertMessageExprToCommandExpr(msg.GetUnary().GetValue()), +// } +// } + +// // ConvertMessageBinaryExprToCommandBinaryExpr converts a message.Expr to a command.BinaryExpr. +// func ConvertMessageBinaryExprToCommandBinaryExpr(msg *Expr) command.BinaryExpr { +// return command.BinaryExpr{ +// Operator: msg.GetBinary().GetOperator(), +// Left: ConvertMessageExprToCommandExpr(msg.GetBinary().GetLeft()), +// Right: ConvertMessageExprToCommandExpr(msg.GetBinary().GetRight()), +// } +// } + +// // ConvertMessageExprSliceToCommandExprSlice converts a []*message.Expr to []command.Expr. +// func ConvertMessageExprSliceToCommandExprSlice(msg []*Expr) []command.Expr { +// msgExprSlice := []command.Expr{} +// for i := range msg { +// msgExprSlice = append(msgExprSlice, ConvertMessageExprToCommandExpr(msg[i])) +// } +// return msgExprSlice +// } + +// // ConvertMessageFunctionalExprToCommandFunctionExpr converts a message.Expr to a command.FunctionExpr. +// func ConvertMessageFunctionalExprToCommandFunctionExpr(msg *Expr) command.FunctionExpr { +// return command.FunctionExpr{ +// Name: msg.GetFunc().GetName(), +// Distinct: msg.GetFunc().GetDistinct(), +// Args: ConvertMessageExprSliceToCommandExprSlice(msg.GetFunc().GetArgs()), +// } +// } + +// // ConvertMessageEqualityExprToCommandEqualityExpr converts a message.Expr to a command.EqualityExpr. +// func ConvertMessageEqualityExprToCommandEqualityExpr(msg *Expr) command.EqualityExpr { +// return command.EqualityExpr{ +// Left: ConvertMessageExprToCommandExpr(msg.GetEquality().GetLeft()), +// Right: ConvertMessageExprToCommandExpr(msg.GetEquality().GetRight()), +// Invert: msg.GetEquality().Invert, +// } +// } + +// // ConvertMessageRangeExprToCommandRangeExpr converts a message.Expr to a command.RangeExpr. +// func ConvertMessageRangeExprToCommandRangeExpr(msg *Expr) command.RangeExpr { +// return command.RangeExpr{ +// Needle: ConvertMessageExprToCommandExpr(msg.GetRange().GetNeedle()), +// Lo: ConvertMessageExprToCommandExpr(msg.GetRange().GetLo()), +// Hi: ConvertMessageExprToCommandExpr(msg.GetRange().GetHi()), +// } +// } + +// // ConvertMessageExprToCommandExpr converts a message.Expr to a command.Expr. +// func ConvertMessageExprToCommandExpr(msg *Expr) command.Expr { +// if msg == nil { +// return nil +// } +// switch msg.Expr.(type) { +// case *Expr_Literal: +// return ConvertMessageLiteralExprToCommandLiteralExpr(msg) +// case *Expr_Constant: +// return ConvertMessageBooleanExprToCommandConstantBooleanExpr(msg) +// case *Expr_Unary: +// return ConvertMessageUnaryExprToCommandUnaryExpr(msg) +// case *Expr_Binary: +// return ConvertMessageBinaryExprToCommandBinaryExpr(msg) +// case *Expr_Func: +// return ConvertMessageFunctionalExprToCommandFunctionExpr(msg) +// case *Expr_Equality: +// return ConvertMessageEqualityExprToCommandEqualityExpr(msg) +// case *Expr_Range: +// return ConvertMessageRangeExprToCommandRangeExpr(msg) +// } +// return nil +// } + +// // ConvertMessageListScanToCommandListScan converts a message.List to a command.Scan. +// func ConvertMessageListScanToCommandListScan(msg *List) command.Scan { +// return command.Scan{ +// Table: ConvertMessageTableToCommandTable(msg.GetScan().GetTable()), +// } +// } + +// // ConvertMessageListSelectToCommandListSelect converts a message.List to a command.Select. +// func ConvertMessageListSelectToCommandListSelect(msg *List) command.Select { +// return command.Select{ +// Filter: ConvertMessageExprToCommandExpr(msg.GetSelect().GetFilter()), +// Input: ConvertMessageListToCommandList(msg.GetSelect().GetInput()), +// } +// } + +// // ConvertMessageListProjectToCommandListProject converts a message.List to a command.Project. +// func ConvertMessageListProjectToCommandListProject(msg *List) command.Project { +// return command.Project{ +// Cols: ConvertMessageColsToCommandCols(msg.GetProject().GetCols()), +// Input: ConvertMessageListToCommandList(msg.GetProject().GetInput()), +// } +// } + +// // ConvertMessageListJoinToCommandListJoin converts a message.List to a command.Join. +// func ConvertMessageListJoinToCommandListJoin(msg *List) command.Join { +// return command.Join{ +// Natural: msg.GetJoin().GetNatural(), +// Type: ConvertMessageJoinTypeToCommandJoinType(msg.GetJoin().GetType()), +// Filter: ConvertMessageExprToCommandExpr(msg.GetJoin().GetFilter()), +// Left: ConvertMessageListToCommandList(msg.GetJoin().GetLeft()), +// Right: ConvertMessageListToCommandList(msg.GetJoin().GetRight()), +// } +// } + +// // ConvertMessageListLimitToCommandListLimit converts a message.List to a command.Limit. +// func ConvertMessageListLimitToCommandListLimit(msg *List) command.Limit { +// return command.Limit{ +// Limit: ConvertMessageExprToCommandExpr(msg.GetLimit().GetLimit()), +// Input: ConvertMessageListToCommandList(msg.GetLimit().GetInput()), +// } +// } + +// // ConvertMessageListOffsetToCommandListOffset converts a message.List to a command.Offset. +// func ConvertMessageListOffsetToCommandListOffset(msg *List) command.Offset { +// return command.Offset{ +// Offset: ConvertMessageExprToCommandExpr(msg.GetOffset().GetOffset()), +// Input: ConvertMessageListToCommandList(msg.GetDistinct().GetInput()), +// } +// } + +// // ConvertMessageListDistinctToCommandListDistinct converts a message.List to a command.Distinct. +// func ConvertMessageListDistinctToCommandListDistinct(msg *List) command.Distinct { +// return command.Distinct{ +// Input: ConvertMessageListToCommandList(msg.GetDistinct().GetInput()), +// } +// } + +// // ConvertMessageExprToCommandExprRepeatedSlice converts a message.RepeatedExpr to a [][]command.Expr. +// func ConvertMessageExprToCommandExprRepeatedSlice(msg []*RepeatedExpr) [][]command.Expr { +// cmdRepeatedExprSlice := [][]command.Expr{} +// for i := range msg { +// cmdRepeatedExpr := []command.Expr{} +// for j := range msg[i].Expr { +// cmdRepeatedExpr = append(cmdRepeatedExpr, ConvertMessageExprToCommandExpr(msg[i].Expr[j])) +// } +// cmdRepeatedExprSlice = append(cmdRepeatedExprSlice, cmdRepeatedExpr) +// } +// return cmdRepeatedExprSlice +// } + +// // ConvertMessageListValuesToCommandListValues converts a message.List to a command.Values. +// func ConvertMessageListValuesToCommandListValues(msg *List) command.Values { +// return command.Values{ +// Values: ConvertMessageExprToCommandExprRepeatedSlice(msg.GetValues().GetExpr()), +// } +// } + +// // ConvertMessageListToCommandList converts a message.List to a command.List. +// func ConvertMessageListToCommandList(msg *List) command.List { +// if msg == nil { +// return nil +// } +// switch msg.List.(type) { +// case *List_Scan: +// return ConvertMessageListScanToCommandListScan(msg) +// case *List_Select: +// return ConvertMessageListSelectToCommandListSelect(msg) +// case *List_Project: +// return ConvertMessageListProjectToCommandListProject(msg) +// case *List_Join: +// return ConvertMessageListJoinToCommandListJoin(msg) +// case *List_Limit: +// return ConvertMessageListLimitToCommandListLimit(msg) +// case *List_Offset: +// return ConvertMessageListOffsetToCommandListOffset(msg) +// case *List_Distinct: +// return ConvertMessageListDistinctToCommandListDistinct(msg) +// case *List_Values: +// return ConvertMessageListValuesToCommandListValues(msg) +// } +// return nil +// } + +// // ConvertMessageSelectToCommandSelect converts a message.Command_Select to a command.Select. +// func ConvertMessageSelectToCommandSelect(msg *Command_Select) command.Select { +// return command.Select{ +// Filter: ConvertMessageExprToCommandExpr(msg.GetFilter()), +// Input: ConvertMessageListToCommandList(msg.GetInput()), +// } +// } + +// // ConvertMessageColToCommandCol converts a message.Column to a command.Column. +// func ConvertMessageColToCommandCol(msg *Column) command.Column { +// return command.Column{ +// Table: msg.GetTable(), +// Column: ConvertMessageExprToCommandExpr(msg.GetColumn()), +// Alias: msg.GetAlias(), +// } +// } + +// // ConvertMessageColsToCommandCols converts a []message.Column to a []command.Column. +// func ConvertMessageColsToCommandCols(msg []*Column) []command.Column { +// cmdCols := []command.Column{} +// for i := range msg { +// cmdCols = append(cmdCols, ConvertMessageColToCommandCol(msg[i])) +// } +// return cmdCols +// } + +// // ConvertMessageProjectToCommandProject converts a message.Command_Project to a command.Project. +// func ConvertMessageProjectToCommandProject(msg *Command_Project) command.Project { +// return command.Project{ +// Cols: ConvertMessageColsToCommandCols(msg.GetCols()), +// Input: ConvertMessageListToCommandList(msg.GetInput()), +// } +// } + +// // ConvertMessageDeleteToCommandDelete converts a message.Command_Delete to a command.Delete. +// func ConvertMessageDeleteToCommandDelete(msg *Command_Delete) command.Delete { +// return command.Delete{ +// Filter: ConvertMessageExprToCommandExpr(msg.GetFilter()), +// Table: ConvertMessageTableToCommandTable(msg.GetTable()), +// } +// } + +// // ConvertMessageDropToCommandDropTable converts a message.CommandDrop to a command.Drop. +// func ConvertMessageDropToCommandDropTable(msg *CommandDrop) command.DropTable { +// return command.DropTable{ +// IfExists: msg.GetIfExists(), +// Schema: msg.GetSchema(), +// Name: msg.GetName(), +// } +// } + +// // ConvertMessageDropToCommandDropView converts a message.CommandDrop to a command.Drop. +// func ConvertMessageDropToCommandDropView(msg *CommandDrop) command.DropView { +// return command.DropView{ +// IfExists: msg.GetIfExists(), +// Schema: msg.GetSchema(), +// Name: msg.GetName(), +// } +// } + +// // ConvertMessageDropToCommandDropIndex converts a message.CommandDrop to a command.Drop. +// func ConvertMessageDropToCommandDropIndex(msg *CommandDrop) command.DropIndex { +// return command.DropIndex{ +// IfExists: msg.GetIfExists(), +// Schema: msg.GetSchema(), +// Name: msg.GetName(), +// } +// } + +// // ConvertMessageDropToCommandDropTrigger converts a message.CommandDrop to a command.Drop. +// func ConvertMessageDropToCommandDropTrigger(msg *CommandDrop) command.DropTrigger { +// return command.DropTrigger{ +// IfExists: msg.GetIfExists(), +// Schema: msg.GetSchema(), +// Name: msg.GetName(), +// } +// } + +// // ConvertMessageUpdateOrToCommandUpdateOr converts a message.UpdateOr to command.UpdateOr. +// func ConvertMessageUpdateOrToCommandUpdateOr(msg UpdateOr) command.UpdateOr { +// return command.UpdateOr(msg.Number()) +// } + +// // ConvertMessageUpdateSetterLiteralExprToCommandUpdateSetterLiteralExpr converts +// // a message.LiteralExpr to command.Expr. +// func ConvertMessageUpdateSetterLiteralExprToCommandUpdateSetterLiteralExpr( +// msg *LiteralExpr, +// ) command.Expr { +// return command.LiteralExpr{ +// Value: msg.Value, +// } +// } + +// // ConvertMessageUpdateSetterConstantExprToCommandUpdateSetterConstantExpr converts +// // a message.ConstantBooleanExpr to a command.Expr. +// func ConvertMessageUpdateSetterConstantExprToCommandUpdateSetterConstantExpr( +// msg *ConstantBooleanExpr, +// ) command.Expr { +// return command.ConstantBooleanExpr{ +// Value: msg.Value, +// } +// } + +// // ConvertMessageUpdateSetterUnaryExprToCommandUpdateSetterUnaryExpr converts +// // a message.UnaryExpr to command.Expr. +// func ConvertMessageUpdateSetterUnaryExprToCommandUpdateSetterUnaryExpr( +// msg *UnaryExpr, +// ) command.Expr { +// return command.UnaryExpr{ +// Operator: msg.Operator, +// Value: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Value), +// } +// } + +// // ConvertMessageUpdateSetterBinaryExprToCommandUpdateSetterBinaryExpr converts +// // a message.BinaryExpr to command.Expr. +// func ConvertMessageUpdateSetterBinaryExprToCommandUpdateSetterBinaryExpr( +// msg *BinaryExpr, +// ) command.Expr { +// return command.BinaryExpr{ +// Operator: msg.Operator, +// Left: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Left), +// Right: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Right), +// } +// } + +// // ConvertMessageUpdateSetterFuncExprToCommandUpdateSetterFuncExpr converts +// // a message.FunctionExpr tp command.Expr. +// func ConvertMessageUpdateSetterFuncExprToCommandUpdateSetterFuncExpr( +// msg *FunctionExpr, +// ) command.Expr { +// return command.FunctionExpr{ +// Name: msg.Name, +// Distinct: msg.Distinct, +// Args: ConvertMessageExprSliceToCommandExprSlice(msg.Args), +// } +// } + +// // ConvertMessageUpdateEqualityExprToCommandUpdateSetterEqualityExpr converts +// // a message.EqualityExpr to a command.Expr. +// func ConvertMessageUpdateEqualityExprToCommandUpdateSetterEqualityExpr( +// msg *EqualityExpr, +// ) command.Expr { +// return command.EqualityExpr{ +// Left: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Left), +// Right: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Right), +// Invert: msg.Invert, +// } +// } + +// // ConvertMessageUpdateSetterRangeExprToCommandUpdateSetterRangeExpr converts +// // a message.RangeExpr to a command.Expr. +// func ConvertMessageUpdateSetterRangeExprToCommandUpdateSetterRangeExpr( +// msg *RangeExpr, +// ) command.Expr { +// return command.RangeExpr{ +// Needle: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Needle), +// Lo: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Lo), +// Hi: ConvertMessageBinaryExprToCommandBinaryExpr(msg.Hi), +// Invert: msg.Invert, +// } +// } + +// // ConvertMessageUpdateSetterToCommandUpdateSetter converts +// // a message.UpdateSetter to a command.UpdateSetter. +// func ConvertMessageUpdateSetterToCommandUpdateSetter(msg *UpdateSetter) command.UpdateSetter { +// cmdUpdateSetter := command.UpdateSetter{} +// cmdUpdateSetter.Cols = msg.Cols +// switch msg.Value.(type) { +// case *UpdateSetter_Literal: +// cmdUpdateSetter.Value = ConvertMessageUpdateSetterLiteralExprToCommandUpdateSetterLiteralExpr(msg.GetLiteral()) +// case *UpdateSetter_Constant: +// cmdUpdateSetter.Value = ConvertMessageUpdateSetterConstantExprToCommandUpdateSetterConstantExpr(msg.GetConstant()) +// case *UpdateSetter_Unary: +// cmdUpdateSetter.Value = ConvertMessageUpdateSetterUnaryExprToCommandUpdateSetterUnaryExpr(msg.GetUnary()) +// case *UpdateSetter_Binary: +// cmdUpdateSetter.Value = ConvertMessageUpdateSetterBinaryExprToCommandUpdateSetterBinaryExpr(msg.GetBinary()) +// case *UpdateSetter_Func: +// cmdUpdateSetter.Value = ConvertMessageUpdateSetterFuncExprToCommandUpdateSetterFuncExpr(msg.GetFunc()) +// case *UpdateSetter_Equality: +// cmdUpdateSetter.Value = ConvertMessageUpdateEqualityExprToCommandUpdateSetterEqualityExpr(msg.GetEquality()) +// case *UpdateSetter_Range: +// cmdUpdateSetter.Value = ConvertMessageUpdateSetterRangeExprToCommandUpdateSetterRangeExpr(msg.GetRange()) +// } +// return cmdUpdateSetter +// } + +// // ConvertMessageUpdateSetterSliceToCommandUpdateSetterSlice converts +// // a []message.UpdateSetter to a []command.UpdateSetter. +// func ConvertMessageUpdateSetterSliceToCommandUpdateSetterSlice( +// msg []*UpdateSetter, +// ) []command.UpdateSetter { +// cmdUpdateSetterSlice := []command.UpdateSetter{} +// for i := range msg { +// cmdUpdateSetterSlice = append(cmdUpdateSetterSlice, ConvertMessageUpdateSetterToCommandUpdateSetter(msg[i])) +// } +// return cmdUpdateSetterSlice +// } + +// // ConvertMessageUpdateToCommandUpdate converts a message.Command_Update to a command.Update. +// func ConvertMessageUpdateToCommandUpdate(msg *Command_Update) command.Update { +// return command.Update{ +// UpdateOr: ConvertMessageUpdateOrToCommandUpdateOr(msg.GetUpdateOr()), +// Updates: ConvertMessageUpdateSetterSliceToCommandUpdateSetterSlice(msg.GetUpdates()), +// Table: ConvertMessageTableToCommandTable(msg.GetTable()), +// Filter: ConvertMessageExprToCommandExpr(msg.GetFilter()), +// } +// } + +// // ConvertMessageJoinTypeToCommandJoinType converts a message.JoinType to a command.JoinType. +// func ConvertMessageJoinTypeToCommandJoinType(msg JoinType) command.JoinType { +// return command.JoinType(msg.Number()) +// } + +// // ConvertMessageJoinToCommandJoin converts a message.Command_Join to a command.Join. +// func ConvertMessageJoinToCommandJoin(msg *Command_Join) command.Join { +// return command.Join{ +// Natural: msg.Natural, +// Type: ConvertMessageJoinTypeToCommandJoinType(msg.GetType()), +// Filter: ConvertMessageExprToCommandExpr(msg.GetFilter()), +// Left: ConvertMessageListToCommandList(msg.GetLeft()), +// Right: ConvertMessageListToCommandList(msg.GetRight()), +// } +// } + +// // ConvertMessageLimitToCommandLimit converts a message.Command_Limit to a command.Limit. +// func ConvertMessageLimitToCommandLimit(msg *Command_Limit) command.Limit { +// return command.Limit{ +// Limit: ConvertMessageExprToCommandExpr(msg.GetLimit()), +// Input: ConvertMessageListToCommandList(msg.GetInput()), +// } +// } + +// // ConvertMessageInsertOrToCommandInsertOr converts a message.InsertOr to command.InsertOr. +// func ConvertMessageInsertOrToCommandInsertOr(msg InsertOr) command.InsertOr { +// return command.InsertOr(msg.Number()) +// } + +// // ConvertMessageInsertToCommandInsert converts a message.Command_Insert to a command.Insert +// func ConvertMessageInsertToCommandInsert(msg *Command_Insert) command.Insert { +// return command.Insert{ +// InsertOr: ConvertMessageInsertOrToCommandInsertOr(msg.GetInsertOr()), +// Table: ConvertMessageTableToCommandTable(msg.GetTable()), +// Cols: ConvertMessageColsToCommandCols(msg.GetCols()), +// DefaultValues: msg.GetDefaultValues(), +// Input: ConvertMessageListToCommandList(msg.GetInput()), +// } +// } diff --git a/internal/raft/message/convert_test.go b/internal/raft/message/convert_test.go new file mode 100644 index 00000000..24315486 --- /dev/null +++ b/internal/raft/message/convert_test.go @@ -0,0 +1,1180 @@ +package message + +// import ( +// "reflect" +// "testing" + +// "github.com/xqueries/xdb/internal/compiler/command" +// ) + +// var commandToMessageTests = []struct { +// in command.Command +// out Message +// }{ +// { +// // SCAN +// command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// { +// // SELECT +// command.Select{ +// Filter: command.LiteralExpr{ +// Value: "literal", +// }, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// &Command_Select{ +// Filter: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// }, +// { +// // PROJECT +// command.Project{ +// Cols: []command.Column{ +// { +// Table: "myTable1", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias2", +// }, +// }, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// &Command_Project{ +// Cols: []*Column{ +// { +// Table: "myTable1", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias2", +// }, +// }, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// }, +// { +// // DELETE +// command.Delete{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Filter: command.BinaryExpr{ +// Operator: "operator", +// Left: command.LiteralExpr{ +// Value: "leftLiteral", +// }, +// Right: command.LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// &Command_Delete{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Filter: &Expr{ +// Expr: &Expr_Binary{ +// Binary: &BinaryExpr{ +// Operator: "operator", +// Left: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "leftLiteral", +// }, +// }, +// }, +// Right: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// { +// // DROP TABLE +// &command.DropTable{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// &CommandDrop{ +// Target: 0, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // DROP VIEW +// &command.DropView{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// &CommandDrop{ +// Target: 1, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // DROP INDEX +// &command.DropIndex{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// &CommandDrop{ +// Target: 2, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // DROP TRIGGER +// &command.DropTrigger{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// &CommandDrop{ +// Target: 3, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // UPDATE +// command.Update{ +// UpdateOr: 0, +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Updates: []command.UpdateSetter{ +// { +// Cols: []string{ +// "col1", +// "col2", +// }, +// Value: command.ConstantBooleanExpr{ +// Value: true, +// }, +// }, +// }, +// Filter: command.EqualityExpr{ +// Left: command.LiteralExpr{ +// Value: "leftLiteral", +// }, +// Right: command.LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// &Command_Update{ +// UpdateOr: 0, +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Updates: []*UpdateSetter{ +// { +// Cols: []string{ +// "col1", +// "col2", +// }, +// Value: &UpdateSetter_Constant{ +// Constant: &ConstantBooleanExpr{ +// Value: true, +// }, +// }, +// }, +// }, +// Filter: &Expr{ +// Expr: &Expr_Equality{ +// Equality: &EqualityExpr{ +// Left: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "leftLiteral", +// }, +// }, +// }, +// Right: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// { +// // JOIN +// command.Join{ +// Natural: true, +// Type: 0, +// Filter: command.FunctionExpr{ +// Name: "function", +// Distinct: true, +// Args: []command.Expr{ +// command.RangeExpr{ +// Needle: command.LiteralExpr{ +// Value: "literal", +// }, +// Lo: command.LiteralExpr{ +// Value: "literal", +// }, +// Hi: command.LiteralExpr{ +// Value: "literal", +// }, +// Invert: false, +// }, +// command.UnaryExpr{ +// Operator: "operator", +// Value: command.LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// }, +// Left: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// Right: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// &Command_Join{ +// Natural: true, +// Type: 0, +// Filter: &Expr{ +// Expr: &Expr_Func{ +// Func: &FunctionExpr{ +// Name: "function", +// Distinct: true, +// Args: []*Expr{ +// { +// Expr: &Expr_Range{ +// &RangeExpr{ +// Needle: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Lo: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Hi: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Invert: false, +// }, +// }, +// }, +// { +// Expr: &Expr_Unary{ +// Unary: &UnaryExpr{ +// Operator: "operator", +// Value: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// Left: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// Right: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// }, +// { +// // LIMIT +// command.Limit{ +// Limit: command.LiteralExpr{ +// Value: "literal", +// }, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// &Command_Limit{ +// Limit: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// }, +// { +// // INSERT +// command.Insert{ +// InsertOr: 0, +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Cols: []command.Column{ +// { +// Table: "myTable1", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias2", +// }, +// }, +// DefaultValues: false, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// &Command_Insert{ +// InsertOr: 0, +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Cols: []*Column{ +// { +// Table: "myTable1", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias2", +// }, +// }, +// DefaultValues: false, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// }, +// } + +// func TestConvertCommandToMessage(t *testing.T) { +// t.SkipNow() +// for _, tt := range commandToMessageTests { +// t.Run(tt.in.String(), func(t *testing.T) { +// msg, _ := ConvertCommandToMessage(tt.in) +// if !reflect.DeepEqual(msg, tt.out) { +// t.Errorf("got %q, want %q", msg, tt.out) +// } +// }) +// } +// } + +// var messageToCommandTests = []struct { +// in Message +// out command.Command +// }{ +// { +// // SCAN +// &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// { +// // SELECT +// &Command_Select{ +// Filter: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// command.Select{ +// Filter: command.LiteralExpr{ +// Value: "literal", +// }, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// { +// // PROJECT +// &Command_Project{ +// Cols: []*Column{ +// { +// Table: "myTable1", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias2", +// }, +// }, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// command.Project{ +// Cols: []command.Column{ +// { +// Table: "myTable1", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias2", +// }, +// }, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// { +// // DELETE +// &Command_Delete{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Filter: &Expr{ +// Expr: &Expr_Binary{ +// Binary: &BinaryExpr{ +// Operator: "operator", +// Left: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "leftLiteral", +// }, +// }, +// }, +// Right: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// command.Delete{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Filter: command.BinaryExpr{ +// Operator: "operator", +// Left: command.LiteralExpr{ +// Value: "leftLiteral", +// }, +// Right: command.LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// }, +// { +// // DROP TABLE +// &CommandDrop{ +// Target: 0, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// command.DropTable{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // DROP VIEW +// &CommandDrop{ +// Target: 1, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// command.DropView{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // DROP INDEX +// &CommandDrop{ +// Target: 2, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// command.DropIndex{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // DROP TRIGGER +// &CommandDrop{ +// Target: 3, +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// command.DropTrigger{ +// IfExists: true, +// Schema: "mySchema", +// Name: "tableName", +// }, +// }, +// { +// // UPDATE +// &Command_Update{ +// UpdateOr: 0, +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Updates: []*UpdateSetter{ +// { +// Cols: []string{ +// "col1", +// "col2", +// }, +// Value: &UpdateSetter_Constant{ +// Constant: &ConstantBooleanExpr{ +// Value: true, +// }, +// }, +// }, +// }, +// Filter: &Expr{ +// Expr: &Expr_Equality{ +// Equality: &EqualityExpr{ +// Left: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "leftLiteral", +// }, +// }, +// }, +// Right: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// command.Update{ +// UpdateOr: 0, +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Updates: []command.UpdateSetter{ +// { +// Cols: []string{ +// "col1", +// "col2", +// }, +// Value: command.ConstantBooleanExpr{ +// Value: true, +// }, +// }, +// }, +// Filter: command.EqualityExpr{ +// Left: command.LiteralExpr{ +// Value: "leftLiteral", +// }, +// Right: command.LiteralExpr{ +// Value: "rightLiteral", +// }, +// }, +// }, +// }, +// { +// // JOIN +// &Command_Join{ +// Natural: true, +// Type: 0, +// Filter: &Expr{ +// Expr: &Expr_Func{ +// Func: &FunctionExpr{ +// Name: "function", +// Distinct: true, +// Args: []*Expr{ +// { +// Expr: &Expr_Range{ +// &RangeExpr{ +// Needle: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Lo: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Hi: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Invert: false, +// }, +// }, +// }, +// { +// Expr: &Expr_Unary{ +// Unary: &UnaryExpr{ +// Operator: "operator", +// Value: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// }, +// Left: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// Right: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// command.Join{ +// Natural: true, +// Type: 0, +// Filter: command.FunctionExpr{ +// Name: "function", +// Distinct: true, +// Args: []command.Expr{ +// command.RangeExpr{ +// Needle: command.LiteralExpr{ +// Value: "literal", +// }, +// Lo: command.LiteralExpr{ +// Value: "literal", +// }, +// Hi: command.LiteralExpr{ +// Value: "literal", +// }, +// Invert: false, +// }, +// command.UnaryExpr{ +// Operator: "operator", +// Value: command.LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// }, +// Left: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// Right: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// { +// // LIMIT +// &Command_Limit{ +// Limit: &Expr{ +// Expr: &Expr_Literal{ +// Literal: &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// command.Limit{ +// Limit: command.LiteralExpr{ +// Value: "literal", +// }, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// { +// // INSERT +// &Command_Insert{ +// InsertOr: 0, +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Cols: []*Column{ +// { +// Table: "myTable1", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: &Expr{ +// Expr: &Expr_Literal{ +// &LiteralExpr{ +// Value: "literal", +// }, +// }, +// }, +// Alias: "myAlias2", +// }, +// }, +// DefaultValues: false, +// Input: &List{ +// List: &List_Scan{ +// Scan: &Command_Scan{ +// Table: &SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// }, +// command.Insert{ +// InsertOr: 0, +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// Cols: []command.Column{ +// { +// Table: "myTable1", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias1", +// }, +// { +// Table: "myTable2", +// Column: command.LiteralExpr{ +// Value: "literal", +// }, +// Alias: "myAlias2", +// }, +// }, +// DefaultValues: false, +// Input: command.Scan{ +// Table: &command.SimpleTable{ +// Schema: "mySchema", +// Table: "myTable", +// Alias: "myAlias", +// Indexed: true, +// Index: "myIndex", +// }, +// }, +// }, +// }, +// } + +// func TestConvertMessageToCommand(t *testing.T) { +// t.SkipNow() +// for _, tt := range messageToCommandTests { +// t.Run(tt.in.Kind().String(), func(t *testing.T) { +// msg := ConvertMessageToCommand(tt.in) +// if !reflect.DeepEqual(msg, tt.out) { +// t.Errorf("got %q, want %q", msg, tt.out) +// } +// }) +// } +// } diff --git a/internal/raft/message/doc.go b/internal/raft/message/doc.go new file mode 100644 index 00000000..b737b75b --- /dev/null +++ b/internal/raft/message/doc.go @@ -0,0 +1,22 @@ +// Package message implements messages used in the raft module for +// communication. Create a message by calling constructor functions. An example +// follows +// +// // need to create a request-vote-message and send it +// msg := message.NewRequestVoteRequest(term, candidate.ID(), lastLogIndex, lastLogTerm) // create the message +// data, err := message.Marshal(msg) // marshal it +// // handle err +// conn.Send(data) // sent it through the network +// +// When receiving data however, follow this example. In here, we will receive +// bytes, unmarshal them as a message, and then process the message. +// +// data := conn.Receive() +// msg, err := message.Unmarshal(data) +// switch msg.Kind() { +// case message.KindRequestVoteResponse: +// // process a request-vote-response +// default: +// panic("cannot handle the message") +// } +package message diff --git a/internal/raft/message/error.go b/internal/raft/message/error.go new file mode 100644 index 00000000..9ef506fa --- /dev/null +++ b/internal/raft/message/error.go @@ -0,0 +1,17 @@ +package message + +// Error is a helper type that allows constant errors. +type Error string + +func (e Error) Error() string { return string(e) } + +const ( + // ErrUnknownKind indicates that the kind of the message is not known to + // this implementation. + ErrUnknownKind Error = "unknown message kind" + // ErrUnknownCommandKind indicates that the kind of command is not known + // to this implemenatation. + ErrUnknownCommandKind Error = "unknown command kind" + // ErrNilCommand indicates that the command variable found is nil. + ErrNilCommand Error = "nil command found" +) diff --git a/internal/raft/message/follower_location_list.go b/internal/raft/message/follower_location_list.go new file mode 100644 index 00000000..e2333984 --- /dev/null +++ b/internal/raft/message/follower_location_list.go @@ -0,0 +1,30 @@ +package message + +//go:generate protoc --go_out=. follower_location_list.proto + +var _ Message = (*FollowerLocationListRequest)(nil) +var _ Message = (*FollowerLocationListResponse)(nil) + +// NewFollowerLocationListRequest creates a new follower-location-list-request +// message with the given parameters. +func NewFollowerLocationListRequest() *FollowerLocationListRequest { + return &FollowerLocationListRequest{} +} + +// Kind returns KindFollowerLocationListRequest. +func (*FollowerLocationListRequest) Kind() Kind { + return KindFollowerLocationListRequest +} + +// NewFollowerLocationListResponse creates a new follower-location-list-response +// message with the given parameters. +func NewFollowerLocationListResponse(followerLocations []string) *FollowerLocationListResponse { + return &FollowerLocationListResponse{ + FollowerAddress: followerLocations, + } +} + +// Kind returns KindFollowerLocationListResponse. +func (*FollowerLocationListResponse) Kind() Kind { + return KindFollowerLocationListResponse +} diff --git a/internal/raft/message/follower_location_list.pb.go b/internal/raft/message/follower_location_list.pb.go new file mode 100644 index 00000000..88264c2d --- /dev/null +++ b/internal/raft/message/follower_location_list.pb.go @@ -0,0 +1,205 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.11.4 +// source: follower_location_list.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type FollowerLocationListRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *FollowerLocationListRequest) Reset() { + *x = FollowerLocationListRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_follower_location_list_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FollowerLocationListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FollowerLocationListRequest) ProtoMessage() {} + +func (x *FollowerLocationListRequest) ProtoReflect() protoreflect.Message { + mi := &file_follower_location_list_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FollowerLocationListRequest.ProtoReflect.Descriptor instead. +func (*FollowerLocationListRequest) Descriptor() ([]byte, []int) { + return file_follower_location_list_proto_rawDescGZIP(), []int{0} +} + +type FollowerLocationListResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FollowerAddress []string `protobuf:"bytes,1,rep,name=followerAddress,proto3" json:"followerAddress,omitempty"` +} + +func (x *FollowerLocationListResponse) Reset() { + *x = FollowerLocationListResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_follower_location_list_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FollowerLocationListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FollowerLocationListResponse) ProtoMessage() {} + +func (x *FollowerLocationListResponse) ProtoReflect() protoreflect.Message { + mi := &file_follower_location_list_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FollowerLocationListResponse.ProtoReflect.Descriptor instead. +func (*FollowerLocationListResponse) Descriptor() ([]byte, []int) { + return file_follower_location_list_proto_rawDescGZIP(), []int{1} +} + +func (x *FollowerLocationListResponse) GetFollowerAddress() []string { + if x != nil { + return x.FollowerAddress + } + return nil +} + +var File_follower_location_list_proto protoreflect.FileDescriptor + +var file_follower_location_list_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x1d, 0x0a, 0x1b, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, + 0x77, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x48, 0x0a, 0x1c, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x0f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, + 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0f, 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_follower_location_list_proto_rawDescOnce sync.Once + file_follower_location_list_proto_rawDescData = file_follower_location_list_proto_rawDesc +) + +func file_follower_location_list_proto_rawDescGZIP() []byte { + file_follower_location_list_proto_rawDescOnce.Do(func() { + file_follower_location_list_proto_rawDescData = protoimpl.X.CompressGZIP(file_follower_location_list_proto_rawDescData) + }) + return file_follower_location_list_proto_rawDescData +} + +var file_follower_location_list_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_follower_location_list_proto_goTypes = []interface{}{ + (*FollowerLocationListRequest)(nil), // 0: message.FollowerLocationListRequest + (*FollowerLocationListResponse)(nil), // 1: message.FollowerLocationListResponse +} +var file_follower_location_list_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_follower_location_list_proto_init() } +func file_follower_location_list_proto_init() { + if File_follower_location_list_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_follower_location_list_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FollowerLocationListRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_follower_location_list_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FollowerLocationListResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_follower_location_list_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_follower_location_list_proto_goTypes, + DependencyIndexes: file_follower_location_list_proto_depIdxs, + MessageInfos: file_follower_location_list_proto_msgTypes, + }.Build() + File_follower_location_list_proto = out.File + file_follower_location_list_proto_rawDesc = nil + file_follower_location_list_proto_goTypes = nil + file_follower_location_list_proto_depIdxs = nil +} diff --git a/internal/raft/message/follower_location_list.proto b/internal/raft/message/follower_location_list.proto new file mode 100644 index 00000000..5a80bbf3 --- /dev/null +++ b/internal/raft/message/follower_location_list.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; + +message FollowerLocationListRequest { +} + +message FollowerLocationListResponse { + repeated string followerAddress = 1; +} \ No newline at end of file diff --git a/internal/raft/message/kind.go b/internal/raft/message/kind.go new file mode 100644 index 00000000..eaeabcde --- /dev/null +++ b/internal/raft/message/kind.go @@ -0,0 +1,49 @@ +package message + +//go:generate stringer -type=Kind + +// Kind describes a kind of a message, that is used by the raft module. +type Kind uint32 + +// Available kinds +const ( + // KindUnknown must not be used. It is the default value for Kind. If this + // value occurs, something was not initialized properly. + KindUnknown Kind = iota + // KindTestMessage must not be used. It is used for tests only. + KindTestMessage + + KindAppendEntriesRequest + KindAppendEntriesResponse + + KindFollowerLocationListRequest + KindFollowerLocationListResponse + + KindLeaderLocationRequest + KindLeaderLocationResponse + + KindRequestVoteRequest + KindRequestVoteResponse + + KindLogAppendRequest + + KindCommand + KindCommandScan + KindCommandSelect + KindCommandProject + KindCommandDelete + KindCommandDrop + KindCommandUpdate + KindCommandJoin + KindCommandLimit + KindCommandInsert + + KindExpr + KindLiteralExpr + KindConstantBooleanExpr + KindUnaryExpr + KindBinaryExpr + KindFunctionExpr + KindEqualityExpr + KindRangeExpr +) diff --git a/internal/raft/message/kind_string.go b/internal/raft/message/kind_string.go new file mode 100644 index 00000000..0ad01c1a --- /dev/null +++ b/internal/raft/message/kind_string.go @@ -0,0 +1,51 @@ +// Code generated by "stringer -type=Kind"; DO NOT EDIT. + +package message + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[KindUnknown-0] + _ = x[KindTestMessage-1] + _ = x[KindAppendEntriesRequest-2] + _ = x[KindAppendEntriesResponse-3] + _ = x[KindFollowerLocationListRequest-4] + _ = x[KindFollowerLocationListResponse-5] + _ = x[KindLeaderLocationRequest-6] + _ = x[KindLeaderLocationResponse-7] + _ = x[KindRequestVoteRequest-8] + _ = x[KindRequestVoteResponse-9] + _ = x[KindLogAppendRequest-10] + _ = x[KindCommand-11] + _ = x[KindCommandScan-12] + _ = x[KindCommandSelect-13] + _ = x[KindCommandProject-14] + _ = x[KindCommandDelete-15] + _ = x[KindCommandDrop-16] + _ = x[KindCommandUpdate-17] + _ = x[KindCommandJoin-18] + _ = x[KindCommandLimit-19] + _ = x[KindCommandInsert-20] + _ = x[KindExpr-21] + _ = x[KindLiteralExpr-22] + _ = x[KindConstantBooleanExpr-23] + _ = x[KindUnaryExpr-24] + _ = x[KindBinaryExpr-25] + _ = x[KindFunctionExpr-26] + _ = x[KindEqualityExpr-27] + _ = x[KindRangeExpr-28] +} + +const _Kind_name = "KindUnknownKindTestMessageKindAppendEntriesRequestKindAppendEntriesResponseKindFollowerLocationListRequestKindFollowerLocationListResponseKindLeaderLocationRequestKindLeaderLocationResponseKindRequestVoteRequestKindRequestVoteResponseKindLogAppendRequestKindCommandKindCommandScanKindCommandSelectKindCommandProjectKindCommandDeleteKindCommandDropKindCommandUpdateKindCommandJoinKindCommandLimitKindCommandInsertKindExprKindLiteralExprKindConstantBooleanExprKindUnaryExprKindBinaryExprKindFunctionExprKindEqualityExprKindRangeExpr" + +var _Kind_index = [...]uint16{0, 11, 26, 50, 75, 106, 138, 163, 189, 211, 234, 254, 265, 280, 297, 315, 332, 347, 364, 379, 395, 412, 420, 435, 458, 471, 485, 501, 517, 530} + +func (i Kind) String() string { + if i >= Kind(len(_Kind_index)-1) { + return "Kind(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _Kind_name[_Kind_index[i]:_Kind_index[i+1]] +} diff --git a/internal/raft/message/leader_location.go b/internal/raft/message/leader_location.go new file mode 100644 index 00000000..4ad31887 --- /dev/null +++ b/internal/raft/message/leader_location.go @@ -0,0 +1,30 @@ +package message + +//go:generate protoc --go_out=. leader_location.proto + +var _ Message = (*LeaderLocationRequest)(nil) +var _ Message = (*LeaderLocationResponse)(nil) + +// NewLeaderLocationRequest creates a new leader-location-request message with +// the given parameters. +func NewLeaderLocationRequest() *LeaderLocationRequest { + return &LeaderLocationRequest{} +} + +// Kind returns KindLeaderLocationRequest. +func (*LeaderLocationRequest) Kind() Kind { + return KindLeaderLocationRequest +} + +// NewLeaderLocationResponse creates a new leader-location-response message with +// the given parameters. +func NewLeaderLocationResponse(leaderAddress string) *LeaderLocationResponse { + return &LeaderLocationResponse{ + LeaderAddress: leaderAddress, + } +} + +// Kind returns KindLeaderLocationResponse. +func (*LeaderLocationResponse) Kind() Kind { + return KindLeaderLocationResponse +} diff --git a/internal/raft/message/leader_location.pb.go b/internal/raft/message/leader_location.pb.go new file mode 100644 index 00000000..452e0fed --- /dev/null +++ b/internal/raft/message/leader_location.pb.go @@ -0,0 +1,203 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.11.4 +// source: leader_location.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type LeaderLocationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *LeaderLocationRequest) Reset() { + *x = LeaderLocationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_leader_location_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LeaderLocationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LeaderLocationRequest) ProtoMessage() {} + +func (x *LeaderLocationRequest) ProtoReflect() protoreflect.Message { + mi := &file_leader_location_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LeaderLocationRequest.ProtoReflect.Descriptor instead. +func (*LeaderLocationRequest) Descriptor() ([]byte, []int) { + return file_leader_location_proto_rawDescGZIP(), []int{0} +} + +type LeaderLocationResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + LeaderAddress string `protobuf:"bytes,1,opt,name=leaderAddress,proto3" json:"leaderAddress,omitempty"` +} + +func (x *LeaderLocationResponse) Reset() { + *x = LeaderLocationResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_leader_location_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LeaderLocationResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LeaderLocationResponse) ProtoMessage() {} + +func (x *LeaderLocationResponse) ProtoReflect() protoreflect.Message { + mi := &file_leader_location_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LeaderLocationResponse.ProtoReflect.Descriptor instead. +func (*LeaderLocationResponse) Descriptor() ([]byte, []int) { + return file_leader_location_proto_rawDescGZIP(), []int{1} +} + +func (x *LeaderLocationResponse) GetLeaderAddress() string { + if x != nil { + return x.LeaderAddress + } + return "" +} + +var File_leader_location_proto protoreflect.FileDescriptor + +var file_leader_location_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x3e, 0x0a, 0x16, 0x4c, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x65, 0x61, 0x64, 0x65, 0x72, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6c, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x3b, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_leader_location_proto_rawDescOnce sync.Once + file_leader_location_proto_rawDescData = file_leader_location_proto_rawDesc +) + +func file_leader_location_proto_rawDescGZIP() []byte { + file_leader_location_proto_rawDescOnce.Do(func() { + file_leader_location_proto_rawDescData = protoimpl.X.CompressGZIP(file_leader_location_proto_rawDescData) + }) + return file_leader_location_proto_rawDescData +} + +var file_leader_location_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_leader_location_proto_goTypes = []interface{}{ + (*LeaderLocationRequest)(nil), // 0: message.LeaderLocationRequest + (*LeaderLocationResponse)(nil), // 1: message.LeaderLocationResponse +} +var file_leader_location_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_leader_location_proto_init() } +func file_leader_location_proto_init() { + if File_leader_location_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_leader_location_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LeaderLocationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_leader_location_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LeaderLocationResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_leader_location_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_leader_location_proto_goTypes, + DependencyIndexes: file_leader_location_proto_depIdxs, + MessageInfos: file_leader_location_proto_msgTypes, + }.Build() + File_leader_location_proto = out.File + file_leader_location_proto_rawDesc = nil + file_leader_location_proto_goTypes = nil + file_leader_location_proto_depIdxs = nil +} diff --git a/internal/raft/message/leader_location.proto b/internal/raft/message/leader_location.proto new file mode 100644 index 00000000..0cb11f3b --- /dev/null +++ b/internal/raft/message/leader_location.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; + +message LeaderLocationRequest { +} + +message LeaderLocationResponse { + string leaderAddress = 1; +} \ No newline at end of file diff --git a/internal/raft/message/log_append_request.go b/internal/raft/message/log_append_request.go new file mode 100644 index 00000000..5fec7f5f --- /dev/null +++ b/internal/raft/message/log_append_request.go @@ -0,0 +1,18 @@ +package message + +//go:generate protoc --go_out=. append_entries.proto + +var _ Message = (*AppendEntriesRequest)(nil) + +// NewLogAppendRequest creates a new append-entries-request message with the +// given parameters. +func NewLogAppendRequest(data *Command) *LogAppendRequest { + return &LogAppendRequest{ + Data: data, + } +} + +// Kind returns KindAppendEntriesResponse. +func (*LogAppendRequest) Kind() Kind { + return KindAppendEntriesResponse +} diff --git a/internal/raft/message/log_append_request.pb.go b/internal/raft/message/log_append_request.pb.go new file mode 100644 index 00000000..6ba4efee --- /dev/null +++ b/internal/raft/message/log_append_request.pb.go @@ -0,0 +1,155 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.11.4 +// source: log_append_request.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type LogAppendRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data *Command `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *LogAppendRequest) Reset() { + *x = LogAppendRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_log_append_request_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *LogAppendRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*LogAppendRequest) ProtoMessage() {} + +func (x *LogAppendRequest) ProtoReflect() protoreflect.Message { + mi := &file_log_append_request_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use LogAppendRequest.ProtoReflect.Descriptor instead. +func (*LogAppendRequest) Descriptor() ([]byte, []int) { + return file_log_append_request_proto_rawDescGZIP(), []int{0} +} + +func (x *LogAppendRequest) GetData() *Command { + if x != nil { + return x.Data + } + return nil +} + +var File_log_append_request_proto protoreflect.FileDescriptor + +var file_log_append_request_proto_rawDesc = []byte{ + 0x0a, 0x18, 0x6c, 0x6f, 0x67, 0x5f, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x38, 0x0a, 0x10, 0x4c, 0x6f, 0x67, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x0b, 0x5a, 0x09, + 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, +} + +var ( + file_log_append_request_proto_rawDescOnce sync.Once + file_log_append_request_proto_rawDescData = file_log_append_request_proto_rawDesc +) + +func file_log_append_request_proto_rawDescGZIP() []byte { + file_log_append_request_proto_rawDescOnce.Do(func() { + file_log_append_request_proto_rawDescData = protoimpl.X.CompressGZIP(file_log_append_request_proto_rawDescData) + }) + return file_log_append_request_proto_rawDescData +} + +var file_log_append_request_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_log_append_request_proto_goTypes = []interface{}{ + (*LogAppendRequest)(nil), // 0: message.LogAppendRequest + (*Command)(nil), // 1: message.Command +} +var file_log_append_request_proto_depIdxs = []int32{ + 1, // 0: message.LogAppendRequest.data:type_name -> message.Command + 1, // [1:1] is the sub-list for method output_type + 1, // [1:1] is the sub-list for method input_type + 1, // [1:1] is the sub-list for extension type_name + 1, // [1:1] is the sub-list for extension extendee + 0, // [0:1] is the sub-list for field type_name +} + +func init() { file_log_append_request_proto_init() } +func file_log_append_request_proto_init() { + if File_log_append_request_proto != nil { + return + } + file_command_proto_init() + if !protoimpl.UnsafeEnabled { + file_log_append_request_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*LogAppendRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_log_append_request_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_log_append_request_proto_goTypes, + DependencyIndexes: file_log_append_request_proto_depIdxs, + MessageInfos: file_log_append_request_proto_msgTypes, + }.Build() + File_log_append_request_proto = out.File + file_log_append_request_proto_rawDesc = nil + file_log_append_request_proto_goTypes = nil + file_log_append_request_proto_depIdxs = nil +} diff --git a/internal/raft/message/log_append_request.proto b/internal/raft/message/log_append_request.proto new file mode 100644 index 00000000..3ed0a136 --- /dev/null +++ b/internal/raft/message/log_append_request.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; +import "command.proto"; + +message LogAppendRequest { + Command data = 1; +} \ No newline at end of file diff --git a/internal/raft/message/message.go b/internal/raft/message/message.go new file mode 100644 index 00000000..a3be587e --- /dev/null +++ b/internal/raft/message/message.go @@ -0,0 +1,75 @@ +package message + +import ( + "bytes" + "encoding/binary" + "fmt" + + "google.golang.org/protobuf/proto" +) + +// Message describes a serializable, more or less self-describing protobuf +// message. A message consists of a kind (message.Kind) and an actual protobuf +// message. +type Message interface { + proto.Message + // Kind returns the kind of this message. If this returns + // message.KindUnknown, something went wrong, or the client and server + // versions are not matching. + Kind() Kind +} + +// Marshal converts the given message to a byte slice that can be unmarshalled +// with message.Unmarshal. The kind is encoded with 4 bytes big endian as uint32 +// and is the first 4 bytes of the serialized message. The rest of the message +// is the serialized protobuf message. +func Marshal(m Message) ([]byte, error) { + data, err := proto.Marshal(m) + if err != nil { + return nil, fmt.Errorf("proto marshal: %w", err) + } + + var buf bytes.Buffer + kind := make([]byte, 4) + binary.BigEndian.PutUint32(kind, uint32(m.Kind())) + buf.Write(kind) + buf.Write(data) + return buf.Bytes(), nil +} + +// Unmarshal converts bytes to a message. For using the returned message, check +// Message.Kind() and process a it accordingly. +func Unmarshal(data []byte) (Message, error) { + kindBytes := data[:4] // kind is uint32, which has 4 bytes + payload := data[4:] + + kind := Kind(binary.BigEndian.Uint32(kindBytes)) + var msg Message + switch kind { + case KindAppendEntriesRequest: + msg = &AppendEntriesRequest{} + case KindAppendEntriesResponse: + msg = &AppendEntriesResponse{} + case KindFollowerLocationListRequest: + msg = &FollowerLocationListRequest{} + case KindFollowerLocationListResponse: + msg = &FollowerLocationListResponse{} + case KindLeaderLocationRequest: + msg = &LeaderLocationRequest{} + case KindLeaderLocationResponse: + msg = &LeaderLocationResponse{} + case KindRequestVoteRequest: + msg = &RequestVoteRequest{} + case KindRequestVoteResponse: + msg = &RequestVoteResponse{} + case KindTestMessage: + msg = &TestMessage{} + default: + return nil, ErrUnknownKind + } + + if err := proto.Unmarshal(payload, msg); err != nil { + return nil, fmt.Errorf("unmarshal: %w", err) + } + return msg, nil +} diff --git a/internal/raft/message/request_vote.go b/internal/raft/message/request_vote.go new file mode 100644 index 00000000..2a249316 --- /dev/null +++ b/internal/raft/message/request_vote.go @@ -0,0 +1,38 @@ +package message + +import "github.com/xqueries/xdb/internal/id" + +//go:generate protoc --go_out=. request_vote.proto + +var _ Message = (*RequestVoteRequest)(nil) +var _ Message = (*RequestVoteResponse)(nil) + +// NewRequestVoteRequest creates a new request-vote-request message with the +// given parameters. +func NewRequestVoteRequest(term int32, candidateID id.ID, lastLogIndex int32, lastLogTerm int32) *RequestVoteRequest { + return &RequestVoteRequest{ + Term: term, + CandidateID: candidateID.Bytes(), + LastLogIndex: lastLogIndex, + LastLogTerm: lastLogTerm, + } +} + +// Kind returns KindRequestVoteRequest. +func (*RequestVoteRequest) Kind() Kind { + return KindRequestVoteRequest +} + +// NewRequestVoteResponse creates a new request-vote-response message with the +// given parameters. +func NewRequestVoteResponse(term int32, voteGranted bool) *RequestVoteResponse { + return &RequestVoteResponse{ + Term: term, + VoteGranted: voteGranted, + } +} + +// Kind returns KindRequestVoteResponse. +func (*RequestVoteResponse) Kind() Kind { + return KindRequestVoteResponse +} diff --git a/internal/raft/message/request_vote.pb.go b/internal/raft/message/request_vote.pb.go new file mode 100644 index 00000000..1ea44e62 --- /dev/null +++ b/internal/raft/message/request_vote.pb.go @@ -0,0 +1,253 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.11.4 +// source: request_vote.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type RequestVoteRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Term int32 `protobuf:"varint,1,opt,name=term,proto3" json:"term,omitempty"` + CandidateID []byte `protobuf:"bytes,2,opt,name=candidateID,proto3" json:"candidateID,omitempty"` + LastLogIndex int32 `protobuf:"varint,3,opt,name=lastLogIndex,proto3" json:"lastLogIndex,omitempty"` + LastLogTerm int32 `protobuf:"varint,4,opt,name=lastLogTerm,proto3" json:"lastLogTerm,omitempty"` +} + +func (x *RequestVoteRequest) Reset() { + *x = RequestVoteRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_request_vote_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestVoteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestVoteRequest) ProtoMessage() {} + +func (x *RequestVoteRequest) ProtoReflect() protoreflect.Message { + mi := &file_request_vote_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestVoteRequest.ProtoReflect.Descriptor instead. +func (*RequestVoteRequest) Descriptor() ([]byte, []int) { + return file_request_vote_proto_rawDescGZIP(), []int{0} +} + +func (x *RequestVoteRequest) GetTerm() int32 { + if x != nil { + return x.Term + } + return 0 +} + +func (x *RequestVoteRequest) GetCandidateID() []byte { + if x != nil { + return x.CandidateID + } + return nil +} + +func (x *RequestVoteRequest) GetLastLogIndex() int32 { + if x != nil { + return x.LastLogIndex + } + return 0 +} + +func (x *RequestVoteRequest) GetLastLogTerm() int32 { + if x != nil { + return x.LastLogTerm + } + return 0 +} + +type RequestVoteResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Term int32 `protobuf:"varint,1,opt,name=term,proto3" json:"term,omitempty"` + VoteGranted bool `protobuf:"varint,2,opt,name=voteGranted,proto3" json:"voteGranted,omitempty"` +} + +func (x *RequestVoteResponse) Reset() { + *x = RequestVoteResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_request_vote_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RequestVoteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestVoteResponse) ProtoMessage() {} + +func (x *RequestVoteResponse) ProtoReflect() protoreflect.Message { + mi := &file_request_vote_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestVoteResponse.ProtoReflect.Descriptor instead. +func (*RequestVoteResponse) Descriptor() ([]byte, []int) { + return file_request_vote_proto_rawDescGZIP(), []int{1} +} + +func (x *RequestVoteResponse) GetTerm() int32 { + if x != nil { + return x.Term + } + return 0 +} + +func (x *RequestVoteResponse) GetVoteGranted() bool { + if x != nil { + return x.VoteGranted + } + return false +} + +var File_request_vote_proto protoreflect.FileDescriptor + +var file_request_vote_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x76, 0x6f, 0x74, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x90, 0x01, + 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x61, 0x6e, 0x64, + 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x63, + 0x61, 0x6e, 0x64, 0x69, 0x64, 0x61, 0x74, 0x65, 0x49, 0x44, 0x12, 0x22, 0x0a, 0x0c, 0x6c, 0x61, + 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x20, + 0x0a, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x54, 0x65, 0x72, 0x6d, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0b, 0x6c, 0x61, 0x73, 0x74, 0x4c, 0x6f, 0x67, 0x54, 0x65, 0x72, 0x6d, + 0x22, 0x4b, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x6f, 0x74, 0x65, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x74, 0x65, 0x72, 0x6d, 0x12, 0x20, 0x0a, 0x0b, 0x76, + 0x6f, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0b, 0x76, 0x6f, 0x74, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x64, 0x42, 0x0b, 0x5a, + 0x09, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_request_vote_proto_rawDescOnce sync.Once + file_request_vote_proto_rawDescData = file_request_vote_proto_rawDesc +) + +func file_request_vote_proto_rawDescGZIP() []byte { + file_request_vote_proto_rawDescOnce.Do(func() { + file_request_vote_proto_rawDescData = protoimpl.X.CompressGZIP(file_request_vote_proto_rawDescData) + }) + return file_request_vote_proto_rawDescData +} + +var file_request_vote_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_request_vote_proto_goTypes = []interface{}{ + (*RequestVoteRequest)(nil), // 0: message.RequestVoteRequest + (*RequestVoteResponse)(nil), // 1: message.RequestVoteResponse +} +var file_request_vote_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_request_vote_proto_init() } +func file_request_vote_proto_init() { + if File_request_vote_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_request_vote_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestVoteRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_request_vote_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RequestVoteResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_request_vote_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_request_vote_proto_goTypes, + DependencyIndexes: file_request_vote_proto_depIdxs, + MessageInfos: file_request_vote_proto_msgTypes, + }.Build() + File_request_vote_proto = out.File + file_request_vote_proto_rawDesc = nil + file_request_vote_proto_goTypes = nil + file_request_vote_proto_depIdxs = nil +} diff --git a/internal/raft/message/request_vote.proto b/internal/raft/message/request_vote.proto new file mode 100644 index 00000000..b973cf67 --- /dev/null +++ b/internal/raft/message/request_vote.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; + +message RequestVoteRequest { + int32 term = 1; + bytes candidateID = 2; + int32 lastLogIndex = 3; + int32 lastLogTerm = 4; +} + +message RequestVoteResponse { + int32 term = 1; + bool voteGranted = 2; +} \ No newline at end of file diff --git a/internal/raft/message/test_message.go b/internal/raft/message/test_message.go new file mode 100644 index 00000000..fcf501eb --- /dev/null +++ b/internal/raft/message/test_message.go @@ -0,0 +1,17 @@ +package message + +//go:generate protoc --go_out=. test_message.proto + +var _ Message = (*TestMessage)(nil) + +// NewTestMessage creates a new test message with the given data. +func NewTestMessage(data string) *TestMessage { + return &TestMessage{ + Data: data, + } +} + +// Kind returns KindTestMessage. +func (*TestMessage) Kind() Kind { + return KindTestMessage +} diff --git a/internal/raft/message/test_message.pb.go b/internal/raft/message/test_message.pb.go new file mode 100644 index 00000000..031323ea --- /dev/null +++ b/internal/raft/message/test_message.pb.go @@ -0,0 +1,149 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.22.0 +// protoc v3.11.4 +// source: test_message.proto + +//lint:file-ignore SA1019 Generated deprecated import + +package message + +import ( + proto "github.com/golang/protobuf/proto" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// This is a compile-time assertion that a sufficiently up-to-date version +// of the legacy proto package is being used. +const _ = proto.ProtoPackageIsVersion4 + +type TestMessage struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *TestMessage) Reset() { + *x = TestMessage{} + if protoimpl.UnsafeEnabled { + mi := &file_test_message_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TestMessage) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TestMessage) ProtoMessage() {} + +func (x *TestMessage) ProtoReflect() protoreflect.Message { + mi := &file_test_message_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TestMessage.ProtoReflect.Descriptor instead. +func (*TestMessage) Descriptor() ([]byte, []int) { + return file_test_message_proto_rawDescGZIP(), []int{0} +} + +func (x *TestMessage) GetData() string { + if x != nil { + return x.Data + } + return "" +} + +var File_test_message_proto protoreflect.FileDescriptor + +var file_test_message_proto_rawDesc = []byte{ + 0x0a, 0x12, 0x74, 0x65, 0x73, 0x74, 0x5f, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x21, 0x0a, + 0x0b, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x42, 0x0b, 0x5a, 0x09, 0x2e, 0x3b, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_test_message_proto_rawDescOnce sync.Once + file_test_message_proto_rawDescData = file_test_message_proto_rawDesc +) + +func file_test_message_proto_rawDescGZIP() []byte { + file_test_message_proto_rawDescOnce.Do(func() { + file_test_message_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_message_proto_rawDescData) + }) + return file_test_message_proto_rawDescData +} + +var file_test_message_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_test_message_proto_goTypes = []interface{}{ + (*TestMessage)(nil), // 0: message.TestMessage +} +var file_test_message_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_test_message_proto_init() } +func file_test_message_proto_init() { + if File_test_message_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_message_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TestMessage); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_message_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_test_message_proto_goTypes, + DependencyIndexes: file_test_message_proto_depIdxs, + MessageInfos: file_test_message_proto_msgTypes, + }.Build() + File_test_message_proto = out.File + file_test_message_proto_rawDesc = nil + file_test_message_proto_goTypes = nil + file_test_message_proto_depIdxs = nil +} diff --git a/internal/raft/message/test_message.proto b/internal/raft/message/test_message.proto new file mode 100644 index 00000000..8b59dd2f --- /dev/null +++ b/internal/raft/message/test_message.proto @@ -0,0 +1,10 @@ +syntax = "proto3"; + +//lint:file-ignore SA1019 Generated deprecated import + +package message; +option go_package = ".;message"; + +message TestMessage { + string data = 1; +} \ No newline at end of file diff --git a/internal/raft/mocks/cluster.go b/internal/raft/mocks/cluster.go new file mode 100644 index 00000000..0355fe0a --- /dev/null +++ b/internal/raft/mocks/cluster.go @@ -0,0 +1,111 @@ +// Code generated by mockery v1.0.0. DO NOT EDIT. + +package mocks + +import ( + context "context" + + id "github.com/xqueries/xdb/internal/id" + message "github.com/xqueries/xdb/internal/raft/message" + + mock "github.com/stretchr/testify/mock" + + network "github.com/xqueries/xdb/internal/network" +) + +// Cluster is an autogenerated mock type for the Cluster type +type Cluster struct { + mock.Mock +} + +// Broadcast provides a mock function with given fields: _a0, _a1 +func (_m *Cluster) Broadcast(ctx context.Context, _a1 message.Message) error { + ret := _m.Called(ctx, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, message.Message) error); ok { + r0 = rf(ctx, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Close provides a mock function with given fields: +func (_m *Cluster) Close() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Nodes provides a mock function with given fields: +func (_m *Cluster) Nodes() []network.Conn { + ret := _m.Called() + + var r0 []network.Conn + if rf, ok := ret.Get(0).(func() []network.Conn); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]network.Conn) + } + } + + return r0 +} + +// OwnID provides a mock function with given fields: +func (_m *Cluster) OwnID() id.ID { + ret := _m.Called() + + var r0 id.ID + if rf, ok := ret.Get(0).(func() id.ID); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(id.ID) + } + } + + return r0 +} + +// Receive provides a mock function with given fields: ctx +func (_m *Cluster) Receive(ctx context.Context) (network.Conn, message.Message, error) { + ret := _m.Called(ctx) + + var r0 network.Conn + if rf, ok := ret.Get(0).(func(context.Context) network.Conn); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(network.Conn) + } + } + + var r1 message.Message + if rf, ok := ret.Get(1).(func(context.Context) message.Message); ok { + r1 = rf(ctx) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(message.Message) + } + } + + var r2 error + if rf, ok := ret.Get(2).(func(context.Context) error); ok { + r2 = rf(ctx) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} diff --git a/internal/raft/mocks/doc.go b/internal/raft/mocks/doc.go new file mode 100644 index 00000000..35abed3d --- /dev/null +++ b/internal/raft/mocks/doc.go @@ -0,0 +1,2 @@ +// Package mocks provides generated mock implementations for easy testing. +package mocks diff --git a/internal/raft/raft.go b/internal/raft/raft.go new file mode 100644 index 00000000..8ae13745 --- /dev/null +++ b/internal/raft/raft.go @@ -0,0 +1,591 @@ +package raft + +import ( + "context" + "fmt" + "io" + "log" + "math/rand" + "strconv" + "sync" + "sync/atomic" + "time" + + "github.com/rs/zerolog" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/message" +) + +// Server is a description of a raft server. +type Server interface { + Start(context.Context) error + OnReplication(ReplicationHandler) + Input(*message.Command) + io.Closer +} + +// ReplicationHandler is a handler setter. +// It takes in the log entries as a string and returns the number +// of succeeded application of entries. +type ReplicationHandler func([]*message.Command) int + +// Node describes the current state of a raft node. +// The raft paper describes this as a "State" but node +// seemed more intuitive. +type Node struct { + State string + log zerolog.Logger + + PersistentState *PersistentState + VolatileState *VolatileState + VolatileStateLeader *VolatileStateLeader + + Closed bool +} + +// PersistentState describes the persistent state data on a raft node. +type PersistentState struct { + CurrentTerm int32 + VotedFor id.ID // VotedFor is nil at init, and id.ID of the node after voting is complete. + Log []*message.LogData // Logs are commands for the state machine to execute. + + peerIPs []network.Conn // peerIPs has the connection variables of all the other nodes in the cluster. + + SelfID id.ID + LeaderID id.ID // LeaderID is nil at init, and the ID of the node after the leader is elected. + ConnIDMap map[id.ID]int // ConnIDMap has a mapping of the ID of the server to its connection. + mu sync.Mutex +} + +// VolatileState describes the volatile state data on a raft node. +type VolatileState struct { + CommitIndex int32 + LastApplied int32 + Votes int32 + + mu sync.Mutex +} + +// VolatileStateLeader describes the volatile state data +// that exists on a raft leader. +type VolatileStateLeader struct { + NextIndex []int // Holds the nextIndex value for each of the followers in the cluster. + MatchIndex []int // Holds the matchIndex value for each of the followers in the cluster. +} + +var _ Server = (*SimpleServer)(nil) + +// SimpleServer implements a server in a cluster. +type SimpleServer struct { + node *Node + cluster Cluster + log zerolog.Logger + timeoutProvider func(*Node) *time.Timer + lock sync.Mutex + + + + // Function setters. + onReplication ReplicationHandler + onRequestVotes func(network.Conn) + onLeaderElected func() + onAppendEntriesRequest func(network.Conn) + onAppendEntriesResponse func() + // onCompleteOneRound signifies whether a single + // round of raft completed successfully(?). + onCompleteOneRound func() + + timerReset chan struct{} +} + +// incomingData describes every request that the server gets. +type incomingData struct { + conn network.Conn + msg message.Message +} + +// NewServer enables starting a raft server/cluster. +func NewServer(log zerolog.Logger, cluster Cluster) *SimpleServer { + return newServer(log, cluster, nil) +} + +// newServer returns a new instance of a server that is connected +// to the cluster that is provided as the argument. +func newServer(log zerolog.Logger, cluster Cluster, timeoutProvider func(*Node) *time.Timer) *SimpleServer { + if timeoutProvider == nil { + timeoutProvider = randomTimer + } + resetChan := make(chan struct{}, 2) + return &SimpleServer{ + log: log.With().Str("component", "raft").Logger(), + cluster: cluster, + timeoutProvider: timeoutProvider, + timerReset: resetChan, + } +} + +// NewRaftNode creates a raft node for the given cluster. +// +// It returns with default values for the raft variables +// and accompanying data structures for operation. +func NewRaftNode(cluster Cluster) *Node { + var nextIndex, matchIndex []int + + for range cluster.Nodes() { + nextIndex = append(nextIndex, -1) + matchIndex = append(matchIndex, -1) + } + + connIDMap := make(map[id.ID]int) + for i := range cluster.Nodes() { + connIDMap[cluster.Nodes()[i].RemoteID()] = i + } + + node := &Node{ + // All servers start as followers, on timeouts, they become candidates. + State: StateFollower.String(), + PersistentState: &PersistentState{ + CurrentTerm: 0, + VotedFor: nil, + SelfID: cluster.OwnID(), + peerIPs: cluster.Nodes(), + ConnIDMap: connIDMap, + }, + VolatileState: &VolatileState{ + CommitIndex: -1, + LastApplied: -1, + Votes: 0, + }, + VolatileStateLeader: &VolatileStateLeader{ + NextIndex: nextIndex, + MatchIndex: matchIndex, + }, + Closed: false, + } + return node +} + +// Start starts a single raft node into beginning raft operations. +// +// This function starts the leader election and keeps a check on whether +// regular heartbeats to the node exists. It restarts leader election on +// failure to do so. This function also continuously listens on all the +// connections to the nodes and routes the requests to appropriate functions. +// +// This function is responsible for ALL the data entering this node. +// Once a goroutine is spawned to requesting votes or appending logs, those +// don't wait for the responses, instead those are waited for in this function. +// This allows us to have a HQ for all data coming to the node and have all +// related data that has to be worked on with the requests in the same place, +// making it more efficient and easier. +// +// This function returns when the contextually upper level functions return +// or the network/raft nodes are closed. +func (s *SimpleServer) Start(ctx context.Context) (err error) { + // Making the function idempotent, returns whether the server is already open. + s.lock.Lock() + if s.node != nil && !s.node.Closed { + s.log.Debug(). + Str("self-id", s.node.PersistentState.SelfID.String()). + Msg("already open") + s.lock.Unlock() + return network.ErrOpen + } + + // Initialise all raft variables in this node. + node := NewRaftNode(s.cluster) + node.PersistentState.mu.Lock() + node.log = s.log + s.node = node + + s.node.Closed = false + + selfID := node.PersistentState.SelfID + node.PersistentState.mu.Unlock() + s.lock.Unlock() + + // liveChan is a channel that passes the incomingData once received. + liveChan := make(chan *incomingData) + // Listen forever on all node connections. + go func() { + for { + s.node.PersistentState.mu.Lock() + if s.node.Closed { + s.node.PersistentState.mu.Unlock() + return + } + s.node.PersistentState.mu.Unlock() + + // Parallelly start waiting for incoming data. + conn, msg, err := s.cluster.Receive(ctx) + if err != nil { + // log.Printf("error in receiving from the cluster: %v\n", err) + return + } + + if msg != nil { + node.log. + Debug(). + Str("self-id", selfID.String()). + Str("received", msg.Kind().String()). + Msg("received request") + liveChan <- newIncomingData(conn, msg) + } + } + }() + + // This block of code checks what kind of request has to be serviced + // and calls the necessary function to complete it. + for { + // If any sort of request (heartbeat,appendEntries,requestVote) + // isn't received by the server(node) it restarts leader election. + s.node.PersistentState.mu.Lock() + if s.node.Closed { + s.node.PersistentState.mu.Unlock() + return + } + s.node.PersistentState.mu.Unlock() + + select { + case <-s.timeoutProvider(node).C: + if s.node.PersistentState.LeaderID == s.node.PersistentState.SelfID { + break + } + s.lock.Lock() + if s.node.Closed { + log.Printf("node was closed, exiting") + s.lock.Unlock() + return + } + // If this node is already the leader the time-outs are irrelevant. + if s.node.PersistentState.LeaderID != s.node.PersistentState.SelfID { + // One round is said to be complete when the state machines + // are in the first non-initial term (i.e >=2) + if s.node.PersistentState.CurrentTerm != 1 && s.onCompleteOneRound != nil { + s.onCompleteOneRound() + } + s.lock.Unlock() + s.StartElection(ctx) + } else { + s.lock.Unlock() + } + case data := <-liveChan: + err = s.processIncomingData(ctx, data) + if err != nil { + log.Printf("error in processing data: %v\n", err) + return + } + case <-ctx.Done(): + return + case <-s.timerReset: + // When a timer reset signal is received, this + // select loop is restarted, effectively restarting + // the timer. + } + } +} + +// OnReplication is a handler setter. +// +// This must be called from the Database functions before +// executing the commands that were received. Once this function's +// handler returns the number of commands that were safely +// replicated on a majority of the nodes, only then, those +// commands will be executed by the Database functions. +// +// The actual details of the above functionality is handled by the +// onReplication function and the ReplicationHandler, which is +// called on a successful replication. +func (s *SimpleServer) OnReplication(handler ReplicationHandler) { + s.onReplication = handler +} + +// Input appends the input log into the leaders log, only if the +// current node is the leader. If this was not a leader, the +// request is routed to the leader. +// +// This function must be called by the Database functionalities +// once am operation is received by it. This must be used in conjunction +// with the OnReplication handler setter which +func (s *SimpleServer) Input(input *message.Command) { + s.node.PersistentState.mu.Lock() + defer s.node.PersistentState.mu.Unlock() + + if s.node.State == StateLeader.String() { + logData := message.NewLogData(s.node.PersistentState.CurrentTerm, input) + s.node.PersistentState.Log = append(s.node.PersistentState.Log, logData) + } else { + // Relay data to leader. + logAppendRequest := message.NewLogAppendRequest(input) + s.relayDataToServer(logAppendRequest) + } +} + +// Close closes the node and returns an error on failure. +func (s *SimpleServer) Close() error { + s.lock.Lock() + // Maintaining idempotency of the close function. + if s.node.Closed { + return network.ErrClosed + } + s.node. + log. + Debug(). + Str("self-id", s.node.PersistentState.SelfID.String()). + Msg("closing node") + + s.node.PersistentState.mu.Lock() + s.node.Closed = true + s.node.PersistentState.mu.Unlock() + + err := s.cluster.Close() + s.lock.Unlock() + return err +} + +// randomTimer returns timers ranging from 150ms to 300ms. +func randomTimer(node *Node) *time.Timer { + /* #nosec */ + randomInt := rand.Intn(150) + 150 + node.log. + Debug(). + Str("self-id", node.PersistentState.SelfID.String()). + Int("random timer set to", randomInt). + Msg("heart beat timer") + return time.NewTimer(time.Duration(randomInt) * time.Millisecond) +} + +// processIncomingData is responsible for parsing the incoming data and calling +// appropriate functions based on the request type. +// This function receives data from the core of the raft module's functionality. +func (s *SimpleServer) processIncomingData(ctx context.Context, data *incomingData) error { + + switch data.msg.Kind() { + case message.KindRequestVoteRequest: + requestVoteRequest := data.msg.(*message.RequestVoteRequest) + requestVoteResponse := s.RequestVoteResponse(requestVoteRequest) + payload, err := message.Marshal(requestVoteResponse) + if err != nil { + return err + } + + err = data.conn.Send(ctx, payload) + if err != nil { + return err + } + case message.KindRequestVoteResponse: + requestVoteResponse := data.msg.(*message.RequestVoteResponse) + if requestVoteResponse.GetVoteGranted() { + s.lock.Lock() + voterID := s.getNodeID(data.conn) + s.node.log. + Debug(). + Str("received vote from", voterID.String()). + Msg("voting from peer") + selfID := s.node.PersistentState.SelfID + s.lock.Unlock() + votesReceived := atomic.AddInt32(&s.node.VolatileState.Votes, 1) + + // Check whether this node has already voted. + // Else it can vote for itself. + s.node.PersistentState.mu.Lock() + + if s.node.PersistentState.VotedFor == nil { + s.node.PersistentState.VotedFor = selfID + s.node.log. + Debug(). + Str("self-id", selfID.String()). + Msg("node voting for itself") + votesReceived = atomic.AddInt32(&s.node.VolatileState.Votes, 1) + } + // Election win criteria: votes this node has is majority in the cluster and + // this node is not already the Leader. + if votesReceived >= int32(len(s.node.PersistentState.peerIPs)/2) && s.node.State != StateLeader.String() { + // This node has won the election. + s.node.State = StateLeader.String() + s.node.PersistentState.LeaderID = selfID + s.node.log. + Debug(). + Str("self-id", selfID.String()). + Msg("node elected leader at " + strconv.Itoa(int(votesReceived)) + " votes") + // Reset the votes of this term once its elected leader. + s.node.resetVolatileStateLeader() + s.node.setNextIndexValues() + s.node.VolatileState.Votes = 0 + s.node.PersistentState.mu.Unlock() + s.startLeader(ctx, selfID.String()) + return nil + } + s.node.PersistentState.mu.Unlock() + } + case message.KindAppendEntriesRequest: + // An appropriate AppendEntriesResponse is crafted using the + // dedicated function and returned using the same connection. + appendEntriesRequest := data.msg.(*message.AppendEntriesRequest) + appendEntriesResponse := s.AppendEntriesResponse(appendEntriesRequest) + payload, err := message.Marshal(appendEntriesResponse) + if err != nil { + return err + } + err = data.conn.Send(ctx, payload) + if err != nil { + log.Printf("error in sending AppendEntriesResponse: %v\n", err) + return err + } + case message.KindAppendEntriesResponse: + + s.node.log.Debug(). + Str("node-id", s.getNodeID(data.conn).String()). + Msg("received append entries response") + + appendEntriesResponse := data.msg.(*message.AppendEntriesResponse) + + s.node.PersistentState.mu.Lock() + savedCurrentTerm := s.node.PersistentState.CurrentTerm + selfID := s.node.PersistentState.SelfID.String() + s.node.PersistentState.mu.Unlock() + + currNextIndex, offset := s.getNextIndex(data.conn) + // If the term in the other node is greater than this node's term, + // it means that this node is not up to date and has to step down + // from being a leader. + if appendEntriesResponse.Term > savedCurrentTerm { + s.node.log.Debug(). + Str(selfID, "stale term"). + Str("following newer node", data.conn.RemoteID().String()) + s.node.becomeFollower(appendEntriesResponse.Term, s.getNodeID(data.conn)) + return nil + } + + if s.node.State == StateLeader.String() && appendEntriesResponse.Term == savedCurrentTerm { + if appendEntriesResponse.Success { + s.node.PersistentState.mu.Lock() + s.updateNextIndex(int(appendEntriesResponse.EntriesLength), offset, currNextIndex) + s.node.PersistentState.mu.Unlock() + } else { + // If this appendEntries request failed, + // proceed and retry in the next cycle. + s.node.log. + Debug(). + Str("self-id", selfID). + Str("received failure to append entries from", data.conn.RemoteID().String()). + Msg("failed to append entries") + } + } + // When the leader gets a forwarded append input message from one of it's followers. + case message.KindLogAppendRequest: + // This log append request was meant to the leader ONLY. + // This handles issues where the leader changed in the transit. + if s.node.PersistentState.LeaderID != s.node.PersistentState.SelfID { + s.relayDataToServer(data.msg.(*message.LogAppendRequest)) + return nil + } + logAppendRequest := data.msg.(*message.LogAppendRequest) + input := logAppendRequest.Data + logData := message.NewLogData(s.node.PersistentState.CurrentTerm, input) + s.node.PersistentState.Log = append(s.node.PersistentState.Log, logData) + } + return nil +} + +// relayDataToServer sends the input log from the follower to a leader node. +// TODO: Figure out what to do with the errors generated here. +func (s *SimpleServer) relayDataToServer(req *message.LogAppendRequest) { + ctx := context.Background() + + payload, _ := message.Marshal(req) + + leaderNodeConn := s.cluster.Nodes()[s.node.PersistentState.ConnIDMap[s.node.PersistentState.LeaderID]] + _ = leaderNodeConn.Send(ctx, payload) +} + +// OnRequestVotes is a hook setter for RequestVotesRequest. +func (s *SimpleServer) OnRequestVotes(hook func(network.Conn)) { + s.onRequestVotes = hook +} + +// OnLeaderElected is a hook setter for LeadeElectedRequest. +func (s *SimpleServer) OnLeaderElected(hook func()) { + s.onLeaderElected = hook +} + +// OnAppendEntriesRequest is a hook setter for AppenEntriesRequest. +func (s *SimpleServer) OnAppendEntriesRequest(hook func(network.Conn)) { + s.onAppendEntriesRequest = hook +} + +// OnAppendEntriesResponse is a hook setter for AppenEntriesRequest. +func (s *SimpleServer) OnAppendEntriesResponse(hook func()) { + s.onAppendEntriesResponse = hook +} + +// OnCompleteOneRound is a hook setter for completion for one round of raft. +func (s *SimpleServer) OnCompleteOneRound(hook func()) { + s.onCompleteOneRound = hook +} + +// getNodeID finds the ID of the node from it's connection. +func (s *SimpleServer) getNodeID(conn network.Conn) id.ID { + s.node.PersistentState.mu.Lock() + for k, v := range s.node.PersistentState.ConnIDMap { + if s.node.PersistentState.peerIPs[v] == conn { + s.node.PersistentState.mu.Unlock() + return k + } + } + s.node.PersistentState.mu.Unlock() + return nil +} + +// getNextIndex allows the leader to iterate through the available +// slice of connections of its peers and find the respective "nextIndex" +// value of the node which sent the AppendEntriesResponse. It returns +// the nextIndex value and the offset of the node for future use. +// +// A -1 int is returned on not finding the connection - which is not +// supposed to happen, EVER. +func (s *SimpleServer) getNextIndex(conn network.Conn) (int, int) { + s.node.PersistentState.mu.Lock() + for i := range s.node.PersistentState.peerIPs { + if conn == s.node.PersistentState.peerIPs[i] { + s.node.PersistentState.mu.Unlock() + return s.node.VolatileStateLeader.NextIndex[i], i + } + } + s.node.PersistentState.mu.Unlock() + return -1, -1 +} + +func (s *SimpleServer) updateNextIndex(len, offset, currNextIndex int) { + s.node.VolatileStateLeader.NextIndex[offset] = currNextIndex + len +} + +// resetVolatileState resets the volatile state of the given node. +// +// This assumes that the necessary locks are in place in the contextual +// upper level to operate on the underlying parameters. +func (node *Node) resetVolatileStateLeader() { + node.VolatileStateLeader.NextIndex = []int{} + node.VolatileStateLeader.MatchIndex = []int{} +} + +// setNextIndexValues sets the values for the next index for each +// node respectively. The value set will be the index just after the +// last one in its log (leader's). +func (node *Node) setNextIndexValues() { + nextIndex := len(node.PersistentState.Log) + + for range node.PersistentState.peerIPs { + node.VolatileStateLeader.NextIndex = append(node.VolatileStateLeader.NextIndex,nextIndex) + } + + fmt.Println("G") +} + +func newIncomingData(conn network.Conn, msg message.Message) *incomingData { + return &incomingData{ + conn, + msg, + } +} diff --git a/internal/raft/raft_test.go b/internal/raft/raft_test.go new file mode 100644 index 00000000..013cc871 --- /dev/null +++ b/internal/raft/raft_test.go @@ -0,0 +1,411 @@ +package raft + +import ( + "context" + "github.com/xqueries/xdb/internal/compiler/command" + "os" + "testing" + "time" + + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + networkmocks "github.com/xqueries/xdb/internal/network/mocks" + "github.com/xqueries/xdb/internal/raft/cluster" + "github.com/xqueries/xdb/internal/raft/message" + raftmocks "github.com/xqueries/xdb/internal/raft/mocks" +) + +// TestRaftFromLeaderPerspective tests the entire raft operation for one round of election +// and AppendEntries where the non-mocked node is the leader. Following is how it operates: +// 1. The test creates a mock cluster and assigns a clusterID to it. +// 2. Four mocked connections are created and ID's are assigned to those connections. +// 3. Send characteristic is set on the four connections to facilitate sending of +// a RequestVoteRequest. It returns nil as no error is expected. +// 4. Receive characteristic is set on the four connections and they're set to respond +// with a response for the votes with a positive response. +// 5. Receive characteristic is set on the four connections again for a heartbeat response. +// 6. Cluster's "Nodes", "OwnID", "Receive" characteristics are set to appropriate responses. +// 7. The hooks are set in order to end the raft operation as soon as the append entries +// requests are registered. +// 8. The mechanism of a response to receive is set only such that a RequestVote is asked for, +// the cluster.Receive function responds. This is done by listening on a closing channel, +// where the channel is closed if the RequestVote or the AppendEntries is received. +func TestRaftFromLeaderPerspective(t *testing.T) { + assert := assert.New(t) + ctx := context.Background() + log := zerolog.New(os.Stdout).With().Logger().Level(zerolog.GlobalLevel()) + + // Create a new cluster. + cluster := new(raftmocks.Cluster) + clusterID := id.Create() + + // Mock 4 other nodes in the cluster. + conn1 := new(networkmocks.Conn) + conn2 := new(networkmocks.Conn) + conn3 := new(networkmocks.Conn) + conn4 := new(networkmocks.Conn) + + connSlice := []network.Conn{ + conn1, + conn2, + conn3, + conn4, + } + + conn1 = addRemoteID(conn1) + conn2 = addRemoteID(conn2) + conn3 = addRemoteID(conn3) + conn4 = addRemoteID(conn4) + + server := newServer( + log, + cluster, + timeoutProvider, + ) + + var ( + chanConn1 = make(chan time.Time) + chanConn2 = make(chan time.Time) + chanConn3 = make(chan time.Time) + chanConn4 = make(chan time.Time) + ) + + // This function lets the other functionality know, + // on which connection the call was made. It does so + // by closing a channel, which would have blocked forever. + server.OnRequestVotes(func(conn network.Conn) { + switch conn { + case conn1: + close(chanConn1) + case conn2: + close(chanConn2) + case conn3: + close(chanConn3) + case conn4: + close(chanConn4) + } + }) + + server.OnLeaderElected(func() {}) + + var ( + chanConnAppE1 = make(chan time.Time) + chanConnAppE2 = make(chan time.Time) + chanConnAppE3 = make(chan time.Time) + chanConnAppE4 = make(chan time.Time) + ) + + server.OnAppendEntriesRequest(func(conn network.Conn) { + switch conn { + case conn1: + close(chanConnAppE1) + case conn2: + close(chanConnAppE2) + case conn3: + close(chanConnAppE3) + case conn4: + close(chanConnAppE4) + } + err := server.Close() + if err != network.ErrClosed { + assert.NoError(err) + } + }) + + // set up cluster to return the slice of connections on demand. + cluster. + On("Nodes"). + Return(connSlice) + + // return cluster ID + cluster. + On("OwnID"). + Return(clusterID) + + cluster.On("Close").Return(nil) + + conn1.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn2.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn3.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn4.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + + reqVRes1 := message.NewRequestVoteResponse(1, true) + + // These lines wait until their respective call was made to the connection and then return. + cluster.On("Receive", ctx).Return(conn1, reqVRes1, nil).WaitUntil(chanConn1).Once() + cluster.On("Receive", ctx).Return(conn2, reqVRes1, nil).WaitUntil(chanConn2).Once() + cluster.On("Receive", ctx).Return(conn3, reqVRes1, nil).WaitUntil(chanConn3).Once() + cluster.On("Receive", ctx).Return(conn4, reqVRes1, nil).WaitUntil(chanConn4).Once() + + appERes1 := message.NewAppendEntriesResponse(1, true, 1) + + cluster.On("Receive", ctx).Return(conn1, appERes1, nil).WaitUntil(chanConnAppE1) + cluster.On("Receive", ctx).Return(conn2, appERes1, nil).WaitUntil(chanConnAppE2) + cluster.On("Receive", ctx).Return(conn3, appERes1, nil).WaitUntil(chanConnAppE3) + cluster.On("Receive", ctx).Return(conn4, appERes1, nil).WaitUntil(chanConnAppE4) + + err := server.Start(ctx) + assert.NoError(err) + +} + +func TestRaftFromFollowerPerspective(t *testing.T) { + assert := assert.New(t) + ctx := context.Background() + log := zerolog.New(os.Stdout).With().Logger().Level(zerolog.GlobalLevel()) + + // Create a new cluster. + cluster := new(raftmocks.Cluster) + clusterID := id.Create() + + // Mock 4 other nodes in the cluster. + conn1Leader := new(networkmocks.Conn) + conn2 := new(networkmocks.Conn) + conn3 := new(networkmocks.Conn) + conn4 := new(networkmocks.Conn) + + // The real connection. + connSlice := []network.Conn{ + conn1Leader, + conn2, + conn3, + conn4, + } + + conn1Leader = addRemoteID(conn1Leader) + conn2 = addRemoteID(conn2) + conn3 = addRemoteID(conn3) + conn4 = addRemoteID(conn4) + + cluster. + On("Nodes"). + Return(connSlice) + + cluster. + On("OwnID"). + Return(clusterID) + + cluster.On("Close").Return(nil) + + server := newServer( + log, + cluster, + timeoutProvider, + ) + + server.OnRequestVotes(func(network.Conn) {}) + + reqV := message.NewRequestVoteRequest(1, id.Create(), 1, 1) + + cluster.On("Receive", ctx).Return(conn1Leader, reqV, nil).Once() + + leaderID := id.Create() + + // Allows this node to send a request vote to all nodes. + conn1Leader.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn2.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn3.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + conn4.On("Send", ctx, mock.IsType([]byte{})).Return(nil) + + appEnt := message.NewAppendEntriesRequest(3, leaderID, -1, -1, nil, 1) + + cluster.On("Receive", ctx).Return(conn1Leader, appEnt, nil) + + times := 0 + + server.OnLeaderElected(func() {}) + server.OnAppendEntriesResponse(func() { + times++ + if times == 5 { + err := server.Close() + if err != network.ErrClosed { + assert.NoError(err) + } + } + }) + + err := server.Start(ctx) + assert.NoError(err) +} + +func addRemoteID(conn *networkmocks.Conn) *networkmocks.Conn { + cID := id.Create() + conn.On("RemoteID").Return(cID) + return conn +} + +func timeoutProvider(node *Node) *time.Timer { + node.log. + Debug(). + Str("self-id", node.PersistentState.SelfID.String()). + Int("random timer set to", 150). + Msg("heart beat timer") + return time.NewTimer(time.Duration(150) * time.Millisecond) +} + +// TestRaftIntegration was created on the principles of witnessing +// raft run in all its glory. While doing this, it is validated for +// every state it moves past while accounting for the random nature +// of the election and raft itself. +// +// The test creates a raft cluster, lets it reach consensus and +// throws some problems at it to see whether it can handle it. +func TestRaftIntegration(t *testing.T) { + + log := zerolog.New(os.Stdout).With().Logger().Level(zerolog.GlobalLevel()) + + assert := assert.New(t) + operations := []OpData{ + { + Op: SendData, + Data: &OpSendData{ + Data: []*command.Command{}, + }, + }, + { + Op: StopNode, + Data: &OpStopNode{ + 3, + }, + }, + { + Op: StopNode, + Data: &OpStopNode{ + 4, + }, + }, + { + Op: StopNode, + Data: &OpStopNode{ + 2, + }, + }, + // TODO: Restart needs a deeper look into network. + //{ + // Op: RestartNode, + // Data: &OpRestartNode{ + // 3, + // }, + //}, + } + opParams := OperationParameters{ + Rounds: 10, + TimeLimit: 5, + Operations: operations, + OperationPushDelay: 500, + } + + testNetwork := cluster.NewTCPTestNetwork(t, 5) + + cfg := NetworkConfiguration{} + ctx := context.Background() + ctx, cancelFunc := context.WithCancel(ctx) + + raftNodes := createRaftNodes(log, testNetwork) + + raftTest := NewSimpleRaftTest(log, opParams, cfg, raftNodes, cancelFunc) + + err := raftTest.BeginTest(ctx) + assert.Nil(err) +} + +// TestRaftSendDataToNode tests whether sending data through a functioning +// raft cluster achieves consensus in the cluster. +func TestRaftSendDataToNode(t *testing.T) { + + assert := assert.New(t) + + operations := []OpData { + { + Op: SendData, + Data: &OpSendData{ + Data: []*command.Command{}, + }, + }, + } + + opParams := OperationParameters{ + Rounds: 5, + TimeLimit: 5, + Operations: operations, + OperationPushDelay: 500, + } + + assert.Nil(_TestRaftOperationWithOpInjection(t, opParams)) +} + +// TestRaftStopSingleNode tests whether a functioning raft cluster is +// robust enough to suffer a single node fault. (Which is acceptable +// in theory) +func TestRaftStopSingleNode(t *testing.T) { + assert := assert.New(t) + + operations := []OpData { + { + Op: StopNode, + Data: &OpStopNode{ + 1, + }, + }, + } + + opParams := OperationParameters{ + Rounds: 5, + TimeLimit: 5, + Operations: operations, + OperationPushDelay: 500, + } + + assert.Nil(_TestRaftOperationWithOpInjection(t, opParams)) +} + +// TestRaftRestartNode tests whether restarting a functioning node +// in a perfectly functioning raft cluster can later lead to the cluster +// achieving consensus. +func TestRaftRestartNode(t *testing.T) { + t.SkipNow() + assert := assert.New(t) + + operations := []OpData { + { + Op: StopNode, + Data: &OpStopNode{ + 1, + }, + }, + { + Op: RestartNode, + Data: &OpRestartNode{ + 1, + }, + }, + } + + opParams := OperationParameters{ + Rounds: 5, + TimeLimit: 5, + Operations: operations, + OperationPushDelay: 500, + } + + assert.Nil(_TestRaftOperationWithOpInjection(t, opParams)) +} + +func _TestRaftOperationWithOpInjection(t *testing.T, opParams OperationParameters) error { + log := zerolog.New(os.Stdout).With().Logger().Level(zerolog.GlobalLevel()) + + testNetwork := cluster.NewTCPTestNetwork(t,3) + cfg := NetworkConfiguration{} + ctx := context.Background() + ctx, cancelFunc := context.WithCancel(ctx) + + raftNodes := createRaftNodes(log, testNetwork) + + raftTest := NewSimpleRaftTest(log, opParams, cfg, raftNodes, cancelFunc) + + err := raftTest.BeginTest(ctx) + return err +} \ No newline at end of file diff --git a/internal/raft/raft_test_framework.go b/internal/raft/raft_test_framework.go new file mode 100644 index 00000000..51578ba5 --- /dev/null +++ b/internal/raft/raft_test_framework.go @@ -0,0 +1,301 @@ +package raft + +import ( + "context" + "fmt" + "log" + "sync" + "time" + + "github.com/xqueries/xdb/internal/network" + + "github.com/rs/zerolog" + "github.com/xqueries/xdb/internal/raft/cluster" +) + +// Usage of framework: +// +// * Create a new instance of the RaftTestFramework; +// this begins the raft cluster and all operations. +// +// raftTest := NewSimpleRaftTest(log,opParams,cfg) +// +// * Use "InjectOperation" with appropriate args to +// trigger an operation in the cluster. +var _ TestFramework = (*SimpleRaftTest)(nil) + +// SimpleRaftTest implements TestFramework. +type SimpleRaftTest struct { + log zerolog.Logger + parameters OperationParameters + config NetworkConfiguration + raftNodes []*SimpleServer + + opChannel chan OpData + execChannel chan OpData + roundsChan chan bool + opQueue []OpData + round int + shutdown chan bool + mu sync.Mutex + cancelFunc context.CancelFunc + ctx context.Context +} + +// NewSimpleRaftTest provides a ready to use raft test framework. +func NewSimpleRaftTest( + log zerolog.Logger, + parameters OperationParameters, + config NetworkConfiguration, + raftNodes []*SimpleServer, + cancel context.CancelFunc, +) *SimpleRaftTest { + opChan := make(chan OpData, len(parameters.Operations)) + execChan := make(chan OpData, len(parameters.Operations)) + shutdownChan := make(chan bool, 4) + roundsChan := make(chan bool, 4) + return &SimpleRaftTest{ + log: log, + parameters: parameters, + config: config, + raftNodes: raftNodes, + opChannel: opChan, + execChannel: execChan, + roundsChan: roundsChan, + opQueue: []OpData{}, + round: 0, + shutdown: shutdownChan, + cancelFunc: cancel, + } +} + +// OpParams returns the parameters of operations of the test. +func (t *SimpleRaftTest) OpParams() OperationParameters { + return t.parameters +} + +// Config returns the configuration under which the test is running. +func (t *SimpleRaftTest) Config() NetworkConfiguration { + return t.config +} + +// BeginTest starts all the cluster operations by creating and +// starting the cluster and the nodes. This operation will be +// completely stable and allows failing of servers underneath +// while monitoring their behavior. +// +// BeginTest will wrapped under a Go Test for ease of use. +func (t *SimpleRaftTest) BeginTest(ctx context.Context) error { + + t.ctx = ctx + // start up the raft operation. + for i := range t.raftNodes { + go func(i int) { + t.raftNodes[i].OnCompleteOneRound(t.roundHook) + _ = t.raftNodes[i].Start(ctx) + }(i) + } + + shutDownTimer := time.NewTimer(time.Duration(t.OpParams().TimeLimit) * time.Second) + + // start the execution goroutine. + t.log.Debug().Msg("beginning execution goroutine") + go t.executeOperation() + + t.log.Debug().Msg("initiating operation injection") + go t.pushOperations() + + // Look for incoming operations and parallelly run them + // while waiting for the limit of the execution. + // + // Once the limit of the execution is reached, wait for + // all operations to finish and end the test. + for { + select { + case data := <-t.opChannel: + t.log.Debug(). + Str("executing", fmt.Sprint(data.Op)). + Msg("beginning execution") + go t.execute(data) + case <-shutDownTimer.C: + t.log.Debug(). + Msg("shutting down - reached time limit") + return t.GracefulShutdown() + case <-t.roundsChan: + t.log.Debug(). + Msg("shutting down - reached round limit") + return t.GracefulShutdown() + } + } +} + +// GracefulShutdown shuts down all operations of the server after waiting +// all running operations to complete while not accepting any more op reqs. +func (t *SimpleRaftTest) GracefulShutdown() error { + t.cancelFunc() + var errSlice multiError + var errLock sync.Mutex + for i := range t.raftNodes { + t.raftNodes[i].lock.Lock() + if !t.raftNodes[i].node.Closed { + t.raftNodes[i].lock.Unlock() + err := t.raftNodes[i].Close() + if err != nil && err != network.ErrClosed { + errLock.Lock() + errSlice = append(errSlice, err) + errLock.Unlock() + } + } + } + + if len(errSlice) != 0 { + return errSlice + } + + t.shutdown <- true + t.log.Debug(). + Msg("gracefully shutting down") + return nil +} + +// InjectOperation initiates an operation in the raft cluster based on the args. +func (t *SimpleRaftTest) InjectOperation(op Operation, args interface{}) { + opData := OpData{ + Op: op, + Data: args, + } + t.log.Debug().Msg("injecting operation") + t.opChannel <- opData +} + +// pushOperations pushes operations into the execution queue. +func (t *SimpleRaftTest) pushOperations() { + for i := range t.parameters.Operations { + time.Sleep(time.Duration(t.parameters.OperationPushDelay) * time.Millisecond) + t.opChannel <- t.parameters.Operations[i] + } +} + +// execute appends the operation to the queue which will +// be cleared in definite intervals. +func (t *SimpleRaftTest) execute(opData OpData) { + t.log.Debug().Msg("operation moved to execution channel") + t.execChannel <- opData +} + +// executeOperation is always ready to run an incoming operation. +// It looks for the shutdown signal from the hook channel and +// shutdown by not allowing further operations to execute. +// +// When both cases of the select statement recieve a signal, +// select chooses one at random. This doesn't affect the operation +// as the execution will shutdown right after that operation is +// completed. +func (t *SimpleRaftTest) executeOperation() { + for { + select { + case <-t.shutdown: + t.log.Debug().Msg("execution shutting down") + return + case operation := <-t.execChannel: + t.log.Debug().Msg("executing operation") + switch operation.Op { + case SendData: + d := operation.Data.(*OpSendData) + t.SendData(d) + case StopNode: + d := operation.Data.(*OpStopNode) + t.StopNode(d) + case PartitionNetwork: + d := operation.Data.(*OpPartitionNetwork) + t.PartitionNetwork(d) + case RestartNode: + d := operation.Data.(*OpRestartNode) + t.RestartNode(d) + } + } + } +} + +func (t *SimpleRaftTest) roundHook() { + t.mu.Lock() + defer t.mu.Unlock() + t.round++ + if t.round == t.parameters.Rounds*len(t.raftNodes) { + t.roundsChan <- true + } +} + +// SendData sends command data to the cluster by calling +// the appropriate function in the raft module. +func (t *SimpleRaftTest) SendData(d *OpSendData) { + fmt.Println("Send data invoked") +} + +// StopNode stops the given node in the network. +// This is a test of robustness in the system to recover from +// a failure of a node. +func (t *SimpleRaftTest) StopNode(d *OpStopNode) { + t.raftNodes[d.NodeID].node.PersistentState.mu.Lock() + if t.raftNodes[d.NodeID].node.Closed { + t.log.Debug(). + Int("node ID", d.NodeID). + Msg("can't stop node, already stopped") + t.raftNodes[d.NodeID].node.PersistentState.mu.Unlock() + return + } + t.raftNodes[d.NodeID].node.PersistentState.mu.Unlock() + t.log.Debug(). + Int("node ID", d.NodeID). + Msg("stopping the node") + + err := t.raftNodes[d.NodeID].Close() + if err != nil { + log.Fatalf("cant stop node: %d, error: %v\n", d.NodeID, err) + } +} + +// PartitionNetwork partitions the network into one or more +// groups as dictated by the arguments. This means that the +// nodes in different groups cannot communicate with the +// nodes in a different group. +// +// The implementation can involve removing the nodes in the +// in the respective "cluster" variable so that they are no +// longer available to access it. +func (t *SimpleRaftTest) PartitionNetwork(d *OpPartitionNetwork) { + fmt.Println("Partition network invoked") +} + +// StartNode starts a previously stopped node which has +// all resources allocated to it but went down for any reason. +// TODO: Definition change needs some changes wrt to approach. +func (t *SimpleRaftTest) StartNode(d *OpRestartNode) { + t.log.Debug(). + Int("node ID", d.NodeID). + Msg("restarting the node") + if !t.raftNodes[d.NodeID].node.Closed { + t.log.Debug(). + Int("node ID", d.NodeID). + Msg("node already open, can't restart it") + return + } + go func() { + _ = t.raftNodes[d.NodeID].Start(t.ctx) + }() +} + +// RestartNode restarts a functioning node. This involves +// stopping the node and then starting it again. +func (t *SimpleRaftTest) RestartNode(d *OpRestartNode) { + +} + +func createRaftNodes(log zerolog.Logger, cluster *cluster.TCPTestNetwork) []*SimpleServer { + var raftNodes []*SimpleServer + for i := range cluster.Clusters { + node := NewServer(log, cluster.Clusters[i]) + raftNodes = append(raftNodes, node) + } + return raftNodes +} diff --git a/internal/raft/request_votes.go b/internal/raft/request_votes.go new file mode 100644 index 00000000..5508e870 --- /dev/null +++ b/internal/raft/request_votes.go @@ -0,0 +1,102 @@ +package raft + +import ( + "context" + "fmt" + + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" + "github.com/xqueries/xdb/internal/raft/message" +) + +// RequestVote enables a node to send out the RequestVotes RPC. +// This function requests a vote from one node and returns that node's response. +// It opens a connection to the intended node using the network layer and waits for a response. +func (s *SimpleServer) RequestVote(ctx context.Context, nodeConn network.Conn, req *message.RequestVoteRequest) error { + + s.lock.Lock() + selfID := s.node.PersistentState.SelfID + s.node.log. + Debug(). + Str("self-id", selfID.String()). + Str("request-vote sent to", nodeConn.RemoteID().String()). + Msg("request vote") + s.lock.Unlock() + + payload, err := message.Marshal(req) + if err != nil { + return err + } + + err = nodeConn.Send(ctx, payload) + if err != nil { + return err + } + + // Set the hook for a request vote completion. + if s.onRequestVotes != nil { + s.onRequestVotes(nodeConn) + } + + return nil +} + +// RequestVoteResponse function is called on a request from a +// candidate for a vote. This function generates the response +// for the responder node to send back to the candidate node. +func (s *SimpleServer) RequestVoteResponse( + req *message.RequestVoteRequest, + ) *message.RequestVoteResponse { + s.lock.Lock() + s.node.PersistentState.mu.Lock() + currentTerm := s.node.PersistentState.CurrentTerm + selfID := s.node.PersistentState.SelfID.String() + s.node.PersistentState.mu.Unlock() + s.lock.Unlock() + + // If the candidate is not up to date with the term, reject the vote. + if req.Term < currentTerm { + s.node.log. + Debug(). + Str("leader ID", string(req.CandidateID)). + Msg("is stale") + return &message.RequestVoteResponse{ + Term: currentTerm, + VoteGranted: false, + } + } + + s.node.PersistentState.mu.Lock() + // If this node hasn't voted for any other node, + // vote only then. + // TODO: Check whether candidate's log is at least as up to date as mine only then grant vote. + isSelfTermLesser := currentTerm < req.GetTerm() + isSelfTermEqual := currentTerm == req.GetTerm() + hasVotedYet := isSelfTermEqual && (s.node.PersistentState.VotedFor == nil) + if isSelfTermLesser || hasVotedYet { + cID, err := id.Parse(req.CandidateID) + if err != nil { + // no point in handling this because I really need that to parse into ID. + fmt.Println(err) + } + s.node.PersistentState.VotedFor = cID + s.node.log. + Debug(). + Str("self-id", selfID). + Str("vote granted to", cID.String()). + Msg("voting a peer") + + s.timerReset <- struct{}{} + s.node.PersistentState.mu.Unlock() + return &message.RequestVoteResponse{ + Term: currentTerm, + VoteGranted: true, + } + } + s.node.PersistentState.mu.Unlock() + + return &message.RequestVoteResponse{ + Term: currentTerm, + VoteGranted: false, + } +} diff --git a/internal/raft/request_votes_test.go b/internal/raft/request_votes_test.go new file mode 100644 index 00000000..d805d0c4 --- /dev/null +++ b/internal/raft/request_votes_test.go @@ -0,0 +1,7 @@ +package raft + +import "testing" + +func Test_RequestVoteFail1(t *testing.T) { + +} \ No newline at end of file diff --git a/internal/raft/state.go b/internal/raft/state.go new file mode 100644 index 00000000..5aaec736 --- /dev/null +++ b/internal/raft/state.go @@ -0,0 +1,14 @@ +package raft + +//go:generate stringer -type=State + +// State is a raft state that a node can be in. +type State uint8 + +// Available states +const ( + StateUnknown State = iota + StateLeader + StateCandidate + StateFollower +) diff --git a/internal/raft/state_string.go b/internal/raft/state_string.go new file mode 100644 index 00000000..a478845f --- /dev/null +++ b/internal/raft/state_string.go @@ -0,0 +1,26 @@ +// Code generated by "stringer -type=State"; DO NOT EDIT. + +package raft + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[StateUnknown-0] + _ = x[StateLeader-1] + _ = x[StateCandidate-2] + _ = x[StateFollower-3] +} + +const _State_name = "StateUnknownStateLeaderStateCandidateStateFollower" + +var _State_index = [...]uint8{0, 12, 23, 37, 50} + +func (i State) String() string { + if i >= State(len(_State_index)-1) { + return "State(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _State_name[_State_index[i]:_State_index[i+1]] +} diff --git a/internal/raft/test_framework.go b/internal/raft/test_framework.go new file mode 100644 index 00000000..8f6c5923 --- /dev/null +++ b/internal/raft/test_framework.go @@ -0,0 +1,104 @@ +package raft + +import ( + "context" + + "github.com/xqueries/xdb/internal/compiler/command" + "github.com/xqueries/xdb/internal/id" + "github.com/xqueries/xdb/internal/network" +) + +// TestFramework describes a testing framework for creating +// a complete integration testing of the different modules of a +// raft implementation. +// +// The framework allows injecting mutiple types of operations, like, +// stopping a node, partitioning the cluster, adding an entry to the log +// of the cluster whilst allowing to monitor the operations of the cluster. +// +// The framework will be completely stable and run obeying the Operation +// parameters while running the cluster operations and logging their behaviour. +type TestFramework interface { + // OpParams provides the parameters for operation of the raft cluster. + OpParams() OperationParameters + // Cfg provides the network configuration of the cluster. + Config() NetworkConfiguration + // BeginTest kicks of all operations by starting the raft cluster. + // It obeys the parameters of operation and raises an error if the + // conditions for the test don't satisfy. + BeginTest(context.Context) error + // InjectOperation will initiate the given operation in the cluster. + InjectOperation(op Operation, args interface{}) + // GracefulShutdown ensures the cluster is shutdown by waiting for + // all the running operations to complete. + GracefulShutdown() error +} + +// OperationParameters are the bounds which dictate the parameters +// for the running integration test. +// +// The raft operation will run until it reaches the first of the two bounds. +// If the operation is in consensus in the first round, the TimeLimit variable +// will stop the operation once it's reached. +// +// All operations will be stopped gracefully whenever possible after the bounds +// are reached. +type OperationParameters struct { + // Rounds specifies how many rounds the raft operation must proceed until. + Rounds int + // TimeLimit specifies the limit until which the raft operation will run. + TimeLimit int + // Operations are all the operations that wil be performed in the test + Operations []OpData + // OperationPushDelay is the time in millisecond, that can be provided, + // to have a delay between pushing operations in the test framework. + // Zero can be passed if no delay is intended. + OperationPushDelay int +} + +// NetworkConfiguration holds the details of the network of the cluster. +type NetworkConfiguration struct { + IPs []network.Conn + IDs []id.ID +} + +// Operation describes the different types of operations that can be performed on the cluster. +type Operation int + +// Types of Operations. +const ( + SendData Operation = 1 + iota + StopNode + PartitionNetwork + RestartNode +) + +// OpData fully describes a runnable operation on the raft cluster. +// The "data" field can be either of the data related to the operation. +type OpData struct { + Op Operation + Data interface{} +} + +// OpSendData describes the data related to SendData. +type OpSendData struct { + Data []*command.Command +} + +// OpStopNode describes the data related to StopNode. +// The integer describes the position of the node in the provided node slice. +type OpStopNode struct { + NodeID int +} + +// OpPartitionNetwork describes the data related to PartitionNetwork. +// The integer describes the position of the node in the provided node slice. +type OpPartitionNetwork struct { + Groups int +} + +// OpRestartNode describes the data related to RestartNode. +// The integer describes the position of the node in the provided node slice. +type OpRestartNode struct { + NodeID int +} diff --git a/internal/tool/generate/keywordtrie/main.go b/internal/tool/generate/keywordtrie/main.go index fa6658d5..ceccec67 100644 --- a/internal/tool/generate/keywordtrie/main.go +++ b/internal/tool/generate/keywordtrie/main.go @@ -41,8 +41,8 @@ func defaultKeywordsRule(s RuneScanner) (token.Type, bool) { if !ok { return token.Unknown, false } - peek, noEof := s.Lookahead() - if noEof && defaultLiteral.Matches(peek) { // keywords must be terminated with a whitespace + peek, noEOF := s.Lookahead() + if noEOF && defaultLiteral.Matches(peek) { // keywords must be terminated with a whitespace return token.Unknown, false } return tok, ok