From 057bcc92191ccb29fbf45fad3c1cf33acc508f80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vicent=20Mart=C3=AD?= <42793+vmg@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:34:30 +0100 Subject: [PATCH 01/19] smartconnpool: Better handling for idle expiration (#17757) Signed-off-by: Vicent Marti --- go/pools/smartconnpool/connection.go | 5 +- go/pools/smartconnpool/pool.go | 83 ++++++++++++++---------- go/pools/smartconnpool/pool_test.go | 8 ++- go/pools/smartconnpool/stack.go | 26 ++------ go/pools/smartconnpool/timestamp.go | 94 ++++++++++++++++++++++++++++ 5 files changed, 160 insertions(+), 56 deletions(-) create mode 100644 go/pools/smartconnpool/timestamp.go diff --git a/go/pools/smartconnpool/connection.go b/go/pools/smartconnpool/connection.go index cdb5720596e..dbc235a8218 100644 --- a/go/pools/smartconnpool/connection.go +++ b/go/pools/smartconnpool/connection.go @@ -19,7 +19,6 @@ package smartconnpool import ( "context" "sync/atomic" - "time" ) type Connection interface { @@ -33,8 +32,8 @@ type Connection interface { type Pooled[C Connection] struct { next atomic.Pointer[Pooled[C]] - timeCreated time.Time - timeUsed time.Time + timeCreated timestamp + timeUsed timestamp pool *ConnPool[C] Conn C diff --git a/go/pools/smartconnpool/pool.go b/go/pools/smartconnpool/pool.go index 52346adb1a4..87a288bec3d 100644 --- a/go/pools/smartconnpool/pool.go +++ b/go/pools/smartconnpool/pool.go @@ -19,7 +19,6 @@ package smartconnpool import ( "context" "math/rand/v2" - "slices" "sync" "sync/atomic" "time" @@ -408,13 +407,13 @@ func (pool *ConnPool[C]) put(conn *Pooled[C]) { return } } else { - conn.timeUsed = time.Now() + conn.timeUsed.update() lifetime := pool.extendedMaxLifetime() - if lifetime > 0 && time.Until(conn.timeCreated.Add(lifetime)) < 0 { + if lifetime > 0 && conn.timeCreated.elapsed() > lifetime { pool.Metrics.maxLifetimeClosed.Add(1) conn.Close() - if err := pool.connReopen(context.Background(), conn, conn.timeUsed); err != nil { + if err := pool.connReopen(context.Background(), conn, conn.timeUsed.get()); err != nil { pool.closedConn() return } @@ -442,12 +441,30 @@ func (pool *ConnPool[C]) tryReturnConn(conn *Pooled[C]) bool { return false } +func (pool *ConnPool[C]) pop(stack *connStack[C]) *Pooled[C] { + // retry-loop: pop a connection from the stack and atomically check whether + // its timeout has elapsed. If the timeout has elapsed, the borrow will fail, + // which means that a background worker has already marked this connection + // as stale and is in the process of shutting it down. If we successfully mark + // the timeout as borrowed, we know that background workers will not be able + // to expire this connection (even if it's still visible to them), so it's + // safe to return it + for conn, ok := stack.Pop(); ok; conn, ok = stack.Pop() { + if conn.timeUsed.borrow() { + return conn + } + } + return nil +} + func (pool *ConnPool[C]) tryReturnAnyConn() bool { - if conn, ok := pool.clean.Pop(); ok { + if conn := pool.pop(&pool.clean); conn != nil { + conn.timeUsed.update() return pool.tryReturnConn(conn) } for u := 0; u <= stackMask; u++ { - if conn, ok := pool.settings[u].Pop(); ok { + if conn := pool.pop(&pool.settings[u]); conn != nil { + conn.timeUsed.update() return pool.tryReturnConn(conn) } } @@ -479,15 +496,15 @@ func (pool *ConnPool[D]) extendedMaxLifetime() time.Duration { return time.Duration(maxLifetime) + time.Duration(rand.Uint32N(uint32(maxLifetime))) } -func (pool *ConnPool[C]) connReopen(ctx context.Context, dbconn *Pooled[C], now time.Time) error { +func (pool *ConnPool[C]) connReopen(ctx context.Context, dbconn *Pooled[C], now time.Duration) error { var err error dbconn.Conn, err = pool.config.connect(ctx) if err != nil { return err } - dbconn.timeUsed = now - dbconn.timeCreated = now + dbconn.timeUsed.set(now) + dbconn.timeCreated.set(now) return nil } @@ -496,13 +513,14 @@ func (pool *ConnPool[C]) connNew(ctx context.Context) (*Pooled[C], error) { if err != nil { return nil, err } - now := time.Now() - return &Pooled[C]{ - timeCreated: now, - timeUsed: now, - pool: pool, - Conn: conn, - }, nil + pooled := &Pooled[C]{ + pool: pool, + Conn: conn, + } + now := monotonicNow() + pooled.timeUsed.set(now) + pooled.timeCreated.set(now) + return pooled, nil } func (pool *ConnPool[C]) getFromSettingsStack(setting *Setting) *Pooled[C] { @@ -515,7 +533,7 @@ func (pool *ConnPool[C]) getFromSettingsStack(setting *Setting) *Pooled[C] { for i := uint32(0); i <= stackMask; i++ { pos := (i + start) & stackMask - if conn, ok := pool.settings[pos].Pop(); ok { + if conn := pool.pop(&pool.settings[pos]); conn != nil { return conn } } @@ -549,7 +567,7 @@ func (pool *ConnPool[C]) get(ctx context.Context) (*Pooled[C], error) { pool.Metrics.getCount.Add(1) // best case: if there's a connection in the clean stack, return it right away - if conn, ok := pool.clean.Pop(); ok { + if conn := pool.pop(&pool.clean); conn != nil { pool.borrowed.Add(1) return conn, nil } @@ -585,7 +603,7 @@ func (pool *ConnPool[C]) get(ctx context.Context) (*Pooled[C], error) { err = conn.Conn.ResetSetting(ctx) if err != nil { conn.Close() - err = pool.connReopen(ctx, conn, time.Now()) + err = pool.connReopen(ctx, conn, monotonicNow()) if err != nil { pool.closedConn() return nil, err @@ -603,10 +621,10 @@ func (pool *ConnPool[C]) getWithSetting(ctx context.Context, setting *Setting) ( var err error // best case: check if there's a connection in the setting stack where our Setting belongs - conn, _ := pool.settings[setting.bucket&stackMask].Pop() + conn := pool.pop(&pool.settings[setting.bucket&stackMask]) // if there's connection with our setting, try popping a clean connection if conn == nil { - conn, _ = pool.clean.Pop() + conn = pool.pop(&pool.clean) } // otherwise try opening a brand new connection and we'll apply the setting to it if conn == nil { @@ -645,7 +663,7 @@ func (pool *ConnPool[C]) getWithSetting(ctx context.Context, setting *Setting) ( err = conn.Conn.ResetSetting(ctx) if err != nil { conn.Close() - err = pool.connReopen(ctx, conn, time.Now()) + err = pool.connReopen(ctx, conn, monotonicNow()) if err != nil { pool.closedConn() return nil, err @@ -710,7 +728,7 @@ func (pool *ConnPool[C]) setCapacity(ctx context.Context, newcap int64) error { // try closing from connections which are currently idle in the stacks conn := pool.getFromSettingsStack(nil) if conn == nil { - conn, _ = pool.clean.Pop() + conn = pool.pop(&pool.clean) } if conn == nil { time.Sleep(delay) @@ -732,21 +750,22 @@ func (pool *ConnPool[C]) closeIdleResources(now time.Time) { return } - var conns []*Pooled[C] + mono := monotonicFromTime(now) closeInStack := func(s *connStack[C]) { - conns = s.PopAll(conns[:0]) - slices.Reverse(conns) - - for _, conn := range conns { - if conn.timeUsed.Add(timeout).Sub(now) < 0 { + // Do a read-only best effort iteration of all the connection in this + // stack and atomically attempt to mark them as expired. + // Any connections that are marked as expired are _not_ removed from + // the stack; it's generally unsafe to remove nodes from the stack + // besides the head. When clients pop from the stack, they'll immediately + // notice the expired connection and ignore it. + // see: timestamp.expired + for conn := s.Peek(); conn != nil; conn = conn.next.Load() { + if conn.timeUsed.expired(mono, timeout) { pool.Metrics.idleClosed.Add(1) conn.Close() pool.closedConn() - continue } - - s.Push(conn) } } diff --git a/go/pools/smartconnpool/pool_test.go b/go/pools/smartconnpool/pool_test.go index 2ac3d1b00e3..202261e6f3b 100644 --- a/go/pools/smartconnpool/pool_test.go +++ b/go/pools/smartconnpool/pool_test.go @@ -619,8 +619,14 @@ func TestIdleTimeout(t *testing.T) { p.put(conn) } + time.Sleep(1 * time.Second) + for _, closed := range closers { - <-closed + select { + case <-closed: + default: + t.Fatalf("Connections remain open after 1 second") + } } // no need to assert anything: all the connections in the pool should are idle-closed diff --git a/go/pools/smartconnpool/stack.go b/go/pools/smartconnpool/stack.go index ea7ae50201e..8d656ee4e8d 100644 --- a/go/pools/smartconnpool/stack.go +++ b/go/pools/smartconnpool/stack.go @@ -25,6 +25,9 @@ import ( // connStack is a lock-free stack for Connection objects. It is safe to // use from several goroutines. type connStack[C Connection] struct { + // top is a pointer to the top node on the stack and to an increasing + // counter of pop operations, to prevent A-B-A races. + // See: https://en.wikipedia.org/wiki/ABA_problem top atomic2.PointerAndUint64[Pooled[C]] } @@ -54,24 +57,7 @@ func (s *connStack[C]) Pop() (*Pooled[C], bool) { } } -func (s *connStack[C]) PopAll(out []*Pooled[C]) []*Pooled[C] { - var oldHead *Pooled[C] - - for { - var popCount uint64 - oldHead, popCount = s.top.Load() - if oldHead == nil { - return out - } - if s.top.CompareAndSwap(oldHead, popCount, nil, popCount+1) { - break - } - runtime.Gosched() - } - - for oldHead != nil { - out = append(out, oldHead) - oldHead = oldHead.next.Load() - } - return out +func (s *connStack[C]) Peek() *Pooled[C] { + top, _ := s.top.Load() + return top } diff --git a/go/pools/smartconnpool/timestamp.go b/go/pools/smartconnpool/timestamp.go new file mode 100644 index 00000000000..961ff18a5c5 --- /dev/null +++ b/go/pools/smartconnpool/timestamp.go @@ -0,0 +1,94 @@ +package smartconnpool + +import ( + "math" + "sync/atomic" + "time" +) + +var monotonicRoot = time.Now() + +// timestamp is a monotonic point in time, stored as a number of +// nanoseconds since the monotonic root. This type is only 8 bytes +// and hence can always be accessed atomically +type timestamp struct { + nano atomic.Int64 +} + +// timestampExpired is a special value that means this timestamp is now past +// an arbitrary expiration point, and hence doesn't need to store +const timestampExpired = math.MaxInt64 + +// timestampBusy is a special value that means this timestamp no longer +// tracks an expiration point +const timestampBusy = math.MinInt64 + +// monotonicNow returns the current monotonic time as a time.Duration. +// This is a very efficient operation because time.Since performs direct +// substraction of monotonic times without considering the wall clock times. +func monotonicNow() time.Duration { + return time.Since(monotonicRoot) +} + +// monotonicFromTime converts a wall-clock time from time.Now into a +// monotonic timestamp. +// This is a very efficient operation because time.(*Time).Sub performs direct +// substraction of monotonic times without considering the wall clock times. +func monotonicFromTime(now time.Time) time.Duration { + return now.Sub(monotonicRoot) +} + +// set sets this timestamp to the given monotonic value +func (t *timestamp) set(mono time.Duration) { + t.nano.Store(int64(mono)) +} + +// get returns the monotonic time of this timestamp as the number of nanoseconds +// since the monotonic root. +func (t *timestamp) get() time.Duration { + return time.Duration(t.nano.Load()) +} + +// elapsed returns the number of nanoseconds that have passed since +// this timestamp was updated +func (t *timestamp) elapsed() time.Duration { + return monotonicNow() - t.get() +} + +// update sets this timestamp's value to the current monotonic time +func (t *timestamp) update() { + t.nano.Store(int64(monotonicNow())) +} + +// borrow attempts to borrow this timestamp atomically. +// It only succeeds if we can ensure that nobody else has marked +// this timestamp as expired. When succeeded, the timestamp +// is cleared as "busy" as it no longer tracks an expiration point. +func (t *timestamp) borrow() bool { + stamp := t.nano.Load() + switch stamp { + case timestampExpired: + return false + case timestampBusy: + panic("timestampBusy when borrowing a time") + default: + return t.nano.CompareAndSwap(stamp, timestampBusy) + } +} + +// expired attempts to atomically expire this timestamp. +// It only succeeds if we can ensure the timestamp hasn't been +// concurrently expired or borrowed. +func (t *timestamp) expired(now time.Duration, timeout time.Duration) bool { + stamp := t.nano.Load() + if stamp == timestampExpired { + return false + } + if stamp == timestampBusy { + return false + } + if now-time.Duration(stamp) > timeout { + return t.nano.CompareAndSwap(stamp, timestampExpired) + } + return false +} From 000fbbe0f848da5bd2d0a9781665fe6e9dc3cd72 Mon Sep 17 00:00:00 2001 From: Lucas Date: Thu, 13 Feb 2025 11:08:36 -0800 Subject: [PATCH 02/19] [Feature]: Sort results of getTablets for consistency in output/readability (#17771) Signed-off-by: Lucas Morduchowicz Co-authored-by: Lucas Morduchowicz --- go/vt/vtctl/grpcvtctldserver/server.go | 8 ++++++++ go/vt/vtctl/grpcvtctldserver/server_test.go | 6 +++--- .../grpcvtctldserver/testutil/proto_compare.go | 13 ------------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/go/vt/vtctl/grpcvtctldserver/server.go b/go/vt/vtctl/grpcvtctldserver/server.go index 2afb508e4a6..09896ffab9d 100644 --- a/go/vt/vtctl/grpcvtctldserver/server.go +++ b/go/vt/vtctl/grpcvtctldserver/server.go @@ -2326,6 +2326,10 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable tablets = append(tablets, ti.Tablet) } + // Sort the list of tablets alphabetically by alias to improve readability of output. + sort.Slice(tablets, func(i, j int) bool { + return topoproto.TabletAliasString(tablets[i].Alias) < topoproto.TabletAliasString(tablets[j].Alias) + }) return &vtctldatapb.GetTabletsResponse{Tablets: tablets}, nil } @@ -2414,6 +2418,10 @@ func (s *VtctldServer) GetTablets(ctx context.Context, req *vtctldatapb.GetTable adjustedTablets[i] = ti.Tablet } + // Sort the list of tablets alphabetically by alias to improve readability of output. + sort.Slice(adjustedTablets, func(i, j int) bool { + return topoproto.TabletAliasString(adjustedTablets[i].Alias) < topoproto.TabletAliasString(adjustedTablets[j].Alias) + }) return &vtctldatapb.GetTabletsResponse{ Tablets: adjustedTablets, diff --git a/go/vt/vtctl/grpcvtctldserver/server_test.go b/go/vt/vtctl/grpcvtctldserver/server_test.go index 252efc7d894..ac90cc0b8e5 100644 --- a/go/vt/vtctl/grpcvtctldserver/server_test.go +++ b/go/vt/vtctl/grpcvtctldserver/server_test.go @@ -4605,7 +4605,7 @@ func TestDeleteTablets(t *testing.T) { resp, err := vtctld.GetTablets(ctx, &vtctldatapb.GetTabletsRequest{}) assert.NoError(t, err, "cannot look up tablets from topo after issuing DeleteTablets request") - testutil.AssertSameTablets(t, tt.expectedRemainingTablets, resp.Tablets) + utils.MustMatch(t, tt.expectedRemainingTablets, resp.Tablets) } // Run the test @@ -8277,7 +8277,7 @@ func TestGetTablets(t *testing.T) { } assert.NoError(t, err) - testutil.AssertSameTablets(t, tt.expected, resp.Tablets) + utils.MustMatch(t, tt.expected, resp.Tablets) }) } } @@ -13338,7 +13338,7 @@ func TestTabletExternallyReparented(t *testing.T) { resp, err := vtctld.GetTablets(ctx, &vtctldatapb.GetTabletsRequest{}) require.NoError(t, err, "cannot get all tablets in the topo") - testutil.AssertSameTablets(t, tt.expectedTopo, resp.Tablets) + utils.MustMatch(t, tt.expectedTopo, resp.Tablets) }() } diff --git a/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go b/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go index 20ad0f692b0..eaf0786b12d 100644 --- a/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go +++ b/go/vt/vtctl/grpcvtctldserver/testutil/proto_compare.go @@ -18,15 +18,12 @@ package testutil import ( "encoding/json" - "fmt" - "sort" "testing" "github.com/stretchr/testify/assert" "vitess.io/vitess/go/test/utils" logutilpb "vitess.io/vitess/go/vt/proto/logutil" - topodatapb "vitess.io/vitess/go/vt/proto/topodata" vtctldatapb "vitess.io/vitess/go/vt/proto/vtctldata" ) @@ -108,16 +105,6 @@ func AssertPlannedReparentShardResponsesEqual(t *testing.T, expected *vtctldatap utils.MustMatch(t, expected, actual) } -func AssertSameTablets(t *testing.T, expected, actual []*topodatapb.Tablet) { - sort.Slice(expected, func(i, j int) bool { - return fmt.Sprintf("%v", expected[i]) < fmt.Sprintf("%v", expected[j]) - }) - sort.Slice(actual, func(i, j int) bool { - return fmt.Sprintf("%v", actual[i]) < fmt.Sprintf("%v", actual[j]) - }) - utils.MustMatch(t, expected, actual) -} - // AssertKeyspacesEqual is a convenience function to assert that two // vtctldatapb.Keyspace objects are equal, after clearing out any reserved // proto XXX_ fields. From 624a7ea37c8fb53c34bfd1e324de9611d1ad8ade Mon Sep 17 00:00:00 2001 From: Deepthi Sigireddi Date: Thu, 13 Feb 2025 15:40:23 -0800 Subject: [PATCH 03/19] Get some CLOMonitor checks passing (#17773) Signed-off-by: deepthi --- .clomonitor.yml | 8 ++++++++ README.md | 29 ++++++++++++++++++----------- 2 files changed, 26 insertions(+), 11 deletions(-) create mode 100644 .clomonitor.yml diff --git a/.clomonitor.yml b/.clomonitor.yml new file mode 100644 index 00000000000..92a86f5fc9d --- /dev/null +++ b/.clomonitor.yml @@ -0,0 +1,8 @@ +# CLOMonitor metadata file +# This file must be located at the root of the repository + +# Checks exemptions +exemptions: + - check: slack_presence # Check identifier (see https://github.com/cncf/clomonitor/blob/main/docs/checks.md#exemptions) + reason: "This project has a separate Slack workspace that predates its donation to CNCF. A link to it is present in the README." # Justification of this exemption (mandatory, it will be displayed on the UI) + diff --git a/README.md b/README.md index b1247a29469..e8cc7a0c118 100644 --- a/README.md +++ b/README.md @@ -7,29 +7,36 @@ # Vitess -Vitess is a database clustering system for horizontal scaling of MySQL -through generalized sharding. +Vitess is a cloud-native horizontally-scalable distributed database system that is built around MySQL. +Vitess can achieve unlimited scaling through generalized sharding. -By encapsulating shard-routing logic, Vitess allows application code and -database queries to remain agnostic to the distribution of data onto -multiple shards. With Vitess, you can even split and merge shards as your needs +Vitess allows application code and database queries to remain agnostic to the distribution of data onto +multiple database servers. With Vitess, you can even split and merge shards as your needs grow, with an atomic cutover step that takes only a few seconds. -Vitess has been a core component of YouTube's database infrastructure -since 2011, and has grown to encompass tens of thousands of MySQL nodes. +Vitess was a core component of YouTube's database infrastructure +from 2011, and grew to encompass tens of thousands of MySQL nodes. +Starting in 2015, Vitess was adopted by many other large companies, including Slack, Square (now Block), and JD.com. For more about Vitess, please visit [vitess.io](https://vitess.io). -Vitess has a growing community. [View the list of adopters](https://github.com/vitessio/vitess/blob/main/ADOPTERS.md). +## Community + +Vitess has a growing [community](https://github.com/vitessio/vitess/blob/main/ADOPTERS.md). + +If you are interested in contributing or participating in our monthly community meetings, please visit the [Community page on our website](https://vitess.io/community/). + +We also maintain a [roadmap](https://vitess.io/docs/roadmap/) on our website. + +Follow our [blog](https://blog.vitess.io/) for low-frequency updates like new features and releases. ## Reporting a Problem, Issue, or Bug -To report a problem, create a [GitHub issue](https://github.com/vitessio/vitess/issues). + +To report a problem, create a [GitHub issue](https://github.com/vitessio/vitess/issues). For topics that are better discussed live, please join the [Vitess Slack](https://vitess.io/slack) workspace. You may post any questions on the #general channel or join some of the special-interest channels. -Follow [Vitess Blog](https://blog.vitess.io/) for low-frequency updates like new features and releases. - ## Security ### Reporting Security Vulnerabilities From efa30d4f1a7a56ba81dc5be6fcd684e52703108a Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 14 Feb 2025 01:28:53 +0100 Subject: [PATCH 04/19] Simply changing GH Actions runner (#17788) Signed-off-by: Tim Vaillancourt --- test/ci_workflow_gen.go | 16 +++++++++++----- test/templates/cluster_endtoend_test.tpl | 2 +- test/templates/cluster_endtoend_test_docker.tpl | 2 +- test/templates/cluster_endtoend_test_mysql57.tpl | 2 +- test/templates/cluster_vitess_tester.tpl | 2 +- test/templates/unit_test.tpl | 2 +- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index bf42825d73c..a8f1a82e56f 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -33,6 +33,8 @@ const ( mysql80 mysqlVersion = "mysql80" mysql84 mysqlVersion = "mysql84" + cores16RunnerName = "gh-hosted-runners-16cores-1-24.04" + defaultRunnerName = "ubuntu-24.04" defaultMySQLVersion = mysql80 ) @@ -164,13 +166,14 @@ var ( ) type unitTest struct { - Name, Platform, FileName, Evalengine string + Name, RunsOn, Platform, FileName, Evalengine string } type clusterTest struct { Name, Shard, Platform string FileName string BuildTag string + RunsOn string MemoryCheck bool MakeTools, InstallXtraBackup bool Docker bool @@ -178,13 +181,13 @@ type clusterTest struct { EnableBinlogTransactionCompression bool EnablePartialJSON bool PartialKeyspace bool - Cores16 bool NeedsMinio bool } type vitessTesterTest struct { FileName string Name string + RunsOn string Path string } @@ -241,8 +244,9 @@ func canonnizeList(list []string) []string { func generateVitessTesterWorkflows(mp map[string]string, tpl string) { for test, testPath := range mp { tt := &vitessTesterTest{ - Name: fmt.Sprintf("Vitess Tester (%v)", test), - Path: testPath, + Name: fmt.Sprintf("Vitess Tester (%v)", test), + RunsOn: defaultRunnerName, + Path: testPath, } templateFileName := tpl @@ -263,11 +267,12 @@ func generateClusterWorkflows(list []string, tpl string) { Name: fmt.Sprintf("Cluster (%s)", cluster), Shard: cluster, BuildTag: buildTag[cluster], + RunsOn: defaultRunnerName, } cores16Clusters := canonnizeList(clusterRequiring16CoresMachines) for _, cores16Cluster := range cores16Clusters { if cores16Cluster == cluster { - test.Cores16 = true + test.RunsOn = cores16RunnerName break } } @@ -339,6 +344,7 @@ func generateUnitTestWorkflows() { for _, evalengine := range []string{"1", "0"} { test := &unitTest{ Name: fmt.Sprintf("Unit Test (%s%s)", evalengineToString(evalengine), platform), + RunsOn: defaultRunnerName, Platform: string(platform), Evalengine: evalengine, } diff --git a/test/templates/cluster_endtoend_test.tpl b/test/templates/cluster_endtoend_test.tpl index c5129805126..632bda5e407 100644 --- a/test/templates/cluster_endtoend_test.tpl +++ b/test/templates/cluster_endtoend_test.tpl @@ -15,7 +15,7 @@ jobs: build: timeout-minutes: 60 name: Run endtoend tests on {{.Name}} - runs-on: {{if .Cores16}}gh-hosted-runners-16cores-1-24.04{{else}}ubuntu-24.04{{end}} + runs-on: {{.RunsOn}} steps: - name: Skip CI diff --git a/test/templates/cluster_endtoend_test_docker.tpl b/test/templates/cluster_endtoend_test_docker.tpl index 39a36b88c89..619413391c5 100644 --- a/test/templates/cluster_endtoend_test_docker.tpl +++ b/test/templates/cluster_endtoend_test_docker.tpl @@ -6,7 +6,7 @@ permissions: read-all jobs: build: name: Run endtoend tests on {{.Name}} - runs-on: {{if .Cores16}}gh-hosted-runners-16cores-1-24.04{{else}}ubuntu-24.04{{end}} + runs-on: {{.RunsOn}} steps: - name: Skip CI diff --git a/test/templates/cluster_endtoend_test_mysql57.tpl b/test/templates/cluster_endtoend_test_mysql57.tpl index a6cbc969c1a..39932816c9b 100644 --- a/test/templates/cluster_endtoend_test_mysql57.tpl +++ b/test/templates/cluster_endtoend_test_mysql57.tpl @@ -19,7 +19,7 @@ env: jobs: build: name: Run endtoend tests on {{.Name}} - runs-on: {{if .Cores16}}gh-hosted-runners-16cores-1-24.04{{else}}ubuntu-24.04{{end}} + runs-on: {{.RunsOn}} steps: - name: Skip CI diff --git a/test/templates/cluster_vitess_tester.tpl b/test/templates/cluster_vitess_tester.tpl index 508824dde87..db8eb7d75ff 100644 --- a/test/templates/cluster_vitess_tester.tpl +++ b/test/templates/cluster_vitess_tester.tpl @@ -14,7 +14,7 @@ env: jobs: build: name: Run endtoend tests on {{.Name}} - runs-on: ubuntu-24.04 + runs-on: {{.RunsOn}} steps: - name: Skip CI diff --git a/test/templates/unit_test.tpl b/test/templates/unit_test.tpl index be71af987ed..3f6ab44bacd 100644 --- a/test/templates/unit_test.tpl +++ b/test/templates/unit_test.tpl @@ -14,7 +14,7 @@ env: jobs: test: name: {{.Name}} - runs-on: ubuntu-24.04 + runs-on: {{.RunsOn}} steps: - name: Skip CI From 420342fddb0ea91df012f7be4d1ae0b59e71448a Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:31:20 +0100 Subject: [PATCH 05/19] VReplication Atomic Copy Workflows: fix bugs around concurrent inserts (#17772) Signed-off-by: Rohit Nayak --- go/test/endtoend/vreplication/fk_ext_test.go | 5 ++++- go/test/endtoend/vreplication/fk_test.go | 14 +++++++++----- .../vreplication/vcopier_atomic.go | 17 ++++++++--------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/go/test/endtoend/vreplication/fk_ext_test.go b/go/test/endtoend/vreplication/fk_ext_test.go index d6716bcbf2d..74aac2cbed2 100644 --- a/go/test/endtoend/vreplication/fk_ext_test.go +++ b/go/test/endtoend/vreplication/fk_ext_test.go @@ -86,7 +86,10 @@ func TestFKExt(t *testing.T) { setSidecarDBName("_vt") // Ensure that there are multiple copy phase cycles per table. - extraVTTabletArgs = append(extraVTTabletArgs, "--vstream_packet_size=256", "--queryserver-config-schema-change-signal") + extraVTTabletArgs = append(extraVTTabletArgs, + "--vstream_packet_size=256", + "--queryserver-config-schema-change-signal", + parallelInsertWorkers) extraVTGateArgs = append(extraVTGateArgs, "--schema_change_signal=true", "--planner-version", "Gen4") defer func() { extraVTTabletArgs = nil }() initFKExtConfig(t) diff --git a/go/test/endtoend/vreplication/fk_test.go b/go/test/endtoend/vreplication/fk_test.go index 15664be51d9..a349a94ffa1 100644 --- a/go/test/endtoend/vreplication/fk_test.go +++ b/go/test/endtoend/vreplication/fk_test.go @@ -39,6 +39,7 @@ const testWorkflowFlavor = workflowFlavorVtctld // It inserts initial data, then simulates load. We insert both child rows with foreign keys and those without, // i.e. with foreign_key_checks=0. func TestFKWorkflow(t *testing.T) { + setSidecarDBName("_vt") extraVTTabletArgs = []string{ // Ensure that there are multiple copy phase cycles per table. "--vstream_packet_size=256", @@ -128,11 +129,14 @@ func TestFKWorkflow(t *testing.T) { vtgateConn, closeConn := getVTGateConn() defer closeConn() - t11Count := getRowCount(t, vtgateConn, "t11") - t12Count := getRowCount(t, vtgateConn, "t12") - require.Greater(t, t11Count, 1) - require.Greater(t, t12Count, 1) - require.Equal(t, t11Count, t12Count) + if withLoad { + t11Count := getRowCount(t, vtgateConn, "t11") + t12Count := getRowCount(t, vtgateConn, "t12") + require.Greater(t, t11Count, 1) + require.Greater(t, t12Count, 1) + require.Equal(t, t11Count, t12Count) + } + } func insertInitialFKData(t *testing.T) { diff --git a/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go b/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go index 1e3892c0f05..aae17027bc4 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vcopier_atomic.go @@ -84,11 +84,7 @@ func (vc *vcopier) copyAll(ctx context.Context, settings binlogplayer.VRSettings defer rowsCopiedTicker.Stop() parallelism := int(math.Max(1, float64(vc.vr.workflowConfig.ParallelInsertWorkers))) - // For now do not support concurrent inserts for atomic copies. - if parallelism > 1 { - parallelism = 1 - log.Infof("Disabling concurrent inserts for atomic copies") - } + copyWorkerFactory := vc.newCopyWorkerFactory(parallelism) var copyWorkQueue *vcopierCopyWorkQueue @@ -115,7 +111,6 @@ func (vc *vcopier) copyAll(ctx context.Context, settings binlogplayer.VRSettings resp.TableName, len(resp.Fields), len(resp.Rows), resp.Gtid, resp.Lastpk) tableName := resp.TableName gtid = resp.Gtid - updateRowsCopied := func() error { updateRowsQuery := binlogplayer.GenerateUpdateRowsCopied(vc.vr.id, vc.vr.stats.CopyRowCount.Get()) _, err := vc.vr.dbClient.Execute(updateRowsQuery) @@ -205,6 +200,10 @@ func (vc *vcopier) copyAll(ctx context.Context, settings binlogplayer.VRSettings log.Infof("copying table %s with lastpk %v", tableName, lastpkbv) // Prepare a vcopierCopyTask for the current batch of work. currCh := make(chan *vcopierCopyTaskResult, 1) + + if parallelism > 1 { + resp = resp.CloneVT() + } currT := newVCopierCopyTask(newVCopierCopyTaskArgs(resp.Rows, resp.Lastpk)) // Send result to the global resultCh and currCh. resultCh is used by @@ -292,12 +291,12 @@ func (vc *vcopier) copyAll(ctx context.Context, settings binlogplayer.VRSettings log.Infof("Copy of %v stopped", state.currentTableName) return fmt.Errorf("CopyAll was interrupted due to context expiration") default: - if err := vc.deleteCopyState(state.currentTableName); err != nil { - return err - } if copyWorkQueue != nil { copyWorkQueue.close() } + if err := vc.deleteCopyState(state.currentTableName); err != nil { + return err + } if err := vc.updatePos(ctx, gtid); err != nil { return err } From 70114ad687660d8fe4d6cb50bf4bf890ee0c66f5 Mon Sep 17 00:00:00 2001 From: Rohit Nayak <57520317+rohit-nayak-ps@users.noreply.github.com> Date: Fri, 14 Feb 2025 16:53:10 +0100 Subject: [PATCH 06/19] Multi-tenant workflow SwitchWrites: Don't add denied tables on cancelMigration() (#17782) Signed-off-by: Rohit Nayak --- go/vt/topotools/mirror_rules.go | 2 +- go/vt/vtctl/workflow/server.go | 1 - go/vt/vtctl/workflow/traffic_switcher.go | 25 +++++++++++++------ .../tabletmanager/vreplication/controller.go | 3 ++- .../tabletmanager/vreplication/vplayer.go | 5 ++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/go/vt/topotools/mirror_rules.go b/go/vt/topotools/mirror_rules.go index 3076a12b394..067b0544dab 100644 --- a/go/vt/topotools/mirror_rules.go +++ b/go/vt/topotools/mirror_rules.go @@ -55,7 +55,7 @@ func GetMirrorRules(ctx context.Context, ts *topo.Server) (map[string]map[string // SaveMirrorRules converts a mapping of fromTable=>[]toTables into a // vschemapb.MirrorRules protobuf message and saves it in the topology. func SaveMirrorRules(ctx context.Context, ts *topo.Server, rules map[string]map[string]float32) error { - log.Infof("Saving mirror rules %v\n", rules) + log.V(2).Infof("Saving mirror rules %v\n", rules) rrs := &vschemapb.MirrorRules{Rules: make([]*vschemapb.MirrorRule, 0)} for fromTable, mrs := range rules { diff --git a/go/vt/vtctl/workflow/server.go b/go/vt/vtctl/workflow/server.go index 4a1fb2e461a..efa7d6448b0 100644 --- a/go/vt/vtctl/workflow/server.go +++ b/go/vt/vtctl/workflow/server.go @@ -2977,7 +2977,6 @@ func (s *Server) switchWrites(ctx context.Context, req *vtctldatapb.WorkflowSwit time.Sleep(lockTablesCycleDelay) } } - // Get the source positions now that writes are stopped, the streams were stopped (e.g. // intra-keyspace materializations that write on the source), and we know for certain // that any in progress writes are done. diff --git a/go/vt/vtctl/workflow/traffic_switcher.go b/go/vt/vtctl/workflow/traffic_switcher.go index 4463e30b711..7e1df4a07ce 100644 --- a/go/vt/vtctl/workflow/traffic_switcher.go +++ b/go/vt/vtctl/workflow/traffic_switcher.go @@ -1154,9 +1154,9 @@ func (ts *trafficSwitcher) cancelMigration(ctx context.Context, sm *StreamMigrat if ctx.Err() != nil { // Even though we create a new context later on we still record any context error: // for forensics in case of failures. - ts.Logger().Infof("In Cancel migration: original context invalid: %s", ctx.Err()) + ts.Logger().Infof("cancelMigration (%v): original context invalid: %s", ts.WorkflowName(), ctx.Err()) } - + ts.Logger().Infof("cancelMigration (%v): starting", ts.WorkflowName()) // We create a new context while canceling the migration, so that we are independent of the original // context being canceled prior to or during the cancel operation itself. // First we create a copy of the parent context, so that we maintain the locks, but which cannot be @@ -1168,20 +1168,27 @@ func (ts *trafficSwitcher) cancelMigration(ctx context.Context, sm *StreamMigrat defer cmCancel() if ts.MigrationType() == binlogdatapb.MigrationType_TABLES { - err = ts.switchDeniedTables(cmCtx, true /* revert */) + if !ts.IsMultiTenantMigration() { + ts.Logger().Infof("cancelMigration (%v): adding denied tables to target", ts.WorkflowName()) + err = ts.switchDeniedTables(cmCtx, true /* revert */) + } else { + ts.Logger().Infof("cancelMigration (%v): multi-tenant, not adding denied tables to target", ts.WorkflowName()) + } } else { + ts.Logger().Infof("cancelMigration (%v): allowing writes on source shards", ts.WorkflowName()) err = ts.changeShardsAccess(cmCtx, ts.SourceKeyspaceName(), ts.SourceShards(), allowWrites) } if err != nil { cancelErrs.RecordError(fmt.Errorf("could not revert denied tables / shard access: %v", err)) - ts.Logger().Errorf("Cancel migration failed: could not revert denied tables / shard access: %v", err) + ts.Logger().Errorf("Cancel migration failed (%v): could not revert denied tables / shard access: %v", ts.WorkflowName(), err) } if err := sm.CancelStreamMigrations(cmCtx); err != nil { cancelErrs.RecordError(fmt.Errorf("could not cancel stream migrations: %v", err)) - ts.Logger().Errorf("Cancel migration failed: could not cancel stream migrations: %v", err) + ts.Logger().Errorf("Cancel migration failed (%v): could not cancel stream migrations: %v", ts.WorkflowName(), err) } + ts.Logger().Infof("cancelMigration (%v): restarting vreplication workflows", ts.WorkflowName()) err = ts.ForAllTargets(func(target *MigrationTarget) error { query := fmt.Sprintf("update _vt.vreplication set state='Running', message='' where db_name=%s and workflow=%s", encodeString(target.GetPrimary().DbName()), encodeString(ts.WorkflowName())) @@ -1190,17 +1197,21 @@ func (ts *trafficSwitcher) cancelMigration(ctx context.Context, sm *StreamMigrat }) if err != nil { cancelErrs.RecordError(fmt.Errorf("could not restart vreplication: %v", err)) - ts.Logger().Errorf("Cancel migration failed: could not restart vreplication: %v", err) + ts.Logger().Errorf("Cancel migration failed (%v): could not restart vreplication: %v", ts.WorkflowName(), err) } + ts.Logger().Infof("cancelMigration (%v): deleting reverse vreplication workflows", ts.WorkflowName()) if err := ts.deleteReverseVReplication(cmCtx); err != nil { cancelErrs.RecordError(fmt.Errorf("could not delete reverse vreplication streams: %v", err)) - ts.Logger().Errorf("Cancel migration failed: could not delete reverse vreplication streams: %v", err) + ts.Logger().Errorf("Cancel migration failed (%v): could not delete reverse vreplication streams: %v", ts.WorkflowName(), err) } if cancelErrs.HasErrors() { + ts.Logger().Errorf("Cancel migration failed for %v, manual cleanup work may be necessary: %v", ts.WorkflowName(), cancelErrs.AggrError(vterrors.Aggregate)) return vterrors.Wrap(cancelErrs.AggrError(vterrors.Aggregate), "cancel migration failed, manual cleanup work may be necessary") } + + ts.Logger().Infof("cancelMigration (%v): completed", ts.WorkflowName()) return nil } diff --git a/go/vt/vttablet/tabletmanager/vreplication/controller.go b/go/vt/vttablet/tabletmanager/vreplication/controller.go index 7067211ff10..113cb2314a0 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/controller.go +++ b/go/vt/vttablet/tabletmanager/vreplication/controller.go @@ -115,7 +115,6 @@ func newController(ctx context.Context, params map[string]string, dbClientFactor } blpStats.WorkflowConfig = workflowConfig.String() ct.sourceTablet.Store(&topodatapb.TabletAlias{}) - log.Infof("creating controller with cell: %v, tabletTypes: %v, and params: %v", cell, tabletTypesStr, params) id, err := strconv.ParseInt(params["id"], 10, 32) if err != nil { @@ -123,6 +122,8 @@ func newController(ctx context.Context, params map[string]string, dbClientFactor } ct.id = int32(id) ct.workflow = params["workflow"] + log.Infof("creating controller with id: %v, name: %v, cell: %v, tabletTypes: %v", ct.id, ct.workflow, cell, tabletTypesStr) + ct.lastWorkflowError = vterrors.NewLastError(fmt.Sprintf("VReplication controller %d for workflow %q", ct.id, ct.workflow), workflowConfig.MaxTimeToRetryError) state := params["state"] diff --git a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go index 31ab895934c..ae7a19db4dd 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/vplayer.go +++ b/go/vt/vttablet/tabletmanager/vreplication/vplayer.go @@ -125,7 +125,8 @@ func newVPlayer(vr *vreplicator, settings binlogplayer.VRSettings, copyState map settings.StopPos = pausePos saveStop = false } - log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, filter: %+v", + log.Infof("Starting VReplication player id: %v, name: %v, startPos: %v, stop: %v", vr.id, vr.WorkflowName, settings.StartPos, settings.StopPos) + log.V(2).Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, filter: %+v", vr.id, settings.StartPos, settings.StopPos, vr.source.Filter) queryFunc := func(ctx context.Context, sql string) (*sqltypes.Result, error) { return vr.dbClient.ExecuteWithRetry(ctx, sql) @@ -266,7 +267,7 @@ func (vp *vplayer) updateFKCheck(ctx context.Context, flags2 uint32) error { // one. This allows for the apply thread to catch up more quickly if // a backlog builds up. func (vp *vplayer) fetchAndApply(ctx context.Context) (err error) { - log.Infof("Starting VReplication player id: %v, startPos: %v, stop: %v, filter: %v", vp.vr.id, vp.startPos, vp.stopPos, vp.vr.source) + log.Infof("Starting VReplication player id: %v, name: %v, startPos: %v, stop: %v", vp.vr.id, vp.vr.WorkflowName, vp.startPos, vp.stopPos) ctx, cancel := context.WithCancel(ctx) defer cancel() From 1c064271cc056f1a604d5d8ef326f27e12431b3c Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 14 Feb 2025 23:21:17 +0100 Subject: [PATCH 07/19] `vtorc`: improve handling of partial cell topo results (#17718) Signed-off-by: Tim Vaillancourt --- go/vt/topo/faketopo/faketopo.go | 70 +++++++++++++++++----- go/vt/vtorc/logic/tablet_discovery.go | 67 ++++++++++++--------- go/vt/vtorc/logic/tablet_discovery_test.go | 60 +++++++++++++++++++ 3 files changed, 156 insertions(+), 41 deletions(-) diff --git a/go/vt/topo/faketopo/faketopo.go b/go/vt/topo/faketopo/faketopo.go index 0c88b95e3da..c49072c043f 100644 --- a/go/vt/topo/faketopo/faketopo.go +++ b/go/vt/topo/faketopo/faketopo.go @@ -45,17 +45,26 @@ func NewFakeTopoFactory() *FakeFactory { mu: sync.Mutex{}, cells: map[string][]*FakeConn{}, } - factory.cells[topo.GlobalCell] = []*FakeConn{newFakeConnection()} + factory.cells[topo.GlobalCell] = []*FakeConn{NewFakeConnection()} return factory } // AddCell is used to add a cell to the factory. It returns the fake connection created. This connection can then be used to set get and update errors func (f *FakeFactory) AddCell(cell string) *FakeConn { - conn := newFakeConnection() + f.mu.Lock() + defer f.mu.Unlock() + conn := NewFakeConnection() f.cells[cell] = []*FakeConn{conn} return conn } +// SetCell is used to set a cell in the factory. +func (f *FakeFactory) SetCell(cell string, fakeConn *FakeConn) { + f.mu.Lock() + defer f.mu.Unlock() + f.cells[cell] = []*FakeConn{fakeConn} +} + // HasGlobalReadOnlyCell implements the Factory interface func (f *FakeFactory) HasGlobalReadOnlyCell(serverAddr, root string) bool { return false @@ -70,7 +79,7 @@ func (f *FakeFactory) Create(cell, serverAddr, root string) (topo.Conn, error) { if !ok || len(connections) == 0 { return nil, topo.NewError(topo.NoNode, cell) } - // pick the first connection and remove it from the list + // pick the first connection and remove it from the list. conn := connections[0] f.cells[cell] = connections[1:] @@ -84,15 +93,19 @@ type FakeConn struct { cell string serverAddr string - // mutex to protect all the operations + // mutex to protect all the operations. mu sync.Mutex - // getResultMap is a map storing the results for each filepath + // getResultMap is a map storing the results for each filepath. getResultMap map[string]result - // updateErrors stores whether update function call should error or not + // listResultMap is a map storing the resuls for each filepath prefix. + listResultMap map[string][]topo.KVInfo + // updateErrors stores whether update function call should error or not. updateErrors []updateError - // getErrors stores whether the get function call should error or not + // getErrors stores whether the get function call should error or not. getErrors []bool + // listErrors stores whether the list function call should error or not. + listErrors []bool // watches is a map of all watches for this connection to the cell keyed by the filepath. watches map[string][]chan *topo.WatchData @@ -105,13 +118,15 @@ type updateError struct { writePersists bool } -// newFakeConnection creates a new fake connection -func newFakeConnection() *FakeConn { +// NewFakeConnection creates a new fake connection +func NewFakeConnection() *FakeConn { return &FakeConn{ - getResultMap: map[string]result{}, - watches: map[string][]chan *topo.WatchData{}, - getErrors: []bool{}, - updateErrors: []updateError{}, + getResultMap: map[string]result{}, + listResultMap: map[string][]topo.KVInfo{}, + watches: map[string][]chan *topo.WatchData{}, + getErrors: []bool{}, + listErrors: []bool{}, + updateErrors: []updateError{}, } } @@ -122,6 +137,20 @@ func (f *FakeConn) AddGetError(shouldErr bool) { f.getErrors = append(f.getErrors, shouldErr) } +// AddListError is used to add a list error to the fake connection +func (f *FakeConn) AddListError(shouldErr bool) { + f.mu.Lock() + defer f.mu.Unlock() + f.listErrors = append(f.listErrors, shouldErr) +} + +// AddListResult is used to add a list result to the fake connection +func (f *FakeConn) AddListResult(filePathPrefix string, result []topo.KVInfo) { + f.mu.Lock() + defer f.mu.Unlock() + f.listResultMap[filePathPrefix] = result +} + // AddUpdateError is used to add an update error to the fake connection func (f *FakeConn) AddUpdateError(shouldErr bool, writePersists bool) { f.mu.Lock() @@ -261,7 +290,20 @@ func (f *FakeConn) GetVersion(ctx context.Context, filePath string, version int6 // List is part of the topo.Conn interface. func (f *FakeConn) List(ctx context.Context, filePathPrefix string) ([]topo.KVInfo, error) { - return nil, topo.NewError(topo.NoImplementation, "List not supported in fake topo") + f.mu.Lock() + defer f.mu.Unlock() + if len(f.listErrors) > 0 { + shouldErr := f.listErrors[0] + f.listErrors = f.listErrors[1:] + if shouldErr { + return nil, topo.NewError(topo.Timeout, filePathPrefix) + } + } + kvInfos, isPresent := f.listResultMap[filePathPrefix] + if !isPresent { + return nil, topo.NewError(topo.NoNode, filePathPrefix) + } + return kvInfos, nil } // Delete implements the Conn interface diff --git a/go/vt/vtorc/logic/tablet_discovery.go b/go/vt/vtorc/logic/tablet_discovery.go index c5c23df0cd0..d90247409aa 100644 --- a/go/vt/vtorc/logic/tablet_discovery.go +++ b/go/vt/vtorc/logic/tablet_discovery.go @@ -150,26 +150,30 @@ func OpenTabletDiscovery() <-chan time.Time { return time.Tick(config.GetTopoInformationRefreshDuration()) //nolint SA1015: using time.Tick leaks the underlying ticker } -// getAllTablets gets all tablets from all cells using a goroutine per cell. -func getAllTablets(ctx context.Context, cells []string) []*topo.TabletInfo { - var tabletsMu sync.Mutex - tablets := make([]*topo.TabletInfo, 0) +// getAllTablets gets all tablets from all cells using a goroutine per cell. It returns a map of +// cells (string) to slices of tablets (as topo.TabletInfo) and a slice of cells (string) that +// failed to return a result. +func getAllTablets(ctx context.Context, cells []string) (tabletsByCell map[string][]*topo.TabletInfo, failedCells []string) { + var mu sync.Mutex + failedCells = make([]string, 0, len(cells)) + tabletsByCell = make(map[string][]*topo.TabletInfo, len(cells)) eg, ctx := errgroup.WithContext(ctx) for _, cell := range cells { eg.Go(func() error { - t, err := ts.GetTabletsByCell(ctx, cell, nil) + tablets, err := ts.GetTabletsByCell(ctx, cell, nil) + mu.Lock() + defer mu.Unlock() if err != nil { log.Errorf("Failed to load tablets from cell %s: %+v", cell, err) - return nil + failedCells = append(failedCells, cell) + } else { + tabletsByCell[cell] = tablets } - tabletsMu.Lock() - defer tabletsMu.Unlock() - tablets = append(tablets, t...) return nil }) } _ = eg.Wait() // always nil - return tablets + return tabletsByCell, failedCells } // refreshAllTablets reloads the tablets from topo and discovers the ones which haven't been refreshed in a while @@ -182,9 +186,9 @@ func refreshAllTablets(ctx context.Context) error { // refreshTabletsUsing refreshes tablets using a provided loader. func refreshTabletsUsing(ctx context.Context, loader func(tabletAlias string), forceRefresh bool) error { // Get all cells. - ctx, cancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) - defer cancel() - cells, err := ts.GetKnownCells(ctx) + cellsCtx, cellsCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) + defer cellsCancel() + cells, err := ts.GetKnownCells(cellsCtx) if err != nil { return err } @@ -192,25 +196,34 @@ func refreshTabletsUsing(ctx context.Context, loader func(tabletAlias string), f // Get all tablets from all cells. getTabletsCtx, getTabletsCancel := context.WithTimeout(ctx, topo.RemoteOperationTimeout) defer getTabletsCancel() - tablets := getAllTablets(getTabletsCtx, cells) - if len(tablets) == 0 { - log.Error("Found no tablets") + tabletsByCell, failedCells := getAllTablets(getTabletsCtx, cells) + if len(tabletsByCell) == 0 { + log.Error("Found no cells with tablets") return nil } + if len(failedCells) > 0 { + log.Errorf("Got partial topo result. Failed cells: %s", strings.Join(failedCells, ", ")) + } - // Filter tablets that should not be watched using shardsToWatch map. - matchedTablets := make([]*topo.TabletInfo, 0, len(tablets)) - func() { - for _, t := range tablets { - if shouldWatchTablet(t.Tablet) { - matchedTablets = append(matchedTablets, t) + // Update each cell that provided a response. This ensures only cells that provided a + // response are updated in the backend and are considered for forgetting stale tablets. + for cell, tablets := range tabletsByCell { + // Filter tablets that should not be watched using func shouldWatchTablet. + matchedTablets := make([]*topo.TabletInfo, 0, len(tablets)) + func() { + for _, t := range tablets { + if shouldWatchTablet(t.Tablet) { + matchedTablets = append(matchedTablets, t) + } } - } - }() + }() + + // Refresh the filtered tablets and forget stale tablets. + query := "select alias from vitess_tablet where cell = ?" + args := sqlutils.Args(cell) + refreshTablets(matchedTablets, query, args, loader, forceRefresh, nil) + } - // Refresh the filtered tablets. - query := "select alias from vitess_tablet" - refreshTablets(matchedTablets, query, nil, loader, forceRefresh, nil) return nil } diff --git a/go/vt/vtorc/logic/tablet_discovery_test.go b/go/vt/vtorc/logic/tablet_discovery_test.go index 4514ef81724..c351fb41c0a 100644 --- a/go/vt/vtorc/logic/tablet_discovery_test.go +++ b/go/vt/vtorc/logic/tablet_discovery_test.go @@ -19,6 +19,7 @@ package logic import ( "context" "fmt" + "slices" "strings" "sync/atomic" "testing" @@ -34,6 +35,7 @@ import ( topodatapb "vitess.io/vitess/go/vt/proto/topodata" "vitess.io/vitess/go/vt/proto/vttime" "vitess.io/vitess/go/vt/topo" + "vitess.io/vitess/go/vt/topo/faketopo" "vitess.io/vitess/go/vt/topo/memorytopo" "vitess.io/vitess/go/vt/topo/topoproto" "vitess.io/vitess/go/vt/vtctl/grpcvtctldserver/testutil" @@ -840,3 +842,61 @@ func TestSetReplicationSource(t *testing.T) { }) } } + +func TestGetAllTablets(t *testing.T) { + tablet := &topodatapb.Tablet{ + Hostname: t.Name(), + } + tabletProto, _ := tablet.MarshalVT() + + factory := faketopo.NewFakeTopoFactory() + + // zone1 (success) + goodCell1 := faketopo.NewFakeConnection() + goodCell1.AddListResult("tablets", []topo.KVInfo{ + { + Key: []byte("zone1-00000001"), + Value: tabletProto, + }, + }) + factory.SetCell("zone1", goodCell1) + + // zone2 (success) + goodCell2 := faketopo.NewFakeConnection() + goodCell2.AddListResult("tablets", []topo.KVInfo{ + { + Key: []byte("zone2-00000002"), + Value: tabletProto, + }, + }) + factory.SetCell("zone2", goodCell2) + + // zone3 (fail) + badCell1 := faketopo.NewFakeConnection() + badCell1.AddListError(true) + factory.SetCell("zone3", badCell1) + + // zone4 (fail) + badCell2 := faketopo.NewFakeConnection() + badCell2.AddListError(true) + factory.SetCell("zone4", badCell2) + + oldTs := ts + defer func() { + ts = oldTs + }() + ctx := context.Background() + ts = faketopo.NewFakeTopoServer(ctx, factory) + + // confirm zone1 + zone2 succeeded and zone3 + zone4 failed + tabletsByCell, failedCells := getAllTablets(ctx, []string{"zone1", "zone2", "zone3", "zone4"}) + require.Len(t, tabletsByCell, 2) + slices.Sort(failedCells) + require.Equal(t, []string{"zone3", "zone4"}, failedCells) + for _, tablets := range tabletsByCell { + require.Len(t, tablets, 1) + for _, tablet := range tablets { + require.Equal(t, t.Name(), tablet.Tablet.GetHostname()) + } + } +} From cf7fa682d12f19eeefe90891bc3090982a99c71a Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Fri, 14 Feb 2025 23:22:10 +0100 Subject: [PATCH 08/19] nit: move new `const`s to own section (#17802) Signed-off-by: Tim Vaillancourt --- test/ci_workflow_gen.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go index a8f1a82e56f..a00d5bec9bf 100644 --- a/test/ci_workflow_gen.go +++ b/test/ci_workflow_gen.go @@ -33,8 +33,6 @@ const ( mysql80 mysqlVersion = "mysql80" mysql84 mysqlVersion = "mysql84" - cores16RunnerName = "gh-hosted-runners-16cores-1-24.04" - defaultRunnerName = "ubuntu-24.04" defaultMySQLVersion = mysql80 ) @@ -48,6 +46,11 @@ var ( unitTestDatabases = []mysqlVersion{mysql57, mysql80, mysql84} ) +const ( + cores16RunnerName = "gh-hosted-runners-16cores-1-24.04" + defaultRunnerName = "ubuntu-24.04" +) + const ( workflowConfigDir = "../.github/workflows" From f131dd6d3142f05b6b1265d403df242aca1ff0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Taylor?= Date: Sat, 15 Feb 2025 08:26:47 +0100 Subject: [PATCH 09/19] Use ast-paths for subquery planning to improve performance (#17738) Signed-off-by: Andres Taylor Signed-off-by: Manan Gupta Signed-off-by: Vicent Marti Signed-off-by: Harshit Gangal Co-authored-by: Manan Gupta Co-authored-by: Vicent Marti Co-authored-by: Harshit Gangal --- go/tools/asthelpergen/asthelpergen.go | 10 +- go/tools/asthelpergen/clone_gen.go | 2 +- go/tools/asthelpergen/copy_on_rewrite_gen.go | 2 +- go/tools/asthelpergen/equals_gen.go | 6 +- .../asthelpergen/integration/ast_clone.go | 27 +- .../integration/ast_copy_on_rewrite.go | 26 +- .../asthelpergen/integration/ast_equals.go | 36 +- go/tools/asthelpergen/integration/ast_path.go | 136 + .../asthelpergen/integration/ast_path_test.go | 65 + .../asthelpergen/integration/ast_rewrite.go | 163 +- .../asthelpergen/integration/ast_visit.go | 14 +- .../integration/integration_rewriter_test.go | 6 +- .../integration/integration_visit_test.go | 4 +- go/tools/asthelpergen/integration/paths.go | 43 + .../asthelpergen/integration/test_helpers.go | 69 + go/tools/asthelpergen/integration/types.go | 138 +- go/tools/asthelpergen/paths_gen.go | 266 ++ go/tools/asthelpergen/rewrite_gen.go | 152 +- go/tools/asthelpergen/visit_gen.go | 5 +- go/vt/sqlparser/ast_clone.go | 2 +- go/vt/sqlparser/ast_copy_on_rewrite.go | 2 +- go/vt/sqlparser/ast_equals.go | 2 +- go/vt/sqlparser/ast_path.go | 2777 ++++++++++++++ go/vt/sqlparser/ast_rewrite.go | 3329 ++++++++++++++++- go/vt/sqlparser/ast_visit.go | 2 +- go/vt/sqlparser/pathbuilder/builder.go | 71 + go/vt/sqlparser/pathbuilder/builder_test.go | 134 + go/vt/sqlparser/paths.go | 88 + go/vt/sqlparser/paths_test.go | 51 + go/vt/sqlparser/rewriter_api.go | 31 +- go/vt/sqlparser/rewriter_test.go | 39 + go/vt/vtgate/planbuilder/operators/join.go | 2 +- .../planbuilder/operators/subquery_builder.go | 59 +- go/vt/vtgate/semantics/semantic_table.go | 15 + 34 files changed, 7571 insertions(+), 203 deletions(-) create mode 100644 go/tools/asthelpergen/integration/ast_path.go create mode 100644 go/tools/asthelpergen/integration/ast_path_test.go create mode 100644 go/tools/asthelpergen/integration/paths.go create mode 100644 go/tools/asthelpergen/paths_gen.go create mode 100644 go/vt/sqlparser/ast_path.go create mode 100644 go/vt/sqlparser/pathbuilder/builder.go create mode 100644 go/vt/sqlparser/pathbuilder/builder_test.go create mode 100644 go/vt/sqlparser/paths.go create mode 100644 go/vt/sqlparser/paths_test.go diff --git a/go/tools/asthelpergen/asthelpergen.go b/go/tools/asthelpergen/asthelpergen.go index ebb015b7339..746463767bd 100644 --- a/go/tools/asthelpergen/asthelpergen.go +++ b/go/tools/asthelpergen/asthelpergen.go @@ -32,7 +32,7 @@ import ( "vitess.io/vitess/go/tools/codegen" ) -const licenseFileHeader = `Copyright 2023 The Vitess Authors. +const licenseFileHeader = `Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -51,10 +51,10 @@ type ( addType(t types.Type) scope() *types.Scope findImplementations(iff *types.Interface, impl func(types.Type) error) error - iface() *types.Interface + iface() *types.Interface // the root interface that all nodes are expected to implement } generator interface { - genFile() (string, *jen.File) + genFile(generatorSPI) (string, *jen.File) interfaceMethod(t types.Type, iface *types.Interface, spi generatorSPI) error structMethod(t types.Type, strct *types.Struct, spi generatorSPI) error ptrToStructMethod(t types.Type, strct *types.Struct, spi generatorSPI) error @@ -206,9 +206,11 @@ func GenerateASTHelpers(options *Options) (map[string]*jen.File, error) { nt := tt.Type().(*types.Named) pName := nt.Obj().Pkg().Name() + ifaceName := types.TypeString(nt, noQualifier) generator := newGenerator(loaded[0].Module, loaded[0].TypesSizes, nt, newEqualsGen(pName, &options.Equals), newCloneGen(pName, &options.Clone), + newPathGen(pName, ifaceName), newVisitGen(pName), newRewriterGen(pName, types.TypeString(nt, noQualifier)), newCOWGen(pName, nt), @@ -298,7 +300,7 @@ func (gen *astHelperGen) createFiles() map[string]*jen.File { result := map[string]*jen.File{} for _, g := range gen.gens { - fName, jenFile := g.genFile() + fName, jenFile := g.genFile(gen) result[fName] = jenFile } return result diff --git a/go/tools/asthelpergen/clone_gen.go b/go/tools/asthelpergen/clone_gen.go index 10387a5dc25..eed3ff685ee 100644 --- a/go/tools/asthelpergen/clone_gen.go +++ b/go/tools/asthelpergen/clone_gen.go @@ -56,7 +56,7 @@ func (c *cloneGen) addFunc(name string, code *jen.Statement) { c.file.Add(code) } -func (c *cloneGen) genFile() (string, *jen.File) { +func (c *cloneGen) genFile(generatorSPI) (string, *jen.File) { return "ast_clone.go", c.file } diff --git a/go/tools/asthelpergen/copy_on_rewrite_gen.go b/go/tools/asthelpergen/copy_on_rewrite_gen.go index 1daa8d18981..a12e71cbe8f 100644 --- a/go/tools/asthelpergen/copy_on_rewrite_gen.go +++ b/go/tools/asthelpergen/copy_on_rewrite_gen.go @@ -44,7 +44,7 @@ func (c *cowGen) addFunc(code *jen.Statement) { c.file.Add(code) } -func (c *cowGen) genFile() (string, *jen.File) { +func (c *cowGen) genFile(generatorSPI) (string, *jen.File) { return "ast_copy_on_rewrite.go", c.file } diff --git a/go/tools/asthelpergen/equals_gen.go b/go/tools/asthelpergen/equals_gen.go index e00c3ef596a..2e34eb5a36c 100644 --- a/go/tools/asthelpergen/equals_gen.go +++ b/go/tools/asthelpergen/equals_gen.go @@ -62,7 +62,7 @@ func (e *equalsGen) customComparatorField(t types.Type) string { return printableTypeName(t) + "_" } -func (e *equalsGen) genFile() (string, *jen.File) { +func (e *equalsGen) genFile(generatorSPI) (string, *jen.File) { e.file.Type().Id(Comparator).StructFunc(func(g *jen.Group) { for tname, t := range e.comparators { if t == nil { @@ -303,6 +303,4 @@ func (e *equalsGen) sliceMethod(t types.Type, slice *types.Slice, spi generatorS return nil } -func (e *equalsGen) basicMethod(types.Type, *types.Basic, generatorSPI) error { - return nil -} +func (*equalsGen) basicMethod(types.Type, *types.Basic, generatorSPI) error { return nil } diff --git a/go/tools/asthelpergen/integration/ast_clone.go b/go/tools/asthelpergen/integration/ast_clone.go index d5857c89834..7b085a4c034 100644 --- a/go/tools/asthelpergen/integration/ast_clone.go +++ b/go/tools/asthelpergen/integration/ast_clone.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -115,6 +115,7 @@ func CloneRefOfRefContainer(n *RefContainer) *RefContainer { } out := *n out.ASTType = CloneAST(n.ASTType) + out.Opts = CloneSliceOfRefOfOptions(n.Opts) out.ASTImplementationType = CloneRefOfLeaf(n.ASTImplementationType) return &out } @@ -176,6 +177,18 @@ func CloneRefOfInterfaceContainer(n *InterfaceContainer) *InterfaceContainer { return &out } +// CloneSliceOfRefOfOptions creates a deep clone of the input. +func CloneSliceOfRefOfOptions(n []*Options) []*Options { + if n == nil { + return nil + } + res := make([]*Options, len(n)) + for i, x := range n { + res[i] = CloneRefOfOptions(x) + } + return res +} + // CloneSliceOfAST creates a deep clone of the input. func CloneSliceOfAST(n []AST) []AST { if n == nil { @@ -238,6 +251,16 @@ func CloneRefOfValueSliceContainer(n *ValueSliceContainer) *ValueSliceContainer out := *n out.ASTElements = CloneSliceOfAST(n.ASTElements) out.NotASTElements = CloneSliceOfInt(n.NotASTElements) - out.ASTImplementationElements = CloneSliceOfRefOfLeaf(n.ASTImplementationElements) + out.ASTImplementationElements = CloneLeafSlice(n.ASTImplementationElements) + return &out +} + +// CloneRefOfOptions creates a deep clone of the input. +func CloneRefOfOptions(n *Options) *Options { + if n == nil { + return nil + } + out := *n + out.l = CloneRefOfLeaf(n.l) return &out } diff --git a/go/tools/asthelpergen/integration/ast_copy_on_rewrite.go b/go/tools/asthelpergen/integration/ast_copy_on_rewrite.go index d48e8621692..84c13fac6a7 100644 --- a/go/tools/asthelpergen/integration/ast_copy_on_rewrite.go +++ b/go/tools/asthelpergen/integration/ast_copy_on_rewrite.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -262,19 +262,11 @@ func (c *cow) copyOnRewriteValueSliceContainer(n ValueSliceContainer, parent AST changedASTElements = true } } - var changedASTImplementationElements bool - _ASTImplementationElements := make([]*Leaf, len(n.ASTImplementationElements)) - for x, el := range n.ASTImplementationElements { - this, changed := c.copyOnRewriteRefOfLeaf(el, n) - _ASTImplementationElements[x] = this.(*Leaf) - if changed { - changedASTImplementationElements = true - } - } + _ASTImplementationElements, changedASTImplementationElements := c.copyOnRewriteLeafSlice(n.ASTImplementationElements, n) if changedASTElements || changedASTImplementationElements { res := n res.ASTElements = _ASTElements - res.ASTImplementationElements = _ASTImplementationElements + res.ASTImplementationElements, _ = _ASTImplementationElements.(LeafSlice) out = &res if c.cloned != nil { c.cloned(n, out) @@ -364,19 +356,11 @@ func (c *cow) copyOnRewriteRefOfValueSliceContainer(n *ValueSliceContainer, pare changedASTElements = true } } - var changedASTImplementationElements bool - _ASTImplementationElements := make([]*Leaf, len(n.ASTImplementationElements)) - for x, el := range n.ASTImplementationElements { - this, changed := c.copyOnRewriteRefOfLeaf(el, n) - _ASTImplementationElements[x] = this.(*Leaf) - if changed { - changedASTImplementationElements = true - } - } + _ASTImplementationElements, changedASTImplementationElements := c.copyOnRewriteLeafSlice(n.ASTImplementationElements, n) if changedASTElements || changedASTImplementationElements { res := *n res.ASTElements = _ASTElements - res.ASTImplementationElements = _ASTImplementationElements + res.ASTImplementationElements, _ = _ASTImplementationElements.(LeafSlice) out = &res if c.cloned != nil { c.cloned(n, out) diff --git a/go/tools/asthelpergen/integration/ast_equals.go b/go/tools/asthelpergen/integration/ast_equals.go index 553851a8c97..5ca81b6e90a 100644 --- a/go/tools/asthelpergen/integration/ast_equals.go +++ b/go/tools/asthelpergen/integration/ast_equals.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -180,6 +180,7 @@ func (cmp *Comparator) RefOfRefContainer(a, b *RefContainer) bool { } return a.NotASTType == b.NotASTType && cmp.AST(a.ASTType, b.ASTType) && + cmp.SliceOfRefOfOptions(a.Opts, b.Opts) && cmp.RefOfLeaf(a.ASTImplementationType, b.ASTImplementationType) } @@ -191,7 +192,8 @@ func (cmp *Comparator) RefOfRefSliceContainer(a, b *RefSliceContainer) bool { if a == nil || b == nil { return false } - return cmp.SliceOfAST(a.ASTElements, b.ASTElements) && + return a.something == b.something && + cmp.SliceOfAST(a.ASTElements, b.ASTElements) && cmp.SliceOfInt(a.NotASTElements, b.NotASTElements) && cmp.SliceOfRefOfLeaf(a.ASTImplementationElements, b.ASTImplementationElements) } @@ -219,7 +221,7 @@ func (cmp *Comparator) ValueContainer(a, b ValueContainer) bool { func (cmp *Comparator) ValueSliceContainer(a, b ValueSliceContainer) bool { return cmp.SliceOfAST(a.ASTElements, b.ASTElements) && cmp.SliceOfInt(a.NotASTElements, b.NotASTElements) && - cmp.SliceOfRefOfLeaf(a.ASTImplementationElements, b.ASTImplementationElements) + cmp.LeafSlice(a.ASTImplementationElements, b.ASTImplementationElements) } // SubIface does deep equals between the two objects. @@ -254,6 +256,19 @@ func (cmp *Comparator) RefOfInterfaceContainer(a, b *InterfaceContainer) bool { return true } +// SliceOfRefOfOptions does deep equals between the two objects. +func (cmp *Comparator) SliceOfRefOfOptions(a, b []*Options) bool { + if len(a) != len(b) { + return false + } + for i := 0; i < len(a); i++ { + if !cmp.RefOfOptions(a[i], b[i]) { + return false + } + } + return true +} + // SliceOfAST does deep equals between the two objects. func (cmp *Comparator) SliceOfAST(a, b []AST) bool { if len(a) != len(b) { @@ -327,7 +342,20 @@ func (cmp *Comparator) RefOfValueSliceContainer(a, b *ValueSliceContainer) bool } return cmp.SliceOfAST(a.ASTElements, b.ASTElements) && cmp.SliceOfInt(a.NotASTElements, b.NotASTElements) && - cmp.SliceOfRefOfLeaf(a.ASTImplementationElements, b.ASTImplementationElements) + cmp.LeafSlice(a.ASTImplementationElements, b.ASTImplementationElements) +} + +// RefOfOptions does deep equals between the two objects. +func (cmp *Comparator) RefOfOptions(a, b *Options) bool { + if a == b { + return true + } + if a == nil || b == nil { + return false + } + return a.a == b.a && + a.b == b.b && + cmp.RefOfLeaf(a.l, b.l) } type Comparator struct{} diff --git a/go/tools/asthelpergen/integration/ast_path.go b/go/tools/asthelpergen/integration/ast_path.go new file mode 100644 index 00000000000..a1fd838b170 --- /dev/null +++ b/go/tools/asthelpergen/integration/ast_path.go @@ -0,0 +1,136 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by ASTHelperGen. DO NOT EDIT. + +package integration + +type ASTStep uint16 + +const ( + InterfaceSliceOffset ASTStep = iota + LeafSliceOffset + RefOfRefContainerASTType + RefOfRefContainerASTImplementationType + RefOfRefSliceContainerASTElementsOffset + RefOfRefSliceContainerASTImplementationElementsOffset + RefOfSubImplinner + ValueContainerASTType + ValueContainerASTImplementationType + ValueSliceContainerASTElementsOffset + ValueSliceContainerASTImplementationElements + SliceOfASTOffset + SliceOfRefOfLeafOffset + RefOfValueContainerASTType + RefOfValueContainerASTImplementationType + RefOfValueSliceContainerASTElementsOffset + RefOfValueSliceContainerASTImplementationElements + RefOfOptionsl +) + +func (s ASTStep) DebugString() string { + switch s { + case InterfaceSliceOffset: + return "(InterfaceSlice)[]Offset" + case LeafSliceOffset: + return "(LeafSlice)[]Offset" + case RefOfRefContainerASTType: + return "(*RefContainer).ASTType" + case RefOfRefContainerASTImplementationType: + return "(*RefContainer).ASTImplementationType" + case RefOfRefSliceContainerASTElementsOffset: + return "(*RefSliceContainer).ASTElementsOffset" + case RefOfRefSliceContainerASTImplementationElementsOffset: + return "(*RefSliceContainer).ASTImplementationElementsOffset" + case RefOfSubImplinner: + return "(*SubImpl).inner" + case ValueContainerASTType: + return "(ValueContainer).ASTType" + case ValueContainerASTImplementationType: + return "(ValueContainer).ASTImplementationType" + case ValueSliceContainerASTElementsOffset: + return "(ValueSliceContainer).ASTElementsOffset" + case ValueSliceContainerASTImplementationElements: + return "(ValueSliceContainer).ASTImplementationElements" + case SliceOfASTOffset: + return "([]AST)[]Offset" + case SliceOfRefOfLeafOffset: + return "([]*Leaf)[]Offset" + case RefOfValueContainerASTType: + return "(*ValueContainer).ASTType" + case RefOfValueContainerASTImplementationType: + return "(*ValueContainer).ASTImplementationType" + case RefOfValueSliceContainerASTElementsOffset: + return "(*ValueSliceContainer).ASTElementsOffset" + case RefOfValueSliceContainerASTImplementationElements: + return "(*ValueSliceContainer).ASTImplementationElements" + case RefOfOptionsl: + return "(*Options).l" + } + panic("unknown ASTStep") +} +func GetNodeFromPath(node AST, path ASTPath) AST { + for len(path) >= 2 { + step := path.nextPathStep() + path = path[2:] + switch step { + case InterfaceSliceOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(InterfaceSlice)[idx] + case LeafSliceOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(LeafSlice)[idx] + case RefOfRefContainerASTType: + node = node.(*RefContainer).ASTType + case RefOfRefContainerASTImplementationType: + node = node.(*RefContainer).ASTImplementationType + case RefOfRefSliceContainerASTElementsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*RefSliceContainer).ASTElements[idx] + case RefOfRefSliceContainerASTImplementationElementsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*RefSliceContainer).ASTImplementationElements[idx] + case RefOfSubImplinner: + node = node.(*SubImpl).inner + case ValueContainerASTType: + node = node.(ValueContainer).ASTType + case ValueContainerASTImplementationType: + node = node.(ValueContainer).ASTImplementationType + case ValueSliceContainerASTElementsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(ValueSliceContainer).ASTElements[idx] + case ValueSliceContainerASTImplementationElements: + node = node.(ValueSliceContainer).ASTImplementationElements + case RefOfValueContainerASTType: + node = node.(*ValueContainer).ASTType + case RefOfValueContainerASTImplementationType: + node = node.(*ValueContainer).ASTImplementationType + case RefOfValueSliceContainerASTElementsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*ValueSliceContainer).ASTElements[idx] + case RefOfValueSliceContainerASTImplementationElements: + node = node.(*ValueSliceContainer).ASTImplementationElements + default: + return nil + } + } + return node +} diff --git a/go/tools/asthelpergen/integration/ast_path_test.go b/go/tools/asthelpergen/integration/ast_path_test.go new file mode 100644 index 00000000000..36ef35951aa --- /dev/null +++ b/go/tools/asthelpergen/integration/ast_path_test.go @@ -0,0 +1,65 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +import ( + "fmt" + "reflect" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestWalkAllPartsOfAST(t *testing.T) { + sliceContainer := &RefSliceContainer{ + something: 12, + ASTElements: []AST{}, + NotASTElements: []int{1, 2}, + ASTImplementationElements: []*Leaf{{v: 1}, {v: 2}}, + } + + for i := range 20 { + sliceContainer.ASTImplementationElements = append(sliceContainer.ASTImplementationElements, &Leaf{v: 3 + i}) + } + + ast := &RefContainer{ + ASTType: sliceContainer, + NotASTType: 2, + ASTImplementationType: &Leaf{v: 23}, + } + + var leafPaths []ASTPath + RewriteWithPaths(ast, func(c *Cursor) bool { + node := c.Node() + if !reflect.TypeOf(node).Comparable() { + return true + } + if _, isLeaf := node.(*Leaf); isLeaf { + leafPaths = append(leafPaths, c.Path()) + } + fmt.Println(c.Path().DebugString()) + return true + }, nil) + + require.Len(t, leafPaths, 23) + for idx, path := range leafPaths { + fmt.Println("Walking: " + path.DebugString()) + node := GetNodeFromPath(ast, path) + require.IsType(t, &Leaf{}, node) + require.EqualValues(t, idx+1, node.(*Leaf).v) + } +} diff --git a/go/tools/asthelpergen/integration/ast_rewrite.go b/go/tools/asthelpergen/integration/ast_rewrite.go index 74dc743a581..89f6966558e 100644 --- a/go/tools/asthelpergen/integration/ast_rewrite.go +++ b/go/tools/asthelpergen/integration/ast_rewrite.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ limitations under the License. package integration +// Function Generation Source: InterfaceMethod func (a *application) rewriteAST(parent AST, node AST, replacer replacerFunc) bool { if node == nil { return true @@ -51,6 +52,8 @@ func (a *application) rewriteAST(parent AST, node AST, replacer replacerFunc) bo return true } } + +// Function Generation Source: SliceMethod func (a *application) rewriteBytes(parent AST, node Bytes, replacer replacerFunc) bool { if node == nil { return true @@ -80,6 +83,8 @@ func (a *application) rewriteBytes(parent AST, node Bytes, replacer replacerFunc } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteInterfaceContainer(parent AST, node InterfaceContainer, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -106,6 +111,8 @@ func (a *application) rewriteInterfaceContainer(parent AST, node InterfaceContai } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteInterfaceSlice(parent AST, node InterfaceSlice, replacer replacerFunc) bool { if node == nil { return true @@ -124,6 +131,13 @@ func (a *application) rewriteInterfaceSlice(parent AST, node InterfaceSlice, rep } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(InterfaceSliceOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteAST(node, el, func(idx int) replacerFunc { return func(newNode, parent AST) { parent.(InterfaceSlice)[idx] = newNode.(AST) @@ -132,6 +146,9 @@ func (a *application) rewriteInterfaceSlice(parent AST, node InterfaceSlice, rep return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -142,6 +159,8 @@ func (a *application) rewriteInterfaceSlice(parent AST, node InterfaceSlice, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLeaf(parent AST, node *Leaf, replacer replacerFunc) bool { if node == nil { return true @@ -171,6 +190,8 @@ func (a *application) rewriteRefOfLeaf(parent AST, node *Leaf, replacer replacer } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteLeafSlice(parent AST, node LeafSlice, replacer replacerFunc) bool { if node == nil { return true @@ -189,6 +210,13 @@ func (a *application) rewriteLeafSlice(parent AST, node LeafSlice, replacer repl } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(LeafSliceOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfLeaf(node, el, func(idx int) replacerFunc { return func(newNode, parent AST) { parent.(LeafSlice)[idx] = newNode.(*Leaf) @@ -197,6 +225,9 @@ func (a *application) rewriteLeafSlice(parent AST, node LeafSlice, replacer repl return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -207,6 +238,8 @@ func (a *application) rewriteLeafSlice(parent AST, node LeafSlice, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNoCloneType(parent AST, node *NoCloneType, replacer replacerFunc) bool { if node == nil { return true @@ -236,6 +269,8 @@ func (a *application) rewriteRefOfNoCloneType(parent AST, node *NoCloneType, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRefContainer(parent AST, node *RefContainer, replacer replacerFunc) bool { if node == nil { return true @@ -253,16 +288,26 @@ func (a *application) rewriteRefOfRefContainer(parent AST, node *RefContainer, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRefContainerASTType)) + } if !a.rewriteAST(node, node.ASTType, func(newNode, parent AST) { parent.(*RefContainer).ASTType = newNode.(AST) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRefContainerASTImplementationType)) + } if !a.rewriteRefOfLeaf(node, node.ASTImplementationType, func(newNode, parent AST) { parent.(*RefContainer).ASTImplementationType = newNode.(*Leaf) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -273,6 +318,8 @@ func (a *application) rewriteRefOfRefContainer(parent AST, node *RefContainer, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRefSliceContainer(parent AST, node *RefSliceContainer, replacer replacerFunc) bool { if node == nil { return true @@ -291,6 +338,13 @@ func (a *application) rewriteRefOfRefSliceContainer(parent AST, node *RefSliceCo } } for x, el := range node.ASTElements { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfRefSliceContainerASTElementsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteAST(node, el, func(idx int) replacerFunc { return func(newNode, parent AST) { parent.(*RefSliceContainer).ASTElements[idx] = newNode.(AST) @@ -299,7 +353,17 @@ func (a *application) rewriteRefOfRefSliceContainer(parent AST, node *RefSliceCo return false } } + if a.collectPaths && len(node.ASTElements) > 0 { + a.cur.current.Pop() + } for x, el := range node.ASTImplementationElements { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfRefSliceContainerASTImplementationElementsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfLeaf(node, el, func(idx int) replacerFunc { return func(newNode, parent AST) { parent.(*RefSliceContainer).ASTImplementationElements[idx] = newNode.(*Leaf) @@ -308,6 +372,9 @@ func (a *application) rewriteRefOfRefSliceContainer(parent AST, node *RefSliceCo return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -318,6 +385,8 @@ func (a *application) rewriteRefOfRefSliceContainer(parent AST, node *RefSliceCo } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSubImpl(parent AST, node *SubImpl, replacer replacerFunc) bool { if node == nil { return true @@ -335,11 +404,17 @@ func (a *application) rewriteRefOfSubImpl(parent AST, node *SubImpl, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSubImplinner)) + } if !a.rewriteSubIface(node, node.inner, func(newNode, parent AST) { parent.(*SubImpl).inner = newNode.(SubIface) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -350,6 +425,8 @@ func (a *application) rewriteRefOfSubImpl(parent AST, node *SubImpl, replacer re } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteValueContainer(parent AST, node ValueContainer, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -364,16 +441,26 @@ func (a *application) rewriteValueContainer(parent AST, node ValueContainer, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(ValueContainerASTType)) + } if !a.rewriteAST(node, node.ASTType, func(newNode, parent AST) { panic("[BUG] tried to replace 'ASTType' on 'ValueContainer'") }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(ValueContainerASTImplementationType)) + } if !a.rewriteRefOfLeaf(node, node.ASTImplementationType, func(newNode, parent AST) { panic("[BUG] tried to replace 'ASTImplementationType' on 'ValueContainer'") }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -384,6 +471,8 @@ func (a *application) rewriteValueContainer(parent AST, node ValueContainer, rep } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteValueSliceContainer(parent AST, node ValueSliceContainer, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -398,19 +487,31 @@ func (a *application) rewriteValueSliceContainer(parent AST, node ValueSliceCont return true } } - for _, el := range node.ASTElements { + for x, el := range node.ASTElements { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(ValueSliceContainerASTElementsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteAST(node, el, func(newNode, parent AST) { panic("[BUG] tried to replace 'ASTElements' on 'ValueSliceContainer'") }) { return false } } - for _, el := range node.ASTImplementationElements { - if !a.rewriteRefOfLeaf(node, el, func(newNode, parent AST) { - panic("[BUG] tried to replace 'ASTImplementationElements' on 'ValueSliceContainer'") - }) { - return false - } + if a.collectPaths && len(node.ASTElements) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(ValueSliceContainerASTImplementationElements)) + } + if !a.rewriteLeafSlice(node, node.ASTImplementationElements, func(newNode, parent AST) { + panic("[BUG] tried to replace 'ASTImplementationElements' on 'ValueSliceContainer'") + }) { + return false + } + if a.collectPaths { + a.cur.current.Pop() } if a.post != nil { a.cur.replacer = replacer @@ -422,6 +523,8 @@ func (a *application) rewriteValueSliceContainer(parent AST, node ValueSliceCont } return true } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteSubIface(parent AST, node SubIface, replacer replacerFunc) bool { if node == nil { return true @@ -434,6 +537,8 @@ func (a *application) rewriteSubIface(parent AST, node SubIface, replacer replac return true } } + +// Function Generation Source: BasicMethod func (a *application) rewriteBasicType(parent AST, node BasicType, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -460,6 +565,8 @@ func (a *application) rewriteBasicType(parent AST, node BasicType, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfInterfaceContainer(parent AST, node *InterfaceContainer, replacer replacerFunc) bool { if node == nil { return true @@ -489,6 +596,8 @@ func (a *application) rewriteRefOfInterfaceContainer(parent AST, node *Interface } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfValueContainer(parent AST, node *ValueContainer, replacer replacerFunc) bool { if node == nil { return true @@ -506,16 +615,26 @@ func (a *application) rewriteRefOfValueContainer(parent AST, node *ValueContaine return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfValueContainerASTType)) + } if !a.rewriteAST(node, node.ASTType, func(newNode, parent AST) { parent.(*ValueContainer).ASTType = newNode.(AST) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValueContainerASTImplementationType)) + } if !a.rewriteRefOfLeaf(node, node.ASTImplementationType, func(newNode, parent AST) { parent.(*ValueContainer).ASTImplementationType = newNode.(*Leaf) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -526,6 +645,8 @@ func (a *application) rewriteRefOfValueContainer(parent AST, node *ValueContaine } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfValueSliceContainer(parent AST, node *ValueSliceContainer, replacer replacerFunc) bool { if node == nil { return true @@ -544,6 +665,13 @@ func (a *application) rewriteRefOfValueSliceContainer(parent AST, node *ValueSli } } for x, el := range node.ASTElements { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfValueSliceContainerASTElementsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteAST(node, el, func(idx int) replacerFunc { return func(newNode, parent AST) { parent.(*ValueSliceContainer).ASTElements[idx] = newNode.(AST) @@ -552,14 +680,17 @@ func (a *application) rewriteRefOfValueSliceContainer(parent AST, node *ValueSli return false } } - for x, el := range node.ASTImplementationElements { - if !a.rewriteRefOfLeaf(node, el, func(idx int) replacerFunc { - return func(newNode, parent AST) { - parent.(*ValueSliceContainer).ASTImplementationElements[idx] = newNode.(*Leaf) - } - }(x)) { - return false - } + if a.collectPaths && len(node.ASTElements) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValueSliceContainerASTImplementationElements)) + } + if !a.rewriteLeafSlice(node, node.ASTImplementationElements, func(newNode, parent AST) { + parent.(*ValueSliceContainer).ASTImplementationElements = newNode.(LeafSlice) + }) { + return false + } + if a.collectPaths { + a.cur.current.Pop() } if a.post != nil { a.cur.replacer = replacer diff --git a/go/tools/asthelpergen/integration/ast_visit.go b/go/tools/asthelpergen/integration/ast_visit.go index 6ceec4e2fc5..252541677eb 100644 --- a/go/tools/asthelpergen/integration/ast_visit.go +++ b/go/tools/asthelpergen/integration/ast_visit.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -174,10 +174,8 @@ func VisitValueSliceContainer(in ValueSliceContainer, f Visit) error { return err } } - for _, el := range in.ASTImplementationElements { - if err := VisitRefOfLeaf(el, f); err != nil { - return err - } + if err := VisitLeafSlice(in.ASTImplementationElements, f); err != nil { + return err } return nil } @@ -233,10 +231,8 @@ func VisitRefOfValueSliceContainer(in *ValueSliceContainer, f Visit) error { return err } } - for _, el := range in.ASTImplementationElements { - if err := VisitRefOfLeaf(el, f); err != nil { - return err - } + if err := VisitLeafSlice(in.ASTImplementationElements, f); err != nil { + return err } return nil } diff --git a/go/tools/asthelpergen/integration/integration_rewriter_test.go b/go/tools/asthelpergen/integration/integration_rewriter_test.go index af7483b5916..067417ecbf9 100644 --- a/go/tools/asthelpergen/integration/integration_rewriter_test.go +++ b/go/tools/asthelpergen/integration/integration_rewriter_test.go @@ -105,7 +105,8 @@ func TestRewriteVisitValueSliceContainer(t *testing.T) { leaf2 := &Leaf{2} leaf3 := &Leaf{3} leaf4 := &Leaf{4} - container := ValueSliceContainer{ASTElements: []AST{leaf1, leaf2}, ASTImplementationElements: []*Leaf{leaf3, leaf4}} + ls := LeafSlice{leaf3, leaf4} + container := ValueSliceContainer{ASTElements: []AST{leaf1, leaf2}, ASTImplementationElements: ls} containerContainer := ValueSliceContainer{ASTElements: []AST{container}} tv := &rewriteTestVisitor{} @@ -119,10 +120,12 @@ func TestRewriteVisitValueSliceContainer(t *testing.T) { Post{leaf1}, Pre{leaf2}, Post{leaf2}, + Pre{ls}, Pre{leaf3}, Post{leaf3}, Pre{leaf4}, Post{leaf4}, + Post{ls}, Post{container}, Post{containerContainer}, }) @@ -402,6 +405,7 @@ func (tv *rewriteTestVisitor) assertEquals(t *testing.T, expected []step) { expectedSize := len(expected) for i, step := range tv.walk { t.Run(fmt.Sprintf("step %d", i), func(t *testing.T) { + t.Helper() if expectedSize <= i { t.Fatalf("❌️ - Expected less elements %v", tv.walk[i:]) } else { diff --git a/go/tools/asthelpergen/integration/integration_visit_test.go b/go/tools/asthelpergen/integration/integration_visit_test.go index 31c0d6451c4..05773e73b8c 100644 --- a/go/tools/asthelpergen/integration/integration_visit_test.go +++ b/go/tools/asthelpergen/integration/integration_visit_test.go @@ -100,7 +100,8 @@ func TestVisitValueSliceContainer(t *testing.T) { leaf2 := &Leaf{2} leaf3 := &Leaf{3} leaf4 := &Leaf{4} - container := ValueSliceContainer{ASTElements: []AST{leaf1, leaf2}, ASTImplementationElements: []*Leaf{leaf3, leaf4}} + ls := LeafSlice{leaf3, leaf4} + container := ValueSliceContainer{ASTElements: []AST{leaf1, leaf2}, ASTImplementationElements: ls} containerContainer := ValueSliceContainer{ASTElements: []AST{container}} tv := &testVisitor{} @@ -113,6 +114,7 @@ func TestVisitValueSliceContainer(t *testing.T) { container, leaf1, leaf2, + ls, leaf3, leaf4, }) diff --git a/go/tools/asthelpergen/integration/paths.go b/go/tools/asthelpergen/integration/paths.go new file mode 100644 index 00000000000..c0ac1b588ce --- /dev/null +++ b/go/tools/asthelpergen/integration/paths.go @@ -0,0 +1,43 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package integration + +// This file is a copy of the file go/vt/sqlparser/paths.go +// We need it here to be able to test the path accumulation of the rewriter + +type ASTPath string + +// nextPathOffset is an implementation of binary.Uvarint that works directly on +// the ASTPath without having to cast and allocate a byte slice +func (path ASTPath) nextPathOffset() (uint64, int) { + var x uint64 + var s uint + for i := 0; i < len(path); i++ { + b := path[i] + if b < 0x80 { + return x | uint64(b)<= 2 { + // Read the step code (2 bytes) + stepVal := binary.BigEndian.Uint16(remaining[:2]) + remaining = remaining[2:] + + step := ASTStep(stepVal) + stepStr := step.DebugString() // e.g. "CaseExprWhens8" or "CaseExprWhens32" + + // If this isn't the very first step in the path, prepend a separator + if stepCount > 0 { + sb.WriteString("->") + } + stepCount++ + + // Write the step name + sb.WriteString(stepStr) + + // Check suffix to see if we need to read an offset + switch { + case strings.HasSuffix(stepStr, "Offset"): + if len(remaining) < 1 { + sb.WriteString("(ERR-no-offset-byte)") + return sb.String() + } + offset, readBytes := binary.Varint(remaining) + remaining = remaining[readBytes:] + sb.WriteString(fmt.Sprintf("(%d)", offset)) + } + } + + // If there's leftover data that doesn't fit into 2 (or more) bytes, you could note it: + if len(remaining) != 0 { + sb.WriteString("->(ERR-unaligned-extra-bytes)") + } + + return sb.String() +} diff --git a/go/tools/asthelpergen/integration/types.go b/go/tools/asthelpergen/integration/types.go index 921759f3ad1..b190fbb2fcf 100644 --- a/go/tools/asthelpergen/integration/types.go +++ b/go/tools/asthelpergen/integration/types.go @@ -24,15 +24,74 @@ import ( //go:generate go run ../main --in . --iface vitess.io/vitess/go/tools/asthelpergen/integration.AST --clone_exclude "*NoCloneType" -// AST is the interface all interface types implement -type AST interface { - String() string -} +type ( + // AST is the interface all interface types implement + AST interface { + String() string + } + // Empty struct impl of the iface + Leaf struct { + v int + } -// Empty struct impl of the iface -type Leaf struct { - v int -} + // Options have been added to test the behaviour + // of a struct that doesn't implement the AST interface + // but includes a field that does. + Options struct { + a int + b string + l *Leaf + } + + // Container implements the interface ByRef + RefContainer struct { + ASTType AST + NotASTType int + Opts []*Options + ASTImplementationType *Leaf + } + // Container implements the interface ByRef + RefSliceContainer struct { + something int // want a non-AST field first + ASTElements []AST + NotASTElements []int + ASTImplementationElements []*Leaf + } + // Container implements the interface ByValue + ValueContainer struct { + ASTType AST + NotASTType int + ASTImplementationType *Leaf + } + // Container implements the interface ByValue + ValueSliceContainer struct { + ASTElements []AST + NotASTElements []int + ASTImplementationElements LeafSlice + } + // We need to support these types - a slice of AST elements can implement the interface + InterfaceSlice []AST + // We need to support these types - a slice of AST elements can implement the interface + Bytes []byte + LeafSlice []*Leaf + BasicType int + NoCloneType struct { + v int + } + // We want to support all types that are used as field types, which can include interfaces. + // Example would be sqlparser.Expr that implements sqlparser.SQLNode + SubIface interface { + AST + iface() + } + SubImpl struct { + inner SubIface + field *bool + } + InterfaceContainer struct { + v any + } +) func (l *Leaf) String() string { if l == nil { @@ -41,13 +100,6 @@ func (l *Leaf) String() string { return fmt.Sprintf("Leaf(%d)", l.v) } -// Container implements the interface ByRef -type RefContainer struct { - ASTType AST - NotASTType int - ASTImplementationType *Leaf -} - func (r *RefContainer) String() string { if r == nil { return "nil" @@ -61,42 +113,18 @@ func (r *RefContainer) String() string { return fmt.Sprintf("RefContainer{%s, %d, %s}", astType, r.NotASTType, r.ASTImplementationType.String()) } -// Container implements the interface ByRef -type RefSliceContainer struct { - ASTElements []AST - NotASTElements []int - ASTImplementationElements []*Leaf -} - func (r *RefSliceContainer) String() string { return fmt.Sprintf("RefSliceContainer{%s, %s, %s}", sliceStringAST(r.ASTElements...), "r.NotASTType", sliceStringLeaf(r.ASTImplementationElements...)) } -// Container implements the interface ByValue -type ValueContainer struct { - ASTType AST - NotASTType int - ASTImplementationType *Leaf -} - func (r ValueContainer) String() string { return fmt.Sprintf("ValueContainer{%s, %d, %s}", r.ASTType.String(), r.NotASTType, r.ASTImplementationType.String()) } -// Container implements the interface ByValue -type ValueSliceContainer struct { - ASTElements []AST - NotASTElements []int - ASTImplementationElements []*Leaf -} - func (r ValueSliceContainer) String() string { return fmt.Sprintf("ValueSliceContainer{%s, %s, %s}", sliceStringAST(r.ASTElements...), "r.NotASTType", sliceStringLeaf(r.ASTImplementationElements...)) } -// We need to support these types - a slice of AST elements can implement the interface -type InterfaceSlice []AST - func (r InterfaceSlice) String() string { var elements []string for _, el := range r { @@ -106,15 +134,10 @@ func (r InterfaceSlice) String() string { return "[" + strings.Join(elements, ", ") + "]" } -// We need to support these types - a slice of AST elements can implement the interface -type Bytes []byte - func (r Bytes) String() string { return string(r) } -type LeafSlice []*Leaf - func (r LeafSlice) String() string { var elements []string for _, el := range r { @@ -123,8 +146,6 @@ func (r LeafSlice) String() string { return strings.Join(elements, ", ") } -type BasicType int - func (r BasicType) String() string { return fmt.Sprintf("int(%d)", r) } @@ -135,35 +156,15 @@ const ( thisIsNotAType2 BasicType = 2 ) -// We want to support all types that are used as field types, which can include interfaces. -// Example would be sqlparser.Expr that implements sqlparser.SQLNode -type SubIface interface { - AST - iface() -} - -type SubImpl struct { - inner SubIface - field *bool -} - func (r *SubImpl) String() string { return "SubImpl" } func (r *SubImpl) iface() {} -type InterfaceContainer struct { - v any -} - func (r InterfaceContainer) String() string { return fmt.Sprintf("%v", r.v) } -type NoCloneType struct { - v int -} - func (r *NoCloneType) String() string { return fmt.Sprintf("NoClone(%d)", r.v) } @@ -171,8 +172,9 @@ func (r *NoCloneType) String() string { type Visit func(node AST) (bool, error) type application struct { - pre, post ApplyFunc - cur Cursor + pre, post ApplyFunc + cur Cursor + collectPaths bool } var Equals = &Comparator{} diff --git a/go/tools/asthelpergen/paths_gen.go b/go/tools/asthelpergen/paths_gen.go new file mode 100644 index 00000000000..d5d114e2554 --- /dev/null +++ b/go/tools/asthelpergen/paths_gen.go @@ -0,0 +1,266 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package asthelpergen + +import ( + "fmt" + "go/types" + + "github.com/dave/jennifer/jen" +) + +type ( + pathGen struct { + file *jen.File + steps []step + ifaceName string + } + step struct { + container types.Type // the type of the container + typ types.Type // the type of the field + name string // the name of the field + slice bool // whether the field is a slice + } +) + +const sliceMarker = " -SLICE- " + +var _ generator = (*pathGen)(nil) + +func newPathGen(pkgname, ifaceName string) *pathGen { + file := jen.NewFile(pkgname) + file.HeaderComment(licenseFileHeader) + file.HeaderComment("Code generated by ASTHelperGen. DO NOT EDIT.") + + return &pathGen{ + file: file, + ifaceName: ifaceName, + } +} + +func (s step) AsEnum() string { + if s.name == sliceMarker { + return printableTypeName(s.container) + } + return printableTypeName(s.container) + s.name +} + +func (p *pathGen) genFile(spi generatorSPI) (string, *jen.File) { + p.file.ImportName("fmt", "fmt") + + // Declare the ASTStep type with underlying type uint16 + p.file.Add(jen.Type().Id("ASTStep").Uint16()) + + // Add the const block + p.file.Add(p.buildConstWithEnum()) + + // Add the ASTStep#DebugString() method to the file + p.file.Add(p.debugString()) + + // Add the generated GetNodeFromPath method + p.file.Add(p.generateGetNodeFromPath(spi)) + + return "ast_path.go", p.file +} + +func (p *pathGen) interfaceMethod(t types.Type, iface *types.Interface, spi generatorSPI) error { + return nil +} + +func (p *pathGen) structMethod(t types.Type, strct *types.Struct, spi generatorSPI) error { + p.addStructFields(t, strct, spi) + return nil +} + +func (p *pathGen) ptrToStructMethod(t types.Type, strct *types.Struct, spi generatorSPI) error { + p.addStructFields(t, strct, spi) + return nil +} + +func (p *pathGen) addStep( + container types.Type, // the name of the container type + typ types.Type, // the type of the field + name string, // the name of the field + slice bool, // whether the field is a slice +) { + s := step{ + container: container, + name: name, + typ: typ, + slice: slice, + } + p.steps = append(p.steps, s) + +} + +func (p *pathGen) addStructFields(t types.Type, strct *types.Struct, spi generatorSPI) { + val := types.TypeString(t, noQualifier) + _ = val + for i := 0; i < strct.NumFields(); i++ { + field := strct.Field(i) + // Check if the field type implements the interface + if types.Implements(field.Type(), spi.iface()) { + p.addStep(t, field.Type(), field.Name(), false) + continue + } + // Check if the field type is a slice + slice, isSlice := field.Type().(*types.Slice) + if isSlice { + // Check if the slice type implements the interface + if types.Implements(slice, spi.iface()) { + p.addStep(t, slice, field.Name(), true) + } else if types.Implements(slice.Elem(), spi.iface()) { + // Check if the element type of the slice implements the interface + p.addStep(t, slice.Elem(), field.Name(), true) + } + } + } +} + +func (p *pathGen) ptrToBasicMethod(t types.Type, basic *types.Basic, spi generatorSPI) error { + return nil +} + +func (p *pathGen) sliceMethod(t types.Type, slice *types.Slice, spi generatorSPI) error { + elemType := slice.Elem() + if types.Implements(elemType, spi.iface()) { + p.addStep(t, elemType, sliceMarker, true) + } + + return nil +} + +func (p *pathGen) basicMethod(t types.Type, basic *types.Basic, spi generatorSPI) error { + return nil +} + +func (p *pathGen) debugString() *jen.Statement { + var switchCases []jen.Code + + for _, step := range p.steps { + stepName := step.AsEnum() + + // Generate the debug string using the helper function + var debugStr string + if step.name == sliceMarker { + debugStr = fmt.Sprintf("(%s)[]", types.TypeString(step.container, noQualifier)) + } else { + debugStr = fmt.Sprintf("(%s).%s", types.TypeString(step.container, noQualifier), step.name) + } + + if !step.slice { + switchCases = append(switchCases, jen.Case(jen.Id(stepName)).Block( + jen.Return(jen.Lit(debugStr)), + )) + continue + } + + switchCases = append(switchCases, jen.Case(jen.Id(stepName+"Offset")).Block( + jen.Return(jen.Lit(debugStr+"Offset")), + )) + + } + + debugStringMethod := jen.Func().Params(jen.Id("s").Id("ASTStep")).Id("DebugString").Params().String().Block( + jen.Switch(jen.Id("s")).Block(switchCases...), + jen.Panic(jen.Lit("unknown ASTStep")), + ) + return debugStringMethod +} + +func (p *pathGen) buildConstWithEnum() *jen.Statement { + // Create the const block with all step constants + var constDefs []jen.Code + addStep := func(step string) { + if constDefs == nil { + // Use iota for the first constant + constDefs = append(constDefs, jen.Id(step).Id("ASTStep").Op("=").Id("iota")) + return + } + + constDefs = append(constDefs, jen.Id(step)) + } + for _, step := range p.steps { + stepName := step.AsEnum() + if step.slice { + addStep(stepName + "Offset") + continue + } + + addStep(stepName) + } + + constBlock := jen.Const().Defs(constDefs...) + return constBlock +} + +func (p *pathGen) generateGetNodeFromPath(spi generatorSPI) *jen.Statement { + method := jen.Func().Id("GetNodeFromPath").Params( + jen.Id("node").Id(p.ifaceName), + jen.Id("path").Id("ASTPath"), + ).Id(p.ifaceName).Block( + jen.For(jen.Len(jen.Id("path")).Op(">=").Lit(2)).Block( + jen.Id("step").Op(":=").Id("path").Dot("nextPathStep").Call(), + jen.Id("path").Op("=").Id("path[2:]"), + jen.Switch(jen.Id("step")).Block(p.generateWalkCases(spi)...), + ), + jen.Return(jen.Id("node")), // Fallback return + ) + return method +} + +func (p *pathGen) generateWalkCases(spi generatorSPI) []jen.Code { + var cases []jen.Code + + for _, step := range p.steps { + stepName := step.AsEnum() + + // Check if the type implements the interface + if !types.Implements(step.container, spi.iface()) { + continue + } + + if !step.slice { + // return GetNodeFromPath(node.(*RefContainer).ASTType, path) + t := types.TypeString(step.container, noQualifier) + + cases = append(cases, jen.Case(jen.Id(stepName)).Block( + jen.Id("node").Op("=").Id("node").Dot(fmt.Sprintf("(%s)", t)).Dot(step.name), + )) + continue + } + + var assignNode jen.Code + t := types.TypeString(step.container, noQualifier) + if step.name == sliceMarker { + assignNode = jen.Id("node").Dot(fmt.Sprintf("(%s)", t)).Index(jen.Id("idx")) + } else { + assignNode = jen.Id("node").Dot(fmt.Sprintf("(%s)", t)).Dot(step.name).Index(jen.Id("idx")) + } + + cases = append(cases, jen.Case(jen.Id(stepName+"Offset")).Block( + jen.Id("idx, bytesRead").Op(":=").Id("path").Dot("nextPathOffset").Call(), + jen.Id("path").Op("=").Id("path[bytesRead:]"), + jen.Id("node").Op("=").Add(assignNode), + )) + } + + cases = append(cases, jen.Default().Block( + jen.Return(jen.Nil()), + )) + return cases +} diff --git a/go/tools/asthelpergen/rewrite_gen.go b/go/tools/asthelpergen/rewrite_gen.go index 29ffcee3d5b..52b476a7c9d 100644 --- a/go/tools/asthelpergen/rewrite_gen.go +++ b/go/tools/asthelpergen/rewrite_gen.go @@ -45,7 +45,7 @@ func newRewriterGen(pkgname string, ifaceName string) *rewriteGen { } } -func (r *rewriteGen) genFile() (string, *jen.File) { +func (r *rewriteGen) genFile(generatorSPI) (string, *jen.File) { return "ast_rewrite.go", r.file } @@ -95,22 +95,29 @@ func (r *rewriteGen) interfaceMethod(t types.Type, iface *types.Interface, spi g cases..., ))) - r.rewriteFunc(t, stmts) + r.rewriteFunc(t, stmts, "InterfaceMethod") return nil } +func (r *rewriteGen) visitStructFields(t types.Type, strct *types.Struct, spi generatorSPI, fail bool) (stmts []jen.Code) { + fields := r.rewriteAllStructFields(t, strct, spi, fail) + stmts = append(stmts, r.executePre()) + stmts = append(stmts, fields...) + + if len(fields) > 0 { + stmts = append(stmts, jen.If(jen.Id("a.collectPaths")).Block(jen.Id("a.cur.current.Pop").Params())) + } + stmts = append(stmts, executePost(len(fields) > 0)) + stmts = append(stmts, returnTrue()) + return +} + func (r *rewriteGen) structMethod(t types.Type, strct *types.Struct, spi generatorSPI) error { if !shouldAdd(t, spi.iface()) { return nil } - fields := r.rewriteAllStructFields(t, strct, spi, true) - - stmts := []jen.Code{r.executePre()} - stmts = append(stmts, fields...) - stmts = append(stmts, executePost(len(fields) > 0)) - stmts = append(stmts, returnTrue()) - r.rewriteFunc(t, stmts) + r.rewriteFunc(t, r.visitStructFields(t, strct, spi, true), "StructMethod") return nil } @@ -124,19 +131,9 @@ func (r *rewriteGen) ptrToStructMethod(t types.Type, strct *types.Struct, spi ge if node == nil { return nil } */ stmts := []jen.Code{jen.If(jen.Id("node == nil").Block(returnTrue()))} + stmts = append(stmts, r.visitStructFields(t, strct, spi, false)...) - /* - if !pre(&cur) { - return nil - } - */ - stmts = append(stmts, r.executePre()) - fields := r.rewriteAllStructFields(t, strct, spi, false) - stmts = append(stmts, fields...) - stmts = append(stmts, executePost(len(fields) > 0)) - stmts = append(stmts, returnTrue()) - - r.rewriteFunc(t, stmts) + r.rewriteFunc(t, stmts, "PtrToStructMethod") return nil } @@ -146,13 +143,10 @@ func (r *rewriteGen) ptrToBasicMethod(t types.Type, _ *types.Basic, spi generato return nil } - /* - */ - stmts := []jen.Code{ jen.Comment("ptrToBasicMethod"), } - r.rewriteFunc(t, stmts) + r.rewriteFunc(t, stmts, "PtrToBasicMethod") return nil } @@ -189,29 +183,41 @@ func (r *rewriteGen) sliceMethod(t types.Type, slice *types.Slice, spi generator jen.If(jen.Id("kontinue").Block(jen.Return(jen.True()))), ) - stmts = append(stmts, jen.If(jen.Id("a.pre!= nil").Block(preStmts...))) + stmts = append(stmts, + jen.If(jen.Id("a.pre != nil").Block(preStmts...)), + ) haveChildren := false if shouldAdd(slice.Elem(), spi.iface()) { /* + var path ASTPath + if a.collectPaths { + path = a.cur.current + } for i, el := range node { - if err := rewriteRefOfLeaf(node, el, func(newNode, parent AST) { - parent.(LeafSlice)[i] = newNode.(*Leaf) - }, pre, post); err != nil { - return err - } - } + if err := rewriteRefOfLeaf(node, el, func(newNode, parent AST) { + parent.(LeafSlice)[i] = newNode.(*Leaf) + }, pre, post); err != nil { + return err + } + } */ haveChildren = true + rewriteChild := r.rewriteChildSlice(t, slice.Elem(), "", jen.Id("el"), jen.Index(jen.Id("idx")), false) + stmts = append(stmts, jen.For(jen.Id("x, el").Op(":=").Id("range node")). - Block(r.rewriteChildSlice(t, slice.Elem(), "notUsed", jen.Id("el"), jen.Index(jen.Id("idx")), false))) + Block(rewriteChild...)) + } + + if haveChildren { + stmts = append(stmts, jen.If(jen.Id("a.collectPaths").Op("&&").Len(jen.Id("node")).Op(">").Lit(0)).Block(jen.Id("a.cur.current.Pop").Params())) } stmts = append(stmts, executePost(haveChildren)) stmts = append(stmts, returnTrue()) - r.rewriteFunc(t, stmts) + r.rewriteFunc(t, stmts, "SliceMethod") return nil } @@ -233,7 +239,7 @@ func (r *rewriteGen) executePre() jen.Code { )), jen.If(jen.Id("kontinue").Block(jen.Return(jen.True()))), ) - return jen.If(jen.Id("a.pre!= nil").Block(curStmts...)) + return jen.If(jen.Id("a.pre != nil").Block(curStmts...)) } func executePost(seenChildren bool) jen.Code { @@ -257,11 +263,11 @@ func (r *rewriteGen) basicMethod(t types.Type, _ *types.Basic, spi generatorSPI) } stmts := []jen.Code{r.executePre(), executePost(false), returnTrue()} - r.rewriteFunc(t, stmts) + r.rewriteFunc(t, stmts, "BasicMethod") return nil } -func (r *rewriteGen) rewriteFunc(t types.Type, stmts []jen.Code) { +func (r *rewriteGen) rewriteFunc(t types.Type, stmts []jen.Code, source string) { /* func (a *application) rewriteNodeType(parent AST, node NodeType, replacer replacerFunc) { @@ -269,7 +275,7 @@ func (r *rewriteGen) rewriteFunc(t types.Type, stmts []jen.Code) { typeString := types.TypeString(t, noQualifier) funcName := fmt.Sprintf("%s%s", rewriteName, printableTypeName(t)) - code := jen.Func().Params( + code := jen.Commentf("Function Generation Source: %s", source).Line().Func().Params( jen.Id("a").Op("*").Id("application"), ).Id(funcName).Params( jen.Id(fmt.Sprintf("parent %s, node %s, replacer replacerFunc", r.ifaceName, typeString)), @@ -288,23 +294,36 @@ func (r *rewriteGen) rewriteAllStructFields(t types.Type, strct *types.Struct, s */ var output []jen.Code + fieldNumber := 0 + prevSliceField := "" for i := 0; i < strct.NumFields(); i++ { field := strct.Field(i) if types.Implements(field.Type(), spi.iface()) { spi.addType(field.Type()) - output = append(output, r.rewriteChild(t, field.Type(), field.Name(), jen.Id("node").Dot(field.Name()), jen.Dot(field.Name()), fail)) + rewriteLines := r.rewriteChild(t, field.Type(), field.Name(), jen.Id("node").Dot(field.Name()), jen.Dot(field.Name()), fail, fieldNumber == 0, prevSliceField) + prevSliceField = "" + output = append(output, rewriteLines...) + fieldNumber++ continue } slice, isSlice := field.Type().(*types.Slice) if isSlice && types.Implements(slice.Elem(), spi.iface()) { - spi.addType(slice.Elem()) - id := jen.Id("x") - if fail { - id = jen.Id("_") + ifCondition := jen.Id("a.collectPaths") + if prevSliceField != "" { + ifCondition = ifCondition.Op("&&").Len(jen.Id("node." + prevSliceField)).Op(">").Lit(0) } + ifCollectPath := jen.If(ifCondition).Block( + jen.Id("a.cur.current.Pop").Params(), + ) + if fieldNumber != 0 { + output = append(output, ifCollectPath) + } + prevSliceField = field.Name() + spi.addType(slice.Elem()) output = append(output, - jen.For(jen.List(id, jen.Id("el")).Op(":=").Id("range node."+field.Name())). - Block(r.rewriteChildSlice(t, slice.Elem(), field.Name(), jen.Id("el"), jen.Dot(field.Name()).Index(jen.Id("idx")), fail))) + jen.For(jen.List(jen.Id("x"), jen.Id("el")).Op(":=").Id("range node."+field.Name())). + Block(r.rewriteChildSlice(t, slice.Elem(), field.Name(), jen.Id("el"), jen.Dot(field.Name()).Index(jen.Id("idx")), fail)...)) + fieldNumber++ } } return output @@ -315,7 +334,7 @@ func failReplacer(t types.Type, f string) *jen.Statement { return jen.Panic(jen.Lit(fmt.Sprintf("[BUG] tried to replace '%s' on '%s'", f, typeString))) } -func (r *rewriteGen) rewriteChild(t, field types.Type, fieldName string, param jen.Code, replace jen.Code, fail bool) jen.Code { +func (r *rewriteGen) rewriteChild(t, field types.Type, fieldName string, param jen.Code, replace jen.Code, fail, firstChild bool, prevSliceField string) []jen.Code { /* if errF := rewriteAST(node, node.ASTType, func(newNode, parent AST) { parent.(*RefContainer).ASTType = newNode.(AST) @@ -351,10 +370,27 @@ func (r *rewriteGen) rewriteChild(t, field types.Type, fieldName string, param j param, funcBlock).Block(returnFalse())) - return rewriteField + collectPathBlock := []jen.Code{ + jen.Id("a.cur.current.AddStep").Params(jen.Id("uint16").Params(jen.Id(printableTypeName(t) + fieldName))), + } + if !firstChild { + collectPathBlock = append([]jen.Code{jen.Id("a.cur.current.Pop").Params()}, collectPathBlock...) + } + ifCondition := jen.Id("a.collectPaths") + if prevSliceField != "" { + ifCondition = ifCondition.Op("&&").Len(jen.Id("node." + prevSliceField)).Op(">").Lit(0) + } + ifCollectPath := jen.If(ifCondition).Block( + collectPathBlock..., + ) + + return []jen.Code{ + ifCollectPath, + rewriteField, + } } -func (r *rewriteGen) rewriteChildSlice(t, field types.Type, fieldName string, param jen.Code, replace jen.Code, fail bool) jen.Code { +func (r *rewriteGen) rewriteChildSlice(t, field types.Type, fieldName string, param jen.Code, replace jen.Code, fail bool) []jen.Code { /* if errF := a.rewriteAST(node, el, func(idx int) replacerFunc { return func(newNode, parent AST) { @@ -390,7 +426,25 @@ func (r *rewriteGen) rewriteChildSlice(t, field types.Type, fieldName string, pa param, funcBlock).Block(returnFalse())) - return rewriteField + // if a.collectPaths { + // if x == 0 { + // a.cur.current.AddStepWithOffset(LeafSliceOffset) + // } else { + // a.cur.current.ChangeOffset(x) + // } + // } + savePath := jen.If(jen.Id("a.collectPaths")).Block( + jen.If(jen.Id("x").Op("==").Lit(0)).Block( + jen.Id("a.cur.current.AddStepWithOffset").Params(jen.Id("uint16").Params(jen.Id(printableTypeName(t) + fieldName + "Offset"))), + ).Else().Block( + jen.Id("a.cur.current.ChangeOffset").Params(jen.Id("x")), + ), + ) + + return []jen.Code{ + savePath, + rewriteField, + } } var noQualifier = func(p *types.Package) string { diff --git a/go/tools/asthelpergen/visit_gen.go b/go/tools/asthelpergen/visit_gen.go index 51d8651f090..dca2cfcd0f0 100644 --- a/go/tools/asthelpergen/visit_gen.go +++ b/go/tools/asthelpergen/visit_gen.go @@ -40,7 +40,7 @@ func newVisitGen(pkgname string) *visitGen { } } -func (v *visitGen) genFile() (string, *jen.File) { +func (v *visitGen) genFile(generatorSPI) (string, *jen.File) { return "ast_visit.go", v.file } @@ -220,7 +220,8 @@ func visitAllStructFields(strct *types.Struct, spi generatorSPI) []jen.Code { output := []jen.Code{ visitIn(), } - for i := 0; i < strct.NumFields(); i++ { + + for i := range strct.NumFields() { field := strct.Field(i) if types.Implements(field.Type(), spi.iface()) { spi.addType(field.Type()) diff --git a/go/vt/sqlparser/ast_clone.go b/go/vt/sqlparser/ast_clone.go index 997485e086c..9d476801eaf 100644 --- a/go/vt/sqlparser/ast_clone.go +++ b/go/vt/sqlparser/ast_clone.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/sqlparser/ast_copy_on_rewrite.go b/go/vt/sqlparser/ast_copy_on_rewrite.go index 46ce38ee29d..dee416599e6 100644 --- a/go/vt/sqlparser/ast_copy_on_rewrite.go +++ b/go/vt/sqlparser/ast_copy_on_rewrite.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/sqlparser/ast_equals.go b/go/vt/sqlparser/ast_equals.go index 2795daab2c5..1e5fbb1f6d3 100644 --- a/go/vt/sqlparser/ast_equals.go +++ b/go/vt/sqlparser/ast_equals.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/sqlparser/ast_path.go b/go/vt/sqlparser/ast_path.go new file mode 100644 index 00000000000..0218f7ca9e9 --- /dev/null +++ b/go/vt/sqlparser/ast_path.go @@ -0,0 +1,2777 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +// Code generated by ASTHelperGen. DO NOT EDIT. + +package sqlparser + +type ASTStep uint16 + +const ( + RefOfAddColumnsColumnsOffset ASTStep = iota + RefOfAddColumnsAfter + RefOfAddConstraintDefinitionConstraintDefinition + RefOfAddIndexDefinitionIndexDefinition + RefOfAliasedExprExpr + RefOfAliasedExprAs + RefOfAliasedTableExprExpr + RefOfAliasedTableExprPartitions + RefOfAliasedTableExprAs + RefOfAliasedTableExprHints + RefOfAliasedTableExprColumns + RefOfAlterCheckName + RefOfAlterColumnColumn + RefOfAlterColumnDefaultVal + RefOfAlterDatabaseComments + RefOfAlterDatabaseDBName + RefOfAlterIndexName + RefOfAlterMigrationRatio + RefOfAlterTableTable + RefOfAlterTableAlterOptionsOffset + RefOfAlterTablePartitionSpec + RefOfAlterTablePartitionOption + RefOfAlterTableComments + RefOfAlterViewViewName + RefOfAlterViewDefiner + RefOfAlterViewColumns + RefOfAlterViewSelect + RefOfAlterViewComments + RefOfAlterVschemaTable + RefOfAlterVschemaVindexSpec + RefOfAlterVschemaVindexColsOffset + RefOfAlterVschemaAutoIncSpec + RefOfAnalyzeTable + RefOfAndExprLeft + RefOfAndExprRight + RefOfAnyValueArg + RefOfArgumentLessWindowExprOverClause + RefOfAssignmentExprLeft + RefOfAssignmentExprRight + RefOfAutoIncSpecColumn + RefOfAutoIncSpecSequence + RefOfAvgArg + RefOfAvgOverClause + RefOfBetweenExprLeft + RefOfBetweenExprFrom + RefOfBetweenExprTo + RefOfBinaryExprLeft + RefOfBinaryExprRight + RefOfBitAndArg + RefOfBitAndOverClause + RefOfBitOrArg + RefOfBitOrOverClause + RefOfBitXorArg + RefOfBitXorOverClause + RefOfCallProcName + RefOfCallProcParamsOffset + RefOfCaseExprExpr + RefOfCaseExprWhensOffset + RefOfCaseExprElse + RefOfCastExprExpr + RefOfCastExprType + RefOfChangeColumnOldColumn + RefOfChangeColumnNewColDefinition + RefOfChangeColumnAfter + RefOfCharExprExprsOffset + RefOfCheckConstraintDefinitionExpr + RefOfColNameName + RefOfColNameQualifier + RefOfCollateExprExpr + RefOfColumnDefinitionName + RefOfColumnDefinitionType + ColumnsOffset + RefOfCommonTableExprID + RefOfCommonTableExprColumns + RefOfCommonTableExprSubquery + RefOfComparisonExprLeft + RefOfComparisonExprRight + RefOfComparisonExprEscape + RefOfConstraintDefinitionName + RefOfConstraintDefinitionDetails + RefOfConvertExprExpr + RefOfConvertExprType + RefOfConvertUsingExprExpr + RefOfCountArgsOffset + RefOfCountOverClause + RefOfCountStarOverClause + RefOfCreateDatabaseComments + RefOfCreateDatabaseDBName + RefOfCreateTableTable + RefOfCreateTableTableSpec + RefOfCreateTableOptLike + RefOfCreateTableComments + RefOfCreateViewViewName + RefOfCreateViewDefiner + RefOfCreateViewColumns + RefOfCreateViewSelect + RefOfCreateViewComments + RefOfCurTimeFuncExprName + RefOfDeallocateStmtComments + RefOfDeallocateStmtName + RefOfDeleteWith + RefOfDeleteComments + RefOfDeleteTableExprsOffset + RefOfDeleteTargets + RefOfDeletePartitions + RefOfDeleteWhere + RefOfDeleteOrderBy + RefOfDeleteLimit + RefOfDerivedTableSelect + RefOfDropColumnName + RefOfDropDatabaseComments + RefOfDropDatabaseDBName + RefOfDropKeyName + RefOfDropTableFromTables + RefOfDropTableComments + RefOfDropViewFromTables + RefOfDropViewComments + RefOfExecuteStmtName + RefOfExecuteStmtComments + RefOfExecuteStmtArgumentsOffset + RefOfExistsExprSubquery + RefOfExplainStmtStatement + RefOfExplainStmtComments + RefOfExplainTabTable + RefOfExprsExprsOffset + RefOfExtractFuncExprExpr + RefOfExtractValueExprFragment + RefOfExtractValueExprXPathExpr + RefOfFirstOrLastValueExprExpr + RefOfFirstOrLastValueExprNullTreatmentClause + RefOfFirstOrLastValueExprOverClause + RefOfFlushTableNames + RefOfForeignKeyDefinitionSource + RefOfForeignKeyDefinitionIndexName + RefOfForeignKeyDefinitionReferenceDefinition + RefOfFrameClauseStart + RefOfFrameClauseEnd + RefOfFramePointExpr + RefOfFuncExprQualifier + RefOfFuncExprName + RefOfFuncExprExprsOffset + RefOfGTIDFuncExprSet1 + RefOfGTIDFuncExprSet2 + RefOfGTIDFuncExprTimeout + RefOfGTIDFuncExprChannel + RefOfGeoHashFromLatLongExprLatitude + RefOfGeoHashFromLatLongExprLongitude + RefOfGeoHashFromLatLongExprMaxLength + RefOfGeoHashFromPointExprPoint + RefOfGeoHashFromPointExprMaxLength + RefOfGeoJSONFromGeomExprGeom + RefOfGeoJSONFromGeomExprMaxDecimalDigits + RefOfGeoJSONFromGeomExprBitmask + RefOfGeomCollPropertyFuncExprGeomColl + RefOfGeomCollPropertyFuncExprPropertyDefArg + RefOfGeomFormatExprGeom + RefOfGeomFormatExprAxisOrderOpt + RefOfGeomFromGeoHashExprGeoHash + RefOfGeomFromGeoHashExprSridOpt + RefOfGeomFromGeoJSONExprGeoJSON + RefOfGeomFromGeoJSONExprHigherDimHandlerOpt + RefOfGeomFromGeoJSONExprSrid + RefOfGeomFromTextExprWktText + RefOfGeomFromTextExprSrid + RefOfGeomFromTextExprAxisOrderOpt + RefOfGeomFromWKBExprWkbBlob + RefOfGeomFromWKBExprSrid + RefOfGeomFromWKBExprAxisOrderOpt + RefOfGeomPropertyFuncExprGeom + RefOfGroupByExprsOffset + RefOfGroupConcatExprExprsOffset + RefOfGroupConcatExprOrderBy + RefOfGroupConcatExprLimit + RefOfIndexDefinitionInfo + RefOfIndexHintIndexesOffset + IndexHintsOffset + RefOfIndexInfoName + RefOfIndexInfoConstraintName + RefOfInsertComments + RefOfInsertTable + RefOfInsertPartitions + RefOfInsertColumns + RefOfInsertRows + RefOfInsertRowAlias + RefOfInsertOnDup + RefOfInsertExprStr + RefOfInsertExprPos + RefOfInsertExprLen + RefOfInsertExprNewStr + RefOfIntervalDateExprDate + RefOfIntervalDateExprInterval + RefOfIntervalFuncExprExpr + RefOfIntervalFuncExprExprsOffset + RefOfIntroducerExprExpr + RefOfIsExprLeft + RefOfJSONArrayAggExpr + RefOfJSONArrayAggOverClause + RefOfJSONArrayExprParamsOffset + RefOfJSONAttributesExprJSONDoc + RefOfJSONAttributesExprPath + RefOfJSONContainsExprTarget + RefOfJSONContainsExprCandidate + RefOfJSONContainsExprPathListOffset + RefOfJSONContainsPathExprJSONDoc + RefOfJSONContainsPathExprOneOrAll + RefOfJSONContainsPathExprPathListOffset + RefOfJSONExtractExprJSONDoc + RefOfJSONExtractExprPathListOffset + RefOfJSONKeysExprJSONDoc + RefOfJSONKeysExprPath + RefOfJSONObjectAggKey + RefOfJSONObjectAggValue + RefOfJSONObjectAggOverClause + RefOfJSONObjectExprParamsOffset + RefOfJSONObjectParamKey + RefOfJSONObjectParamValue + RefOfJSONOverlapsExprJSONDoc1 + RefOfJSONOverlapsExprJSONDoc2 + RefOfJSONPrettyExprJSONVal + RefOfJSONQuoteExprStringArg + RefOfJSONRemoveExprJSONDoc + RefOfJSONRemoveExprPathListOffset + RefOfJSONSchemaValidFuncExprSchema + RefOfJSONSchemaValidFuncExprDocument + RefOfJSONSchemaValidationReportFuncExprSchema + RefOfJSONSchemaValidationReportFuncExprDocument + RefOfJSONSearchExprJSONDoc + RefOfJSONSearchExprOneOrAll + RefOfJSONSearchExprSearchStr + RefOfJSONSearchExprEscapeChar + RefOfJSONSearchExprPathListOffset + RefOfJSONStorageFreeExprJSONVal + RefOfJSONStorageSizeExprJSONVal + RefOfJSONTableExprExpr + RefOfJSONTableExprAlias + RefOfJSONTableExprFilter + RefOfJSONTableExprColumnsOffset + RefOfJSONUnquoteExprJSONValue + RefOfJSONValueExprJSONDoc + RefOfJSONValueExprPath + RefOfJSONValueExprReturningType + RefOfJSONValueExprEmptyOnResponse + RefOfJSONValueExprErrorOnResponse + RefOfJSONValueMergeExprJSONDoc + RefOfJSONValueMergeExprJSONDocListOffset + RefOfJSONValueModifierExprJSONDoc + RefOfJSONValueModifierExprParamsOffset + RefOfJoinConditionOn + RefOfJoinConditionUsing + RefOfJoinTableExprLeftExpr + RefOfJoinTableExprRightExpr + RefOfJoinTableExprCondition + RefOfJtOnResponseExpr + RefOfLagLeadExprExpr + RefOfLagLeadExprN + RefOfLagLeadExprDefault + RefOfLagLeadExprOverClause + RefOfLagLeadExprNullTreatmentClause + RefOfLimitOffset + RefOfLimitRowcount + RefOfLineStringExprPointParamsOffset + RefOfLinestrPropertyFuncExprLinestring + RefOfLinestrPropertyFuncExprPropertyDefArg + RefOfLocateExprSubStr + RefOfLocateExprStr + RefOfLocateExprPos + RefOfLockingFuncName + RefOfLockingFuncTimeout + RefOfMatchExprColumnsOffset + RefOfMatchExprExpr + RefOfMaxArg + RefOfMaxOverClause + RefOfMemberOfExprValue + RefOfMemberOfExprJSONArr + RefOfMinArg + RefOfMinOverClause + RefOfModifyColumnNewColDefinition + RefOfModifyColumnAfter + RefOfMultiLinestringExprLinestringParamsOffset + RefOfMultiPointExprPointParamsOffset + RefOfMultiPolygonExprPolygonParamsOffset + RefOfNTHValueExprExpr + RefOfNTHValueExprN + RefOfNTHValueExprOverClause + RefOfNTHValueExprFromFirstLastClause + RefOfNTHValueExprNullTreatmentClause + RefOfNamedWindowWindows + NamedWindowsOffset + RefOfNextvalExpr + RefOfNotExprExpr + RefOfNtileExprN + RefOfNtileExprOverClause + RefOfOffsetOriginal + OnDupOffset + RefOfOptLikeLikeTable + RefOfOrExprLeft + RefOfOrExprRight + RefOfOrderExpr + OrderByOffset + RefOfOrderByOptionCols + RefOfOverClauseWindowName + RefOfOverClauseWindowSpec + RefOfParenTableExprExprs + RefOfPartitionDefinitionName + RefOfPartitionDefinitionOptions + RefOfPartitionDefinitionOptionsValueRange + RefOfPartitionDefinitionOptionsComment + RefOfPartitionDefinitionOptionsEngine + RefOfPartitionDefinitionOptionsDataDirectory + RefOfPartitionDefinitionOptionsIndexDirectory + RefOfPartitionDefinitionOptionsSubPartitionDefinitions + RefOfPartitionOptionColList + RefOfPartitionOptionExpr + RefOfPartitionOptionSubPartition + RefOfPartitionOptionDefinitionsOffset + RefOfPartitionSpecNames + RefOfPartitionSpecNumber + RefOfPartitionSpecTableName + RefOfPartitionSpecDefinitionsOffset + RefOfPartitionValueRangeRange + PartitionsOffset + RefOfPerformanceSchemaFuncExprArgument + RefOfPointExprXCordinate + RefOfPointExprYCordinate + RefOfPointPropertyFuncExprPoint + RefOfPointPropertyFuncExprValueToSet + RefOfPolygonExprLinestringParamsOffset + RefOfPolygonPropertyFuncExprPolygon + RefOfPolygonPropertyFuncExprPropertyDefArg + RefOfPrepareStmtName + RefOfPrepareStmtStatement + RefOfPrepareStmtComments + RefOfReferenceDefinitionReferencedTable + RefOfReferenceDefinitionReferencedColumns + RefOfReferenceDefinitionMatch + RefOfReferenceDefinitionOnDelete + RefOfReferenceDefinitionOnUpdate + RefOfRegexpInstrExprExpr + RefOfRegexpInstrExprPattern + RefOfRegexpInstrExprPosition + RefOfRegexpInstrExprOccurrence + RefOfRegexpInstrExprReturnOption + RefOfRegexpInstrExprMatchType + RefOfRegexpLikeExprExpr + RefOfRegexpLikeExprPattern + RefOfRegexpLikeExprMatchType + RefOfRegexpReplaceExprExpr + RefOfRegexpReplaceExprPattern + RefOfRegexpReplaceExprRepl + RefOfRegexpReplaceExprOccurrence + RefOfRegexpReplaceExprPosition + RefOfRegexpReplaceExprMatchType + RefOfRegexpSubstrExprExpr + RefOfRegexpSubstrExprPattern + RefOfRegexpSubstrExprOccurrence + RefOfRegexpSubstrExprPosition + RefOfRegexpSubstrExprMatchType + RefOfReleaseName + RefOfRenameColumnOldName + RefOfRenameColumnNewName + RefOfRenameIndexOldName + RefOfRenameIndexNewName + RefOfRenameTableNameTable + RefOfRevertMigrationComments + RootNodeSQLNode + RefOfRowAliasTableName + RefOfRowAliasColumns + RefOfSRollbackName + RefOfSavepointName + RefOfSelectWith + RefOfSelectFromOffset + RefOfSelectComments + RefOfSelectSelectExprs + RefOfSelectWhere + RefOfSelectGroupBy + RefOfSelectHaving + RefOfSelectWindows + RefOfSelectOrderBy + RefOfSelectLimit + RefOfSelectInto + RefOfSelectExprsExprsOffset + RefOfSetComments + RefOfSetExprs + RefOfSetExprVar + RefOfSetExprExpr + SetExprsOffset + RefOfShowInternal + RefOfShowBasicTbl + RefOfShowBasicDbName + RefOfShowBasicFilter + RefOfShowCreateOp + RefOfShowFilterFilter + RefOfShowMigrationLogsComments + RefOfStarExprTableName + RefOfStdArg + RefOfStdOverClause + RefOfStdDevArg + RefOfStdDevOverClause + RefOfStdPopArg + RefOfStdPopOverClause + RefOfStdSampArg + RefOfStdSampOverClause + RefOfStreamComments + RefOfStreamSelectExpr + RefOfStreamTable + RefOfSubPartitionColList + RefOfSubPartitionExpr + RefOfSubPartitionDefinitionName + RefOfSubPartitionDefinitionOptions + RefOfSubPartitionDefinitionOptionsComment + RefOfSubPartitionDefinitionOptionsEngine + RefOfSubPartitionDefinitionOptionsDataDirectory + RefOfSubPartitionDefinitionOptionsIndexDirectory + SubPartitionDefinitionsOffset + RefOfSubquerySelect + RefOfSubstrExprName + RefOfSubstrExprFrom + RefOfSubstrExprTo + RefOfSumArg + RefOfSumOverClause + TableExprsOffset + TableNameName + TableNameQualifier + TableNamesOffset + RefOfTableSpecColumnsOffset + RefOfTableSpecIndexesOffset + RefOfTableSpecConstraintsOffset + RefOfTableSpecOptions + RefOfTableSpecPartitionOption + RefOfTimestampDiffExprExpr1 + RefOfTimestampDiffExprExpr2 + RefOfTrimFuncExprTrimArg + RefOfTrimFuncExprStringArg + RefOfTruncateTableTable + RefOfUnaryExprExpr + RefOfUnionWith + RefOfUnionLeft + RefOfUnionRight + RefOfUnionOrderBy + RefOfUnionLimit + RefOfUnionInto + RefOfUpdateWith + RefOfUpdateComments + RefOfUpdateTableExprsOffset + RefOfUpdateExprs + RefOfUpdateWhere + RefOfUpdateOrderBy + RefOfUpdateLimit + RefOfUpdateExprName + RefOfUpdateExprExpr + UpdateExprsOffset + RefOfUpdateXMLExprTarget + RefOfUpdateXMLExprXPathExpr + RefOfUpdateXMLExprNewXML + RefOfUseDBName + RefOfVExplainStmtStatement + RefOfVExplainStmtComments + RefOfVStreamComments + RefOfVStreamSelectExpr + RefOfVStreamTable + RefOfVStreamWhere + RefOfVStreamLimit + ValTupleOffset + ValuesOffset + RefOfValuesFuncExprName + RefOfValuesStatementWith + RefOfValuesStatementRows + RefOfValuesStatementListArg + RefOfValuesStatementComments + RefOfValuesStatementOrder + RefOfValuesStatementLimit + RefOfVarPopArg + RefOfVarPopOverClause + RefOfVarSampArg + RefOfVarSampOverClause + RefOfVariableName + RefOfVarianceArg + RefOfVarianceOverClause + VindexParamKey + RefOfVindexSpecName + RefOfVindexSpecType + RefOfVindexSpecParamsOffset + RefOfWeightStringFuncExprExpr + RefOfWeightStringFuncExprAs + RefOfWhenCond + RefOfWhenVal + RefOfWhereExpr + RefOfWindowDefinitionName + RefOfWindowDefinitionWindowSpec + WindowDefinitionsOffset + RefOfWindowSpecificationName + RefOfWindowSpecificationPartitionClauseOffset + RefOfWindowSpecificationOrderClause + RefOfWindowSpecificationFrameClause + RefOfWithCTEsOffset + RefOfXorExprLeft + RefOfXorExprRight + SliceOfRefOfColumnDefinitionOffset + SliceOfAlterOptionOffset + SliceOfIdentifierCIOffset + SliceOfExprOffset + SliceOfRefOfWhenOffset + RefOfColumnTypeOptionsDefault + RefOfColumnTypeOptionsOnUpdate + RefOfColumnTypeOptionsAs + RefOfColumnTypeOptionsComment + RefOfColumnTypeOptionsReference + RefOfColumnTypeOptionsEngineAttribute + RefOfColumnTypeOptionsSecondaryEngineAttribute + RefOfColumnTypeOptionsSRID + SliceOfTableExprOffset + SliceOfRefOfVariableOffset + SliceOfRefOfJSONObjectParamOffset + SliceOfRefOfJtColumnDefinitionOffset + RefOfJtOrdinalColDefName + RefOfJtPathColDefName + RefOfJtPathColDefType + RefOfJtPathColDefPath + RefOfJtPathColDefEmptyOnResponse + RefOfJtPathColDefErrorOnResponse + RefOfJtNestedPathColDefPath + RefOfJtNestedPathColDefColumnsOffset + SliceOfRefOfColNameOffset + SliceOfRefOfPartitionDefinitionOffset + RefOfRootNodeSQLNode + SliceOfSelectExprOffset + RefOfTableNameName + RefOfTableNameQualifier + RefOfTableOptionValue + RefOfTableOptionTables + SliceOfRefOfIndexDefinitionOffset + SliceOfRefOfConstraintDefinitionOffset + RefOfVindexParamKey + SliceOfVindexParamOffset + SliceOfRefOfCommonTableExprOffset + RefOfIndexColumnColumn + RefOfIndexColumnExpression + RefOfIndexOptionValue + RefOfTableAndLockTypeTable + RefOfRenameTablePairFromTable + RefOfRenameTablePairToTable +) + +func (s ASTStep) DebugString() string { + switch s { + case RefOfAddColumnsColumnsOffset: + return "(*AddColumns).ColumnsOffset" + case RefOfAddColumnsAfter: + return "(*AddColumns).After" + case RefOfAddConstraintDefinitionConstraintDefinition: + return "(*AddConstraintDefinition).ConstraintDefinition" + case RefOfAddIndexDefinitionIndexDefinition: + return "(*AddIndexDefinition).IndexDefinition" + case RefOfAliasedExprExpr: + return "(*AliasedExpr).Expr" + case RefOfAliasedExprAs: + return "(*AliasedExpr).As" + case RefOfAliasedTableExprExpr: + return "(*AliasedTableExpr).Expr" + case RefOfAliasedTableExprPartitions: + return "(*AliasedTableExpr).Partitions" + case RefOfAliasedTableExprAs: + return "(*AliasedTableExpr).As" + case RefOfAliasedTableExprHints: + return "(*AliasedTableExpr).Hints" + case RefOfAliasedTableExprColumns: + return "(*AliasedTableExpr).Columns" + case RefOfAlterCheckName: + return "(*AlterCheck).Name" + case RefOfAlterColumnColumn: + return "(*AlterColumn).Column" + case RefOfAlterColumnDefaultVal: + return "(*AlterColumn).DefaultVal" + case RefOfAlterDatabaseComments: + return "(*AlterDatabase).Comments" + case RefOfAlterDatabaseDBName: + return "(*AlterDatabase).DBName" + case RefOfAlterIndexName: + return "(*AlterIndex).Name" + case RefOfAlterMigrationRatio: + return "(*AlterMigration).Ratio" + case RefOfAlterTableTable: + return "(*AlterTable).Table" + case RefOfAlterTableAlterOptionsOffset: + return "(*AlterTable).AlterOptionsOffset" + case RefOfAlterTablePartitionSpec: + return "(*AlterTable).PartitionSpec" + case RefOfAlterTablePartitionOption: + return "(*AlterTable).PartitionOption" + case RefOfAlterTableComments: + return "(*AlterTable).Comments" + case RefOfAlterViewViewName: + return "(*AlterView).ViewName" + case RefOfAlterViewDefiner: + return "(*AlterView).Definer" + case RefOfAlterViewColumns: + return "(*AlterView).Columns" + case RefOfAlterViewSelect: + return "(*AlterView).Select" + case RefOfAlterViewComments: + return "(*AlterView).Comments" + case RefOfAlterVschemaTable: + return "(*AlterVschema).Table" + case RefOfAlterVschemaVindexSpec: + return "(*AlterVschema).VindexSpec" + case RefOfAlterVschemaVindexColsOffset: + return "(*AlterVschema).VindexColsOffset" + case RefOfAlterVschemaAutoIncSpec: + return "(*AlterVschema).AutoIncSpec" + case RefOfAnalyzeTable: + return "(*Analyze).Table" + case RefOfAndExprLeft: + return "(*AndExpr).Left" + case RefOfAndExprRight: + return "(*AndExpr).Right" + case RefOfAnyValueArg: + return "(*AnyValue).Arg" + case RefOfArgumentLessWindowExprOverClause: + return "(*ArgumentLessWindowExpr).OverClause" + case RefOfAssignmentExprLeft: + return "(*AssignmentExpr).Left" + case RefOfAssignmentExprRight: + return "(*AssignmentExpr).Right" + case RefOfAutoIncSpecColumn: + return "(*AutoIncSpec).Column" + case RefOfAutoIncSpecSequence: + return "(*AutoIncSpec).Sequence" + case RefOfAvgArg: + return "(*Avg).Arg" + case RefOfAvgOverClause: + return "(*Avg).OverClause" + case RefOfBetweenExprLeft: + return "(*BetweenExpr).Left" + case RefOfBetweenExprFrom: + return "(*BetweenExpr).From" + case RefOfBetweenExprTo: + return "(*BetweenExpr).To" + case RefOfBinaryExprLeft: + return "(*BinaryExpr).Left" + case RefOfBinaryExprRight: + return "(*BinaryExpr).Right" + case RefOfBitAndArg: + return "(*BitAnd).Arg" + case RefOfBitAndOverClause: + return "(*BitAnd).OverClause" + case RefOfBitOrArg: + return "(*BitOr).Arg" + case RefOfBitOrOverClause: + return "(*BitOr).OverClause" + case RefOfBitXorArg: + return "(*BitXor).Arg" + case RefOfBitXorOverClause: + return "(*BitXor).OverClause" + case RefOfCallProcName: + return "(*CallProc).Name" + case RefOfCallProcParamsOffset: + return "(*CallProc).ParamsOffset" + case RefOfCaseExprExpr: + return "(*CaseExpr).Expr" + case RefOfCaseExprWhensOffset: + return "(*CaseExpr).WhensOffset" + case RefOfCaseExprElse: + return "(*CaseExpr).Else" + case RefOfCastExprExpr: + return "(*CastExpr).Expr" + case RefOfCastExprType: + return "(*CastExpr).Type" + case RefOfChangeColumnOldColumn: + return "(*ChangeColumn).OldColumn" + case RefOfChangeColumnNewColDefinition: + return "(*ChangeColumn).NewColDefinition" + case RefOfChangeColumnAfter: + return "(*ChangeColumn).After" + case RefOfCharExprExprsOffset: + return "(*CharExpr).ExprsOffset" + case RefOfCheckConstraintDefinitionExpr: + return "(*CheckConstraintDefinition).Expr" + case RefOfColNameName: + return "(*ColName).Name" + case RefOfColNameQualifier: + return "(*ColName).Qualifier" + case RefOfCollateExprExpr: + return "(*CollateExpr).Expr" + case RefOfColumnDefinitionName: + return "(*ColumnDefinition).Name" + case RefOfColumnDefinitionType: + return "(*ColumnDefinition).Type" + case ColumnsOffset: + return "(Columns)[]Offset" + case RefOfCommonTableExprID: + return "(*CommonTableExpr).ID" + case RefOfCommonTableExprColumns: + return "(*CommonTableExpr).Columns" + case RefOfCommonTableExprSubquery: + return "(*CommonTableExpr).Subquery" + case RefOfComparisonExprLeft: + return "(*ComparisonExpr).Left" + case RefOfComparisonExprRight: + return "(*ComparisonExpr).Right" + case RefOfComparisonExprEscape: + return "(*ComparisonExpr).Escape" + case RefOfConstraintDefinitionName: + return "(*ConstraintDefinition).Name" + case RefOfConstraintDefinitionDetails: + return "(*ConstraintDefinition).Details" + case RefOfConvertExprExpr: + return "(*ConvertExpr).Expr" + case RefOfConvertExprType: + return "(*ConvertExpr).Type" + case RefOfConvertUsingExprExpr: + return "(*ConvertUsingExpr).Expr" + case RefOfCountArgsOffset: + return "(*Count).ArgsOffset" + case RefOfCountOverClause: + return "(*Count).OverClause" + case RefOfCountStarOverClause: + return "(*CountStar).OverClause" + case RefOfCreateDatabaseComments: + return "(*CreateDatabase).Comments" + case RefOfCreateDatabaseDBName: + return "(*CreateDatabase).DBName" + case RefOfCreateTableTable: + return "(*CreateTable).Table" + case RefOfCreateTableTableSpec: + return "(*CreateTable).TableSpec" + case RefOfCreateTableOptLike: + return "(*CreateTable).OptLike" + case RefOfCreateTableComments: + return "(*CreateTable).Comments" + case RefOfCreateViewViewName: + return "(*CreateView).ViewName" + case RefOfCreateViewDefiner: + return "(*CreateView).Definer" + case RefOfCreateViewColumns: + return "(*CreateView).Columns" + case RefOfCreateViewSelect: + return "(*CreateView).Select" + case RefOfCreateViewComments: + return "(*CreateView).Comments" + case RefOfCurTimeFuncExprName: + return "(*CurTimeFuncExpr).Name" + case RefOfDeallocateStmtComments: + return "(*DeallocateStmt).Comments" + case RefOfDeallocateStmtName: + return "(*DeallocateStmt).Name" + case RefOfDeleteWith: + return "(*Delete).With" + case RefOfDeleteComments: + return "(*Delete).Comments" + case RefOfDeleteTableExprsOffset: + return "(*Delete).TableExprsOffset" + case RefOfDeleteTargets: + return "(*Delete).Targets" + case RefOfDeletePartitions: + return "(*Delete).Partitions" + case RefOfDeleteWhere: + return "(*Delete).Where" + case RefOfDeleteOrderBy: + return "(*Delete).OrderBy" + case RefOfDeleteLimit: + return "(*Delete).Limit" + case RefOfDerivedTableSelect: + return "(*DerivedTable).Select" + case RefOfDropColumnName: + return "(*DropColumn).Name" + case RefOfDropDatabaseComments: + return "(*DropDatabase).Comments" + case RefOfDropDatabaseDBName: + return "(*DropDatabase).DBName" + case RefOfDropKeyName: + return "(*DropKey).Name" + case RefOfDropTableFromTables: + return "(*DropTable).FromTables" + case RefOfDropTableComments: + return "(*DropTable).Comments" + case RefOfDropViewFromTables: + return "(*DropView).FromTables" + case RefOfDropViewComments: + return "(*DropView).Comments" + case RefOfExecuteStmtName: + return "(*ExecuteStmt).Name" + case RefOfExecuteStmtComments: + return "(*ExecuteStmt).Comments" + case RefOfExecuteStmtArgumentsOffset: + return "(*ExecuteStmt).ArgumentsOffset" + case RefOfExistsExprSubquery: + return "(*ExistsExpr).Subquery" + case RefOfExplainStmtStatement: + return "(*ExplainStmt).Statement" + case RefOfExplainStmtComments: + return "(*ExplainStmt).Comments" + case RefOfExplainTabTable: + return "(*ExplainTab).Table" + case RefOfExprsExprsOffset: + return "(*Exprs).ExprsOffset" + case RefOfExtractFuncExprExpr: + return "(*ExtractFuncExpr).Expr" + case RefOfExtractValueExprFragment: + return "(*ExtractValueExpr).Fragment" + case RefOfExtractValueExprXPathExpr: + return "(*ExtractValueExpr).XPathExpr" + case RefOfFirstOrLastValueExprExpr: + return "(*FirstOrLastValueExpr).Expr" + case RefOfFirstOrLastValueExprNullTreatmentClause: + return "(*FirstOrLastValueExpr).NullTreatmentClause" + case RefOfFirstOrLastValueExprOverClause: + return "(*FirstOrLastValueExpr).OverClause" + case RefOfFlushTableNames: + return "(*Flush).TableNames" + case RefOfForeignKeyDefinitionSource: + return "(*ForeignKeyDefinition).Source" + case RefOfForeignKeyDefinitionIndexName: + return "(*ForeignKeyDefinition).IndexName" + case RefOfForeignKeyDefinitionReferenceDefinition: + return "(*ForeignKeyDefinition).ReferenceDefinition" + case RefOfFrameClauseStart: + return "(*FrameClause).Start" + case RefOfFrameClauseEnd: + return "(*FrameClause).End" + case RefOfFramePointExpr: + return "(*FramePoint).Expr" + case RefOfFuncExprQualifier: + return "(*FuncExpr).Qualifier" + case RefOfFuncExprName: + return "(*FuncExpr).Name" + case RefOfFuncExprExprsOffset: + return "(*FuncExpr).ExprsOffset" + case RefOfGTIDFuncExprSet1: + return "(*GTIDFuncExpr).Set1" + case RefOfGTIDFuncExprSet2: + return "(*GTIDFuncExpr).Set2" + case RefOfGTIDFuncExprTimeout: + return "(*GTIDFuncExpr).Timeout" + case RefOfGTIDFuncExprChannel: + return "(*GTIDFuncExpr).Channel" + case RefOfGeoHashFromLatLongExprLatitude: + return "(*GeoHashFromLatLongExpr).Latitude" + case RefOfGeoHashFromLatLongExprLongitude: + return "(*GeoHashFromLatLongExpr).Longitude" + case RefOfGeoHashFromLatLongExprMaxLength: + return "(*GeoHashFromLatLongExpr).MaxLength" + case RefOfGeoHashFromPointExprPoint: + return "(*GeoHashFromPointExpr).Point" + case RefOfGeoHashFromPointExprMaxLength: + return "(*GeoHashFromPointExpr).MaxLength" + case RefOfGeoJSONFromGeomExprGeom: + return "(*GeoJSONFromGeomExpr).Geom" + case RefOfGeoJSONFromGeomExprMaxDecimalDigits: + return "(*GeoJSONFromGeomExpr).MaxDecimalDigits" + case RefOfGeoJSONFromGeomExprBitmask: + return "(*GeoJSONFromGeomExpr).Bitmask" + case RefOfGeomCollPropertyFuncExprGeomColl: + return "(*GeomCollPropertyFuncExpr).GeomColl" + case RefOfGeomCollPropertyFuncExprPropertyDefArg: + return "(*GeomCollPropertyFuncExpr).PropertyDefArg" + case RefOfGeomFormatExprGeom: + return "(*GeomFormatExpr).Geom" + case RefOfGeomFormatExprAxisOrderOpt: + return "(*GeomFormatExpr).AxisOrderOpt" + case RefOfGeomFromGeoHashExprGeoHash: + return "(*GeomFromGeoHashExpr).GeoHash" + case RefOfGeomFromGeoHashExprSridOpt: + return "(*GeomFromGeoHashExpr).SridOpt" + case RefOfGeomFromGeoJSONExprGeoJSON: + return "(*GeomFromGeoJSONExpr).GeoJSON" + case RefOfGeomFromGeoJSONExprHigherDimHandlerOpt: + return "(*GeomFromGeoJSONExpr).HigherDimHandlerOpt" + case RefOfGeomFromGeoJSONExprSrid: + return "(*GeomFromGeoJSONExpr).Srid" + case RefOfGeomFromTextExprWktText: + return "(*GeomFromTextExpr).WktText" + case RefOfGeomFromTextExprSrid: + return "(*GeomFromTextExpr).Srid" + case RefOfGeomFromTextExprAxisOrderOpt: + return "(*GeomFromTextExpr).AxisOrderOpt" + case RefOfGeomFromWKBExprWkbBlob: + return "(*GeomFromWKBExpr).WkbBlob" + case RefOfGeomFromWKBExprSrid: + return "(*GeomFromWKBExpr).Srid" + case RefOfGeomFromWKBExprAxisOrderOpt: + return "(*GeomFromWKBExpr).AxisOrderOpt" + case RefOfGeomPropertyFuncExprGeom: + return "(*GeomPropertyFuncExpr).Geom" + case RefOfGroupByExprsOffset: + return "(*GroupBy).ExprsOffset" + case RefOfGroupConcatExprExprsOffset: + return "(*GroupConcatExpr).ExprsOffset" + case RefOfGroupConcatExprOrderBy: + return "(*GroupConcatExpr).OrderBy" + case RefOfGroupConcatExprLimit: + return "(*GroupConcatExpr).Limit" + case RefOfIndexDefinitionInfo: + return "(*IndexDefinition).Info" + case RefOfIndexHintIndexesOffset: + return "(*IndexHint).IndexesOffset" + case IndexHintsOffset: + return "(IndexHints)[]Offset" + case RefOfIndexInfoName: + return "(*IndexInfo).Name" + case RefOfIndexInfoConstraintName: + return "(*IndexInfo).ConstraintName" + case RefOfInsertComments: + return "(*Insert).Comments" + case RefOfInsertTable: + return "(*Insert).Table" + case RefOfInsertPartitions: + return "(*Insert).Partitions" + case RefOfInsertColumns: + return "(*Insert).Columns" + case RefOfInsertRows: + return "(*Insert).Rows" + case RefOfInsertRowAlias: + return "(*Insert).RowAlias" + case RefOfInsertOnDup: + return "(*Insert).OnDup" + case RefOfInsertExprStr: + return "(*InsertExpr).Str" + case RefOfInsertExprPos: + return "(*InsertExpr).Pos" + case RefOfInsertExprLen: + return "(*InsertExpr).Len" + case RefOfInsertExprNewStr: + return "(*InsertExpr).NewStr" + case RefOfIntervalDateExprDate: + return "(*IntervalDateExpr).Date" + case RefOfIntervalDateExprInterval: + return "(*IntervalDateExpr).Interval" + case RefOfIntervalFuncExprExpr: + return "(*IntervalFuncExpr).Expr" + case RefOfIntervalFuncExprExprsOffset: + return "(*IntervalFuncExpr).ExprsOffset" + case RefOfIntroducerExprExpr: + return "(*IntroducerExpr).Expr" + case RefOfIsExprLeft: + return "(*IsExpr).Left" + case RefOfJSONArrayAggExpr: + return "(*JSONArrayAgg).Expr" + case RefOfJSONArrayAggOverClause: + return "(*JSONArrayAgg).OverClause" + case RefOfJSONArrayExprParamsOffset: + return "(*JSONArrayExpr).ParamsOffset" + case RefOfJSONAttributesExprJSONDoc: + return "(*JSONAttributesExpr).JSONDoc" + case RefOfJSONAttributesExprPath: + return "(*JSONAttributesExpr).Path" + case RefOfJSONContainsExprTarget: + return "(*JSONContainsExpr).Target" + case RefOfJSONContainsExprCandidate: + return "(*JSONContainsExpr).Candidate" + case RefOfJSONContainsExprPathListOffset: + return "(*JSONContainsExpr).PathListOffset" + case RefOfJSONContainsPathExprJSONDoc: + return "(*JSONContainsPathExpr).JSONDoc" + case RefOfJSONContainsPathExprOneOrAll: + return "(*JSONContainsPathExpr).OneOrAll" + case RefOfJSONContainsPathExprPathListOffset: + return "(*JSONContainsPathExpr).PathListOffset" + case RefOfJSONExtractExprJSONDoc: + return "(*JSONExtractExpr).JSONDoc" + case RefOfJSONExtractExprPathListOffset: + return "(*JSONExtractExpr).PathListOffset" + case RefOfJSONKeysExprJSONDoc: + return "(*JSONKeysExpr).JSONDoc" + case RefOfJSONKeysExprPath: + return "(*JSONKeysExpr).Path" + case RefOfJSONObjectAggKey: + return "(*JSONObjectAgg).Key" + case RefOfJSONObjectAggValue: + return "(*JSONObjectAgg).Value" + case RefOfJSONObjectAggOverClause: + return "(*JSONObjectAgg).OverClause" + case RefOfJSONObjectExprParamsOffset: + return "(*JSONObjectExpr).ParamsOffset" + case RefOfJSONObjectParamKey: + return "(*JSONObjectParam).Key" + case RefOfJSONObjectParamValue: + return "(*JSONObjectParam).Value" + case RefOfJSONOverlapsExprJSONDoc1: + return "(*JSONOverlapsExpr).JSONDoc1" + case RefOfJSONOverlapsExprJSONDoc2: + return "(*JSONOverlapsExpr).JSONDoc2" + case RefOfJSONPrettyExprJSONVal: + return "(*JSONPrettyExpr).JSONVal" + case RefOfJSONQuoteExprStringArg: + return "(*JSONQuoteExpr).StringArg" + case RefOfJSONRemoveExprJSONDoc: + return "(*JSONRemoveExpr).JSONDoc" + case RefOfJSONRemoveExprPathListOffset: + return "(*JSONRemoveExpr).PathListOffset" + case RefOfJSONSchemaValidFuncExprSchema: + return "(*JSONSchemaValidFuncExpr).Schema" + case RefOfJSONSchemaValidFuncExprDocument: + return "(*JSONSchemaValidFuncExpr).Document" + case RefOfJSONSchemaValidationReportFuncExprSchema: + return "(*JSONSchemaValidationReportFuncExpr).Schema" + case RefOfJSONSchemaValidationReportFuncExprDocument: + return "(*JSONSchemaValidationReportFuncExpr).Document" + case RefOfJSONSearchExprJSONDoc: + return "(*JSONSearchExpr).JSONDoc" + case RefOfJSONSearchExprOneOrAll: + return "(*JSONSearchExpr).OneOrAll" + case RefOfJSONSearchExprSearchStr: + return "(*JSONSearchExpr).SearchStr" + case RefOfJSONSearchExprEscapeChar: + return "(*JSONSearchExpr).EscapeChar" + case RefOfJSONSearchExprPathListOffset: + return "(*JSONSearchExpr).PathListOffset" + case RefOfJSONStorageFreeExprJSONVal: + return "(*JSONStorageFreeExpr).JSONVal" + case RefOfJSONStorageSizeExprJSONVal: + return "(*JSONStorageSizeExpr).JSONVal" + case RefOfJSONTableExprExpr: + return "(*JSONTableExpr).Expr" + case RefOfJSONTableExprAlias: + return "(*JSONTableExpr).Alias" + case RefOfJSONTableExprFilter: + return "(*JSONTableExpr).Filter" + case RefOfJSONTableExprColumnsOffset: + return "(*JSONTableExpr).ColumnsOffset" + case RefOfJSONUnquoteExprJSONValue: + return "(*JSONUnquoteExpr).JSONValue" + case RefOfJSONValueExprJSONDoc: + return "(*JSONValueExpr).JSONDoc" + case RefOfJSONValueExprPath: + return "(*JSONValueExpr).Path" + case RefOfJSONValueExprReturningType: + return "(*JSONValueExpr).ReturningType" + case RefOfJSONValueExprEmptyOnResponse: + return "(*JSONValueExpr).EmptyOnResponse" + case RefOfJSONValueExprErrorOnResponse: + return "(*JSONValueExpr).ErrorOnResponse" + case RefOfJSONValueMergeExprJSONDoc: + return "(*JSONValueMergeExpr).JSONDoc" + case RefOfJSONValueMergeExprJSONDocListOffset: + return "(*JSONValueMergeExpr).JSONDocListOffset" + case RefOfJSONValueModifierExprJSONDoc: + return "(*JSONValueModifierExpr).JSONDoc" + case RefOfJSONValueModifierExprParamsOffset: + return "(*JSONValueModifierExpr).ParamsOffset" + case RefOfJoinConditionOn: + return "(*JoinCondition).On" + case RefOfJoinConditionUsing: + return "(*JoinCondition).Using" + case RefOfJoinTableExprLeftExpr: + return "(*JoinTableExpr).LeftExpr" + case RefOfJoinTableExprRightExpr: + return "(*JoinTableExpr).RightExpr" + case RefOfJoinTableExprCondition: + return "(*JoinTableExpr).Condition" + case RefOfJtOnResponseExpr: + return "(*JtOnResponse).Expr" + case RefOfLagLeadExprExpr: + return "(*LagLeadExpr).Expr" + case RefOfLagLeadExprN: + return "(*LagLeadExpr).N" + case RefOfLagLeadExprDefault: + return "(*LagLeadExpr).Default" + case RefOfLagLeadExprOverClause: + return "(*LagLeadExpr).OverClause" + case RefOfLagLeadExprNullTreatmentClause: + return "(*LagLeadExpr).NullTreatmentClause" + case RefOfLimitOffset: + return "(*Limit).Offset" + case RefOfLimitRowcount: + return "(*Limit).Rowcount" + case RefOfLineStringExprPointParamsOffset: + return "(*LineStringExpr).PointParamsOffset" + case RefOfLinestrPropertyFuncExprLinestring: + return "(*LinestrPropertyFuncExpr).Linestring" + case RefOfLinestrPropertyFuncExprPropertyDefArg: + return "(*LinestrPropertyFuncExpr).PropertyDefArg" + case RefOfLocateExprSubStr: + return "(*LocateExpr).SubStr" + case RefOfLocateExprStr: + return "(*LocateExpr).Str" + case RefOfLocateExprPos: + return "(*LocateExpr).Pos" + case RefOfLockingFuncName: + return "(*LockingFunc).Name" + case RefOfLockingFuncTimeout: + return "(*LockingFunc).Timeout" + case RefOfMatchExprColumnsOffset: + return "(*MatchExpr).ColumnsOffset" + case RefOfMatchExprExpr: + return "(*MatchExpr).Expr" + case RefOfMaxArg: + return "(*Max).Arg" + case RefOfMaxOverClause: + return "(*Max).OverClause" + case RefOfMemberOfExprValue: + return "(*MemberOfExpr).Value" + case RefOfMemberOfExprJSONArr: + return "(*MemberOfExpr).JSONArr" + case RefOfMinArg: + return "(*Min).Arg" + case RefOfMinOverClause: + return "(*Min).OverClause" + case RefOfModifyColumnNewColDefinition: + return "(*ModifyColumn).NewColDefinition" + case RefOfModifyColumnAfter: + return "(*ModifyColumn).After" + case RefOfMultiLinestringExprLinestringParamsOffset: + return "(*MultiLinestringExpr).LinestringParamsOffset" + case RefOfMultiPointExprPointParamsOffset: + return "(*MultiPointExpr).PointParamsOffset" + case RefOfMultiPolygonExprPolygonParamsOffset: + return "(*MultiPolygonExpr).PolygonParamsOffset" + case RefOfNTHValueExprExpr: + return "(*NTHValueExpr).Expr" + case RefOfNTHValueExprN: + return "(*NTHValueExpr).N" + case RefOfNTHValueExprOverClause: + return "(*NTHValueExpr).OverClause" + case RefOfNTHValueExprFromFirstLastClause: + return "(*NTHValueExpr).FromFirstLastClause" + case RefOfNTHValueExprNullTreatmentClause: + return "(*NTHValueExpr).NullTreatmentClause" + case RefOfNamedWindowWindows: + return "(*NamedWindow).Windows" + case NamedWindowsOffset: + return "(NamedWindows)[]Offset" + case RefOfNextvalExpr: + return "(*Nextval).Expr" + case RefOfNotExprExpr: + return "(*NotExpr).Expr" + case RefOfNtileExprN: + return "(*NtileExpr).N" + case RefOfNtileExprOverClause: + return "(*NtileExpr).OverClause" + case RefOfOffsetOriginal: + return "(*Offset).Original" + case OnDupOffset: + return "(OnDup)[]Offset" + case RefOfOptLikeLikeTable: + return "(*OptLike).LikeTable" + case RefOfOrExprLeft: + return "(*OrExpr).Left" + case RefOfOrExprRight: + return "(*OrExpr).Right" + case RefOfOrderExpr: + return "(*Order).Expr" + case OrderByOffset: + return "(OrderBy)[]Offset" + case RefOfOrderByOptionCols: + return "(*OrderByOption).Cols" + case RefOfOverClauseWindowName: + return "(*OverClause).WindowName" + case RefOfOverClauseWindowSpec: + return "(*OverClause).WindowSpec" + case RefOfParenTableExprExprs: + return "(*ParenTableExpr).Exprs" + case RefOfPartitionDefinitionName: + return "(*PartitionDefinition).Name" + case RefOfPartitionDefinitionOptions: + return "(*PartitionDefinition).Options" + case RefOfPartitionDefinitionOptionsValueRange: + return "(*PartitionDefinitionOptions).ValueRange" + case RefOfPartitionDefinitionOptionsComment: + return "(*PartitionDefinitionOptions).Comment" + case RefOfPartitionDefinitionOptionsEngine: + return "(*PartitionDefinitionOptions).Engine" + case RefOfPartitionDefinitionOptionsDataDirectory: + return "(*PartitionDefinitionOptions).DataDirectory" + case RefOfPartitionDefinitionOptionsIndexDirectory: + return "(*PartitionDefinitionOptions).IndexDirectory" + case RefOfPartitionDefinitionOptionsSubPartitionDefinitions: + return "(*PartitionDefinitionOptions).SubPartitionDefinitions" + case RefOfPartitionOptionColList: + return "(*PartitionOption).ColList" + case RefOfPartitionOptionExpr: + return "(*PartitionOption).Expr" + case RefOfPartitionOptionSubPartition: + return "(*PartitionOption).SubPartition" + case RefOfPartitionOptionDefinitionsOffset: + return "(*PartitionOption).DefinitionsOffset" + case RefOfPartitionSpecNames: + return "(*PartitionSpec).Names" + case RefOfPartitionSpecNumber: + return "(*PartitionSpec).Number" + case RefOfPartitionSpecTableName: + return "(*PartitionSpec).TableName" + case RefOfPartitionSpecDefinitionsOffset: + return "(*PartitionSpec).DefinitionsOffset" + case RefOfPartitionValueRangeRange: + return "(*PartitionValueRange).Range" + case PartitionsOffset: + return "(Partitions)[]Offset" + case RefOfPerformanceSchemaFuncExprArgument: + return "(*PerformanceSchemaFuncExpr).Argument" + case RefOfPointExprXCordinate: + return "(*PointExpr).XCordinate" + case RefOfPointExprYCordinate: + return "(*PointExpr).YCordinate" + case RefOfPointPropertyFuncExprPoint: + return "(*PointPropertyFuncExpr).Point" + case RefOfPointPropertyFuncExprValueToSet: + return "(*PointPropertyFuncExpr).ValueToSet" + case RefOfPolygonExprLinestringParamsOffset: + return "(*PolygonExpr).LinestringParamsOffset" + case RefOfPolygonPropertyFuncExprPolygon: + return "(*PolygonPropertyFuncExpr).Polygon" + case RefOfPolygonPropertyFuncExprPropertyDefArg: + return "(*PolygonPropertyFuncExpr).PropertyDefArg" + case RefOfPrepareStmtName: + return "(*PrepareStmt).Name" + case RefOfPrepareStmtStatement: + return "(*PrepareStmt).Statement" + case RefOfPrepareStmtComments: + return "(*PrepareStmt).Comments" + case RefOfReferenceDefinitionReferencedTable: + return "(*ReferenceDefinition).ReferencedTable" + case RefOfReferenceDefinitionReferencedColumns: + return "(*ReferenceDefinition).ReferencedColumns" + case RefOfReferenceDefinitionMatch: + return "(*ReferenceDefinition).Match" + case RefOfReferenceDefinitionOnDelete: + return "(*ReferenceDefinition).OnDelete" + case RefOfReferenceDefinitionOnUpdate: + return "(*ReferenceDefinition).OnUpdate" + case RefOfRegexpInstrExprExpr: + return "(*RegexpInstrExpr).Expr" + case RefOfRegexpInstrExprPattern: + return "(*RegexpInstrExpr).Pattern" + case RefOfRegexpInstrExprPosition: + return "(*RegexpInstrExpr).Position" + case RefOfRegexpInstrExprOccurrence: + return "(*RegexpInstrExpr).Occurrence" + case RefOfRegexpInstrExprReturnOption: + return "(*RegexpInstrExpr).ReturnOption" + case RefOfRegexpInstrExprMatchType: + return "(*RegexpInstrExpr).MatchType" + case RefOfRegexpLikeExprExpr: + return "(*RegexpLikeExpr).Expr" + case RefOfRegexpLikeExprPattern: + return "(*RegexpLikeExpr).Pattern" + case RefOfRegexpLikeExprMatchType: + return "(*RegexpLikeExpr).MatchType" + case RefOfRegexpReplaceExprExpr: + return "(*RegexpReplaceExpr).Expr" + case RefOfRegexpReplaceExprPattern: + return "(*RegexpReplaceExpr).Pattern" + case RefOfRegexpReplaceExprRepl: + return "(*RegexpReplaceExpr).Repl" + case RefOfRegexpReplaceExprOccurrence: + return "(*RegexpReplaceExpr).Occurrence" + case RefOfRegexpReplaceExprPosition: + return "(*RegexpReplaceExpr).Position" + case RefOfRegexpReplaceExprMatchType: + return "(*RegexpReplaceExpr).MatchType" + case RefOfRegexpSubstrExprExpr: + return "(*RegexpSubstrExpr).Expr" + case RefOfRegexpSubstrExprPattern: + return "(*RegexpSubstrExpr).Pattern" + case RefOfRegexpSubstrExprOccurrence: + return "(*RegexpSubstrExpr).Occurrence" + case RefOfRegexpSubstrExprPosition: + return "(*RegexpSubstrExpr).Position" + case RefOfRegexpSubstrExprMatchType: + return "(*RegexpSubstrExpr).MatchType" + case RefOfReleaseName: + return "(*Release).Name" + case RefOfRenameColumnOldName: + return "(*RenameColumn).OldName" + case RefOfRenameColumnNewName: + return "(*RenameColumn).NewName" + case RefOfRenameIndexOldName: + return "(*RenameIndex).OldName" + case RefOfRenameIndexNewName: + return "(*RenameIndex).NewName" + case RefOfRenameTableNameTable: + return "(*RenameTableName).Table" + case RefOfRevertMigrationComments: + return "(*RevertMigration).Comments" + case RootNodeSQLNode: + return "(RootNode).SQLNode" + case RefOfRowAliasTableName: + return "(*RowAlias).TableName" + case RefOfRowAliasColumns: + return "(*RowAlias).Columns" + case RefOfSRollbackName: + return "(*SRollback).Name" + case RefOfSavepointName: + return "(*Savepoint).Name" + case RefOfSelectWith: + return "(*Select).With" + case RefOfSelectFromOffset: + return "(*Select).FromOffset" + case RefOfSelectComments: + return "(*Select).Comments" + case RefOfSelectSelectExprs: + return "(*Select).SelectExprs" + case RefOfSelectWhere: + return "(*Select).Where" + case RefOfSelectGroupBy: + return "(*Select).GroupBy" + case RefOfSelectHaving: + return "(*Select).Having" + case RefOfSelectWindows: + return "(*Select).Windows" + case RefOfSelectOrderBy: + return "(*Select).OrderBy" + case RefOfSelectLimit: + return "(*Select).Limit" + case RefOfSelectInto: + return "(*Select).Into" + case RefOfSelectExprsExprsOffset: + return "(*SelectExprs).ExprsOffset" + case RefOfSetComments: + return "(*Set).Comments" + case RefOfSetExprs: + return "(*Set).Exprs" + case RefOfSetExprVar: + return "(*SetExpr).Var" + case RefOfSetExprExpr: + return "(*SetExpr).Expr" + case SetExprsOffset: + return "(SetExprs)[]Offset" + case RefOfShowInternal: + return "(*Show).Internal" + case RefOfShowBasicTbl: + return "(*ShowBasic).Tbl" + case RefOfShowBasicDbName: + return "(*ShowBasic).DbName" + case RefOfShowBasicFilter: + return "(*ShowBasic).Filter" + case RefOfShowCreateOp: + return "(*ShowCreate).Op" + case RefOfShowFilterFilter: + return "(*ShowFilter).Filter" + case RefOfShowMigrationLogsComments: + return "(*ShowMigrationLogs).Comments" + case RefOfStarExprTableName: + return "(*StarExpr).TableName" + case RefOfStdArg: + return "(*Std).Arg" + case RefOfStdOverClause: + return "(*Std).OverClause" + case RefOfStdDevArg: + return "(*StdDev).Arg" + case RefOfStdDevOverClause: + return "(*StdDev).OverClause" + case RefOfStdPopArg: + return "(*StdPop).Arg" + case RefOfStdPopOverClause: + return "(*StdPop).OverClause" + case RefOfStdSampArg: + return "(*StdSamp).Arg" + case RefOfStdSampOverClause: + return "(*StdSamp).OverClause" + case RefOfStreamComments: + return "(*Stream).Comments" + case RefOfStreamSelectExpr: + return "(*Stream).SelectExpr" + case RefOfStreamTable: + return "(*Stream).Table" + case RefOfSubPartitionColList: + return "(*SubPartition).ColList" + case RefOfSubPartitionExpr: + return "(*SubPartition).Expr" + case RefOfSubPartitionDefinitionName: + return "(*SubPartitionDefinition).Name" + case RefOfSubPartitionDefinitionOptions: + return "(*SubPartitionDefinition).Options" + case RefOfSubPartitionDefinitionOptionsComment: + return "(*SubPartitionDefinitionOptions).Comment" + case RefOfSubPartitionDefinitionOptionsEngine: + return "(*SubPartitionDefinitionOptions).Engine" + case RefOfSubPartitionDefinitionOptionsDataDirectory: + return "(*SubPartitionDefinitionOptions).DataDirectory" + case RefOfSubPartitionDefinitionOptionsIndexDirectory: + return "(*SubPartitionDefinitionOptions).IndexDirectory" + case SubPartitionDefinitionsOffset: + return "(SubPartitionDefinitions)[]Offset" + case RefOfSubquerySelect: + return "(*Subquery).Select" + case RefOfSubstrExprName: + return "(*SubstrExpr).Name" + case RefOfSubstrExprFrom: + return "(*SubstrExpr).From" + case RefOfSubstrExprTo: + return "(*SubstrExpr).To" + case RefOfSumArg: + return "(*Sum).Arg" + case RefOfSumOverClause: + return "(*Sum).OverClause" + case TableExprsOffset: + return "(TableExprs)[]Offset" + case TableNameName: + return "(TableName).Name" + case TableNameQualifier: + return "(TableName).Qualifier" + case TableNamesOffset: + return "(TableNames)[]Offset" + case RefOfTableSpecColumnsOffset: + return "(*TableSpec).ColumnsOffset" + case RefOfTableSpecIndexesOffset: + return "(*TableSpec).IndexesOffset" + case RefOfTableSpecConstraintsOffset: + return "(*TableSpec).ConstraintsOffset" + case RefOfTableSpecOptions: + return "(*TableSpec).Options" + case RefOfTableSpecPartitionOption: + return "(*TableSpec).PartitionOption" + case RefOfTimestampDiffExprExpr1: + return "(*TimestampDiffExpr).Expr1" + case RefOfTimestampDiffExprExpr2: + return "(*TimestampDiffExpr).Expr2" + case RefOfTrimFuncExprTrimArg: + return "(*TrimFuncExpr).TrimArg" + case RefOfTrimFuncExprStringArg: + return "(*TrimFuncExpr).StringArg" + case RefOfTruncateTableTable: + return "(*TruncateTable).Table" + case RefOfUnaryExprExpr: + return "(*UnaryExpr).Expr" + case RefOfUnionWith: + return "(*Union).With" + case RefOfUnionLeft: + return "(*Union).Left" + case RefOfUnionRight: + return "(*Union).Right" + case RefOfUnionOrderBy: + return "(*Union).OrderBy" + case RefOfUnionLimit: + return "(*Union).Limit" + case RefOfUnionInto: + return "(*Union).Into" + case RefOfUpdateWith: + return "(*Update).With" + case RefOfUpdateComments: + return "(*Update).Comments" + case RefOfUpdateTableExprsOffset: + return "(*Update).TableExprsOffset" + case RefOfUpdateExprs: + return "(*Update).Exprs" + case RefOfUpdateWhere: + return "(*Update).Where" + case RefOfUpdateOrderBy: + return "(*Update).OrderBy" + case RefOfUpdateLimit: + return "(*Update).Limit" + case RefOfUpdateExprName: + return "(*UpdateExpr).Name" + case RefOfUpdateExprExpr: + return "(*UpdateExpr).Expr" + case UpdateExprsOffset: + return "(UpdateExprs)[]Offset" + case RefOfUpdateXMLExprTarget: + return "(*UpdateXMLExpr).Target" + case RefOfUpdateXMLExprXPathExpr: + return "(*UpdateXMLExpr).XPathExpr" + case RefOfUpdateXMLExprNewXML: + return "(*UpdateXMLExpr).NewXML" + case RefOfUseDBName: + return "(*Use).DBName" + case RefOfVExplainStmtStatement: + return "(*VExplainStmt).Statement" + case RefOfVExplainStmtComments: + return "(*VExplainStmt).Comments" + case RefOfVStreamComments: + return "(*VStream).Comments" + case RefOfVStreamSelectExpr: + return "(*VStream).SelectExpr" + case RefOfVStreamTable: + return "(*VStream).Table" + case RefOfVStreamWhere: + return "(*VStream).Where" + case RefOfVStreamLimit: + return "(*VStream).Limit" + case ValTupleOffset: + return "(ValTuple)[]Offset" + case ValuesOffset: + return "(Values)[]Offset" + case RefOfValuesFuncExprName: + return "(*ValuesFuncExpr).Name" + case RefOfValuesStatementWith: + return "(*ValuesStatement).With" + case RefOfValuesStatementRows: + return "(*ValuesStatement).Rows" + case RefOfValuesStatementListArg: + return "(*ValuesStatement).ListArg" + case RefOfValuesStatementComments: + return "(*ValuesStatement).Comments" + case RefOfValuesStatementOrder: + return "(*ValuesStatement).Order" + case RefOfValuesStatementLimit: + return "(*ValuesStatement).Limit" + case RefOfVarPopArg: + return "(*VarPop).Arg" + case RefOfVarPopOverClause: + return "(*VarPop).OverClause" + case RefOfVarSampArg: + return "(*VarSamp).Arg" + case RefOfVarSampOverClause: + return "(*VarSamp).OverClause" + case RefOfVariableName: + return "(*Variable).Name" + case RefOfVarianceArg: + return "(*Variance).Arg" + case RefOfVarianceOverClause: + return "(*Variance).OverClause" + case VindexParamKey: + return "(VindexParam).Key" + case RefOfVindexSpecName: + return "(*VindexSpec).Name" + case RefOfVindexSpecType: + return "(*VindexSpec).Type" + case RefOfVindexSpecParamsOffset: + return "(*VindexSpec).ParamsOffset" + case RefOfWeightStringFuncExprExpr: + return "(*WeightStringFuncExpr).Expr" + case RefOfWeightStringFuncExprAs: + return "(*WeightStringFuncExpr).As" + case RefOfWhenCond: + return "(*When).Cond" + case RefOfWhenVal: + return "(*When).Val" + case RefOfWhereExpr: + return "(*Where).Expr" + case RefOfWindowDefinitionName: + return "(*WindowDefinition).Name" + case RefOfWindowDefinitionWindowSpec: + return "(*WindowDefinition).WindowSpec" + case WindowDefinitionsOffset: + return "(WindowDefinitions)[]Offset" + case RefOfWindowSpecificationName: + return "(*WindowSpecification).Name" + case RefOfWindowSpecificationPartitionClauseOffset: + return "(*WindowSpecification).PartitionClauseOffset" + case RefOfWindowSpecificationOrderClause: + return "(*WindowSpecification).OrderClause" + case RefOfWindowSpecificationFrameClause: + return "(*WindowSpecification).FrameClause" + case RefOfWithCTEsOffset: + return "(*With).CTEsOffset" + case RefOfXorExprLeft: + return "(*XorExpr).Left" + case RefOfXorExprRight: + return "(*XorExpr).Right" + case SliceOfRefOfColumnDefinitionOffset: + return "([]*ColumnDefinition)[]Offset" + case SliceOfAlterOptionOffset: + return "([]AlterOption)[]Offset" + case SliceOfIdentifierCIOffset: + return "([]IdentifierCI)[]Offset" + case SliceOfExprOffset: + return "([]Expr)[]Offset" + case SliceOfRefOfWhenOffset: + return "([]*When)[]Offset" + case RefOfColumnTypeOptionsDefault: + return "(*ColumnTypeOptions).Default" + case RefOfColumnTypeOptionsOnUpdate: + return "(*ColumnTypeOptions).OnUpdate" + case RefOfColumnTypeOptionsAs: + return "(*ColumnTypeOptions).As" + case RefOfColumnTypeOptionsComment: + return "(*ColumnTypeOptions).Comment" + case RefOfColumnTypeOptionsReference: + return "(*ColumnTypeOptions).Reference" + case RefOfColumnTypeOptionsEngineAttribute: + return "(*ColumnTypeOptions).EngineAttribute" + case RefOfColumnTypeOptionsSecondaryEngineAttribute: + return "(*ColumnTypeOptions).SecondaryEngineAttribute" + case RefOfColumnTypeOptionsSRID: + return "(*ColumnTypeOptions).SRID" + case SliceOfTableExprOffset: + return "([]TableExpr)[]Offset" + case SliceOfRefOfVariableOffset: + return "([]*Variable)[]Offset" + case SliceOfRefOfJSONObjectParamOffset: + return "([]*JSONObjectParam)[]Offset" + case SliceOfRefOfJtColumnDefinitionOffset: + return "([]*JtColumnDefinition)[]Offset" + case RefOfJtOrdinalColDefName: + return "(*JtOrdinalColDef).Name" + case RefOfJtPathColDefName: + return "(*JtPathColDef).Name" + case RefOfJtPathColDefType: + return "(*JtPathColDef).Type" + case RefOfJtPathColDefPath: + return "(*JtPathColDef).Path" + case RefOfJtPathColDefEmptyOnResponse: + return "(*JtPathColDef).EmptyOnResponse" + case RefOfJtPathColDefErrorOnResponse: + return "(*JtPathColDef).ErrorOnResponse" + case RefOfJtNestedPathColDefPath: + return "(*JtNestedPathColDef).Path" + case RefOfJtNestedPathColDefColumnsOffset: + return "(*JtNestedPathColDef).ColumnsOffset" + case SliceOfRefOfColNameOffset: + return "([]*ColName)[]Offset" + case SliceOfRefOfPartitionDefinitionOffset: + return "([]*PartitionDefinition)[]Offset" + case RefOfRootNodeSQLNode: + return "(*RootNode).SQLNode" + case SliceOfSelectExprOffset: + return "([]SelectExpr)[]Offset" + case RefOfTableNameName: + return "(*TableName).Name" + case RefOfTableNameQualifier: + return "(*TableName).Qualifier" + case RefOfTableOptionValue: + return "(*TableOption).Value" + case RefOfTableOptionTables: + return "(*TableOption).Tables" + case SliceOfRefOfIndexDefinitionOffset: + return "([]*IndexDefinition)[]Offset" + case SliceOfRefOfConstraintDefinitionOffset: + return "([]*ConstraintDefinition)[]Offset" + case RefOfVindexParamKey: + return "(*VindexParam).Key" + case SliceOfVindexParamOffset: + return "([]VindexParam)[]Offset" + case SliceOfRefOfCommonTableExprOffset: + return "([]*CommonTableExpr)[]Offset" + case RefOfIndexColumnColumn: + return "(*IndexColumn).Column" + case RefOfIndexColumnExpression: + return "(*IndexColumn).Expression" + case RefOfIndexOptionValue: + return "(*IndexOption).Value" + case RefOfTableAndLockTypeTable: + return "(*TableAndLockType).Table" + case RefOfRenameTablePairFromTable: + return "(*RenameTablePair).FromTable" + case RefOfRenameTablePairToTable: + return "(*RenameTablePair).ToTable" + } + panic("unknown ASTStep") +} +func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode { + for len(path) >= 2 { + step := path.nextPathStep() + path = path[2:] + switch step { + case RefOfAddColumnsColumnsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*AddColumns).Columns[idx] + case RefOfAddColumnsAfter: + node = node.(*AddColumns).After + case RefOfAddConstraintDefinitionConstraintDefinition: + node = node.(*AddConstraintDefinition).ConstraintDefinition + case RefOfAddIndexDefinitionIndexDefinition: + node = node.(*AddIndexDefinition).IndexDefinition + case RefOfAliasedExprExpr: + node = node.(*AliasedExpr).Expr + case RefOfAliasedExprAs: + node = node.(*AliasedExpr).As + case RefOfAliasedTableExprExpr: + node = node.(*AliasedTableExpr).Expr + case RefOfAliasedTableExprPartitions: + node = node.(*AliasedTableExpr).Partitions + case RefOfAliasedTableExprAs: + node = node.(*AliasedTableExpr).As + case RefOfAliasedTableExprHints: + node = node.(*AliasedTableExpr).Hints + case RefOfAliasedTableExprColumns: + node = node.(*AliasedTableExpr).Columns + case RefOfAlterCheckName: + node = node.(*AlterCheck).Name + case RefOfAlterColumnColumn: + node = node.(*AlterColumn).Column + case RefOfAlterColumnDefaultVal: + node = node.(*AlterColumn).DefaultVal + case RefOfAlterDatabaseComments: + node = node.(*AlterDatabase).Comments + case RefOfAlterDatabaseDBName: + node = node.(*AlterDatabase).DBName + case RefOfAlterIndexName: + node = node.(*AlterIndex).Name + case RefOfAlterMigrationRatio: + node = node.(*AlterMigration).Ratio + case RefOfAlterTableTable: + node = node.(*AlterTable).Table + case RefOfAlterTableAlterOptionsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*AlterTable).AlterOptions[idx] + case RefOfAlterTablePartitionSpec: + node = node.(*AlterTable).PartitionSpec + case RefOfAlterTablePartitionOption: + node = node.(*AlterTable).PartitionOption + case RefOfAlterTableComments: + node = node.(*AlterTable).Comments + case RefOfAlterViewViewName: + node = node.(*AlterView).ViewName + case RefOfAlterViewDefiner: + node = node.(*AlterView).Definer + case RefOfAlterViewColumns: + node = node.(*AlterView).Columns + case RefOfAlterViewSelect: + node = node.(*AlterView).Select + case RefOfAlterViewComments: + node = node.(*AlterView).Comments + case RefOfAlterVschemaTable: + node = node.(*AlterVschema).Table + case RefOfAlterVschemaVindexSpec: + node = node.(*AlterVschema).VindexSpec + case RefOfAlterVschemaVindexColsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*AlterVschema).VindexCols[idx] + case RefOfAlterVschemaAutoIncSpec: + node = node.(*AlterVschema).AutoIncSpec + case RefOfAnalyzeTable: + node = node.(*Analyze).Table + case RefOfAndExprLeft: + node = node.(*AndExpr).Left + case RefOfAndExprRight: + node = node.(*AndExpr).Right + case RefOfAnyValueArg: + node = node.(*AnyValue).Arg + case RefOfArgumentLessWindowExprOverClause: + node = node.(*ArgumentLessWindowExpr).OverClause + case RefOfAssignmentExprLeft: + node = node.(*AssignmentExpr).Left + case RefOfAssignmentExprRight: + node = node.(*AssignmentExpr).Right + case RefOfAutoIncSpecColumn: + node = node.(*AutoIncSpec).Column + case RefOfAutoIncSpecSequence: + node = node.(*AutoIncSpec).Sequence + case RefOfAvgArg: + node = node.(*Avg).Arg + case RefOfAvgOverClause: + node = node.(*Avg).OverClause + case RefOfBetweenExprLeft: + node = node.(*BetweenExpr).Left + case RefOfBetweenExprFrom: + node = node.(*BetweenExpr).From + case RefOfBetweenExprTo: + node = node.(*BetweenExpr).To + case RefOfBinaryExprLeft: + node = node.(*BinaryExpr).Left + case RefOfBinaryExprRight: + node = node.(*BinaryExpr).Right + case RefOfBitAndArg: + node = node.(*BitAnd).Arg + case RefOfBitAndOverClause: + node = node.(*BitAnd).OverClause + case RefOfBitOrArg: + node = node.(*BitOr).Arg + case RefOfBitOrOverClause: + node = node.(*BitOr).OverClause + case RefOfBitXorArg: + node = node.(*BitXor).Arg + case RefOfBitXorOverClause: + node = node.(*BitXor).OverClause + case RefOfCallProcName: + node = node.(*CallProc).Name + case RefOfCallProcParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*CallProc).Params[idx] + case RefOfCaseExprExpr: + node = node.(*CaseExpr).Expr + case RefOfCaseExprWhensOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*CaseExpr).Whens[idx] + case RefOfCaseExprElse: + node = node.(*CaseExpr).Else + case RefOfCastExprExpr: + node = node.(*CastExpr).Expr + case RefOfCastExprType: + node = node.(*CastExpr).Type + case RefOfChangeColumnOldColumn: + node = node.(*ChangeColumn).OldColumn + case RefOfChangeColumnNewColDefinition: + node = node.(*ChangeColumn).NewColDefinition + case RefOfChangeColumnAfter: + node = node.(*ChangeColumn).After + case RefOfCharExprExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*CharExpr).Exprs[idx] + case RefOfCheckConstraintDefinitionExpr: + node = node.(*CheckConstraintDefinition).Expr + case RefOfColNameName: + node = node.(*ColName).Name + case RefOfColNameQualifier: + node = node.(*ColName).Qualifier + case RefOfCollateExprExpr: + node = node.(*CollateExpr).Expr + case RefOfColumnDefinitionName: + node = node.(*ColumnDefinition).Name + case RefOfColumnDefinitionType: + node = node.(*ColumnDefinition).Type + case ColumnsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(Columns)[idx] + case RefOfCommonTableExprID: + node = node.(*CommonTableExpr).ID + case RefOfCommonTableExprColumns: + node = node.(*CommonTableExpr).Columns + case RefOfCommonTableExprSubquery: + node = node.(*CommonTableExpr).Subquery + case RefOfComparisonExprLeft: + node = node.(*ComparisonExpr).Left + case RefOfComparisonExprRight: + node = node.(*ComparisonExpr).Right + case RefOfComparisonExprEscape: + node = node.(*ComparisonExpr).Escape + case RefOfConstraintDefinitionName: + node = node.(*ConstraintDefinition).Name + case RefOfConstraintDefinitionDetails: + node = node.(*ConstraintDefinition).Details + case RefOfConvertExprExpr: + node = node.(*ConvertExpr).Expr + case RefOfConvertExprType: + node = node.(*ConvertExpr).Type + case RefOfConvertUsingExprExpr: + node = node.(*ConvertUsingExpr).Expr + case RefOfCountArgsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*Count).Args[idx] + case RefOfCountOverClause: + node = node.(*Count).OverClause + case RefOfCountStarOverClause: + node = node.(*CountStar).OverClause + case RefOfCreateDatabaseComments: + node = node.(*CreateDatabase).Comments + case RefOfCreateDatabaseDBName: + node = node.(*CreateDatabase).DBName + case RefOfCreateTableTable: + node = node.(*CreateTable).Table + case RefOfCreateTableTableSpec: + node = node.(*CreateTable).TableSpec + case RefOfCreateTableOptLike: + node = node.(*CreateTable).OptLike + case RefOfCreateTableComments: + node = node.(*CreateTable).Comments + case RefOfCreateViewViewName: + node = node.(*CreateView).ViewName + case RefOfCreateViewDefiner: + node = node.(*CreateView).Definer + case RefOfCreateViewColumns: + node = node.(*CreateView).Columns + case RefOfCreateViewSelect: + node = node.(*CreateView).Select + case RefOfCreateViewComments: + node = node.(*CreateView).Comments + case RefOfCurTimeFuncExprName: + node = node.(*CurTimeFuncExpr).Name + case RefOfDeallocateStmtComments: + node = node.(*DeallocateStmt).Comments + case RefOfDeallocateStmtName: + node = node.(*DeallocateStmt).Name + case RefOfDeleteWith: + node = node.(*Delete).With + case RefOfDeleteComments: + node = node.(*Delete).Comments + case RefOfDeleteTableExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*Delete).TableExprs[idx] + case RefOfDeleteTargets: + node = node.(*Delete).Targets + case RefOfDeletePartitions: + node = node.(*Delete).Partitions + case RefOfDeleteWhere: + node = node.(*Delete).Where + case RefOfDeleteOrderBy: + node = node.(*Delete).OrderBy + case RefOfDeleteLimit: + node = node.(*Delete).Limit + case RefOfDerivedTableSelect: + node = node.(*DerivedTable).Select + case RefOfDropColumnName: + node = node.(*DropColumn).Name + case RefOfDropDatabaseComments: + node = node.(*DropDatabase).Comments + case RefOfDropDatabaseDBName: + node = node.(*DropDatabase).DBName + case RefOfDropKeyName: + node = node.(*DropKey).Name + case RefOfDropTableFromTables: + node = node.(*DropTable).FromTables + case RefOfDropTableComments: + node = node.(*DropTable).Comments + case RefOfDropViewFromTables: + node = node.(*DropView).FromTables + case RefOfDropViewComments: + node = node.(*DropView).Comments + case RefOfExecuteStmtName: + node = node.(*ExecuteStmt).Name + case RefOfExecuteStmtComments: + node = node.(*ExecuteStmt).Comments + case RefOfExecuteStmtArgumentsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*ExecuteStmt).Arguments[idx] + case RefOfExistsExprSubquery: + node = node.(*ExistsExpr).Subquery + case RefOfExplainStmtStatement: + node = node.(*ExplainStmt).Statement + case RefOfExplainStmtComments: + node = node.(*ExplainStmt).Comments + case RefOfExplainTabTable: + node = node.(*ExplainTab).Table + case RefOfExprsExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*Exprs).Exprs[idx] + case RefOfExtractFuncExprExpr: + node = node.(*ExtractFuncExpr).Expr + case RefOfExtractValueExprFragment: + node = node.(*ExtractValueExpr).Fragment + case RefOfExtractValueExprXPathExpr: + node = node.(*ExtractValueExpr).XPathExpr + case RefOfFirstOrLastValueExprExpr: + node = node.(*FirstOrLastValueExpr).Expr + case RefOfFirstOrLastValueExprNullTreatmentClause: + node = node.(*FirstOrLastValueExpr).NullTreatmentClause + case RefOfFirstOrLastValueExprOverClause: + node = node.(*FirstOrLastValueExpr).OverClause + case RefOfFlushTableNames: + node = node.(*Flush).TableNames + case RefOfForeignKeyDefinitionSource: + node = node.(*ForeignKeyDefinition).Source + case RefOfForeignKeyDefinitionIndexName: + node = node.(*ForeignKeyDefinition).IndexName + case RefOfForeignKeyDefinitionReferenceDefinition: + node = node.(*ForeignKeyDefinition).ReferenceDefinition + case RefOfFrameClauseStart: + node = node.(*FrameClause).Start + case RefOfFrameClauseEnd: + node = node.(*FrameClause).End + case RefOfFramePointExpr: + node = node.(*FramePoint).Expr + case RefOfFuncExprQualifier: + node = node.(*FuncExpr).Qualifier + case RefOfFuncExprName: + node = node.(*FuncExpr).Name + case RefOfFuncExprExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*FuncExpr).Exprs[idx] + case RefOfGTIDFuncExprSet1: + node = node.(*GTIDFuncExpr).Set1 + case RefOfGTIDFuncExprSet2: + node = node.(*GTIDFuncExpr).Set2 + case RefOfGTIDFuncExprTimeout: + node = node.(*GTIDFuncExpr).Timeout + case RefOfGTIDFuncExprChannel: + node = node.(*GTIDFuncExpr).Channel + case RefOfGeoHashFromLatLongExprLatitude: + node = node.(*GeoHashFromLatLongExpr).Latitude + case RefOfGeoHashFromLatLongExprLongitude: + node = node.(*GeoHashFromLatLongExpr).Longitude + case RefOfGeoHashFromLatLongExprMaxLength: + node = node.(*GeoHashFromLatLongExpr).MaxLength + case RefOfGeoHashFromPointExprPoint: + node = node.(*GeoHashFromPointExpr).Point + case RefOfGeoHashFromPointExprMaxLength: + node = node.(*GeoHashFromPointExpr).MaxLength + case RefOfGeoJSONFromGeomExprGeom: + node = node.(*GeoJSONFromGeomExpr).Geom + case RefOfGeoJSONFromGeomExprMaxDecimalDigits: + node = node.(*GeoJSONFromGeomExpr).MaxDecimalDigits + case RefOfGeoJSONFromGeomExprBitmask: + node = node.(*GeoJSONFromGeomExpr).Bitmask + case RefOfGeomCollPropertyFuncExprGeomColl: + node = node.(*GeomCollPropertyFuncExpr).GeomColl + case RefOfGeomCollPropertyFuncExprPropertyDefArg: + node = node.(*GeomCollPropertyFuncExpr).PropertyDefArg + case RefOfGeomFormatExprGeom: + node = node.(*GeomFormatExpr).Geom + case RefOfGeomFormatExprAxisOrderOpt: + node = node.(*GeomFormatExpr).AxisOrderOpt + case RefOfGeomFromGeoHashExprGeoHash: + node = node.(*GeomFromGeoHashExpr).GeoHash + case RefOfGeomFromGeoHashExprSridOpt: + node = node.(*GeomFromGeoHashExpr).SridOpt + case RefOfGeomFromGeoJSONExprGeoJSON: + node = node.(*GeomFromGeoJSONExpr).GeoJSON + case RefOfGeomFromGeoJSONExprHigherDimHandlerOpt: + node = node.(*GeomFromGeoJSONExpr).HigherDimHandlerOpt + case RefOfGeomFromGeoJSONExprSrid: + node = node.(*GeomFromGeoJSONExpr).Srid + case RefOfGeomFromTextExprWktText: + node = node.(*GeomFromTextExpr).WktText + case RefOfGeomFromTextExprSrid: + node = node.(*GeomFromTextExpr).Srid + case RefOfGeomFromTextExprAxisOrderOpt: + node = node.(*GeomFromTextExpr).AxisOrderOpt + case RefOfGeomFromWKBExprWkbBlob: + node = node.(*GeomFromWKBExpr).WkbBlob + case RefOfGeomFromWKBExprSrid: + node = node.(*GeomFromWKBExpr).Srid + case RefOfGeomFromWKBExprAxisOrderOpt: + node = node.(*GeomFromWKBExpr).AxisOrderOpt + case RefOfGeomPropertyFuncExprGeom: + node = node.(*GeomPropertyFuncExpr).Geom + case RefOfGroupByExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*GroupBy).Exprs[idx] + case RefOfGroupConcatExprExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*GroupConcatExpr).Exprs[idx] + case RefOfGroupConcatExprOrderBy: + node = node.(*GroupConcatExpr).OrderBy + case RefOfGroupConcatExprLimit: + node = node.(*GroupConcatExpr).Limit + case RefOfIndexDefinitionInfo: + node = node.(*IndexDefinition).Info + case RefOfIndexHintIndexesOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*IndexHint).Indexes[idx] + case IndexHintsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(IndexHints)[idx] + case RefOfIndexInfoName: + node = node.(*IndexInfo).Name + case RefOfIndexInfoConstraintName: + node = node.(*IndexInfo).ConstraintName + case RefOfInsertComments: + node = node.(*Insert).Comments + case RefOfInsertTable: + node = node.(*Insert).Table + case RefOfInsertPartitions: + node = node.(*Insert).Partitions + case RefOfInsertColumns: + node = node.(*Insert).Columns + case RefOfInsertRows: + node = node.(*Insert).Rows + case RefOfInsertRowAlias: + node = node.(*Insert).RowAlias + case RefOfInsertOnDup: + node = node.(*Insert).OnDup + case RefOfInsertExprStr: + node = node.(*InsertExpr).Str + case RefOfInsertExprPos: + node = node.(*InsertExpr).Pos + case RefOfInsertExprLen: + node = node.(*InsertExpr).Len + case RefOfInsertExprNewStr: + node = node.(*InsertExpr).NewStr + case RefOfIntervalDateExprDate: + node = node.(*IntervalDateExpr).Date + case RefOfIntervalDateExprInterval: + node = node.(*IntervalDateExpr).Interval + case RefOfIntervalFuncExprExpr: + node = node.(*IntervalFuncExpr).Expr + case RefOfIntervalFuncExprExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*IntervalFuncExpr).Exprs[idx] + case RefOfIntroducerExprExpr: + node = node.(*IntroducerExpr).Expr + case RefOfIsExprLeft: + node = node.(*IsExpr).Left + case RefOfJSONArrayAggExpr: + node = node.(*JSONArrayAgg).Expr + case RefOfJSONArrayAggOverClause: + node = node.(*JSONArrayAgg).OverClause + case RefOfJSONArrayExprParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONArrayExpr).Params[idx] + case RefOfJSONAttributesExprJSONDoc: + node = node.(*JSONAttributesExpr).JSONDoc + case RefOfJSONAttributesExprPath: + node = node.(*JSONAttributesExpr).Path + case RefOfJSONContainsExprTarget: + node = node.(*JSONContainsExpr).Target + case RefOfJSONContainsExprCandidate: + node = node.(*JSONContainsExpr).Candidate + case RefOfJSONContainsExprPathListOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONContainsExpr).PathList[idx] + case RefOfJSONContainsPathExprJSONDoc: + node = node.(*JSONContainsPathExpr).JSONDoc + case RefOfJSONContainsPathExprOneOrAll: + node = node.(*JSONContainsPathExpr).OneOrAll + case RefOfJSONContainsPathExprPathListOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONContainsPathExpr).PathList[idx] + case RefOfJSONExtractExprJSONDoc: + node = node.(*JSONExtractExpr).JSONDoc + case RefOfJSONExtractExprPathListOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONExtractExpr).PathList[idx] + case RefOfJSONKeysExprJSONDoc: + node = node.(*JSONKeysExpr).JSONDoc + case RefOfJSONKeysExprPath: + node = node.(*JSONKeysExpr).Path + case RefOfJSONObjectAggKey: + node = node.(*JSONObjectAgg).Key + case RefOfJSONObjectAggValue: + node = node.(*JSONObjectAgg).Value + case RefOfJSONObjectAggOverClause: + node = node.(*JSONObjectAgg).OverClause + case RefOfJSONObjectExprParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONObjectExpr).Params[idx] + case RefOfJSONObjectParamKey: + node = node.(*JSONObjectParam).Key + case RefOfJSONObjectParamValue: + node = node.(*JSONObjectParam).Value + case RefOfJSONOverlapsExprJSONDoc1: + node = node.(*JSONOverlapsExpr).JSONDoc1 + case RefOfJSONOverlapsExprJSONDoc2: + node = node.(*JSONOverlapsExpr).JSONDoc2 + case RefOfJSONPrettyExprJSONVal: + node = node.(*JSONPrettyExpr).JSONVal + case RefOfJSONQuoteExprStringArg: + node = node.(*JSONQuoteExpr).StringArg + case RefOfJSONRemoveExprJSONDoc: + node = node.(*JSONRemoveExpr).JSONDoc + case RefOfJSONRemoveExprPathListOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONRemoveExpr).PathList[idx] + case RefOfJSONSchemaValidFuncExprSchema: + node = node.(*JSONSchemaValidFuncExpr).Schema + case RefOfJSONSchemaValidFuncExprDocument: + node = node.(*JSONSchemaValidFuncExpr).Document + case RefOfJSONSchemaValidationReportFuncExprSchema: + node = node.(*JSONSchemaValidationReportFuncExpr).Schema + case RefOfJSONSchemaValidationReportFuncExprDocument: + node = node.(*JSONSchemaValidationReportFuncExpr).Document + case RefOfJSONSearchExprJSONDoc: + node = node.(*JSONSearchExpr).JSONDoc + case RefOfJSONSearchExprOneOrAll: + node = node.(*JSONSearchExpr).OneOrAll + case RefOfJSONSearchExprSearchStr: + node = node.(*JSONSearchExpr).SearchStr + case RefOfJSONSearchExprEscapeChar: + node = node.(*JSONSearchExpr).EscapeChar + case RefOfJSONSearchExprPathListOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONSearchExpr).PathList[idx] + case RefOfJSONStorageFreeExprJSONVal: + node = node.(*JSONStorageFreeExpr).JSONVal + case RefOfJSONStorageSizeExprJSONVal: + node = node.(*JSONStorageSizeExpr).JSONVal + case RefOfJSONTableExprExpr: + node = node.(*JSONTableExpr).Expr + case RefOfJSONTableExprAlias: + node = node.(*JSONTableExpr).Alias + case RefOfJSONTableExprFilter: + node = node.(*JSONTableExpr).Filter + case RefOfJSONTableExprColumnsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONTableExpr).Columns[idx] + case RefOfJSONUnquoteExprJSONValue: + node = node.(*JSONUnquoteExpr).JSONValue + case RefOfJSONValueExprJSONDoc: + node = node.(*JSONValueExpr).JSONDoc + case RefOfJSONValueExprPath: + node = node.(*JSONValueExpr).Path + case RefOfJSONValueExprReturningType: + node = node.(*JSONValueExpr).ReturningType + case RefOfJSONValueExprEmptyOnResponse: + node = node.(*JSONValueExpr).EmptyOnResponse + case RefOfJSONValueExprErrorOnResponse: + node = node.(*JSONValueExpr).ErrorOnResponse + case RefOfJSONValueMergeExprJSONDoc: + node = node.(*JSONValueMergeExpr).JSONDoc + case RefOfJSONValueMergeExprJSONDocListOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONValueMergeExpr).JSONDocList[idx] + case RefOfJSONValueModifierExprJSONDoc: + node = node.(*JSONValueModifierExpr).JSONDoc + case RefOfJSONValueModifierExprParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*JSONValueModifierExpr).Params[idx] + case RefOfJoinConditionOn: + node = node.(*JoinCondition).On + case RefOfJoinConditionUsing: + node = node.(*JoinCondition).Using + case RefOfJoinTableExprLeftExpr: + node = node.(*JoinTableExpr).LeftExpr + case RefOfJoinTableExprRightExpr: + node = node.(*JoinTableExpr).RightExpr + case RefOfJoinTableExprCondition: + node = node.(*JoinTableExpr).Condition + case RefOfJtOnResponseExpr: + node = node.(*JtOnResponse).Expr + case RefOfLagLeadExprExpr: + node = node.(*LagLeadExpr).Expr + case RefOfLagLeadExprN: + node = node.(*LagLeadExpr).N + case RefOfLagLeadExprDefault: + node = node.(*LagLeadExpr).Default + case RefOfLagLeadExprOverClause: + node = node.(*LagLeadExpr).OverClause + case RefOfLagLeadExprNullTreatmentClause: + node = node.(*LagLeadExpr).NullTreatmentClause + case RefOfLimitOffset: + node = node.(*Limit).Offset + case RefOfLimitRowcount: + node = node.(*Limit).Rowcount + case RefOfLineStringExprPointParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*LineStringExpr).PointParams[idx] + case RefOfLinestrPropertyFuncExprLinestring: + node = node.(*LinestrPropertyFuncExpr).Linestring + case RefOfLinestrPropertyFuncExprPropertyDefArg: + node = node.(*LinestrPropertyFuncExpr).PropertyDefArg + case RefOfLocateExprSubStr: + node = node.(*LocateExpr).SubStr + case RefOfLocateExprStr: + node = node.(*LocateExpr).Str + case RefOfLocateExprPos: + node = node.(*LocateExpr).Pos + case RefOfLockingFuncName: + node = node.(*LockingFunc).Name + case RefOfLockingFuncTimeout: + node = node.(*LockingFunc).Timeout + case RefOfMatchExprColumnsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*MatchExpr).Columns[idx] + case RefOfMatchExprExpr: + node = node.(*MatchExpr).Expr + case RefOfMaxArg: + node = node.(*Max).Arg + case RefOfMaxOverClause: + node = node.(*Max).OverClause + case RefOfMemberOfExprValue: + node = node.(*MemberOfExpr).Value + case RefOfMemberOfExprJSONArr: + node = node.(*MemberOfExpr).JSONArr + case RefOfMinArg: + node = node.(*Min).Arg + case RefOfMinOverClause: + node = node.(*Min).OverClause + case RefOfModifyColumnNewColDefinition: + node = node.(*ModifyColumn).NewColDefinition + case RefOfModifyColumnAfter: + node = node.(*ModifyColumn).After + case RefOfMultiLinestringExprLinestringParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*MultiLinestringExpr).LinestringParams[idx] + case RefOfMultiPointExprPointParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*MultiPointExpr).PointParams[idx] + case RefOfMultiPolygonExprPolygonParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*MultiPolygonExpr).PolygonParams[idx] + case RefOfNTHValueExprExpr: + node = node.(*NTHValueExpr).Expr + case RefOfNTHValueExprN: + node = node.(*NTHValueExpr).N + case RefOfNTHValueExprOverClause: + node = node.(*NTHValueExpr).OverClause + case RefOfNTHValueExprFromFirstLastClause: + node = node.(*NTHValueExpr).FromFirstLastClause + case RefOfNTHValueExprNullTreatmentClause: + node = node.(*NTHValueExpr).NullTreatmentClause + case RefOfNamedWindowWindows: + node = node.(*NamedWindow).Windows + case NamedWindowsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(NamedWindows)[idx] + case RefOfNextvalExpr: + node = node.(*Nextval).Expr + case RefOfNotExprExpr: + node = node.(*NotExpr).Expr + case RefOfNtileExprN: + node = node.(*NtileExpr).N + case RefOfNtileExprOverClause: + node = node.(*NtileExpr).OverClause + case RefOfOffsetOriginal: + node = node.(*Offset).Original + case OnDupOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(OnDup)[idx] + case RefOfOptLikeLikeTable: + node = node.(*OptLike).LikeTable + case RefOfOrExprLeft: + node = node.(*OrExpr).Left + case RefOfOrExprRight: + node = node.(*OrExpr).Right + case RefOfOrderExpr: + node = node.(*Order).Expr + case OrderByOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(OrderBy)[idx] + case RefOfOrderByOptionCols: + node = node.(*OrderByOption).Cols + case RefOfOverClauseWindowName: + node = node.(*OverClause).WindowName + case RefOfOverClauseWindowSpec: + node = node.(*OverClause).WindowSpec + case RefOfParenTableExprExprs: + node = node.(*ParenTableExpr).Exprs + case RefOfPartitionDefinitionName: + node = node.(*PartitionDefinition).Name + case RefOfPartitionDefinitionOptions: + node = node.(*PartitionDefinition).Options + case RefOfPartitionDefinitionOptionsValueRange: + node = node.(*PartitionDefinitionOptions).ValueRange + case RefOfPartitionDefinitionOptionsComment: + node = node.(*PartitionDefinitionOptions).Comment + case RefOfPartitionDefinitionOptionsEngine: + node = node.(*PartitionDefinitionOptions).Engine + case RefOfPartitionDefinitionOptionsDataDirectory: + node = node.(*PartitionDefinitionOptions).DataDirectory + case RefOfPartitionDefinitionOptionsIndexDirectory: + node = node.(*PartitionDefinitionOptions).IndexDirectory + case RefOfPartitionDefinitionOptionsSubPartitionDefinitions: + node = node.(*PartitionDefinitionOptions).SubPartitionDefinitions + case RefOfPartitionOptionColList: + node = node.(*PartitionOption).ColList + case RefOfPartitionOptionExpr: + node = node.(*PartitionOption).Expr + case RefOfPartitionOptionSubPartition: + node = node.(*PartitionOption).SubPartition + case RefOfPartitionOptionDefinitionsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*PartitionOption).Definitions[idx] + case RefOfPartitionSpecNames: + node = node.(*PartitionSpec).Names + case RefOfPartitionSpecNumber: + node = node.(*PartitionSpec).Number + case RefOfPartitionSpecTableName: + node = node.(*PartitionSpec).TableName + case RefOfPartitionSpecDefinitionsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*PartitionSpec).Definitions[idx] + case RefOfPartitionValueRangeRange: + node = node.(*PartitionValueRange).Range + case PartitionsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(Partitions)[idx] + case RefOfPerformanceSchemaFuncExprArgument: + node = node.(*PerformanceSchemaFuncExpr).Argument + case RefOfPointExprXCordinate: + node = node.(*PointExpr).XCordinate + case RefOfPointExprYCordinate: + node = node.(*PointExpr).YCordinate + case RefOfPointPropertyFuncExprPoint: + node = node.(*PointPropertyFuncExpr).Point + case RefOfPointPropertyFuncExprValueToSet: + node = node.(*PointPropertyFuncExpr).ValueToSet + case RefOfPolygonExprLinestringParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*PolygonExpr).LinestringParams[idx] + case RefOfPolygonPropertyFuncExprPolygon: + node = node.(*PolygonPropertyFuncExpr).Polygon + case RefOfPolygonPropertyFuncExprPropertyDefArg: + node = node.(*PolygonPropertyFuncExpr).PropertyDefArg + case RefOfPrepareStmtName: + node = node.(*PrepareStmt).Name + case RefOfPrepareStmtStatement: + node = node.(*PrepareStmt).Statement + case RefOfPrepareStmtComments: + node = node.(*PrepareStmt).Comments + case RefOfReferenceDefinitionReferencedTable: + node = node.(*ReferenceDefinition).ReferencedTable + case RefOfReferenceDefinitionReferencedColumns: + node = node.(*ReferenceDefinition).ReferencedColumns + case RefOfReferenceDefinitionMatch: + node = node.(*ReferenceDefinition).Match + case RefOfReferenceDefinitionOnDelete: + node = node.(*ReferenceDefinition).OnDelete + case RefOfReferenceDefinitionOnUpdate: + node = node.(*ReferenceDefinition).OnUpdate + case RefOfRegexpInstrExprExpr: + node = node.(*RegexpInstrExpr).Expr + case RefOfRegexpInstrExprPattern: + node = node.(*RegexpInstrExpr).Pattern + case RefOfRegexpInstrExprPosition: + node = node.(*RegexpInstrExpr).Position + case RefOfRegexpInstrExprOccurrence: + node = node.(*RegexpInstrExpr).Occurrence + case RefOfRegexpInstrExprReturnOption: + node = node.(*RegexpInstrExpr).ReturnOption + case RefOfRegexpInstrExprMatchType: + node = node.(*RegexpInstrExpr).MatchType + case RefOfRegexpLikeExprExpr: + node = node.(*RegexpLikeExpr).Expr + case RefOfRegexpLikeExprPattern: + node = node.(*RegexpLikeExpr).Pattern + case RefOfRegexpLikeExprMatchType: + node = node.(*RegexpLikeExpr).MatchType + case RefOfRegexpReplaceExprExpr: + node = node.(*RegexpReplaceExpr).Expr + case RefOfRegexpReplaceExprPattern: + node = node.(*RegexpReplaceExpr).Pattern + case RefOfRegexpReplaceExprRepl: + node = node.(*RegexpReplaceExpr).Repl + case RefOfRegexpReplaceExprOccurrence: + node = node.(*RegexpReplaceExpr).Occurrence + case RefOfRegexpReplaceExprPosition: + node = node.(*RegexpReplaceExpr).Position + case RefOfRegexpReplaceExprMatchType: + node = node.(*RegexpReplaceExpr).MatchType + case RefOfRegexpSubstrExprExpr: + node = node.(*RegexpSubstrExpr).Expr + case RefOfRegexpSubstrExprPattern: + node = node.(*RegexpSubstrExpr).Pattern + case RefOfRegexpSubstrExprOccurrence: + node = node.(*RegexpSubstrExpr).Occurrence + case RefOfRegexpSubstrExprPosition: + node = node.(*RegexpSubstrExpr).Position + case RefOfRegexpSubstrExprMatchType: + node = node.(*RegexpSubstrExpr).MatchType + case RefOfReleaseName: + node = node.(*Release).Name + case RefOfRenameColumnOldName: + node = node.(*RenameColumn).OldName + case RefOfRenameColumnNewName: + node = node.(*RenameColumn).NewName + case RefOfRenameIndexOldName: + node = node.(*RenameIndex).OldName + case RefOfRenameIndexNewName: + node = node.(*RenameIndex).NewName + case RefOfRenameTableNameTable: + node = node.(*RenameTableName).Table + case RefOfRevertMigrationComments: + node = node.(*RevertMigration).Comments + case RootNodeSQLNode: + node = node.(RootNode).SQLNode + case RefOfRowAliasTableName: + node = node.(*RowAlias).TableName + case RefOfRowAliasColumns: + node = node.(*RowAlias).Columns + case RefOfSRollbackName: + node = node.(*SRollback).Name + case RefOfSavepointName: + node = node.(*Savepoint).Name + case RefOfSelectWith: + node = node.(*Select).With + case RefOfSelectFromOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*Select).From[idx] + case RefOfSelectComments: + node = node.(*Select).Comments + case RefOfSelectSelectExprs: + node = node.(*Select).SelectExprs + case RefOfSelectWhere: + node = node.(*Select).Where + case RefOfSelectGroupBy: + node = node.(*Select).GroupBy + case RefOfSelectHaving: + node = node.(*Select).Having + case RefOfSelectWindows: + node = node.(*Select).Windows + case RefOfSelectOrderBy: + node = node.(*Select).OrderBy + case RefOfSelectLimit: + node = node.(*Select).Limit + case RefOfSelectInto: + node = node.(*Select).Into + case RefOfSelectExprsExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*SelectExprs).Exprs[idx] + case RefOfSetComments: + node = node.(*Set).Comments + case RefOfSetExprs: + node = node.(*Set).Exprs + case RefOfSetExprVar: + node = node.(*SetExpr).Var + case RefOfSetExprExpr: + node = node.(*SetExpr).Expr + case SetExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(SetExprs)[idx] + case RefOfShowInternal: + node = node.(*Show).Internal + case RefOfShowBasicTbl: + node = node.(*ShowBasic).Tbl + case RefOfShowBasicDbName: + node = node.(*ShowBasic).DbName + case RefOfShowBasicFilter: + node = node.(*ShowBasic).Filter + case RefOfShowCreateOp: + node = node.(*ShowCreate).Op + case RefOfShowFilterFilter: + node = node.(*ShowFilter).Filter + case RefOfShowMigrationLogsComments: + node = node.(*ShowMigrationLogs).Comments + case RefOfStarExprTableName: + node = node.(*StarExpr).TableName + case RefOfStdArg: + node = node.(*Std).Arg + case RefOfStdOverClause: + node = node.(*Std).OverClause + case RefOfStdDevArg: + node = node.(*StdDev).Arg + case RefOfStdDevOverClause: + node = node.(*StdDev).OverClause + case RefOfStdPopArg: + node = node.(*StdPop).Arg + case RefOfStdPopOverClause: + node = node.(*StdPop).OverClause + case RefOfStdSampArg: + node = node.(*StdSamp).Arg + case RefOfStdSampOverClause: + node = node.(*StdSamp).OverClause + case RefOfStreamComments: + node = node.(*Stream).Comments + case RefOfStreamSelectExpr: + node = node.(*Stream).SelectExpr + case RefOfStreamTable: + node = node.(*Stream).Table + case RefOfSubPartitionColList: + node = node.(*SubPartition).ColList + case RefOfSubPartitionExpr: + node = node.(*SubPartition).Expr + case RefOfSubPartitionDefinitionName: + node = node.(*SubPartitionDefinition).Name + case RefOfSubPartitionDefinitionOptions: + node = node.(*SubPartitionDefinition).Options + case RefOfSubPartitionDefinitionOptionsComment: + node = node.(*SubPartitionDefinitionOptions).Comment + case RefOfSubPartitionDefinitionOptionsEngine: + node = node.(*SubPartitionDefinitionOptions).Engine + case RefOfSubPartitionDefinitionOptionsDataDirectory: + node = node.(*SubPartitionDefinitionOptions).DataDirectory + case RefOfSubPartitionDefinitionOptionsIndexDirectory: + node = node.(*SubPartitionDefinitionOptions).IndexDirectory + case SubPartitionDefinitionsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(SubPartitionDefinitions)[idx] + case RefOfSubquerySelect: + node = node.(*Subquery).Select + case RefOfSubstrExprName: + node = node.(*SubstrExpr).Name + case RefOfSubstrExprFrom: + node = node.(*SubstrExpr).From + case RefOfSubstrExprTo: + node = node.(*SubstrExpr).To + case RefOfSumArg: + node = node.(*Sum).Arg + case RefOfSumOverClause: + node = node.(*Sum).OverClause + case TableExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(TableExprs)[idx] + case TableNameName: + node = node.(TableName).Name + case TableNameQualifier: + node = node.(TableName).Qualifier + case TableNamesOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(TableNames)[idx] + case RefOfTableSpecColumnsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*TableSpec).Columns[idx] + case RefOfTableSpecIndexesOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*TableSpec).Indexes[idx] + case RefOfTableSpecConstraintsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*TableSpec).Constraints[idx] + case RefOfTableSpecOptions: + node = node.(*TableSpec).Options + case RefOfTableSpecPartitionOption: + node = node.(*TableSpec).PartitionOption + case RefOfTimestampDiffExprExpr1: + node = node.(*TimestampDiffExpr).Expr1 + case RefOfTimestampDiffExprExpr2: + node = node.(*TimestampDiffExpr).Expr2 + case RefOfTrimFuncExprTrimArg: + node = node.(*TrimFuncExpr).TrimArg + case RefOfTrimFuncExprStringArg: + node = node.(*TrimFuncExpr).StringArg + case RefOfTruncateTableTable: + node = node.(*TruncateTable).Table + case RefOfUnaryExprExpr: + node = node.(*UnaryExpr).Expr + case RefOfUnionWith: + node = node.(*Union).With + case RefOfUnionLeft: + node = node.(*Union).Left + case RefOfUnionRight: + node = node.(*Union).Right + case RefOfUnionOrderBy: + node = node.(*Union).OrderBy + case RefOfUnionLimit: + node = node.(*Union).Limit + case RefOfUnionInto: + node = node.(*Union).Into + case RefOfUpdateWith: + node = node.(*Update).With + case RefOfUpdateComments: + node = node.(*Update).Comments + case RefOfUpdateTableExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*Update).TableExprs[idx] + case RefOfUpdateExprs: + node = node.(*Update).Exprs + case RefOfUpdateWhere: + node = node.(*Update).Where + case RefOfUpdateOrderBy: + node = node.(*Update).OrderBy + case RefOfUpdateLimit: + node = node.(*Update).Limit + case RefOfUpdateExprName: + node = node.(*UpdateExpr).Name + case RefOfUpdateExprExpr: + node = node.(*UpdateExpr).Expr + case UpdateExprsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(UpdateExprs)[idx] + case RefOfUpdateXMLExprTarget: + node = node.(*UpdateXMLExpr).Target + case RefOfUpdateXMLExprXPathExpr: + node = node.(*UpdateXMLExpr).XPathExpr + case RefOfUpdateXMLExprNewXML: + node = node.(*UpdateXMLExpr).NewXML + case RefOfUseDBName: + node = node.(*Use).DBName + case RefOfVExplainStmtStatement: + node = node.(*VExplainStmt).Statement + case RefOfVExplainStmtComments: + node = node.(*VExplainStmt).Comments + case RefOfVStreamComments: + node = node.(*VStream).Comments + case RefOfVStreamSelectExpr: + node = node.(*VStream).SelectExpr + case RefOfVStreamTable: + node = node.(*VStream).Table + case RefOfVStreamWhere: + node = node.(*VStream).Where + case RefOfVStreamLimit: + node = node.(*VStream).Limit + case ValTupleOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(ValTuple)[idx] + case ValuesOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(Values)[idx] + case RefOfValuesFuncExprName: + node = node.(*ValuesFuncExpr).Name + case RefOfValuesStatementWith: + node = node.(*ValuesStatement).With + case RefOfValuesStatementRows: + node = node.(*ValuesStatement).Rows + case RefOfValuesStatementListArg: + node = node.(*ValuesStatement).ListArg + case RefOfValuesStatementComments: + node = node.(*ValuesStatement).Comments + case RefOfValuesStatementOrder: + node = node.(*ValuesStatement).Order + case RefOfValuesStatementLimit: + node = node.(*ValuesStatement).Limit + case RefOfVarPopArg: + node = node.(*VarPop).Arg + case RefOfVarPopOverClause: + node = node.(*VarPop).OverClause + case RefOfVarSampArg: + node = node.(*VarSamp).Arg + case RefOfVarSampOverClause: + node = node.(*VarSamp).OverClause + case RefOfVariableName: + node = node.(*Variable).Name + case RefOfVarianceArg: + node = node.(*Variance).Arg + case RefOfVarianceOverClause: + node = node.(*Variance).OverClause + case VindexParamKey: + node = node.(VindexParam).Key + case RefOfVindexSpecName: + node = node.(*VindexSpec).Name + case RefOfVindexSpecType: + node = node.(*VindexSpec).Type + case RefOfVindexSpecParamsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*VindexSpec).Params[idx] + case RefOfWeightStringFuncExprExpr: + node = node.(*WeightStringFuncExpr).Expr + case RefOfWeightStringFuncExprAs: + node = node.(*WeightStringFuncExpr).As + case RefOfWhenCond: + node = node.(*When).Cond + case RefOfWhenVal: + node = node.(*When).Val + case RefOfWhereExpr: + node = node.(*Where).Expr + case RefOfWindowDefinitionName: + node = node.(*WindowDefinition).Name + case RefOfWindowDefinitionWindowSpec: + node = node.(*WindowDefinition).WindowSpec + case WindowDefinitionsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(WindowDefinitions)[idx] + case RefOfWindowSpecificationName: + node = node.(*WindowSpecification).Name + case RefOfWindowSpecificationPartitionClauseOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*WindowSpecification).PartitionClause[idx] + case RefOfWindowSpecificationOrderClause: + node = node.(*WindowSpecification).OrderClause + case RefOfWindowSpecificationFrameClause: + node = node.(*WindowSpecification).FrameClause + case RefOfWithCTEsOffset: + idx, bytesRead := path.nextPathOffset() + path = path[bytesRead:] + node = node.(*With).CTEs[idx] + case RefOfXorExprLeft: + node = node.(*XorExpr).Left + case RefOfXorExprRight: + node = node.(*XorExpr).Right + case RefOfRootNodeSQLNode: + node = node.(*RootNode).SQLNode + case RefOfTableNameName: + node = node.(*TableName).Name + case RefOfTableNameQualifier: + node = node.(*TableName).Qualifier + case RefOfVindexParamKey: + node = node.(*VindexParam).Key + default: + return nil + } + } + return node +} diff --git a/go/vt/sqlparser/ast_rewrite.go b/go/vt/sqlparser/ast_rewrite.go index a4cfeb4f01c..33e5b0cda42 100644 --- a/go/vt/sqlparser/ast_rewrite.go +++ b/go/vt/sqlparser/ast_rewrite.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ limitations under the License. package sqlparser +// Function Generation Source: InterfaceMethod func (a *application) rewriteSQLNode(parent SQLNode, node SQLNode, replacer replacerFunc) bool { if node == nil { return true @@ -569,6 +570,8 @@ func (a *application) rewriteSQLNode(parent SQLNode, node SQLNode, replacer repl return true } } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAddColumns(parent SQLNode, node *AddColumns, replacer replacerFunc) bool { if node == nil { return true @@ -587,6 +590,13 @@ func (a *application) rewriteRefOfAddColumns(parent SQLNode, node *AddColumns, r } } for x, el := range node.Columns { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfAddColumnsColumnsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfColumnDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*AddColumns).Columns[idx] = newNode.(*ColumnDefinition) @@ -595,11 +605,18 @@ func (a *application) rewriteRefOfAddColumns(parent SQLNode, node *AddColumns, r return false } } + if a.collectPaths && len(node.Columns) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAddColumnsAfter)) + } if !a.rewriteRefOfColName(node, node.After, func(newNode, parent SQLNode) { parent.(*AddColumns).After = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -610,6 +627,8 @@ func (a *application) rewriteRefOfAddColumns(parent SQLNode, node *AddColumns, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAddConstraintDefinition(parent SQLNode, node *AddConstraintDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -627,11 +646,17 @@ func (a *application) rewriteRefOfAddConstraintDefinition(parent SQLNode, node * return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAddConstraintDefinitionConstraintDefinition)) + } if !a.rewriteRefOfConstraintDefinition(node, node.ConstraintDefinition, func(newNode, parent SQLNode) { parent.(*AddConstraintDefinition).ConstraintDefinition = newNode.(*ConstraintDefinition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -642,6 +667,8 @@ func (a *application) rewriteRefOfAddConstraintDefinition(parent SQLNode, node * } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAddIndexDefinition(parent SQLNode, node *AddIndexDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -659,11 +686,17 @@ func (a *application) rewriteRefOfAddIndexDefinition(parent SQLNode, node *AddIn return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAddIndexDefinitionIndexDefinition)) + } if !a.rewriteRefOfIndexDefinition(node, node.IndexDefinition, func(newNode, parent SQLNode) { parent.(*AddIndexDefinition).IndexDefinition = newNode.(*IndexDefinition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -674,6 +707,8 @@ func (a *application) rewriteRefOfAddIndexDefinition(parent SQLNode, node *AddIn } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAliasedExpr(parent SQLNode, node *AliasedExpr, replacer replacerFunc) bool { if node == nil { return true @@ -691,16 +726,26 @@ func (a *application) rewriteRefOfAliasedExpr(parent SQLNode, node *AliasedExpr, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAliasedExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*AliasedExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAliasedExprAs)) + } if !a.rewriteIdentifierCI(node, node.As, func(newNode, parent SQLNode) { parent.(*AliasedExpr).As = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -711,6 +756,8 @@ func (a *application) rewriteRefOfAliasedExpr(parent SQLNode, node *AliasedExpr, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAliasedTableExpr(parent SQLNode, node *AliasedTableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -728,31 +775,53 @@ func (a *application) rewriteRefOfAliasedTableExpr(parent SQLNode, node *Aliased return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAliasedTableExprExpr)) + } if !a.rewriteSimpleTableExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*AliasedTableExpr).Expr = newNode.(SimpleTableExpr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAliasedTableExprPartitions)) + } if !a.rewritePartitions(node, node.Partitions, func(newNode, parent SQLNode) { parent.(*AliasedTableExpr).Partitions = newNode.(Partitions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAliasedTableExprAs)) + } if !a.rewriteIdentifierCS(node, node.As, func(newNode, parent SQLNode) { parent.(*AliasedTableExpr).As = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAliasedTableExprHints)) + } if !a.rewriteIndexHints(node, node.Hints, func(newNode, parent SQLNode) { parent.(*AliasedTableExpr).Hints = newNode.(IndexHints) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAliasedTableExprColumns)) + } if !a.rewriteColumns(node, node.Columns, func(newNode, parent SQLNode) { parent.(*AliasedTableExpr).Columns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -763,6 +832,8 @@ func (a *application) rewriteRefOfAliasedTableExpr(parent SQLNode, node *Aliased } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterCharset(parent SQLNode, node *AlterCharset, replacer replacerFunc) bool { if node == nil { return true @@ -792,6 +863,8 @@ func (a *application) rewriteRefOfAlterCharset(parent SQLNode, node *AlterCharse } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterCheck(parent SQLNode, node *AlterCheck, replacer replacerFunc) bool { if node == nil { return true @@ -809,11 +882,17 @@ func (a *application) rewriteRefOfAlterCheck(parent SQLNode, node *AlterCheck, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterCheckName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*AlterCheck).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -824,6 +903,8 @@ func (a *application) rewriteRefOfAlterCheck(parent SQLNode, node *AlterCheck, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterColumn(parent SQLNode, node *AlterColumn, replacer replacerFunc) bool { if node == nil { return true @@ -841,16 +922,26 @@ func (a *application) rewriteRefOfAlterColumn(parent SQLNode, node *AlterColumn, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterColumnColumn)) + } if !a.rewriteRefOfColName(node, node.Column, func(newNode, parent SQLNode) { parent.(*AlterColumn).Column = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterColumnDefaultVal)) + } if !a.rewriteExpr(node, node.DefaultVal, func(newNode, parent SQLNode) { parent.(*AlterColumn).DefaultVal = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -861,6 +952,8 @@ func (a *application) rewriteRefOfAlterColumn(parent SQLNode, node *AlterColumn, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterDatabase(parent SQLNode, node *AlterDatabase, replacer replacerFunc) bool { if node == nil { return true @@ -878,16 +971,26 @@ func (a *application) rewriteRefOfAlterDatabase(parent SQLNode, node *AlterDatab return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterDatabaseComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*AlterDatabase).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterDatabaseDBName)) + } if !a.rewriteIdentifierCS(node, node.DBName, func(newNode, parent SQLNode) { parent.(*AlterDatabase).DBName = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -898,6 +1001,8 @@ func (a *application) rewriteRefOfAlterDatabase(parent SQLNode, node *AlterDatab } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterIndex(parent SQLNode, node *AlterIndex, replacer replacerFunc) bool { if node == nil { return true @@ -915,11 +1020,17 @@ func (a *application) rewriteRefOfAlterIndex(parent SQLNode, node *AlterIndex, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterIndexName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*AlterIndex).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -930,6 +1041,8 @@ func (a *application) rewriteRefOfAlterIndex(parent SQLNode, node *AlterIndex, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterMigration(parent SQLNode, node *AlterMigration, replacer replacerFunc) bool { if node == nil { return true @@ -947,11 +1060,17 @@ func (a *application) rewriteRefOfAlterMigration(parent SQLNode, node *AlterMigr return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterMigrationRatio)) + } if !a.rewriteRefOfLiteral(node, node.Ratio, func(newNode, parent SQLNode) { parent.(*AlterMigration).Ratio = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -962,6 +1081,8 @@ func (a *application) rewriteRefOfAlterMigration(parent SQLNode, node *AlterMigr } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterTable(parent SQLNode, node *AlterTable, replacer replacerFunc) bool { if node == nil { return true @@ -979,12 +1100,25 @@ func (a *application) rewriteRefOfAlterTable(parent SQLNode, node *AlterTable, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterTableTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*AlterTable).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.AlterOptions { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfAlterTableAlterOptionsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteAlterOption(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*AlterTable).AlterOptions[idx] = newNode.(AlterOption) @@ -993,21 +1127,36 @@ func (a *application) rewriteRefOfAlterTable(parent SQLNode, node *AlterTable, r return false } } + if a.collectPaths && len(node.AlterOptions) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterTablePartitionSpec)) + } if !a.rewriteRefOfPartitionSpec(node, node.PartitionSpec, func(newNode, parent SQLNode) { parent.(*AlterTable).PartitionSpec = newNode.(*PartitionSpec) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterTablePartitionOption)) + } if !a.rewriteRefOfPartitionOption(node, node.PartitionOption, func(newNode, parent SQLNode) { parent.(*AlterTable).PartitionOption = newNode.(*PartitionOption) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterTableComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*AlterTable).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1018,6 +1167,8 @@ func (a *application) rewriteRefOfAlterTable(parent SQLNode, node *AlterTable, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterView(parent SQLNode, node *AlterView, replacer replacerFunc) bool { if node == nil { return true @@ -1035,31 +1186,53 @@ func (a *application) rewriteRefOfAlterView(parent SQLNode, node *AlterView, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterViewViewName)) + } if !a.rewriteTableName(node, node.ViewName, func(newNode, parent SQLNode) { parent.(*AlterView).ViewName = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterViewDefiner)) + } if !a.rewriteRefOfDefiner(node, node.Definer, func(newNode, parent SQLNode) { parent.(*AlterView).Definer = newNode.(*Definer) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterViewColumns)) + } if !a.rewriteColumns(node, node.Columns, func(newNode, parent SQLNode) { parent.(*AlterView).Columns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterViewSelect)) + } if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { parent.(*AlterView).Select = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterViewComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*AlterView).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1070,6 +1243,8 @@ func (a *application) rewriteRefOfAlterView(parent SQLNode, node *AlterView, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAlterVschema(parent SQLNode, node *AlterVschema, replacer replacerFunc) bool { if node == nil { return true @@ -1087,17 +1262,34 @@ func (a *application) rewriteRefOfAlterVschema(parent SQLNode, node *AlterVschem return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAlterVschemaTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*AlterVschema).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterVschemaVindexSpec)) + } if !a.rewriteRefOfVindexSpec(node, node.VindexSpec, func(newNode, parent SQLNode) { parent.(*AlterVschema).VindexSpec = newNode.(*VindexSpec) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.VindexCols { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfAlterVschemaVindexColsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteIdentifierCI(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*AlterVschema).VindexCols[idx] = newNode.(IdentifierCI) @@ -1106,11 +1298,18 @@ func (a *application) rewriteRefOfAlterVschema(parent SQLNode, node *AlterVschem return false } } + if a.collectPaths && len(node.VindexCols) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAlterVschemaAutoIncSpec)) + } if !a.rewriteRefOfAutoIncSpec(node, node.AutoIncSpec, func(newNode, parent SQLNode) { parent.(*AlterVschema).AutoIncSpec = newNode.(*AutoIncSpec) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1121,6 +1320,8 @@ func (a *application) rewriteRefOfAlterVschema(parent SQLNode, node *AlterVschem } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAnalyze(parent SQLNode, node *Analyze, replacer replacerFunc) bool { if node == nil { return true @@ -1138,11 +1339,17 @@ func (a *application) rewriteRefOfAnalyze(parent SQLNode, node *Analyze, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAnalyzeTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*Analyze).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1153,6 +1360,8 @@ func (a *application) rewriteRefOfAnalyze(parent SQLNode, node *Analyze, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAndExpr(parent SQLNode, node *AndExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1170,16 +1379,26 @@ func (a *application) rewriteRefOfAndExpr(parent SQLNode, node *AndExpr, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAndExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*AndExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAndExprRight)) + } if !a.rewriteExpr(node, node.Right, func(newNode, parent SQLNode) { parent.(*AndExpr).Right = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1190,6 +1409,8 @@ func (a *application) rewriteRefOfAndExpr(parent SQLNode, node *AndExpr, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAnyValue(parent SQLNode, node *AnyValue, replacer replacerFunc) bool { if node == nil { return true @@ -1207,11 +1428,17 @@ func (a *application) rewriteRefOfAnyValue(parent SQLNode, node *AnyValue, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAnyValueArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*AnyValue).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1222,6 +1449,8 @@ func (a *application) rewriteRefOfAnyValue(parent SQLNode, node *AnyValue, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfArgument(parent SQLNode, node *Argument, replacer replacerFunc) bool { if node == nil { return true @@ -1251,6 +1480,8 @@ func (a *application) rewriteRefOfArgument(parent SQLNode, node *Argument, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfArgumentLessWindowExpr(parent SQLNode, node *ArgumentLessWindowExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1268,11 +1499,17 @@ func (a *application) rewriteRefOfArgumentLessWindowExpr(parent SQLNode, node *A return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfArgumentLessWindowExprOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*ArgumentLessWindowExpr).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1283,6 +1520,8 @@ func (a *application) rewriteRefOfArgumentLessWindowExpr(parent SQLNode, node *A } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAssignmentExpr(parent SQLNode, node *AssignmentExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1300,16 +1539,26 @@ func (a *application) rewriteRefOfAssignmentExpr(parent SQLNode, node *Assignmen return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAssignmentExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*AssignmentExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAssignmentExprRight)) + } if !a.rewriteExpr(node, node.Right, func(newNode, parent SQLNode) { parent.(*AssignmentExpr).Right = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1320,6 +1569,8 @@ func (a *application) rewriteRefOfAssignmentExpr(parent SQLNode, node *Assignmen } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAutoIncSpec(parent SQLNode, node *AutoIncSpec, replacer replacerFunc) bool { if node == nil { return true @@ -1337,16 +1588,26 @@ func (a *application) rewriteRefOfAutoIncSpec(parent SQLNode, node *AutoIncSpec, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAutoIncSpecColumn)) + } if !a.rewriteIdentifierCI(node, node.Column, func(newNode, parent SQLNode) { parent.(*AutoIncSpec).Column = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAutoIncSpecSequence)) + } if !a.rewriteTableName(node, node.Sequence, func(newNode, parent SQLNode) { parent.(*AutoIncSpec).Sequence = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1357,6 +1618,8 @@ func (a *application) rewriteRefOfAutoIncSpec(parent SQLNode, node *AutoIncSpec, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfAvg(parent SQLNode, node *Avg, replacer replacerFunc) bool { if node == nil { return true @@ -1374,16 +1637,26 @@ func (a *application) rewriteRefOfAvg(parent SQLNode, node *Avg, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfAvgArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*Avg).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfAvgOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Avg).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1394,6 +1667,8 @@ func (a *application) rewriteRefOfAvg(parent SQLNode, node *Avg, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfBegin(parent SQLNode, node *Begin, replacer replacerFunc) bool { if node == nil { return true @@ -1423,6 +1698,8 @@ func (a *application) rewriteRefOfBegin(parent SQLNode, node *Begin, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfBetweenExpr(parent SQLNode, node *BetweenExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1440,21 +1717,35 @@ func (a *application) rewriteRefOfBetweenExpr(parent SQLNode, node *BetweenExpr, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfBetweenExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*BetweenExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfBetweenExprFrom)) + } if !a.rewriteExpr(node, node.From, func(newNode, parent SQLNode) { parent.(*BetweenExpr).From = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfBetweenExprTo)) + } if !a.rewriteExpr(node, node.To, func(newNode, parent SQLNode) { parent.(*BetweenExpr).To = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1465,6 +1756,8 @@ func (a *application) rewriteRefOfBetweenExpr(parent SQLNode, node *BetweenExpr, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfBinaryExpr(parent SQLNode, node *BinaryExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1482,16 +1775,26 @@ func (a *application) rewriteRefOfBinaryExpr(parent SQLNode, node *BinaryExpr, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfBinaryExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*BinaryExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfBinaryExprRight)) + } if !a.rewriteExpr(node, node.Right, func(newNode, parent SQLNode) { parent.(*BinaryExpr).Right = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1502,6 +1805,8 @@ func (a *application) rewriteRefOfBinaryExpr(parent SQLNode, node *BinaryExpr, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfBitAnd(parent SQLNode, node *BitAnd, replacer replacerFunc) bool { if node == nil { return true @@ -1519,16 +1824,26 @@ func (a *application) rewriteRefOfBitAnd(parent SQLNode, node *BitAnd, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfBitAndArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*BitAnd).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfBitAndOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*BitAnd).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1539,6 +1854,8 @@ func (a *application) rewriteRefOfBitAnd(parent SQLNode, node *BitAnd, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfBitOr(parent SQLNode, node *BitOr, replacer replacerFunc) bool { if node == nil { return true @@ -1556,16 +1873,26 @@ func (a *application) rewriteRefOfBitOr(parent SQLNode, node *BitOr, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfBitOrArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*BitOr).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfBitOrOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*BitOr).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1576,6 +1903,8 @@ func (a *application) rewriteRefOfBitOr(parent SQLNode, node *BitOr, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfBitXor(parent SQLNode, node *BitXor, replacer replacerFunc) bool { if node == nil { return true @@ -1593,16 +1922,26 @@ func (a *application) rewriteRefOfBitXor(parent SQLNode, node *BitXor, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfBitXorArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*BitXor).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfBitXorOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*BitXor).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1613,6 +1952,8 @@ func (a *application) rewriteRefOfBitXor(parent SQLNode, node *BitXor, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCallProc(parent SQLNode, node *CallProc, replacer replacerFunc) bool { if node == nil { return true @@ -1630,12 +1971,25 @@ func (a *application) rewriteRefOfCallProc(parent SQLNode, node *CallProc, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCallProcName)) + } if !a.rewriteTableName(node, node.Name, func(newNode, parent SQLNode) { parent.(*CallProc).Name = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Params { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfCallProcParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*CallProc).Params[idx] = newNode.(Expr) @@ -1644,6 +1998,9 @@ func (a *application) rewriteRefOfCallProc(parent SQLNode, node *CallProc, repla return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1654,6 +2011,8 @@ func (a *application) rewriteRefOfCallProc(parent SQLNode, node *CallProc, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCaseExpr(parent SQLNode, node *CaseExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1671,12 +2030,25 @@ func (a *application) rewriteRefOfCaseExpr(parent SQLNode, node *CaseExpr, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCaseExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*CaseExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Whens { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfCaseExprWhensOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfWhen(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*CaseExpr).Whens[idx] = newNode.(*When) @@ -1685,11 +2057,18 @@ func (a *application) rewriteRefOfCaseExpr(parent SQLNode, node *CaseExpr, repla return false } } + if a.collectPaths && len(node.Whens) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCaseExprElse)) + } if !a.rewriteExpr(node, node.Else, func(newNode, parent SQLNode) { parent.(*CaseExpr).Else = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1700,6 +2079,8 @@ func (a *application) rewriteRefOfCaseExpr(parent SQLNode, node *CaseExpr, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCastExpr(parent SQLNode, node *CastExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1717,16 +2098,26 @@ func (a *application) rewriteRefOfCastExpr(parent SQLNode, node *CastExpr, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCastExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*CastExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCastExprType)) + } if !a.rewriteRefOfConvertType(node, node.Type, func(newNode, parent SQLNode) { parent.(*CastExpr).Type = newNode.(*ConvertType) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1737,6 +2128,8 @@ func (a *application) rewriteRefOfCastExpr(parent SQLNode, node *CastExpr, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfChangeColumn(parent SQLNode, node *ChangeColumn, replacer replacerFunc) bool { if node == nil { return true @@ -1754,21 +2147,35 @@ func (a *application) rewriteRefOfChangeColumn(parent SQLNode, node *ChangeColum return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfChangeColumnOldColumn)) + } if !a.rewriteRefOfColName(node, node.OldColumn, func(newNode, parent SQLNode) { parent.(*ChangeColumn).OldColumn = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfChangeColumnNewColDefinition)) + } if !a.rewriteRefOfColumnDefinition(node, node.NewColDefinition, func(newNode, parent SQLNode) { parent.(*ChangeColumn).NewColDefinition = newNode.(*ColumnDefinition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfChangeColumnAfter)) + } if !a.rewriteRefOfColName(node, node.After, func(newNode, parent SQLNode) { parent.(*ChangeColumn).After = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1779,6 +2186,8 @@ func (a *application) rewriteRefOfChangeColumn(parent SQLNode, node *ChangeColum } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCharExpr(parent SQLNode, node *CharExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1797,6 +2206,13 @@ func (a *application) rewriteRefOfCharExpr(parent SQLNode, node *CharExpr, repla } } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfCharExprExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*CharExpr).Exprs[idx] = newNode.(Expr) @@ -1805,6 +2221,9 @@ func (a *application) rewriteRefOfCharExpr(parent SQLNode, node *CharExpr, repla return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1815,6 +2234,8 @@ func (a *application) rewriteRefOfCharExpr(parent SQLNode, node *CharExpr, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCheckConstraintDefinition(parent SQLNode, node *CheckConstraintDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -1832,11 +2253,17 @@ func (a *application) rewriteRefOfCheckConstraintDefinition(parent SQLNode, node return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCheckConstraintDefinitionExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*CheckConstraintDefinition).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1847,6 +2274,8 @@ func (a *application) rewriteRefOfCheckConstraintDefinition(parent SQLNode, node } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfColName(parent SQLNode, node *ColName, replacer replacerFunc) bool { if node == nil { return true @@ -1864,16 +2293,26 @@ func (a *application) rewriteRefOfColName(parent SQLNode, node *ColName, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfColNameName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*ColName).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfColNameQualifier)) + } if !a.rewriteTableName(node, node.Qualifier, func(newNode, parent SQLNode) { parent.(*ColName).Qualifier = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1884,6 +2323,8 @@ func (a *application) rewriteRefOfColName(parent SQLNode, node *ColName, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCollateExpr(parent SQLNode, node *CollateExpr, replacer replacerFunc) bool { if node == nil { return true @@ -1901,11 +2342,17 @@ func (a *application) rewriteRefOfCollateExpr(parent SQLNode, node *CollateExpr, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCollateExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*CollateExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1916,6 +2363,8 @@ func (a *application) rewriteRefOfCollateExpr(parent SQLNode, node *CollateExpr, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfColumnDefinition(parent SQLNode, node *ColumnDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -1933,16 +2382,26 @@ func (a *application) rewriteRefOfColumnDefinition(parent SQLNode, node *ColumnD return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfColumnDefinitionName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*ColumnDefinition).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfColumnDefinitionType)) + } if !a.rewriteRefOfColumnType(node, node.Type, func(newNode, parent SQLNode) { parent.(*ColumnDefinition).Type = newNode.(*ColumnType) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -1953,6 +2412,8 @@ func (a *application) rewriteRefOfColumnDefinition(parent SQLNode, node *ColumnD } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfColumnType(parent SQLNode, node *ColumnType, replacer replacerFunc) bool { if node == nil { return true @@ -1982,6 +2443,8 @@ func (a *application) rewriteRefOfColumnType(parent SQLNode, node *ColumnType, r } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteColumns(parent SQLNode, node Columns, replacer replacerFunc) bool { if node == nil { return true @@ -2000,6 +2463,13 @@ func (a *application) rewriteColumns(parent SQLNode, node Columns, replacer repl } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(ColumnsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteIdentifierCI(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(Columns)[idx] = newNode.(IdentifierCI) @@ -2008,6 +2478,9 @@ func (a *application) rewriteColumns(parent SQLNode, node Columns, replacer repl return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2018,6 +2491,8 @@ func (a *application) rewriteColumns(parent SQLNode, node Columns, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCommentOnly(parent SQLNode, node *CommentOnly, replacer replacerFunc) bool { if node == nil { return true @@ -2047,6 +2522,8 @@ func (a *application) rewriteRefOfCommentOnly(parent SQLNode, node *CommentOnly, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCommit(parent SQLNode, node *Commit, replacer replacerFunc) bool { if node == nil { return true @@ -2076,6 +2553,8 @@ func (a *application) rewriteRefOfCommit(parent SQLNode, node *Commit, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCommonTableExpr(parent SQLNode, node *CommonTableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -2093,21 +2572,35 @@ func (a *application) rewriteRefOfCommonTableExpr(parent SQLNode, node *CommonTa return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCommonTableExprID)) + } if !a.rewriteIdentifierCS(node, node.ID, func(newNode, parent SQLNode) { parent.(*CommonTableExpr).ID = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCommonTableExprColumns)) + } if !a.rewriteColumns(node, node.Columns, func(newNode, parent SQLNode) { parent.(*CommonTableExpr).Columns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCommonTableExprSubquery)) + } if !a.rewriteTableStatement(node, node.Subquery, func(newNode, parent SQLNode) { parent.(*CommonTableExpr).Subquery = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2118,6 +2611,8 @@ func (a *application) rewriteRefOfCommonTableExpr(parent SQLNode, node *CommonTa } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfComparisonExpr(parent SQLNode, node *ComparisonExpr, replacer replacerFunc) bool { if node == nil { return true @@ -2135,21 +2630,35 @@ func (a *application) rewriteRefOfComparisonExpr(parent SQLNode, node *Compariso return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfComparisonExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*ComparisonExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfComparisonExprRight)) + } if !a.rewriteExpr(node, node.Right, func(newNode, parent SQLNode) { parent.(*ComparisonExpr).Right = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfComparisonExprEscape)) + } if !a.rewriteExpr(node, node.Escape, func(newNode, parent SQLNode) { parent.(*ComparisonExpr).Escape = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2160,6 +2669,8 @@ func (a *application) rewriteRefOfComparisonExpr(parent SQLNode, node *Compariso } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfConstraintDefinition(parent SQLNode, node *ConstraintDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -2177,16 +2688,26 @@ func (a *application) rewriteRefOfConstraintDefinition(parent SQLNode, node *Con return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfConstraintDefinitionName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*ConstraintDefinition).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfConstraintDefinitionDetails)) + } if !a.rewriteConstraintInfo(node, node.Details, func(newNode, parent SQLNode) { parent.(*ConstraintDefinition).Details = newNode.(ConstraintInfo) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2197,6 +2718,8 @@ func (a *application) rewriteRefOfConstraintDefinition(parent SQLNode, node *Con } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfConvertExpr(parent SQLNode, node *ConvertExpr, replacer replacerFunc) bool { if node == nil { return true @@ -2214,16 +2737,26 @@ func (a *application) rewriteRefOfConvertExpr(parent SQLNode, node *ConvertExpr, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfConvertExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*ConvertExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfConvertExprType)) + } if !a.rewriteRefOfConvertType(node, node.Type, func(newNode, parent SQLNode) { parent.(*ConvertExpr).Type = newNode.(*ConvertType) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2234,6 +2767,8 @@ func (a *application) rewriteRefOfConvertExpr(parent SQLNode, node *ConvertExpr, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfConvertType(parent SQLNode, node *ConvertType, replacer replacerFunc) bool { if node == nil { return true @@ -2263,6 +2798,8 @@ func (a *application) rewriteRefOfConvertType(parent SQLNode, node *ConvertType, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfConvertUsingExpr(parent SQLNode, node *ConvertUsingExpr, replacer replacerFunc) bool { if node == nil { return true @@ -2280,11 +2817,17 @@ func (a *application) rewriteRefOfConvertUsingExpr(parent SQLNode, node *Convert return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfConvertUsingExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*ConvertUsingExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2295,6 +2838,8 @@ func (a *application) rewriteRefOfConvertUsingExpr(parent SQLNode, node *Convert } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCount(parent SQLNode, node *Count, replacer replacerFunc) bool { if node == nil { return true @@ -2313,6 +2858,13 @@ func (a *application) rewriteRefOfCount(parent SQLNode, node *Count, replacer re } } for x, el := range node.Args { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfCountArgsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*Count).Args[idx] = newNode.(Expr) @@ -2321,11 +2873,18 @@ func (a *application) rewriteRefOfCount(parent SQLNode, node *Count, replacer re return false } } + if a.collectPaths && len(node.Args) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCountOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Count).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2336,6 +2895,8 @@ func (a *application) rewriteRefOfCount(parent SQLNode, node *Count, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCountStar(parent SQLNode, node *CountStar, replacer replacerFunc) bool { if node == nil { return true @@ -2353,11 +2914,17 @@ func (a *application) rewriteRefOfCountStar(parent SQLNode, node *CountStar, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCountStarOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*CountStar).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2368,6 +2935,8 @@ func (a *application) rewriteRefOfCountStar(parent SQLNode, node *CountStar, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCreateDatabase(parent SQLNode, node *CreateDatabase, replacer replacerFunc) bool { if node == nil { return true @@ -2385,16 +2954,26 @@ func (a *application) rewriteRefOfCreateDatabase(parent SQLNode, node *CreateDat return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCreateDatabaseComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*CreateDatabase).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateDatabaseDBName)) + } if !a.rewriteIdentifierCS(node, node.DBName, func(newNode, parent SQLNode) { parent.(*CreateDatabase).DBName = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2405,6 +2984,8 @@ func (a *application) rewriteRefOfCreateDatabase(parent SQLNode, node *CreateDat } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCreateTable(parent SQLNode, node *CreateTable, replacer replacerFunc) bool { if node == nil { return true @@ -2422,26 +3003,44 @@ func (a *application) rewriteRefOfCreateTable(parent SQLNode, node *CreateTable, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCreateTableTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*CreateTable).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateTableTableSpec)) + } if !a.rewriteRefOfTableSpec(node, node.TableSpec, func(newNode, parent SQLNode) { parent.(*CreateTable).TableSpec = newNode.(*TableSpec) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateTableOptLike)) + } if !a.rewriteRefOfOptLike(node, node.OptLike, func(newNode, parent SQLNode) { parent.(*CreateTable).OptLike = newNode.(*OptLike) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateTableComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*CreateTable).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2452,6 +3051,8 @@ func (a *application) rewriteRefOfCreateTable(parent SQLNode, node *CreateTable, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCreateView(parent SQLNode, node *CreateView, replacer replacerFunc) bool { if node == nil { return true @@ -2469,31 +3070,53 @@ func (a *application) rewriteRefOfCreateView(parent SQLNode, node *CreateView, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCreateViewViewName)) + } if !a.rewriteTableName(node, node.ViewName, func(newNode, parent SQLNode) { parent.(*CreateView).ViewName = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateViewDefiner)) + } if !a.rewriteRefOfDefiner(node, node.Definer, func(newNode, parent SQLNode) { parent.(*CreateView).Definer = newNode.(*Definer) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateViewColumns)) + } if !a.rewriteColumns(node, node.Columns, func(newNode, parent SQLNode) { parent.(*CreateView).Columns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateViewSelect)) + } if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { parent.(*CreateView).Select = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfCreateViewComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*CreateView).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2504,6 +3127,8 @@ func (a *application) rewriteRefOfCreateView(parent SQLNode, node *CreateView, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfCurTimeFuncExpr(parent SQLNode, node *CurTimeFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -2521,11 +3146,17 @@ func (a *application) rewriteRefOfCurTimeFuncExpr(parent SQLNode, node *CurTimeF return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfCurTimeFuncExprName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*CurTimeFuncExpr).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2536,6 +3167,8 @@ func (a *application) rewriteRefOfCurTimeFuncExpr(parent SQLNode, node *CurTimeF } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDeallocateStmt(parent SQLNode, node *DeallocateStmt, replacer replacerFunc) bool { if node == nil { return true @@ -2553,16 +3186,26 @@ func (a *application) rewriteRefOfDeallocateStmt(parent SQLNode, node *Deallocat return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDeallocateStmtComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*DeallocateStmt).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeallocateStmtName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*DeallocateStmt).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2573,6 +3216,8 @@ func (a *application) rewriteRefOfDeallocateStmt(parent SQLNode, node *Deallocat } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDefault(parent SQLNode, node *Default, replacer replacerFunc) bool { if node == nil { return true @@ -2602,6 +3247,8 @@ func (a *application) rewriteRefOfDefault(parent SQLNode, node *Default, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDefiner(parent SQLNode, node *Definer, replacer replacerFunc) bool { if node == nil { return true @@ -2631,6 +3278,8 @@ func (a *application) rewriteRefOfDefiner(parent SQLNode, node *Definer, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDelete(parent SQLNode, node *Delete, replacer replacerFunc) bool { if node == nil { return true @@ -2648,17 +3297,34 @@ func (a *application) rewriteRefOfDelete(parent SQLNode, node *Delete, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDeleteWith)) + } if !a.rewriteRefOfWith(node, node.With, func(newNode, parent SQLNode) { parent.(*Delete).With = newNode.(*With) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeleteComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*Delete).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.TableExprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfDeleteTableExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteTableExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*Delete).TableExprs[idx] = newNode.(TableExpr) @@ -2667,31 +3333,54 @@ func (a *application) rewriteRefOfDelete(parent SQLNode, node *Delete, replacer return false } } + if a.collectPaths && len(node.TableExprs) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeleteTargets)) + } if !a.rewriteTableNames(node, node.Targets, func(newNode, parent SQLNode) { parent.(*Delete).Targets = newNode.(TableNames) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeletePartitions)) + } if !a.rewritePartitions(node, node.Partitions, func(newNode, parent SQLNode) { parent.(*Delete).Partitions = newNode.(Partitions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeleteWhere)) + } if !a.rewriteRefOfWhere(node, node.Where, func(newNode, parent SQLNode) { parent.(*Delete).Where = newNode.(*Where) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeleteOrderBy)) + } if !a.rewriteOrderBy(node, node.OrderBy, func(newNode, parent SQLNode) { parent.(*Delete).OrderBy = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDeleteLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*Delete).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2702,6 +3391,8 @@ func (a *application) rewriteRefOfDelete(parent SQLNode, node *Delete, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDerivedTable(parent SQLNode, node *DerivedTable, replacer replacerFunc) bool { if node == nil { return true @@ -2719,11 +3410,17 @@ func (a *application) rewriteRefOfDerivedTable(parent SQLNode, node *DerivedTabl return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDerivedTableSelect)) + } if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { parent.(*DerivedTable).Select = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2734,6 +3431,8 @@ func (a *application) rewriteRefOfDerivedTable(parent SQLNode, node *DerivedTabl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDropColumn(parent SQLNode, node *DropColumn, replacer replacerFunc) bool { if node == nil { return true @@ -2751,11 +3450,17 @@ func (a *application) rewriteRefOfDropColumn(parent SQLNode, node *DropColumn, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDropColumnName)) + } if !a.rewriteRefOfColName(node, node.Name, func(newNode, parent SQLNode) { parent.(*DropColumn).Name = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2766,6 +3471,8 @@ func (a *application) rewriteRefOfDropColumn(parent SQLNode, node *DropColumn, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDropDatabase(parent SQLNode, node *DropDatabase, replacer replacerFunc) bool { if node == nil { return true @@ -2783,16 +3490,26 @@ func (a *application) rewriteRefOfDropDatabase(parent SQLNode, node *DropDatabas return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDropDatabaseComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*DropDatabase).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDropDatabaseDBName)) + } if !a.rewriteIdentifierCS(node, node.DBName, func(newNode, parent SQLNode) { parent.(*DropDatabase).DBName = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2803,6 +3520,8 @@ func (a *application) rewriteRefOfDropDatabase(parent SQLNode, node *DropDatabas } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDropKey(parent SQLNode, node *DropKey, replacer replacerFunc) bool { if node == nil { return true @@ -2820,11 +3539,17 @@ func (a *application) rewriteRefOfDropKey(parent SQLNode, node *DropKey, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDropKeyName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*DropKey).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2835,6 +3560,8 @@ func (a *application) rewriteRefOfDropKey(parent SQLNode, node *DropKey, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDropTable(parent SQLNode, node *DropTable, replacer replacerFunc) bool { if node == nil { return true @@ -2852,16 +3579,26 @@ func (a *application) rewriteRefOfDropTable(parent SQLNode, node *DropTable, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDropTableFromTables)) + } if !a.rewriteTableNames(node, node.FromTables, func(newNode, parent SQLNode) { parent.(*DropTable).FromTables = newNode.(TableNames) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDropTableComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*DropTable).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2872,6 +3609,8 @@ func (a *application) rewriteRefOfDropTable(parent SQLNode, node *DropTable, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfDropView(parent SQLNode, node *DropView, replacer replacerFunc) bool { if node == nil { return true @@ -2889,16 +3628,26 @@ func (a *application) rewriteRefOfDropView(parent SQLNode, node *DropView, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfDropViewFromTables)) + } if !a.rewriteTableNames(node, node.FromTables, func(newNode, parent SQLNode) { parent.(*DropView).FromTables = newNode.(TableNames) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfDropViewComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*DropView).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2909,6 +3658,8 @@ func (a *application) rewriteRefOfDropView(parent SQLNode, node *DropView, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExecuteStmt(parent SQLNode, node *ExecuteStmt, replacer replacerFunc) bool { if node == nil { return true @@ -2926,17 +3677,34 @@ func (a *application) rewriteRefOfExecuteStmt(parent SQLNode, node *ExecuteStmt, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfExecuteStmtName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*ExecuteStmt).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfExecuteStmtComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*ExecuteStmt).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Arguments { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfExecuteStmtArgumentsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfVariable(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*ExecuteStmt).Arguments[idx] = newNode.(*Variable) @@ -2945,6 +3713,9 @@ func (a *application) rewriteRefOfExecuteStmt(parent SQLNode, node *ExecuteStmt, return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2955,6 +3726,8 @@ func (a *application) rewriteRefOfExecuteStmt(parent SQLNode, node *ExecuteStmt, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExistsExpr(parent SQLNode, node *ExistsExpr, replacer replacerFunc) bool { if node == nil { return true @@ -2972,11 +3745,17 @@ func (a *application) rewriteRefOfExistsExpr(parent SQLNode, node *ExistsExpr, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfExistsExprSubquery)) + } if !a.rewriteRefOfSubquery(node, node.Subquery, func(newNode, parent SQLNode) { parent.(*ExistsExpr).Subquery = newNode.(*Subquery) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -2987,6 +3766,8 @@ func (a *application) rewriteRefOfExistsExpr(parent SQLNode, node *ExistsExpr, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExplainStmt(parent SQLNode, node *ExplainStmt, replacer replacerFunc) bool { if node == nil { return true @@ -3004,16 +3785,26 @@ func (a *application) rewriteRefOfExplainStmt(parent SQLNode, node *ExplainStmt, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfExplainStmtStatement)) + } if !a.rewriteStatement(node, node.Statement, func(newNode, parent SQLNode) { parent.(*ExplainStmt).Statement = newNode.(Statement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfExplainStmtComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*ExplainStmt).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3024,6 +3815,8 @@ func (a *application) rewriteRefOfExplainStmt(parent SQLNode, node *ExplainStmt, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExplainTab(parent SQLNode, node *ExplainTab, replacer replacerFunc) bool { if node == nil { return true @@ -3041,11 +3834,17 @@ func (a *application) rewriteRefOfExplainTab(parent SQLNode, node *ExplainTab, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfExplainTabTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*ExplainTab).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3056,6 +3855,8 @@ func (a *application) rewriteRefOfExplainTab(parent SQLNode, node *ExplainTab, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExprs(parent SQLNode, node *Exprs, replacer replacerFunc) bool { if node == nil { return true @@ -3074,6 +3875,13 @@ func (a *application) rewriteRefOfExprs(parent SQLNode, node *Exprs, replacer re } } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfExprsExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*Exprs).Exprs[idx] = newNode.(Expr) @@ -3082,6 +3890,9 @@ func (a *application) rewriteRefOfExprs(parent SQLNode, node *Exprs, replacer re return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3092,6 +3903,8 @@ func (a *application) rewriteRefOfExprs(parent SQLNode, node *Exprs, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExtractFuncExpr(parent SQLNode, node *ExtractFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3109,11 +3922,17 @@ func (a *application) rewriteRefOfExtractFuncExpr(parent SQLNode, node *ExtractF return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfExtractFuncExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*ExtractFuncExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3124,6 +3943,8 @@ func (a *application) rewriteRefOfExtractFuncExpr(parent SQLNode, node *ExtractF } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfExtractValueExpr(parent SQLNode, node *ExtractValueExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3141,16 +3962,26 @@ func (a *application) rewriteRefOfExtractValueExpr(parent SQLNode, node *Extract return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfExtractValueExprFragment)) + } if !a.rewriteExpr(node, node.Fragment, func(newNode, parent SQLNode) { parent.(*ExtractValueExpr).Fragment = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfExtractValueExprXPathExpr)) + } if !a.rewriteExpr(node, node.XPathExpr, func(newNode, parent SQLNode) { parent.(*ExtractValueExpr).XPathExpr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3161,6 +3992,8 @@ func (a *application) rewriteRefOfExtractValueExpr(parent SQLNode, node *Extract } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfFirstOrLastValueExpr(parent SQLNode, node *FirstOrLastValueExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3178,21 +4011,35 @@ func (a *application) rewriteRefOfFirstOrLastValueExpr(parent SQLNode, node *Fir return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfFirstOrLastValueExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*FirstOrLastValueExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfFirstOrLastValueExprNullTreatmentClause)) + } if !a.rewriteRefOfNullTreatmentClause(node, node.NullTreatmentClause, func(newNode, parent SQLNode) { parent.(*FirstOrLastValueExpr).NullTreatmentClause = newNode.(*NullTreatmentClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfFirstOrLastValueExprOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*FirstOrLastValueExpr).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3203,6 +4050,8 @@ func (a *application) rewriteRefOfFirstOrLastValueExpr(parent SQLNode, node *Fir } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfFlush(parent SQLNode, node *Flush, replacer replacerFunc) bool { if node == nil { return true @@ -3220,11 +4069,17 @@ func (a *application) rewriteRefOfFlush(parent SQLNode, node *Flush, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfFlushTableNames)) + } if !a.rewriteTableNames(node, node.TableNames, func(newNode, parent SQLNode) { parent.(*Flush).TableNames = newNode.(TableNames) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3235,6 +4090,8 @@ func (a *application) rewriteRefOfFlush(parent SQLNode, node *Flush, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfForce(parent SQLNode, node *Force, replacer replacerFunc) bool { if node == nil { return true @@ -3264,6 +4121,8 @@ func (a *application) rewriteRefOfForce(parent SQLNode, node *Force, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfForeignKeyDefinition(parent SQLNode, node *ForeignKeyDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -3281,21 +4140,35 @@ func (a *application) rewriteRefOfForeignKeyDefinition(parent SQLNode, node *For return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfForeignKeyDefinitionSource)) + } if !a.rewriteColumns(node, node.Source, func(newNode, parent SQLNode) { parent.(*ForeignKeyDefinition).Source = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfForeignKeyDefinitionIndexName)) + } if !a.rewriteIdentifierCI(node, node.IndexName, func(newNode, parent SQLNode) { parent.(*ForeignKeyDefinition).IndexName = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfForeignKeyDefinitionReferenceDefinition)) + } if !a.rewriteRefOfReferenceDefinition(node, node.ReferenceDefinition, func(newNode, parent SQLNode) { parent.(*ForeignKeyDefinition).ReferenceDefinition = newNode.(*ReferenceDefinition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3306,6 +4179,8 @@ func (a *application) rewriteRefOfForeignKeyDefinition(parent SQLNode, node *For } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfFrameClause(parent SQLNode, node *FrameClause, replacer replacerFunc) bool { if node == nil { return true @@ -3323,16 +4198,26 @@ func (a *application) rewriteRefOfFrameClause(parent SQLNode, node *FrameClause, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfFrameClauseStart)) + } if !a.rewriteRefOfFramePoint(node, node.Start, func(newNode, parent SQLNode) { parent.(*FrameClause).Start = newNode.(*FramePoint) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfFrameClauseEnd)) + } if !a.rewriteRefOfFramePoint(node, node.End, func(newNode, parent SQLNode) { parent.(*FrameClause).End = newNode.(*FramePoint) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3343,6 +4228,8 @@ func (a *application) rewriteRefOfFrameClause(parent SQLNode, node *FrameClause, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfFramePoint(parent SQLNode, node *FramePoint, replacer replacerFunc) bool { if node == nil { return true @@ -3360,11 +4247,17 @@ func (a *application) rewriteRefOfFramePoint(parent SQLNode, node *FramePoint, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfFramePointExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*FramePoint).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3375,6 +4268,8 @@ func (a *application) rewriteRefOfFramePoint(parent SQLNode, node *FramePoint, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfFromFirstLastClause(parent SQLNode, node *FromFirstLastClause, replacer replacerFunc) bool { if node == nil { return true @@ -3404,6 +4299,8 @@ func (a *application) rewriteRefOfFromFirstLastClause(parent SQLNode, node *From } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfFuncExpr(parent SQLNode, node *FuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3421,17 +4318,34 @@ func (a *application) rewriteRefOfFuncExpr(parent SQLNode, node *FuncExpr, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfFuncExprQualifier)) + } if !a.rewriteIdentifierCS(node, node.Qualifier, func(newNode, parent SQLNode) { parent.(*FuncExpr).Qualifier = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfFuncExprName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*FuncExpr).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfFuncExprExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*FuncExpr).Exprs[idx] = newNode.(Expr) @@ -3440,6 +4354,9 @@ func (a *application) rewriteRefOfFuncExpr(parent SQLNode, node *FuncExpr, repla return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3450,6 +4367,8 @@ func (a *application) rewriteRefOfFuncExpr(parent SQLNode, node *FuncExpr, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGTIDFuncExpr(parent SQLNode, node *GTIDFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3467,26 +4386,44 @@ func (a *application) rewriteRefOfGTIDFuncExpr(parent SQLNode, node *GTIDFuncExp return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGTIDFuncExprSet1)) + } if !a.rewriteExpr(node, node.Set1, func(newNode, parent SQLNode) { parent.(*GTIDFuncExpr).Set1 = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGTIDFuncExprSet2)) + } if !a.rewriteExpr(node, node.Set2, func(newNode, parent SQLNode) { parent.(*GTIDFuncExpr).Set2 = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGTIDFuncExprTimeout)) + } if !a.rewriteExpr(node, node.Timeout, func(newNode, parent SQLNode) { parent.(*GTIDFuncExpr).Timeout = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGTIDFuncExprChannel)) + } if !a.rewriteExpr(node, node.Channel, func(newNode, parent SQLNode) { parent.(*GTIDFuncExpr).Channel = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3497,6 +4434,8 @@ func (a *application) rewriteRefOfGTIDFuncExpr(parent SQLNode, node *GTIDFuncExp } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeoHashFromLatLongExpr(parent SQLNode, node *GeoHashFromLatLongExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3514,21 +4453,35 @@ func (a *application) rewriteRefOfGeoHashFromLatLongExpr(parent SQLNode, node *G return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeoHashFromLatLongExprLatitude)) + } if !a.rewriteExpr(node, node.Latitude, func(newNode, parent SQLNode) { parent.(*GeoHashFromLatLongExpr).Latitude = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeoHashFromLatLongExprLongitude)) + } if !a.rewriteExpr(node, node.Longitude, func(newNode, parent SQLNode) { parent.(*GeoHashFromLatLongExpr).Longitude = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeoHashFromLatLongExprMaxLength)) + } if !a.rewriteExpr(node, node.MaxLength, func(newNode, parent SQLNode) { parent.(*GeoHashFromLatLongExpr).MaxLength = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3539,6 +4492,8 @@ func (a *application) rewriteRefOfGeoHashFromLatLongExpr(parent SQLNode, node *G } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeoHashFromPointExpr(parent SQLNode, node *GeoHashFromPointExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3556,16 +4511,26 @@ func (a *application) rewriteRefOfGeoHashFromPointExpr(parent SQLNode, node *Geo return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeoHashFromPointExprPoint)) + } if !a.rewriteExpr(node, node.Point, func(newNode, parent SQLNode) { parent.(*GeoHashFromPointExpr).Point = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeoHashFromPointExprMaxLength)) + } if !a.rewriteExpr(node, node.MaxLength, func(newNode, parent SQLNode) { parent.(*GeoHashFromPointExpr).MaxLength = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3576,6 +4541,8 @@ func (a *application) rewriteRefOfGeoHashFromPointExpr(parent SQLNode, node *Geo } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeoJSONFromGeomExpr(parent SQLNode, node *GeoJSONFromGeomExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3593,21 +4560,35 @@ func (a *application) rewriteRefOfGeoJSONFromGeomExpr(parent SQLNode, node *GeoJ return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeoJSONFromGeomExprGeom)) + } if !a.rewriteExpr(node, node.Geom, func(newNode, parent SQLNode) { parent.(*GeoJSONFromGeomExpr).Geom = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeoJSONFromGeomExprMaxDecimalDigits)) + } if !a.rewriteExpr(node, node.MaxDecimalDigits, func(newNode, parent SQLNode) { parent.(*GeoJSONFromGeomExpr).MaxDecimalDigits = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeoJSONFromGeomExprBitmask)) + } if !a.rewriteExpr(node, node.Bitmask, func(newNode, parent SQLNode) { parent.(*GeoJSONFromGeomExpr).Bitmask = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3618,6 +4599,8 @@ func (a *application) rewriteRefOfGeoJSONFromGeomExpr(parent SQLNode, node *GeoJ } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomCollPropertyFuncExpr(parent SQLNode, node *GeomCollPropertyFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3635,16 +4618,26 @@ func (a *application) rewriteRefOfGeomCollPropertyFuncExpr(parent SQLNode, node return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomCollPropertyFuncExprGeomColl)) + } if !a.rewriteExpr(node, node.GeomColl, func(newNode, parent SQLNode) { parent.(*GeomCollPropertyFuncExpr).GeomColl = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomCollPropertyFuncExprPropertyDefArg)) + } if !a.rewriteExpr(node, node.PropertyDefArg, func(newNode, parent SQLNode) { parent.(*GeomCollPropertyFuncExpr).PropertyDefArg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3655,6 +4648,8 @@ func (a *application) rewriteRefOfGeomCollPropertyFuncExpr(parent SQLNode, node } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomFormatExpr(parent SQLNode, node *GeomFormatExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3672,16 +4667,26 @@ func (a *application) rewriteRefOfGeomFormatExpr(parent SQLNode, node *GeomForma return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomFormatExprGeom)) + } if !a.rewriteExpr(node, node.Geom, func(newNode, parent SQLNode) { parent.(*GeomFormatExpr).Geom = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFormatExprAxisOrderOpt)) + } if !a.rewriteExpr(node, node.AxisOrderOpt, func(newNode, parent SQLNode) { parent.(*GeomFormatExpr).AxisOrderOpt = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3692,6 +4697,8 @@ func (a *application) rewriteRefOfGeomFormatExpr(parent SQLNode, node *GeomForma } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomFromGeoHashExpr(parent SQLNode, node *GeomFromGeoHashExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3709,16 +4716,26 @@ func (a *application) rewriteRefOfGeomFromGeoHashExpr(parent SQLNode, node *Geom return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomFromGeoHashExprGeoHash)) + } if !a.rewriteExpr(node, node.GeoHash, func(newNode, parent SQLNode) { parent.(*GeomFromGeoHashExpr).GeoHash = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromGeoHashExprSridOpt)) + } if !a.rewriteExpr(node, node.SridOpt, func(newNode, parent SQLNode) { parent.(*GeomFromGeoHashExpr).SridOpt = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3729,6 +4746,8 @@ func (a *application) rewriteRefOfGeomFromGeoHashExpr(parent SQLNode, node *Geom } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomFromGeoJSONExpr(parent SQLNode, node *GeomFromGeoJSONExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3746,21 +4765,35 @@ func (a *application) rewriteRefOfGeomFromGeoJSONExpr(parent SQLNode, node *Geom return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomFromGeoJSONExprGeoJSON)) + } if !a.rewriteExpr(node, node.GeoJSON, func(newNode, parent SQLNode) { parent.(*GeomFromGeoJSONExpr).GeoJSON = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromGeoJSONExprHigherDimHandlerOpt)) + } if !a.rewriteExpr(node, node.HigherDimHandlerOpt, func(newNode, parent SQLNode) { parent.(*GeomFromGeoJSONExpr).HigherDimHandlerOpt = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromGeoJSONExprSrid)) + } if !a.rewriteExpr(node, node.Srid, func(newNode, parent SQLNode) { parent.(*GeomFromGeoJSONExpr).Srid = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3771,6 +4804,8 @@ func (a *application) rewriteRefOfGeomFromGeoJSONExpr(parent SQLNode, node *Geom } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomFromTextExpr(parent SQLNode, node *GeomFromTextExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3788,21 +4823,35 @@ func (a *application) rewriteRefOfGeomFromTextExpr(parent SQLNode, node *GeomFro return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomFromTextExprWktText)) + } if !a.rewriteExpr(node, node.WktText, func(newNode, parent SQLNode) { parent.(*GeomFromTextExpr).WktText = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromTextExprSrid)) + } if !a.rewriteExpr(node, node.Srid, func(newNode, parent SQLNode) { parent.(*GeomFromTextExpr).Srid = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromTextExprAxisOrderOpt)) + } if !a.rewriteExpr(node, node.AxisOrderOpt, func(newNode, parent SQLNode) { parent.(*GeomFromTextExpr).AxisOrderOpt = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3813,6 +4862,8 @@ func (a *application) rewriteRefOfGeomFromTextExpr(parent SQLNode, node *GeomFro } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomFromWKBExpr(parent SQLNode, node *GeomFromWKBExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3830,21 +4881,35 @@ func (a *application) rewriteRefOfGeomFromWKBExpr(parent SQLNode, node *GeomFrom return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomFromWKBExprWkbBlob)) + } if !a.rewriteExpr(node, node.WkbBlob, func(newNode, parent SQLNode) { parent.(*GeomFromWKBExpr).WkbBlob = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromWKBExprSrid)) + } if !a.rewriteExpr(node, node.Srid, func(newNode, parent SQLNode) { parent.(*GeomFromWKBExpr).Srid = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGeomFromWKBExprAxisOrderOpt)) + } if !a.rewriteExpr(node, node.AxisOrderOpt, func(newNode, parent SQLNode) { parent.(*GeomFromWKBExpr).AxisOrderOpt = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3855,6 +4920,8 @@ func (a *application) rewriteRefOfGeomFromWKBExpr(parent SQLNode, node *GeomFrom } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGeomPropertyFuncExpr(parent SQLNode, node *GeomPropertyFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3872,11 +4939,17 @@ func (a *application) rewriteRefOfGeomPropertyFuncExpr(parent SQLNode, node *Geo return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfGeomPropertyFuncExprGeom)) + } if !a.rewriteExpr(node, node.Geom, func(newNode, parent SQLNode) { parent.(*GeomPropertyFuncExpr).Geom = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3887,6 +4960,8 @@ func (a *application) rewriteRefOfGeomPropertyFuncExpr(parent SQLNode, node *Geo } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGroupBy(parent SQLNode, node *GroupBy, replacer replacerFunc) bool { if node == nil { return true @@ -3905,6 +4980,13 @@ func (a *application) rewriteRefOfGroupBy(parent SQLNode, node *GroupBy, replace } } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfGroupByExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*GroupBy).Exprs[idx] = newNode.(Expr) @@ -3913,6 +4995,9 @@ func (a *application) rewriteRefOfGroupBy(parent SQLNode, node *GroupBy, replace return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3923,6 +5008,8 @@ func (a *application) rewriteRefOfGroupBy(parent SQLNode, node *GroupBy, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfGroupConcatExpr(parent SQLNode, node *GroupConcatExpr, replacer replacerFunc) bool { if node == nil { return true @@ -3941,6 +5028,13 @@ func (a *application) rewriteRefOfGroupConcatExpr(parent SQLNode, node *GroupCon } } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfGroupConcatExprExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*GroupConcatExpr).Exprs[idx] = newNode.(Expr) @@ -3949,16 +5043,27 @@ func (a *application) rewriteRefOfGroupConcatExpr(parent SQLNode, node *GroupCon return false } } + if a.collectPaths && len(node.Exprs) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGroupConcatExprOrderBy)) + } if !a.rewriteOrderBy(node, node.OrderBy, func(newNode, parent SQLNode) { parent.(*GroupConcatExpr).OrderBy = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfGroupConcatExprLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*GroupConcatExpr).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -3969,6 +5074,8 @@ func (a *application) rewriteRefOfGroupConcatExpr(parent SQLNode, node *GroupCon } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteIdentifierCI(parent SQLNode, node IdentifierCI, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -3995,6 +5102,8 @@ func (a *application) rewriteIdentifierCI(parent SQLNode, node IdentifierCI, rep } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteIdentifierCS(parent SQLNode, node IdentifierCS, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -4021,6 +5130,8 @@ func (a *application) rewriteIdentifierCS(parent SQLNode, node IdentifierCS, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIndexDefinition(parent SQLNode, node *IndexDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -4038,11 +5149,17 @@ func (a *application) rewriteRefOfIndexDefinition(parent SQLNode, node *IndexDef return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfIndexDefinitionInfo)) + } if !a.rewriteRefOfIndexInfo(node, node.Info, func(newNode, parent SQLNode) { parent.(*IndexDefinition).Info = newNode.(*IndexInfo) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4053,6 +5170,8 @@ func (a *application) rewriteRefOfIndexDefinition(parent SQLNode, node *IndexDef } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIndexHint(parent SQLNode, node *IndexHint, replacer replacerFunc) bool { if node == nil { return true @@ -4071,6 +5190,13 @@ func (a *application) rewriteRefOfIndexHint(parent SQLNode, node *IndexHint, rep } } for x, el := range node.Indexes { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfIndexHintIndexesOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteIdentifierCI(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*IndexHint).Indexes[idx] = newNode.(IdentifierCI) @@ -4079,6 +5205,9 @@ func (a *application) rewriteRefOfIndexHint(parent SQLNode, node *IndexHint, rep return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4089,6 +5218,8 @@ func (a *application) rewriteRefOfIndexHint(parent SQLNode, node *IndexHint, rep } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteIndexHints(parent SQLNode, node IndexHints, replacer replacerFunc) bool { if node == nil { return true @@ -4107,6 +5238,13 @@ func (a *application) rewriteIndexHints(parent SQLNode, node IndexHints, replace } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(IndexHintsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfIndexHint(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(IndexHints)[idx] = newNode.(*IndexHint) @@ -4115,6 +5253,9 @@ func (a *application) rewriteIndexHints(parent SQLNode, node IndexHints, replace return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4125,6 +5266,8 @@ func (a *application) rewriteIndexHints(parent SQLNode, node IndexHints, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIndexInfo(parent SQLNode, node *IndexInfo, replacer replacerFunc) bool { if node == nil { return true @@ -4142,16 +5285,26 @@ func (a *application) rewriteRefOfIndexInfo(parent SQLNode, node *IndexInfo, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfIndexInfoName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*IndexInfo).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfIndexInfoConstraintName)) + } if !a.rewriteIdentifierCI(node, node.ConstraintName, func(newNode, parent SQLNode) { parent.(*IndexInfo).ConstraintName = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4162,6 +5315,8 @@ func (a *application) rewriteRefOfIndexInfo(parent SQLNode, node *IndexInfo, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfInsert(parent SQLNode, node *Insert, replacer replacerFunc) bool { if node == nil { return true @@ -4179,41 +5334,71 @@ func (a *application) rewriteRefOfInsert(parent SQLNode, node *Insert, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfInsertComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*Insert).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertTable)) + } if !a.rewriteRefOfAliasedTableExpr(node, node.Table, func(newNode, parent SQLNode) { parent.(*Insert).Table = newNode.(*AliasedTableExpr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertPartitions)) + } if !a.rewritePartitions(node, node.Partitions, func(newNode, parent SQLNode) { parent.(*Insert).Partitions = newNode.(Partitions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertColumns)) + } if !a.rewriteColumns(node, node.Columns, func(newNode, parent SQLNode) { parent.(*Insert).Columns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertRows)) + } if !a.rewriteInsertRows(node, node.Rows, func(newNode, parent SQLNode) { parent.(*Insert).Rows = newNode.(InsertRows) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertRowAlias)) + } if !a.rewriteRefOfRowAlias(node, node.RowAlias, func(newNode, parent SQLNode) { parent.(*Insert).RowAlias = newNode.(*RowAlias) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertOnDup)) + } if !a.rewriteOnDup(node, node.OnDup, func(newNode, parent SQLNode) { parent.(*Insert).OnDup = newNode.(OnDup) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4224,6 +5409,8 @@ func (a *application) rewriteRefOfInsert(parent SQLNode, node *Insert, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfInsertExpr(parent SQLNode, node *InsertExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4241,26 +5428,44 @@ func (a *application) rewriteRefOfInsertExpr(parent SQLNode, node *InsertExpr, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfInsertExprStr)) + } if !a.rewriteExpr(node, node.Str, func(newNode, parent SQLNode) { parent.(*InsertExpr).Str = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertExprPos)) + } if !a.rewriteExpr(node, node.Pos, func(newNode, parent SQLNode) { parent.(*InsertExpr).Pos = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertExprLen)) + } if !a.rewriteExpr(node, node.Len, func(newNode, parent SQLNode) { parent.(*InsertExpr).Len = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfInsertExprNewStr)) + } if !a.rewriteExpr(node, node.NewStr, func(newNode, parent SQLNode) { parent.(*InsertExpr).NewStr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4271,6 +5476,8 @@ func (a *application) rewriteRefOfInsertExpr(parent SQLNode, node *InsertExpr, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIntervalDateExpr(parent SQLNode, node *IntervalDateExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4288,16 +5495,26 @@ func (a *application) rewriteRefOfIntervalDateExpr(parent SQLNode, node *Interva return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfIntervalDateExprDate)) + } if !a.rewriteExpr(node, node.Date, func(newNode, parent SQLNode) { parent.(*IntervalDateExpr).Date = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfIntervalDateExprInterval)) + } if !a.rewriteExpr(node, node.Interval, func(newNode, parent SQLNode) { parent.(*IntervalDateExpr).Interval = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4308,6 +5525,8 @@ func (a *application) rewriteRefOfIntervalDateExpr(parent SQLNode, node *Interva } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIntervalFuncExpr(parent SQLNode, node *IntervalFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4325,12 +5544,25 @@ func (a *application) rewriteRefOfIntervalFuncExpr(parent SQLNode, node *Interva return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfIntervalFuncExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*IntervalFuncExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfIntervalFuncExprExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*IntervalFuncExpr).Exprs[idx] = newNode.(Expr) @@ -4339,6 +5571,9 @@ func (a *application) rewriteRefOfIntervalFuncExpr(parent SQLNode, node *Interva return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4349,6 +5584,8 @@ func (a *application) rewriteRefOfIntervalFuncExpr(parent SQLNode, node *Interva } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIntroducerExpr(parent SQLNode, node *IntroducerExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4366,11 +5603,17 @@ func (a *application) rewriteRefOfIntroducerExpr(parent SQLNode, node *Introduce return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfIntroducerExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*IntroducerExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4381,6 +5624,8 @@ func (a *application) rewriteRefOfIntroducerExpr(parent SQLNode, node *Introduce } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIsExpr(parent SQLNode, node *IsExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4398,11 +5643,17 @@ func (a *application) rewriteRefOfIsExpr(parent SQLNode, node *IsExpr, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfIsExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*IsExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4413,6 +5664,8 @@ func (a *application) rewriteRefOfIsExpr(parent SQLNode, node *IsExpr, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONArrayAgg(parent SQLNode, node *JSONArrayAgg, replacer replacerFunc) bool { if node == nil { return true @@ -4430,16 +5683,26 @@ func (a *application) rewriteRefOfJSONArrayAgg(parent SQLNode, node *JSONArrayAg return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONArrayAggExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*JSONArrayAgg).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONArrayAggOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*JSONArrayAgg).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4450,6 +5713,8 @@ func (a *application) rewriteRefOfJSONArrayAgg(parent SQLNode, node *JSONArrayAg } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONArrayExpr(parent SQLNode, node *JSONArrayExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4468,6 +5733,13 @@ func (a *application) rewriteRefOfJSONArrayExpr(parent SQLNode, node *JSONArrayE } } for x, el := range node.Params { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONArrayExprParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONArrayExpr).Params[idx] = newNode.(Expr) @@ -4476,6 +5748,9 @@ func (a *application) rewriteRefOfJSONArrayExpr(parent SQLNode, node *JSONArrayE return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4486,6 +5761,8 @@ func (a *application) rewriteRefOfJSONArrayExpr(parent SQLNode, node *JSONArrayE } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONAttributesExpr(parent SQLNode, node *JSONAttributesExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4503,16 +5780,26 @@ func (a *application) rewriteRefOfJSONAttributesExpr(parent SQLNode, node *JSONA return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONAttributesExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONAttributesExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONAttributesExprPath)) + } if !a.rewriteExpr(node, node.Path, func(newNode, parent SQLNode) { parent.(*JSONAttributesExpr).Path = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4523,6 +5810,8 @@ func (a *application) rewriteRefOfJSONAttributesExpr(parent SQLNode, node *JSONA } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONContainsExpr(parent SQLNode, node *JSONContainsExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4540,17 +5829,34 @@ func (a *application) rewriteRefOfJSONContainsExpr(parent SQLNode, node *JSONCon return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONContainsExprTarget)) + } if !a.rewriteExpr(node, node.Target, func(newNode, parent SQLNode) { parent.(*JSONContainsExpr).Target = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONContainsExprCandidate)) + } if !a.rewriteExpr(node, node.Candidate, func(newNode, parent SQLNode) { parent.(*JSONContainsExpr).Candidate = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.PathList { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONContainsExprPathListOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONContainsExpr).PathList[idx] = newNode.(Expr) @@ -4559,6 +5865,9 @@ func (a *application) rewriteRefOfJSONContainsExpr(parent SQLNode, node *JSONCon return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4569,6 +5878,8 @@ func (a *application) rewriteRefOfJSONContainsExpr(parent SQLNode, node *JSONCon } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONContainsPathExpr(parent SQLNode, node *JSONContainsPathExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4586,17 +5897,34 @@ func (a *application) rewriteRefOfJSONContainsPathExpr(parent SQLNode, node *JSO return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONContainsPathExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONContainsPathExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONContainsPathExprOneOrAll)) + } if !a.rewriteExpr(node, node.OneOrAll, func(newNode, parent SQLNode) { parent.(*JSONContainsPathExpr).OneOrAll = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.PathList { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONContainsPathExprPathListOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONContainsPathExpr).PathList[idx] = newNode.(Expr) @@ -4605,6 +5933,9 @@ func (a *application) rewriteRefOfJSONContainsPathExpr(parent SQLNode, node *JSO return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4615,6 +5946,8 @@ func (a *application) rewriteRefOfJSONContainsPathExpr(parent SQLNode, node *JSO } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONExtractExpr(parent SQLNode, node *JSONExtractExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4632,12 +5965,25 @@ func (a *application) rewriteRefOfJSONExtractExpr(parent SQLNode, node *JSONExtr return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONExtractExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONExtractExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.PathList { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONExtractExprPathListOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONExtractExpr).PathList[idx] = newNode.(Expr) @@ -4646,6 +5992,9 @@ func (a *application) rewriteRefOfJSONExtractExpr(parent SQLNode, node *JSONExtr return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4656,6 +6005,8 @@ func (a *application) rewriteRefOfJSONExtractExpr(parent SQLNode, node *JSONExtr } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONKeysExpr(parent SQLNode, node *JSONKeysExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4673,16 +6024,26 @@ func (a *application) rewriteRefOfJSONKeysExpr(parent SQLNode, node *JSONKeysExp return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONKeysExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONKeysExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONKeysExprPath)) + } if !a.rewriteExpr(node, node.Path, func(newNode, parent SQLNode) { parent.(*JSONKeysExpr).Path = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4693,6 +6054,8 @@ func (a *application) rewriteRefOfJSONKeysExpr(parent SQLNode, node *JSONKeysExp } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONObjectAgg(parent SQLNode, node *JSONObjectAgg, replacer replacerFunc) bool { if node == nil { return true @@ -4710,21 +6073,35 @@ func (a *application) rewriteRefOfJSONObjectAgg(parent SQLNode, node *JSONObject return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONObjectAggKey)) + } if !a.rewriteExpr(node, node.Key, func(newNode, parent SQLNode) { parent.(*JSONObjectAgg).Key = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONObjectAggValue)) + } if !a.rewriteExpr(node, node.Value, func(newNode, parent SQLNode) { parent.(*JSONObjectAgg).Value = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONObjectAggOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*JSONObjectAgg).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4735,6 +6112,8 @@ func (a *application) rewriteRefOfJSONObjectAgg(parent SQLNode, node *JSONObject } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONObjectExpr(parent SQLNode, node *JSONObjectExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4753,6 +6132,13 @@ func (a *application) rewriteRefOfJSONObjectExpr(parent SQLNode, node *JSONObjec } } for x, el := range node.Params { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONObjectExprParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfJSONObjectParam(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONObjectExpr).Params[idx] = newNode.(*JSONObjectParam) @@ -4761,6 +6147,9 @@ func (a *application) rewriteRefOfJSONObjectExpr(parent SQLNode, node *JSONObjec return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4771,6 +6160,8 @@ func (a *application) rewriteRefOfJSONObjectExpr(parent SQLNode, node *JSONObjec } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONObjectParam(parent SQLNode, node *JSONObjectParam, replacer replacerFunc) bool { if node == nil { return true @@ -4788,16 +6179,26 @@ func (a *application) rewriteRefOfJSONObjectParam(parent SQLNode, node *JSONObje return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONObjectParamKey)) + } if !a.rewriteExpr(node, node.Key, func(newNode, parent SQLNode) { parent.(*JSONObjectParam).Key = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONObjectParamValue)) + } if !a.rewriteExpr(node, node.Value, func(newNode, parent SQLNode) { parent.(*JSONObjectParam).Value = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4808,6 +6209,8 @@ func (a *application) rewriteRefOfJSONObjectParam(parent SQLNode, node *JSONObje } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONOverlapsExpr(parent SQLNode, node *JSONOverlapsExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4825,16 +6228,26 @@ func (a *application) rewriteRefOfJSONOverlapsExpr(parent SQLNode, node *JSONOve return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONOverlapsExprJSONDoc1)) + } if !a.rewriteExpr(node, node.JSONDoc1, func(newNode, parent SQLNode) { parent.(*JSONOverlapsExpr).JSONDoc1 = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONOverlapsExprJSONDoc2)) + } if !a.rewriteExpr(node, node.JSONDoc2, func(newNode, parent SQLNode) { parent.(*JSONOverlapsExpr).JSONDoc2 = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4845,6 +6258,8 @@ func (a *application) rewriteRefOfJSONOverlapsExpr(parent SQLNode, node *JSONOve } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONPrettyExpr(parent SQLNode, node *JSONPrettyExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4862,11 +6277,17 @@ func (a *application) rewriteRefOfJSONPrettyExpr(parent SQLNode, node *JSONPrett return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONPrettyExprJSONVal)) + } if !a.rewriteExpr(node, node.JSONVal, func(newNode, parent SQLNode) { parent.(*JSONPrettyExpr).JSONVal = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4877,6 +6298,8 @@ func (a *application) rewriteRefOfJSONPrettyExpr(parent SQLNode, node *JSONPrett } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONQuoteExpr(parent SQLNode, node *JSONQuoteExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4894,11 +6317,17 @@ func (a *application) rewriteRefOfJSONQuoteExpr(parent SQLNode, node *JSONQuoteE return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONQuoteExprStringArg)) + } if !a.rewriteExpr(node, node.StringArg, func(newNode, parent SQLNode) { parent.(*JSONQuoteExpr).StringArg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4909,6 +6338,8 @@ func (a *application) rewriteRefOfJSONQuoteExpr(parent SQLNode, node *JSONQuoteE } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONRemoveExpr(parent SQLNode, node *JSONRemoveExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4926,12 +6357,25 @@ func (a *application) rewriteRefOfJSONRemoveExpr(parent SQLNode, node *JSONRemov return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONRemoveExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONRemoveExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.PathList { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONRemoveExprPathListOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONRemoveExpr).PathList[idx] = newNode.(Expr) @@ -4940,6 +6384,9 @@ func (a *application) rewriteRefOfJSONRemoveExpr(parent SQLNode, node *JSONRemov return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4950,6 +6397,8 @@ func (a *application) rewriteRefOfJSONRemoveExpr(parent SQLNode, node *JSONRemov } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONSchemaValidFuncExpr(parent SQLNode, node *JSONSchemaValidFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -4967,16 +6416,26 @@ func (a *application) rewriteRefOfJSONSchemaValidFuncExpr(parent SQLNode, node * return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONSchemaValidFuncExprSchema)) + } if !a.rewriteExpr(node, node.Schema, func(newNode, parent SQLNode) { parent.(*JSONSchemaValidFuncExpr).Schema = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONSchemaValidFuncExprDocument)) + } if !a.rewriteExpr(node, node.Document, func(newNode, parent SQLNode) { parent.(*JSONSchemaValidFuncExpr).Document = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -4987,6 +6446,8 @@ func (a *application) rewriteRefOfJSONSchemaValidFuncExpr(parent SQLNode, node * } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONSchemaValidationReportFuncExpr(parent SQLNode, node *JSONSchemaValidationReportFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5004,16 +6465,26 @@ func (a *application) rewriteRefOfJSONSchemaValidationReportFuncExpr(parent SQLN return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONSchemaValidationReportFuncExprSchema)) + } if !a.rewriteExpr(node, node.Schema, func(newNode, parent SQLNode) { parent.(*JSONSchemaValidationReportFuncExpr).Schema = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONSchemaValidationReportFuncExprDocument)) + } if !a.rewriteExpr(node, node.Document, func(newNode, parent SQLNode) { parent.(*JSONSchemaValidationReportFuncExpr).Document = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5024,6 +6495,8 @@ func (a *application) rewriteRefOfJSONSchemaValidationReportFuncExpr(parent SQLN } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONSearchExpr(parent SQLNode, node *JSONSearchExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5041,27 +6514,52 @@ func (a *application) rewriteRefOfJSONSearchExpr(parent SQLNode, node *JSONSearc return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONSearchExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONSearchExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONSearchExprOneOrAll)) + } if !a.rewriteExpr(node, node.OneOrAll, func(newNode, parent SQLNode) { parent.(*JSONSearchExpr).OneOrAll = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONSearchExprSearchStr)) + } if !a.rewriteExpr(node, node.SearchStr, func(newNode, parent SQLNode) { parent.(*JSONSearchExpr).SearchStr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONSearchExprEscapeChar)) + } if !a.rewriteExpr(node, node.EscapeChar, func(newNode, parent SQLNode) { parent.(*JSONSearchExpr).EscapeChar = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.PathList { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONSearchExprPathListOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONSearchExpr).PathList[idx] = newNode.(Expr) @@ -5070,6 +6568,9 @@ func (a *application) rewriteRefOfJSONSearchExpr(parent SQLNode, node *JSONSearc return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5080,6 +6581,8 @@ func (a *application) rewriteRefOfJSONSearchExpr(parent SQLNode, node *JSONSearc } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONStorageFreeExpr(parent SQLNode, node *JSONStorageFreeExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5097,11 +6600,17 @@ func (a *application) rewriteRefOfJSONStorageFreeExpr(parent SQLNode, node *JSON return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONStorageFreeExprJSONVal)) + } if !a.rewriteExpr(node, node.JSONVal, func(newNode, parent SQLNode) { parent.(*JSONStorageFreeExpr).JSONVal = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5112,6 +6621,8 @@ func (a *application) rewriteRefOfJSONStorageFreeExpr(parent SQLNode, node *JSON } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONStorageSizeExpr(parent SQLNode, node *JSONStorageSizeExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5129,11 +6640,17 @@ func (a *application) rewriteRefOfJSONStorageSizeExpr(parent SQLNode, node *JSON return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONStorageSizeExprJSONVal)) + } if !a.rewriteExpr(node, node.JSONVal, func(newNode, parent SQLNode) { parent.(*JSONStorageSizeExpr).JSONVal = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5144,6 +6661,8 @@ func (a *application) rewriteRefOfJSONStorageSizeExpr(parent SQLNode, node *JSON } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONTableExpr(parent SQLNode, node *JSONTableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5161,22 +6680,43 @@ func (a *application) rewriteRefOfJSONTableExpr(parent SQLNode, node *JSONTableE return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONTableExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*JSONTableExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONTableExprAlias)) + } if !a.rewriteIdentifierCS(node, node.Alias, func(newNode, parent SQLNode) { parent.(*JSONTableExpr).Alias = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONTableExprFilter)) + } if !a.rewriteExpr(node, node.Filter, func(newNode, parent SQLNode) { parent.(*JSONTableExpr).Filter = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Columns { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONTableExprColumnsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfJtColumnDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONTableExpr).Columns[idx] = newNode.(*JtColumnDefinition) @@ -5185,6 +6725,9 @@ func (a *application) rewriteRefOfJSONTableExpr(parent SQLNode, node *JSONTableE return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5195,6 +6738,8 @@ func (a *application) rewriteRefOfJSONTableExpr(parent SQLNode, node *JSONTableE } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONUnquoteExpr(parent SQLNode, node *JSONUnquoteExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5212,11 +6757,17 @@ func (a *application) rewriteRefOfJSONUnquoteExpr(parent SQLNode, node *JSONUnqu return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONUnquoteExprJSONValue)) + } if !a.rewriteExpr(node, node.JSONValue, func(newNode, parent SQLNode) { parent.(*JSONUnquoteExpr).JSONValue = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5227,6 +6778,8 @@ func (a *application) rewriteRefOfJSONUnquoteExpr(parent SQLNode, node *JSONUnqu } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONValueExpr(parent SQLNode, node *JSONValueExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5244,31 +6797,53 @@ func (a *application) rewriteRefOfJSONValueExpr(parent SQLNode, node *JSONValueE return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONValueExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONValueExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONValueExprPath)) + } if !a.rewriteExpr(node, node.Path, func(newNode, parent SQLNode) { parent.(*JSONValueExpr).Path = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONValueExprReturningType)) + } if !a.rewriteRefOfConvertType(node, node.ReturningType, func(newNode, parent SQLNode) { parent.(*JSONValueExpr).ReturningType = newNode.(*ConvertType) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONValueExprEmptyOnResponse)) + } if !a.rewriteRefOfJtOnResponse(node, node.EmptyOnResponse, func(newNode, parent SQLNode) { parent.(*JSONValueExpr).EmptyOnResponse = newNode.(*JtOnResponse) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJSONValueExprErrorOnResponse)) + } if !a.rewriteRefOfJtOnResponse(node, node.ErrorOnResponse, func(newNode, parent SQLNode) { parent.(*JSONValueExpr).ErrorOnResponse = newNode.(*JtOnResponse) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5279,6 +6854,8 @@ func (a *application) rewriteRefOfJSONValueExpr(parent SQLNode, node *JSONValueE } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONValueMergeExpr(parent SQLNode, node *JSONValueMergeExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5296,12 +6873,25 @@ func (a *application) rewriteRefOfJSONValueMergeExpr(parent SQLNode, node *JSONV return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONValueMergeExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONValueMergeExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.JSONDocList { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONValueMergeExprJSONDocListOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONValueMergeExpr).JSONDocList[idx] = newNode.(Expr) @@ -5310,6 +6900,9 @@ func (a *application) rewriteRefOfJSONValueMergeExpr(parent SQLNode, node *JSONV return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5320,6 +6913,8 @@ func (a *application) rewriteRefOfJSONValueMergeExpr(parent SQLNode, node *JSONV } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJSONValueModifierExpr(parent SQLNode, node *JSONValueModifierExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5337,12 +6932,25 @@ func (a *application) rewriteRefOfJSONValueModifierExpr(parent SQLNode, node *JS return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJSONValueModifierExprJSONDoc)) + } if !a.rewriteExpr(node, node.JSONDoc, func(newNode, parent SQLNode) { parent.(*JSONValueModifierExpr).JSONDoc = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Params { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfJSONValueModifierExprParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfJSONObjectParam(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*JSONValueModifierExpr).Params[idx] = newNode.(*JSONObjectParam) @@ -5351,6 +6959,9 @@ func (a *application) rewriteRefOfJSONValueModifierExpr(parent SQLNode, node *JS return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5361,6 +6972,8 @@ func (a *application) rewriteRefOfJSONValueModifierExpr(parent SQLNode, node *JS } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJoinCondition(parent SQLNode, node *JoinCondition, replacer replacerFunc) bool { if node == nil { return true @@ -5378,16 +6991,26 @@ func (a *application) rewriteRefOfJoinCondition(parent SQLNode, node *JoinCondit return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJoinConditionOn)) + } if !a.rewriteExpr(node, node.On, func(newNode, parent SQLNode) { parent.(*JoinCondition).On = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJoinConditionUsing)) + } if !a.rewriteColumns(node, node.Using, func(newNode, parent SQLNode) { parent.(*JoinCondition).Using = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5398,6 +7021,8 @@ func (a *application) rewriteRefOfJoinCondition(parent SQLNode, node *JoinCondit } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJoinTableExpr(parent SQLNode, node *JoinTableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5415,21 +7040,35 @@ func (a *application) rewriteRefOfJoinTableExpr(parent SQLNode, node *JoinTableE return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJoinTableExprLeftExpr)) + } if !a.rewriteTableExpr(node, node.LeftExpr, func(newNode, parent SQLNode) { parent.(*JoinTableExpr).LeftExpr = newNode.(TableExpr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJoinTableExprRightExpr)) + } if !a.rewriteTableExpr(node, node.RightExpr, func(newNode, parent SQLNode) { parent.(*JoinTableExpr).RightExpr = newNode.(TableExpr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfJoinTableExprCondition)) + } if !a.rewriteRefOfJoinCondition(node, node.Condition, func(newNode, parent SQLNode) { parent.(*JoinTableExpr).Condition = newNode.(*JoinCondition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5440,6 +7079,8 @@ func (a *application) rewriteRefOfJoinTableExpr(parent SQLNode, node *JoinTableE } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJtColumnDefinition(parent SQLNode, node *JtColumnDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -5469,6 +7110,8 @@ func (a *application) rewriteRefOfJtColumnDefinition(parent SQLNode, node *JtCol } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfJtOnResponse(parent SQLNode, node *JtOnResponse, replacer replacerFunc) bool { if node == nil { return true @@ -5486,11 +7129,17 @@ func (a *application) rewriteRefOfJtOnResponse(parent SQLNode, node *JtOnRespons return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfJtOnResponseExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*JtOnResponse).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5501,6 +7150,8 @@ func (a *application) rewriteRefOfJtOnResponse(parent SQLNode, node *JtOnRespons } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfKeyState(parent SQLNode, node *KeyState, replacer replacerFunc) bool { if node == nil { return true @@ -5530,6 +7181,8 @@ func (a *application) rewriteRefOfKeyState(parent SQLNode, node *KeyState, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfKill(parent SQLNode, node *Kill, replacer replacerFunc) bool { if node == nil { return true @@ -5559,6 +7212,8 @@ func (a *application) rewriteRefOfKill(parent SQLNode, node *Kill, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLagLeadExpr(parent SQLNode, node *LagLeadExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5576,31 +7231,53 @@ func (a *application) rewriteRefOfLagLeadExpr(parent SQLNode, node *LagLeadExpr, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfLagLeadExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*LagLeadExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLagLeadExprN)) + } if !a.rewriteExpr(node, node.N, func(newNode, parent SQLNode) { parent.(*LagLeadExpr).N = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLagLeadExprDefault)) + } if !a.rewriteExpr(node, node.Default, func(newNode, parent SQLNode) { parent.(*LagLeadExpr).Default = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLagLeadExprOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*LagLeadExpr).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLagLeadExprNullTreatmentClause)) + } if !a.rewriteRefOfNullTreatmentClause(node, node.NullTreatmentClause, func(newNode, parent SQLNode) { parent.(*LagLeadExpr).NullTreatmentClause = newNode.(*NullTreatmentClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5611,6 +7288,8 @@ func (a *application) rewriteRefOfLagLeadExpr(parent SQLNode, node *LagLeadExpr, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLimit(parent SQLNode, node *Limit, replacer replacerFunc) bool { if node == nil { return true @@ -5628,16 +7307,26 @@ func (a *application) rewriteRefOfLimit(parent SQLNode, node *Limit, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfLimitOffset)) + } if !a.rewriteExpr(node, node.Offset, func(newNode, parent SQLNode) { parent.(*Limit).Offset = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLimitRowcount)) + } if !a.rewriteExpr(node, node.Rowcount, func(newNode, parent SQLNode) { parent.(*Limit).Rowcount = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5648,6 +7337,8 @@ func (a *application) rewriteRefOfLimit(parent SQLNode, node *Limit, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLineStringExpr(parent SQLNode, node *LineStringExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5666,6 +7357,13 @@ func (a *application) rewriteRefOfLineStringExpr(parent SQLNode, node *LineStrin } } for x, el := range node.PointParams { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfLineStringExprPointParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*LineStringExpr).PointParams[idx] = newNode.(Expr) @@ -5674,6 +7372,9 @@ func (a *application) rewriteRefOfLineStringExpr(parent SQLNode, node *LineStrin return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5684,6 +7385,8 @@ func (a *application) rewriteRefOfLineStringExpr(parent SQLNode, node *LineStrin } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLinestrPropertyFuncExpr(parent SQLNode, node *LinestrPropertyFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5701,16 +7404,26 @@ func (a *application) rewriteRefOfLinestrPropertyFuncExpr(parent SQLNode, node * return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfLinestrPropertyFuncExprLinestring)) + } if !a.rewriteExpr(node, node.Linestring, func(newNode, parent SQLNode) { parent.(*LinestrPropertyFuncExpr).Linestring = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLinestrPropertyFuncExprPropertyDefArg)) + } if !a.rewriteExpr(node, node.PropertyDefArg, func(newNode, parent SQLNode) { parent.(*LinestrPropertyFuncExpr).PropertyDefArg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5721,6 +7434,8 @@ func (a *application) rewriteRefOfLinestrPropertyFuncExpr(parent SQLNode, node * } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLiteral(parent SQLNode, node *Literal, replacer replacerFunc) bool { if node == nil { return true @@ -5750,6 +7465,8 @@ func (a *application) rewriteRefOfLiteral(parent SQLNode, node *Literal, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLoad(parent SQLNode, node *Load, replacer replacerFunc) bool { if node == nil { return true @@ -5779,6 +7496,8 @@ func (a *application) rewriteRefOfLoad(parent SQLNode, node *Load, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLocateExpr(parent SQLNode, node *LocateExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5796,21 +7515,35 @@ func (a *application) rewriteRefOfLocateExpr(parent SQLNode, node *LocateExpr, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfLocateExprSubStr)) + } if !a.rewriteExpr(node, node.SubStr, func(newNode, parent SQLNode) { parent.(*LocateExpr).SubStr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLocateExprStr)) + } if !a.rewriteExpr(node, node.Str, func(newNode, parent SQLNode) { parent.(*LocateExpr).Str = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLocateExprPos)) + } if !a.rewriteExpr(node, node.Pos, func(newNode, parent SQLNode) { parent.(*LocateExpr).Pos = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5821,6 +7554,8 @@ func (a *application) rewriteRefOfLocateExpr(parent SQLNode, node *LocateExpr, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLockOption(parent SQLNode, node *LockOption, replacer replacerFunc) bool { if node == nil { return true @@ -5850,6 +7585,8 @@ func (a *application) rewriteRefOfLockOption(parent SQLNode, node *LockOption, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLockTables(parent SQLNode, node *LockTables, replacer replacerFunc) bool { if node == nil { return true @@ -5879,6 +7616,8 @@ func (a *application) rewriteRefOfLockTables(parent SQLNode, node *LockTables, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfLockingFunc(parent SQLNode, node *LockingFunc, replacer replacerFunc) bool { if node == nil { return true @@ -5896,16 +7635,26 @@ func (a *application) rewriteRefOfLockingFunc(parent SQLNode, node *LockingFunc, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfLockingFuncName)) + } if !a.rewriteExpr(node, node.Name, func(newNode, parent SQLNode) { parent.(*LockingFunc).Name = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfLockingFuncTimeout)) + } if !a.rewriteExpr(node, node.Timeout, func(newNode, parent SQLNode) { parent.(*LockingFunc).Timeout = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5916,6 +7665,8 @@ func (a *application) rewriteRefOfLockingFunc(parent SQLNode, node *LockingFunc, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMatchExpr(parent SQLNode, node *MatchExpr, replacer replacerFunc) bool { if node == nil { return true @@ -5934,6 +7685,13 @@ func (a *application) rewriteRefOfMatchExpr(parent SQLNode, node *MatchExpr, rep } } for x, el := range node.Columns { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfMatchExprColumnsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfColName(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*MatchExpr).Columns[idx] = newNode.(*ColName) @@ -5942,11 +7700,18 @@ func (a *application) rewriteRefOfMatchExpr(parent SQLNode, node *MatchExpr, rep return false } } + if a.collectPaths && len(node.Columns) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfMatchExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*MatchExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5957,6 +7722,8 @@ func (a *application) rewriteRefOfMatchExpr(parent SQLNode, node *MatchExpr, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMax(parent SQLNode, node *Max, replacer replacerFunc) bool { if node == nil { return true @@ -5974,16 +7741,26 @@ func (a *application) rewriteRefOfMax(parent SQLNode, node *Max, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfMaxArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*Max).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfMaxOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Max).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -5994,6 +7771,8 @@ func (a *application) rewriteRefOfMax(parent SQLNode, node *Max, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMemberOfExpr(parent SQLNode, node *MemberOfExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6011,16 +7790,26 @@ func (a *application) rewriteRefOfMemberOfExpr(parent SQLNode, node *MemberOfExp return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfMemberOfExprValue)) + } if !a.rewriteExpr(node, node.Value, func(newNode, parent SQLNode) { parent.(*MemberOfExpr).Value = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfMemberOfExprJSONArr)) + } if !a.rewriteExpr(node, node.JSONArr, func(newNode, parent SQLNode) { parent.(*MemberOfExpr).JSONArr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6031,6 +7820,8 @@ func (a *application) rewriteRefOfMemberOfExpr(parent SQLNode, node *MemberOfExp } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMin(parent SQLNode, node *Min, replacer replacerFunc) bool { if node == nil { return true @@ -6048,16 +7839,26 @@ func (a *application) rewriteRefOfMin(parent SQLNode, node *Min, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfMinArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*Min).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfMinOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Min).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6068,6 +7869,8 @@ func (a *application) rewriteRefOfMin(parent SQLNode, node *Min, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfModifyColumn(parent SQLNode, node *ModifyColumn, replacer replacerFunc) bool { if node == nil { return true @@ -6085,16 +7888,26 @@ func (a *application) rewriteRefOfModifyColumn(parent SQLNode, node *ModifyColum return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfModifyColumnNewColDefinition)) + } if !a.rewriteRefOfColumnDefinition(node, node.NewColDefinition, func(newNode, parent SQLNode) { parent.(*ModifyColumn).NewColDefinition = newNode.(*ColumnDefinition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfModifyColumnAfter)) + } if !a.rewriteRefOfColName(node, node.After, func(newNode, parent SQLNode) { parent.(*ModifyColumn).After = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6105,6 +7918,8 @@ func (a *application) rewriteRefOfModifyColumn(parent SQLNode, node *ModifyColum } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMultiLinestringExpr(parent SQLNode, node *MultiLinestringExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6123,6 +7938,13 @@ func (a *application) rewriteRefOfMultiLinestringExpr(parent SQLNode, node *Mult } } for x, el := range node.LinestringParams { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfMultiLinestringExprLinestringParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*MultiLinestringExpr).LinestringParams[idx] = newNode.(Expr) @@ -6131,6 +7953,9 @@ func (a *application) rewriteRefOfMultiLinestringExpr(parent SQLNode, node *Mult return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6141,6 +7966,8 @@ func (a *application) rewriteRefOfMultiLinestringExpr(parent SQLNode, node *Mult } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMultiPointExpr(parent SQLNode, node *MultiPointExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6159,6 +7986,13 @@ func (a *application) rewriteRefOfMultiPointExpr(parent SQLNode, node *MultiPoin } } for x, el := range node.PointParams { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfMultiPointExprPointParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*MultiPointExpr).PointParams[idx] = newNode.(Expr) @@ -6167,6 +8001,9 @@ func (a *application) rewriteRefOfMultiPointExpr(parent SQLNode, node *MultiPoin return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6177,6 +8014,8 @@ func (a *application) rewriteRefOfMultiPointExpr(parent SQLNode, node *MultiPoin } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfMultiPolygonExpr(parent SQLNode, node *MultiPolygonExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6195,6 +8034,13 @@ func (a *application) rewriteRefOfMultiPolygonExpr(parent SQLNode, node *MultiPo } } for x, el := range node.PolygonParams { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfMultiPolygonExprPolygonParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*MultiPolygonExpr).PolygonParams[idx] = newNode.(Expr) @@ -6203,6 +8049,9 @@ func (a *application) rewriteRefOfMultiPolygonExpr(parent SQLNode, node *MultiPo return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6213,6 +8062,8 @@ func (a *application) rewriteRefOfMultiPolygonExpr(parent SQLNode, node *MultiPo } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNTHValueExpr(parent SQLNode, node *NTHValueExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6230,31 +8081,53 @@ func (a *application) rewriteRefOfNTHValueExpr(parent SQLNode, node *NTHValueExp return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfNTHValueExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*NTHValueExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfNTHValueExprN)) + } if !a.rewriteExpr(node, node.N, func(newNode, parent SQLNode) { parent.(*NTHValueExpr).N = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfNTHValueExprOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*NTHValueExpr).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfNTHValueExprFromFirstLastClause)) + } if !a.rewriteRefOfFromFirstLastClause(node, node.FromFirstLastClause, func(newNode, parent SQLNode) { parent.(*NTHValueExpr).FromFirstLastClause = newNode.(*FromFirstLastClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfNTHValueExprNullTreatmentClause)) + } if !a.rewriteRefOfNullTreatmentClause(node, node.NullTreatmentClause, func(newNode, parent SQLNode) { parent.(*NTHValueExpr).NullTreatmentClause = newNode.(*NullTreatmentClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6265,6 +8138,8 @@ func (a *application) rewriteRefOfNTHValueExpr(parent SQLNode, node *NTHValueExp } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNamedWindow(parent SQLNode, node *NamedWindow, replacer replacerFunc) bool { if node == nil { return true @@ -6282,11 +8157,17 @@ func (a *application) rewriteRefOfNamedWindow(parent SQLNode, node *NamedWindow, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfNamedWindowWindows)) + } if !a.rewriteWindowDefinitions(node, node.Windows, func(newNode, parent SQLNode) { parent.(*NamedWindow).Windows = newNode.(WindowDefinitions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6297,6 +8178,8 @@ func (a *application) rewriteRefOfNamedWindow(parent SQLNode, node *NamedWindow, } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteNamedWindows(parent SQLNode, node NamedWindows, replacer replacerFunc) bool { if node == nil { return true @@ -6315,6 +8198,13 @@ func (a *application) rewriteNamedWindows(parent SQLNode, node NamedWindows, rep } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(NamedWindowsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfNamedWindow(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(NamedWindows)[idx] = newNode.(*NamedWindow) @@ -6323,6 +8213,9 @@ func (a *application) rewriteNamedWindows(parent SQLNode, node NamedWindows, rep return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6333,6 +8226,8 @@ func (a *application) rewriteNamedWindows(parent SQLNode, node NamedWindows, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNextval(parent SQLNode, node *Nextval, replacer replacerFunc) bool { if node == nil { return true @@ -6350,11 +8245,17 @@ func (a *application) rewriteRefOfNextval(parent SQLNode, node *Nextval, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfNextvalExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*Nextval).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6365,6 +8266,8 @@ func (a *application) rewriteRefOfNextval(parent SQLNode, node *Nextval, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNotExpr(parent SQLNode, node *NotExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6382,11 +8285,17 @@ func (a *application) rewriteRefOfNotExpr(parent SQLNode, node *NotExpr, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfNotExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*NotExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6397,6 +8306,8 @@ func (a *application) rewriteRefOfNotExpr(parent SQLNode, node *NotExpr, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNtileExpr(parent SQLNode, node *NtileExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6414,16 +8325,26 @@ func (a *application) rewriteRefOfNtileExpr(parent SQLNode, node *NtileExpr, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfNtileExprN)) + } if !a.rewriteExpr(node, node.N, func(newNode, parent SQLNode) { parent.(*NtileExpr).N = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfNtileExprOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*NtileExpr).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6434,6 +8355,8 @@ func (a *application) rewriteRefOfNtileExpr(parent SQLNode, node *NtileExpr, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNullTreatmentClause(parent SQLNode, node *NullTreatmentClause, replacer replacerFunc) bool { if node == nil { return true @@ -6463,6 +8386,8 @@ func (a *application) rewriteRefOfNullTreatmentClause(parent SQLNode, node *Null } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfNullVal(parent SQLNode, node *NullVal, replacer replacerFunc) bool { if node == nil { return true @@ -6492,6 +8417,8 @@ func (a *application) rewriteRefOfNullVal(parent SQLNode, node *NullVal, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOffset(parent SQLNode, node *Offset, replacer replacerFunc) bool { if node == nil { return true @@ -6509,11 +8436,17 @@ func (a *application) rewriteRefOfOffset(parent SQLNode, node *Offset, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfOffsetOriginal)) + } if !a.rewriteExpr(node, node.Original, func(newNode, parent SQLNode) { parent.(*Offset).Original = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6524,6 +8457,8 @@ func (a *application) rewriteRefOfOffset(parent SQLNode, node *Offset, replacer } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteOnDup(parent SQLNode, node OnDup, replacer replacerFunc) bool { if node == nil { return true @@ -6542,6 +8477,13 @@ func (a *application) rewriteOnDup(parent SQLNode, node OnDup, replacer replacer } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(OnDupOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfUpdateExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(OnDup)[idx] = newNode.(*UpdateExpr) @@ -6550,6 +8492,9 @@ func (a *application) rewriteOnDup(parent SQLNode, node OnDup, replacer replacer return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6560,6 +8505,8 @@ func (a *application) rewriteOnDup(parent SQLNode, node OnDup, replacer replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOptLike(parent SQLNode, node *OptLike, replacer replacerFunc) bool { if node == nil { return true @@ -6577,11 +8524,17 @@ func (a *application) rewriteRefOfOptLike(parent SQLNode, node *OptLike, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfOptLikeLikeTable)) + } if !a.rewriteTableName(node, node.LikeTable, func(newNode, parent SQLNode) { parent.(*OptLike).LikeTable = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6592,6 +8545,8 @@ func (a *application) rewriteRefOfOptLike(parent SQLNode, node *OptLike, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOrExpr(parent SQLNode, node *OrExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6609,16 +8564,26 @@ func (a *application) rewriteRefOfOrExpr(parent SQLNode, node *OrExpr, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfOrExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*OrExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfOrExprRight)) + } if !a.rewriteExpr(node, node.Right, func(newNode, parent SQLNode) { parent.(*OrExpr).Right = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6629,6 +8594,8 @@ func (a *application) rewriteRefOfOrExpr(parent SQLNode, node *OrExpr, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOrder(parent SQLNode, node *Order, replacer replacerFunc) bool { if node == nil { return true @@ -6646,11 +8613,17 @@ func (a *application) rewriteRefOfOrder(parent SQLNode, node *Order, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfOrderExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*Order).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6661,6 +8634,8 @@ func (a *application) rewriteRefOfOrder(parent SQLNode, node *Order, replacer re } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteOrderBy(parent SQLNode, node OrderBy, replacer replacerFunc) bool { if node == nil { return true @@ -6679,6 +8654,13 @@ func (a *application) rewriteOrderBy(parent SQLNode, node OrderBy, replacer repl } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(OrderByOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfOrder(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(OrderBy)[idx] = newNode.(*Order) @@ -6687,6 +8669,9 @@ func (a *application) rewriteOrderBy(parent SQLNode, node OrderBy, replacer repl return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6697,6 +8682,8 @@ func (a *application) rewriteOrderBy(parent SQLNode, node OrderBy, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOrderByOption(parent SQLNode, node *OrderByOption, replacer replacerFunc) bool { if node == nil { return true @@ -6714,11 +8701,17 @@ func (a *application) rewriteRefOfOrderByOption(parent SQLNode, node *OrderByOpt return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfOrderByOptionCols)) + } if !a.rewriteColumns(node, node.Cols, func(newNode, parent SQLNode) { parent.(*OrderByOption).Cols = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6729,6 +8722,8 @@ func (a *application) rewriteRefOfOrderByOption(parent SQLNode, node *OrderByOpt } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOtherAdmin(parent SQLNode, node *OtherAdmin, replacer replacerFunc) bool { if node == nil { return true @@ -6758,6 +8753,8 @@ func (a *application) rewriteRefOfOtherAdmin(parent SQLNode, node *OtherAdmin, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfOverClause(parent SQLNode, node *OverClause, replacer replacerFunc) bool { if node == nil { return true @@ -6775,16 +8772,26 @@ func (a *application) rewriteRefOfOverClause(parent SQLNode, node *OverClause, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfOverClauseWindowName)) + } if !a.rewriteIdentifierCI(node, node.WindowName, func(newNode, parent SQLNode) { parent.(*OverClause).WindowName = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfOverClauseWindowSpec)) + } if !a.rewriteRefOfWindowSpecification(node, node.WindowSpec, func(newNode, parent SQLNode) { parent.(*OverClause).WindowSpec = newNode.(*WindowSpecification) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6795,6 +8802,8 @@ func (a *application) rewriteRefOfOverClause(parent SQLNode, node *OverClause, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfParenTableExpr(parent SQLNode, node *ParenTableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -6812,11 +8821,17 @@ func (a *application) rewriteRefOfParenTableExpr(parent SQLNode, node *ParenTabl return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfParenTableExprExprs)) + } if !a.rewriteTableExprs(node, node.Exprs, func(newNode, parent SQLNode) { parent.(*ParenTableExpr).Exprs = newNode.(TableExprs) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6827,6 +8842,8 @@ func (a *application) rewriteRefOfParenTableExpr(parent SQLNode, node *ParenTabl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfParsedComments(parent SQLNode, node *ParsedComments, replacer replacerFunc) bool { if node == nil { return true @@ -6856,6 +8873,8 @@ func (a *application) rewriteRefOfParsedComments(parent SQLNode, node *ParsedCom } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPartitionDefinition(parent SQLNode, node *PartitionDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -6873,16 +8892,26 @@ func (a *application) rewriteRefOfPartitionDefinition(parent SQLNode, node *Part return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*PartitionDefinition).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptions)) + } if !a.rewriteRefOfPartitionDefinitionOptions(node, node.Options, func(newNode, parent SQLNode) { parent.(*PartitionDefinition).Options = newNode.(*PartitionDefinitionOptions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6893,6 +8922,8 @@ func (a *application) rewriteRefOfPartitionDefinition(parent SQLNode, node *Part } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPartitionDefinitionOptions(parent SQLNode, node *PartitionDefinitionOptions, replacer replacerFunc) bool { if node == nil { return true @@ -6910,36 +8941,62 @@ func (a *application) rewriteRefOfPartitionDefinitionOptions(parent SQLNode, nod return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptionsValueRange)) + } if !a.rewriteRefOfPartitionValueRange(node, node.ValueRange, func(newNode, parent SQLNode) { parent.(*PartitionDefinitionOptions).ValueRange = newNode.(*PartitionValueRange) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptionsComment)) + } if !a.rewriteRefOfLiteral(node, node.Comment, func(newNode, parent SQLNode) { parent.(*PartitionDefinitionOptions).Comment = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptionsEngine)) + } if !a.rewriteRefOfPartitionEngine(node, node.Engine, func(newNode, parent SQLNode) { parent.(*PartitionDefinitionOptions).Engine = newNode.(*PartitionEngine) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptionsDataDirectory)) + } if !a.rewriteRefOfLiteral(node, node.DataDirectory, func(newNode, parent SQLNode) { parent.(*PartitionDefinitionOptions).DataDirectory = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptionsIndexDirectory)) + } if !a.rewriteRefOfLiteral(node, node.IndexDirectory, func(newNode, parent SQLNode) { parent.(*PartitionDefinitionOptions).IndexDirectory = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionDefinitionOptionsSubPartitionDefinitions)) + } if !a.rewriteSubPartitionDefinitions(node, node.SubPartitionDefinitions, func(newNode, parent SQLNode) { parent.(*PartitionDefinitionOptions).SubPartitionDefinitions = newNode.(SubPartitionDefinitions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -6950,6 +9007,8 @@ func (a *application) rewriteRefOfPartitionDefinitionOptions(parent SQLNode, nod } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPartitionEngine(parent SQLNode, node *PartitionEngine, replacer replacerFunc) bool { if node == nil { return true @@ -6979,6 +9038,8 @@ func (a *application) rewriteRefOfPartitionEngine(parent SQLNode, node *Partitio } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPartitionOption(parent SQLNode, node *PartitionOption, replacer replacerFunc) bool { if node == nil { return true @@ -6996,22 +9057,43 @@ func (a *application) rewriteRefOfPartitionOption(parent SQLNode, node *Partitio return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPartitionOptionColList)) + } if !a.rewriteColumns(node, node.ColList, func(newNode, parent SQLNode) { parent.(*PartitionOption).ColList = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionOptionExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*PartitionOption).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionOptionSubPartition)) + } if !a.rewriteRefOfSubPartition(node, node.SubPartition, func(newNode, parent SQLNode) { parent.(*PartitionOption).SubPartition = newNode.(*SubPartition) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Definitions { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfPartitionOptionDefinitionsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfPartitionDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*PartitionOption).Definitions[idx] = newNode.(*PartitionDefinition) @@ -7020,6 +9102,9 @@ func (a *application) rewriteRefOfPartitionOption(parent SQLNode, node *Partitio return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7030,6 +9115,8 @@ func (a *application) rewriteRefOfPartitionOption(parent SQLNode, node *Partitio } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPartitionSpec(parent SQLNode, node *PartitionSpec, replacer replacerFunc) bool { if node == nil { return true @@ -7047,22 +9134,43 @@ func (a *application) rewriteRefOfPartitionSpec(parent SQLNode, node *PartitionS return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPartitionSpecNames)) + } if !a.rewritePartitions(node, node.Names, func(newNode, parent SQLNode) { parent.(*PartitionSpec).Names = newNode.(Partitions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionSpecNumber)) + } if !a.rewriteRefOfLiteral(node, node.Number, func(newNode, parent SQLNode) { parent.(*PartitionSpec).Number = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPartitionSpecTableName)) + } if !a.rewriteTableName(node, node.TableName, func(newNode, parent SQLNode) { parent.(*PartitionSpec).TableName = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Definitions { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfPartitionSpecDefinitionsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfPartitionDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*PartitionSpec).Definitions[idx] = newNode.(*PartitionDefinition) @@ -7071,6 +9179,9 @@ func (a *application) rewriteRefOfPartitionSpec(parent SQLNode, node *PartitionS return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7081,6 +9192,8 @@ func (a *application) rewriteRefOfPartitionSpec(parent SQLNode, node *PartitionS } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPartitionValueRange(parent SQLNode, node *PartitionValueRange, replacer replacerFunc) bool { if node == nil { return true @@ -7098,11 +9211,17 @@ func (a *application) rewriteRefOfPartitionValueRange(parent SQLNode, node *Part return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPartitionValueRangeRange)) + } if !a.rewriteValTuple(node, node.Range, func(newNode, parent SQLNode) { parent.(*PartitionValueRange).Range = newNode.(ValTuple) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7113,6 +9232,8 @@ func (a *application) rewriteRefOfPartitionValueRange(parent SQLNode, node *Part } return true } + +// Function Generation Source: SliceMethod func (a *application) rewritePartitions(parent SQLNode, node Partitions, replacer replacerFunc) bool { if node == nil { return true @@ -7131,6 +9252,13 @@ func (a *application) rewritePartitions(parent SQLNode, node Partitions, replace } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(PartitionsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteIdentifierCI(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(Partitions)[idx] = newNode.(IdentifierCI) @@ -7139,6 +9267,9 @@ func (a *application) rewritePartitions(parent SQLNode, node Partitions, replace return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7149,6 +9280,8 @@ func (a *application) rewritePartitions(parent SQLNode, node Partitions, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPerformanceSchemaFuncExpr(parent SQLNode, node *PerformanceSchemaFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7166,11 +9299,17 @@ func (a *application) rewriteRefOfPerformanceSchemaFuncExpr(parent SQLNode, node return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPerformanceSchemaFuncExprArgument)) + } if !a.rewriteExpr(node, node.Argument, func(newNode, parent SQLNode) { parent.(*PerformanceSchemaFuncExpr).Argument = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7181,6 +9320,8 @@ func (a *application) rewriteRefOfPerformanceSchemaFuncExpr(parent SQLNode, node } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPointExpr(parent SQLNode, node *PointExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7198,16 +9339,26 @@ func (a *application) rewriteRefOfPointExpr(parent SQLNode, node *PointExpr, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPointExprXCordinate)) + } if !a.rewriteExpr(node, node.XCordinate, func(newNode, parent SQLNode) { parent.(*PointExpr).XCordinate = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPointExprYCordinate)) + } if !a.rewriteExpr(node, node.YCordinate, func(newNode, parent SQLNode) { parent.(*PointExpr).YCordinate = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7218,6 +9369,8 @@ func (a *application) rewriteRefOfPointExpr(parent SQLNode, node *PointExpr, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPointPropertyFuncExpr(parent SQLNode, node *PointPropertyFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7235,16 +9388,26 @@ func (a *application) rewriteRefOfPointPropertyFuncExpr(parent SQLNode, node *Po return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPointPropertyFuncExprPoint)) + } if !a.rewriteExpr(node, node.Point, func(newNode, parent SQLNode) { parent.(*PointPropertyFuncExpr).Point = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPointPropertyFuncExprValueToSet)) + } if !a.rewriteExpr(node, node.ValueToSet, func(newNode, parent SQLNode) { parent.(*PointPropertyFuncExpr).ValueToSet = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7255,6 +9418,8 @@ func (a *application) rewriteRefOfPointPropertyFuncExpr(parent SQLNode, node *Po } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPolygonExpr(parent SQLNode, node *PolygonExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7273,6 +9438,13 @@ func (a *application) rewriteRefOfPolygonExpr(parent SQLNode, node *PolygonExpr, } } for x, el := range node.LinestringParams { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfPolygonExprLinestringParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*PolygonExpr).LinestringParams[idx] = newNode.(Expr) @@ -7281,6 +9453,9 @@ func (a *application) rewriteRefOfPolygonExpr(parent SQLNode, node *PolygonExpr, return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7291,6 +9466,8 @@ func (a *application) rewriteRefOfPolygonExpr(parent SQLNode, node *PolygonExpr, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPolygonPropertyFuncExpr(parent SQLNode, node *PolygonPropertyFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7308,16 +9485,26 @@ func (a *application) rewriteRefOfPolygonPropertyFuncExpr(parent SQLNode, node * return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPolygonPropertyFuncExprPolygon)) + } if !a.rewriteExpr(node, node.Polygon, func(newNode, parent SQLNode) { parent.(*PolygonPropertyFuncExpr).Polygon = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPolygonPropertyFuncExprPropertyDefArg)) + } if !a.rewriteExpr(node, node.PropertyDefArg, func(newNode, parent SQLNode) { parent.(*PolygonPropertyFuncExpr).PropertyDefArg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7328,6 +9515,8 @@ func (a *application) rewriteRefOfPolygonPropertyFuncExpr(parent SQLNode, node * } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPrepareStmt(parent SQLNode, node *PrepareStmt, replacer replacerFunc) bool { if node == nil { return true @@ -7345,21 +9534,35 @@ func (a *application) rewriteRefOfPrepareStmt(parent SQLNode, node *PrepareStmt, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfPrepareStmtName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*PrepareStmt).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPrepareStmtStatement)) + } if !a.rewriteExpr(node, node.Statement, func(newNode, parent SQLNode) { parent.(*PrepareStmt).Statement = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfPrepareStmtComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*PrepareStmt).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7370,6 +9573,8 @@ func (a *application) rewriteRefOfPrepareStmt(parent SQLNode, node *PrepareStmt, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfPurgeBinaryLogs(parent SQLNode, node *PurgeBinaryLogs, replacer replacerFunc) bool { if node == nil { return true @@ -7399,6 +9604,8 @@ func (a *application) rewriteRefOfPurgeBinaryLogs(parent SQLNode, node *PurgeBin } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfReferenceDefinition(parent SQLNode, node *ReferenceDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -7416,31 +9623,53 @@ func (a *application) rewriteRefOfReferenceDefinition(parent SQLNode, node *Refe return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfReferenceDefinitionReferencedTable)) + } if !a.rewriteTableName(node, node.ReferencedTable, func(newNode, parent SQLNode) { parent.(*ReferenceDefinition).ReferencedTable = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfReferenceDefinitionReferencedColumns)) + } if !a.rewriteColumns(node, node.ReferencedColumns, func(newNode, parent SQLNode) { parent.(*ReferenceDefinition).ReferencedColumns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfReferenceDefinitionMatch)) + } if !a.rewriteMatchAction(node, node.Match, func(newNode, parent SQLNode) { parent.(*ReferenceDefinition).Match = newNode.(MatchAction) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfReferenceDefinitionOnDelete)) + } if !a.rewriteReferenceAction(node, node.OnDelete, func(newNode, parent SQLNode) { parent.(*ReferenceDefinition).OnDelete = newNode.(ReferenceAction) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfReferenceDefinitionOnUpdate)) + } if !a.rewriteReferenceAction(node, node.OnUpdate, func(newNode, parent SQLNode) { parent.(*ReferenceDefinition).OnUpdate = newNode.(ReferenceAction) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7451,6 +9680,8 @@ func (a *application) rewriteRefOfReferenceDefinition(parent SQLNode, node *Refe } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRegexpInstrExpr(parent SQLNode, node *RegexpInstrExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7468,36 +9699,62 @@ func (a *application) rewriteRefOfRegexpInstrExpr(parent SQLNode, node *RegexpIn return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRegexpInstrExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*RegexpInstrExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpInstrExprPattern)) + } if !a.rewriteExpr(node, node.Pattern, func(newNode, parent SQLNode) { parent.(*RegexpInstrExpr).Pattern = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpInstrExprPosition)) + } if !a.rewriteExpr(node, node.Position, func(newNode, parent SQLNode) { parent.(*RegexpInstrExpr).Position = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpInstrExprOccurrence)) + } if !a.rewriteExpr(node, node.Occurrence, func(newNode, parent SQLNode) { parent.(*RegexpInstrExpr).Occurrence = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpInstrExprReturnOption)) + } if !a.rewriteExpr(node, node.ReturnOption, func(newNode, parent SQLNode) { parent.(*RegexpInstrExpr).ReturnOption = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpInstrExprMatchType)) + } if !a.rewriteExpr(node, node.MatchType, func(newNode, parent SQLNode) { parent.(*RegexpInstrExpr).MatchType = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7508,6 +9765,8 @@ func (a *application) rewriteRefOfRegexpInstrExpr(parent SQLNode, node *RegexpIn } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRegexpLikeExpr(parent SQLNode, node *RegexpLikeExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7525,21 +9784,35 @@ func (a *application) rewriteRefOfRegexpLikeExpr(parent SQLNode, node *RegexpLik return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRegexpLikeExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*RegexpLikeExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpLikeExprPattern)) + } if !a.rewriteExpr(node, node.Pattern, func(newNode, parent SQLNode) { parent.(*RegexpLikeExpr).Pattern = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpLikeExprMatchType)) + } if !a.rewriteExpr(node, node.MatchType, func(newNode, parent SQLNode) { parent.(*RegexpLikeExpr).MatchType = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7550,6 +9823,8 @@ func (a *application) rewriteRefOfRegexpLikeExpr(parent SQLNode, node *RegexpLik } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRegexpReplaceExpr(parent SQLNode, node *RegexpReplaceExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7567,36 +9842,62 @@ func (a *application) rewriteRefOfRegexpReplaceExpr(parent SQLNode, node *Regexp return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRegexpReplaceExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*RegexpReplaceExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpReplaceExprPattern)) + } if !a.rewriteExpr(node, node.Pattern, func(newNode, parent SQLNode) { parent.(*RegexpReplaceExpr).Pattern = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpReplaceExprRepl)) + } if !a.rewriteExpr(node, node.Repl, func(newNode, parent SQLNode) { parent.(*RegexpReplaceExpr).Repl = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpReplaceExprOccurrence)) + } if !a.rewriteExpr(node, node.Occurrence, func(newNode, parent SQLNode) { parent.(*RegexpReplaceExpr).Occurrence = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpReplaceExprPosition)) + } if !a.rewriteExpr(node, node.Position, func(newNode, parent SQLNode) { parent.(*RegexpReplaceExpr).Position = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpReplaceExprMatchType)) + } if !a.rewriteExpr(node, node.MatchType, func(newNode, parent SQLNode) { parent.(*RegexpReplaceExpr).MatchType = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7607,6 +9908,8 @@ func (a *application) rewriteRefOfRegexpReplaceExpr(parent SQLNode, node *Regexp } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRegexpSubstrExpr(parent SQLNode, node *RegexpSubstrExpr, replacer replacerFunc) bool { if node == nil { return true @@ -7624,31 +9927,53 @@ func (a *application) rewriteRefOfRegexpSubstrExpr(parent SQLNode, node *RegexpS return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRegexpSubstrExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*RegexpSubstrExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpSubstrExprPattern)) + } if !a.rewriteExpr(node, node.Pattern, func(newNode, parent SQLNode) { parent.(*RegexpSubstrExpr).Pattern = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpSubstrExprOccurrence)) + } if !a.rewriteExpr(node, node.Occurrence, func(newNode, parent SQLNode) { parent.(*RegexpSubstrExpr).Occurrence = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpSubstrExprPosition)) + } if !a.rewriteExpr(node, node.Position, func(newNode, parent SQLNode) { parent.(*RegexpSubstrExpr).Position = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRegexpSubstrExprMatchType)) + } if !a.rewriteExpr(node, node.MatchType, func(newNode, parent SQLNode) { parent.(*RegexpSubstrExpr).MatchType = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7659,6 +9984,8 @@ func (a *application) rewriteRefOfRegexpSubstrExpr(parent SQLNode, node *RegexpS } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRelease(parent SQLNode, node *Release, replacer replacerFunc) bool { if node == nil { return true @@ -7676,11 +10003,17 @@ func (a *application) rewriteRefOfRelease(parent SQLNode, node *Release, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfReleaseName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*Release).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7691,6 +10024,8 @@ func (a *application) rewriteRefOfRelease(parent SQLNode, node *Release, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRenameColumn(parent SQLNode, node *RenameColumn, replacer replacerFunc) bool { if node == nil { return true @@ -7708,16 +10043,26 @@ func (a *application) rewriteRefOfRenameColumn(parent SQLNode, node *RenameColum return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRenameColumnOldName)) + } if !a.rewriteRefOfColName(node, node.OldName, func(newNode, parent SQLNode) { parent.(*RenameColumn).OldName = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRenameColumnNewName)) + } if !a.rewriteRefOfColName(node, node.NewName, func(newNode, parent SQLNode) { parent.(*RenameColumn).NewName = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7728,6 +10073,8 @@ func (a *application) rewriteRefOfRenameColumn(parent SQLNode, node *RenameColum } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRenameIndex(parent SQLNode, node *RenameIndex, replacer replacerFunc) bool { if node == nil { return true @@ -7745,16 +10092,26 @@ func (a *application) rewriteRefOfRenameIndex(parent SQLNode, node *RenameIndex, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRenameIndexOldName)) + } if !a.rewriteIdentifierCI(node, node.OldName, func(newNode, parent SQLNode) { parent.(*RenameIndex).OldName = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRenameIndexNewName)) + } if !a.rewriteIdentifierCI(node, node.NewName, func(newNode, parent SQLNode) { parent.(*RenameIndex).NewName = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7765,6 +10122,8 @@ func (a *application) rewriteRefOfRenameIndex(parent SQLNode, node *RenameIndex, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRenameTable(parent SQLNode, node *RenameTable, replacer replacerFunc) bool { if node == nil { return true @@ -7794,6 +10153,8 @@ func (a *application) rewriteRefOfRenameTable(parent SQLNode, node *RenameTable, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRenameTableName(parent SQLNode, node *RenameTableName, replacer replacerFunc) bool { if node == nil { return true @@ -7811,11 +10172,17 @@ func (a *application) rewriteRefOfRenameTableName(parent SQLNode, node *RenameTa return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRenameTableNameTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*RenameTableName).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7826,6 +10193,8 @@ func (a *application) rewriteRefOfRenameTableName(parent SQLNode, node *RenameTa } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRevertMigration(parent SQLNode, node *RevertMigration, replacer replacerFunc) bool { if node == nil { return true @@ -7843,11 +10212,17 @@ func (a *application) rewriteRefOfRevertMigration(parent SQLNode, node *RevertMi return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRevertMigrationComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*RevertMigration).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7858,6 +10233,8 @@ func (a *application) rewriteRefOfRevertMigration(parent SQLNode, node *RevertMi } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRollback(parent SQLNode, node *Rollback, replacer replacerFunc) bool { if node == nil { return true @@ -7887,6 +10264,8 @@ func (a *application) rewriteRefOfRollback(parent SQLNode, node *Rollback, repla } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteRootNode(parent SQLNode, node RootNode, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -7901,11 +10280,17 @@ func (a *application) rewriteRootNode(parent SQLNode, node RootNode, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RootNodeSQLNode)) + } if !a.rewriteSQLNode(node, node.SQLNode, func(newNode, parent SQLNode) { panic("[BUG] tried to replace 'SQLNode' on 'RootNode'") }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7916,6 +10301,8 @@ func (a *application) rewriteRootNode(parent SQLNode, node RootNode, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRowAlias(parent SQLNode, node *RowAlias, replacer replacerFunc) bool { if node == nil { return true @@ -7933,16 +10320,26 @@ func (a *application) rewriteRefOfRowAlias(parent SQLNode, node *RowAlias, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRowAliasTableName)) + } if !a.rewriteIdentifierCS(node, node.TableName, func(newNode, parent SQLNode) { parent.(*RowAlias).TableName = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfRowAliasColumns)) + } if !a.rewriteColumns(node, node.Columns, func(newNode, parent SQLNode) { parent.(*RowAlias).Columns = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7953,6 +10350,8 @@ func (a *application) rewriteRefOfRowAlias(parent SQLNode, node *RowAlias, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSRollback(parent SQLNode, node *SRollback, replacer replacerFunc) bool { if node == nil { return true @@ -7970,11 +10369,17 @@ func (a *application) rewriteRefOfSRollback(parent SQLNode, node *SRollback, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSRollbackName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*SRollback).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -7985,6 +10390,8 @@ func (a *application) rewriteRefOfSRollback(parent SQLNode, node *SRollback, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSavepoint(parent SQLNode, node *Savepoint, replacer replacerFunc) bool { if node == nil { return true @@ -8002,11 +10409,17 @@ func (a *application) rewriteRefOfSavepoint(parent SQLNode, node *Savepoint, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSavepointName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*Savepoint).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8017,6 +10430,8 @@ func (a *application) rewriteRefOfSavepoint(parent SQLNode, node *Savepoint, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSelect(parent SQLNode, node *Select, replacer replacerFunc) bool { if node == nil { return true @@ -8034,12 +10449,25 @@ func (a *application) rewriteRefOfSelect(parent SQLNode, node *Select, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSelectWith)) + } if !a.rewriteRefOfWith(node, node.With, func(newNode, parent SQLNode) { parent.(*Select).With = newNode.(*With) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.From { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfSelectFromOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteTableExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*Select).From[idx] = newNode.(TableExpr) @@ -8048,51 +10476,90 @@ func (a *application) rewriteRefOfSelect(parent SQLNode, node *Select, replacer return false } } + if a.collectPaths && len(node.From) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*Select).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectSelectExprs)) + } if !a.rewriteRefOfSelectExprs(node, node.SelectExprs, func(newNode, parent SQLNode) { parent.(*Select).SelectExprs = newNode.(*SelectExprs) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectWhere)) + } if !a.rewriteRefOfWhere(node, node.Where, func(newNode, parent SQLNode) { parent.(*Select).Where = newNode.(*Where) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectGroupBy)) + } if !a.rewriteRefOfGroupBy(node, node.GroupBy, func(newNode, parent SQLNode) { parent.(*Select).GroupBy = newNode.(*GroupBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectHaving)) + } if !a.rewriteRefOfWhere(node, node.Having, func(newNode, parent SQLNode) { parent.(*Select).Having = newNode.(*Where) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectWindows)) + } if !a.rewriteNamedWindows(node, node.Windows, func(newNode, parent SQLNode) { parent.(*Select).Windows = newNode.(NamedWindows) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectOrderBy)) + } if !a.rewriteOrderBy(node, node.OrderBy, func(newNode, parent SQLNode) { parent.(*Select).OrderBy = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*Select).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSelectInto)) + } if !a.rewriteRefOfSelectInto(node, node.Into, func(newNode, parent SQLNode) { parent.(*Select).Into = newNode.(*SelectInto) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8103,6 +10570,8 @@ func (a *application) rewriteRefOfSelect(parent SQLNode, node *Select, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSelectExprs(parent SQLNode, node *SelectExprs, replacer replacerFunc) bool { if node == nil { return true @@ -8121,6 +10590,13 @@ func (a *application) rewriteRefOfSelectExprs(parent SQLNode, node *SelectExprs, } } for x, el := range node.Exprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfSelectExprsExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteSelectExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*SelectExprs).Exprs[idx] = newNode.(SelectExpr) @@ -8129,6 +10605,9 @@ func (a *application) rewriteRefOfSelectExprs(parent SQLNode, node *SelectExprs, return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8139,6 +10618,8 @@ func (a *application) rewriteRefOfSelectExprs(parent SQLNode, node *SelectExprs, } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSelectInto(parent SQLNode, node *SelectInto, replacer replacerFunc) bool { if node == nil { return true @@ -8168,6 +10649,8 @@ func (a *application) rewriteRefOfSelectInto(parent SQLNode, node *SelectInto, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSet(parent SQLNode, node *Set, replacer replacerFunc) bool { if node == nil { return true @@ -8185,16 +10668,26 @@ func (a *application) rewriteRefOfSet(parent SQLNode, node *Set, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSetComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*Set).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSetExprs)) + } if !a.rewriteSetExprs(node, node.Exprs, func(newNode, parent SQLNode) { parent.(*Set).Exprs = newNode.(SetExprs) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8205,6 +10698,8 @@ func (a *application) rewriteRefOfSet(parent SQLNode, node *Set, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSetExpr(parent SQLNode, node *SetExpr, replacer replacerFunc) bool { if node == nil { return true @@ -8222,16 +10717,26 @@ func (a *application) rewriteRefOfSetExpr(parent SQLNode, node *SetExpr, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSetExprVar)) + } if !a.rewriteRefOfVariable(node, node.Var, func(newNode, parent SQLNode) { parent.(*SetExpr).Var = newNode.(*Variable) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSetExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*SetExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8242,6 +10747,8 @@ func (a *application) rewriteRefOfSetExpr(parent SQLNode, node *SetExpr, replace } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteSetExprs(parent SQLNode, node SetExprs, replacer replacerFunc) bool { if node == nil { return true @@ -8260,6 +10767,13 @@ func (a *application) rewriteSetExprs(parent SQLNode, node SetExprs, replacer re } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(SetExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfSetExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(SetExprs)[idx] = newNode.(*SetExpr) @@ -8268,6 +10782,9 @@ func (a *application) rewriteSetExprs(parent SQLNode, node SetExprs, replacer re return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8278,6 +10795,8 @@ func (a *application) rewriteSetExprs(parent SQLNode, node SetExprs, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShow(parent SQLNode, node *Show, replacer replacerFunc) bool { if node == nil { return true @@ -8295,11 +10814,17 @@ func (a *application) rewriteRefOfShow(parent SQLNode, node *Show, replacer repl return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfShowInternal)) + } if !a.rewriteShowInternal(node, node.Internal, func(newNode, parent SQLNode) { parent.(*Show).Internal = newNode.(ShowInternal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8310,6 +10835,8 @@ func (a *application) rewriteRefOfShow(parent SQLNode, node *Show, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowBasic(parent SQLNode, node *ShowBasic, replacer replacerFunc) bool { if node == nil { return true @@ -8327,21 +10854,35 @@ func (a *application) rewriteRefOfShowBasic(parent SQLNode, node *ShowBasic, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfShowBasicTbl)) + } if !a.rewriteTableName(node, node.Tbl, func(newNode, parent SQLNode) { parent.(*ShowBasic).Tbl = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfShowBasicDbName)) + } if !a.rewriteIdentifierCS(node, node.DbName, func(newNode, parent SQLNode) { parent.(*ShowBasic).DbName = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfShowBasicFilter)) + } if !a.rewriteRefOfShowFilter(node, node.Filter, func(newNode, parent SQLNode) { parent.(*ShowBasic).Filter = newNode.(*ShowFilter) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8352,6 +10893,8 @@ func (a *application) rewriteRefOfShowBasic(parent SQLNode, node *ShowBasic, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowCreate(parent SQLNode, node *ShowCreate, replacer replacerFunc) bool { if node == nil { return true @@ -8369,11 +10912,17 @@ func (a *application) rewriteRefOfShowCreate(parent SQLNode, node *ShowCreate, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfShowCreateOp)) + } if !a.rewriteTableName(node, node.Op, func(newNode, parent SQLNode) { parent.(*ShowCreate).Op = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8384,6 +10933,8 @@ func (a *application) rewriteRefOfShowCreate(parent SQLNode, node *ShowCreate, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowFilter(parent SQLNode, node *ShowFilter, replacer replacerFunc) bool { if node == nil { return true @@ -8401,11 +10952,17 @@ func (a *application) rewriteRefOfShowFilter(parent SQLNode, node *ShowFilter, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfShowFilterFilter)) + } if !a.rewriteExpr(node, node.Filter, func(newNode, parent SQLNode) { parent.(*ShowFilter).Filter = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8416,6 +10973,8 @@ func (a *application) rewriteRefOfShowFilter(parent SQLNode, node *ShowFilter, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowMigrationLogs(parent SQLNode, node *ShowMigrationLogs, replacer replacerFunc) bool { if node == nil { return true @@ -8433,11 +10992,17 @@ func (a *application) rewriteRefOfShowMigrationLogs(parent SQLNode, node *ShowMi return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfShowMigrationLogsComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*ShowMigrationLogs).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8448,6 +11013,8 @@ func (a *application) rewriteRefOfShowMigrationLogs(parent SQLNode, node *ShowMi } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowOther(parent SQLNode, node *ShowOther, replacer replacerFunc) bool { if node == nil { return true @@ -8477,6 +11044,8 @@ func (a *application) rewriteRefOfShowOther(parent SQLNode, node *ShowOther, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowThrottledApps(parent SQLNode, node *ShowThrottledApps, replacer replacerFunc) bool { if node == nil { return true @@ -8506,6 +11075,8 @@ func (a *application) rewriteRefOfShowThrottledApps(parent SQLNode, node *ShowTh } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowThrottlerStatus(parent SQLNode, node *ShowThrottlerStatus, replacer replacerFunc) bool { if node == nil { return true @@ -8535,6 +11106,8 @@ func (a *application) rewriteRefOfShowThrottlerStatus(parent SQLNode, node *Show } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfShowTransactionStatus(parent SQLNode, node *ShowTransactionStatus, replacer replacerFunc) bool { if node == nil { return true @@ -8564,6 +11137,8 @@ func (a *application) rewriteRefOfShowTransactionStatus(parent SQLNode, node *Sh } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfStarExpr(parent SQLNode, node *StarExpr, replacer replacerFunc) bool { if node == nil { return true @@ -8581,11 +11156,17 @@ func (a *application) rewriteRefOfStarExpr(parent SQLNode, node *StarExpr, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfStarExprTableName)) + } if !a.rewriteTableName(node, node.TableName, func(newNode, parent SQLNode) { parent.(*StarExpr).TableName = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8596,6 +11177,8 @@ func (a *application) rewriteRefOfStarExpr(parent SQLNode, node *StarExpr, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfStd(parent SQLNode, node *Std, replacer replacerFunc) bool { if node == nil { return true @@ -8613,16 +11196,26 @@ func (a *application) rewriteRefOfStd(parent SQLNode, node *Std, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfStdArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*Std).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfStdOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Std).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8633,6 +11226,8 @@ func (a *application) rewriteRefOfStd(parent SQLNode, node *Std, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfStdDev(parent SQLNode, node *StdDev, replacer replacerFunc) bool { if node == nil { return true @@ -8650,16 +11245,26 @@ func (a *application) rewriteRefOfStdDev(parent SQLNode, node *StdDev, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfStdDevArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*StdDev).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfStdDevOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*StdDev).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8670,6 +11275,8 @@ func (a *application) rewriteRefOfStdDev(parent SQLNode, node *StdDev, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfStdPop(parent SQLNode, node *StdPop, replacer replacerFunc) bool { if node == nil { return true @@ -8687,16 +11294,26 @@ func (a *application) rewriteRefOfStdPop(parent SQLNode, node *StdPop, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfStdPopArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*StdPop).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfStdPopOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*StdPop).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8707,6 +11324,8 @@ func (a *application) rewriteRefOfStdPop(parent SQLNode, node *StdPop, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfStdSamp(parent SQLNode, node *StdSamp, replacer replacerFunc) bool { if node == nil { return true @@ -8724,16 +11343,26 @@ func (a *application) rewriteRefOfStdSamp(parent SQLNode, node *StdSamp, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfStdSampArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*StdSamp).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfStdSampOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*StdSamp).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8744,6 +11373,8 @@ func (a *application) rewriteRefOfStdSamp(parent SQLNode, node *StdSamp, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfStream(parent SQLNode, node *Stream, replacer replacerFunc) bool { if node == nil { return true @@ -8761,21 +11392,35 @@ func (a *application) rewriteRefOfStream(parent SQLNode, node *Stream, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfStreamComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*Stream).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfStreamSelectExpr)) + } if !a.rewriteSelectExpr(node, node.SelectExpr, func(newNode, parent SQLNode) { parent.(*Stream).SelectExpr = newNode.(SelectExpr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfStreamTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*Stream).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8786,6 +11431,8 @@ func (a *application) rewriteRefOfStream(parent SQLNode, node *Stream, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSubPartition(parent SQLNode, node *SubPartition, replacer replacerFunc) bool { if node == nil { return true @@ -8803,16 +11450,26 @@ func (a *application) rewriteRefOfSubPartition(parent SQLNode, node *SubPartitio return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSubPartitionColList)) + } if !a.rewriteColumns(node, node.ColList, func(newNode, parent SQLNode) { parent.(*SubPartition).ColList = newNode.(Columns) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubPartitionExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*SubPartition).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8823,6 +11480,8 @@ func (a *application) rewriteRefOfSubPartition(parent SQLNode, node *SubPartitio } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSubPartitionDefinition(parent SQLNode, node *SubPartitionDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -8840,16 +11499,26 @@ func (a *application) rewriteRefOfSubPartitionDefinition(parent SQLNode, node *S return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSubPartitionDefinitionName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*SubPartitionDefinition).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubPartitionDefinitionOptions)) + } if !a.rewriteRefOfSubPartitionDefinitionOptions(node, node.Options, func(newNode, parent SQLNode) { parent.(*SubPartitionDefinition).Options = newNode.(*SubPartitionDefinitionOptions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8860,6 +11529,8 @@ func (a *application) rewriteRefOfSubPartitionDefinition(parent SQLNode, node *S } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSubPartitionDefinitionOptions(parent SQLNode, node *SubPartitionDefinitionOptions, replacer replacerFunc) bool { if node == nil { return true @@ -8877,26 +11548,44 @@ func (a *application) rewriteRefOfSubPartitionDefinitionOptions(parent SQLNode, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSubPartitionDefinitionOptionsComment)) + } if !a.rewriteRefOfLiteral(node, node.Comment, func(newNode, parent SQLNode) { parent.(*SubPartitionDefinitionOptions).Comment = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubPartitionDefinitionOptionsEngine)) + } if !a.rewriteRefOfPartitionEngine(node, node.Engine, func(newNode, parent SQLNode) { parent.(*SubPartitionDefinitionOptions).Engine = newNode.(*PartitionEngine) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubPartitionDefinitionOptionsDataDirectory)) + } if !a.rewriteRefOfLiteral(node, node.DataDirectory, func(newNode, parent SQLNode) { parent.(*SubPartitionDefinitionOptions).DataDirectory = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubPartitionDefinitionOptionsIndexDirectory)) + } if !a.rewriteRefOfLiteral(node, node.IndexDirectory, func(newNode, parent SQLNode) { parent.(*SubPartitionDefinitionOptions).IndexDirectory = newNode.(*Literal) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8907,6 +11596,8 @@ func (a *application) rewriteRefOfSubPartitionDefinitionOptions(parent SQLNode, } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteSubPartitionDefinitions(parent SQLNode, node SubPartitionDefinitions, replacer replacerFunc) bool { if node == nil { return true @@ -8925,6 +11616,13 @@ func (a *application) rewriteSubPartitionDefinitions(parent SQLNode, node SubPar } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(SubPartitionDefinitionsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfSubPartitionDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(SubPartitionDefinitions)[idx] = newNode.(*SubPartitionDefinition) @@ -8933,6 +11631,9 @@ func (a *application) rewriteSubPartitionDefinitions(parent SQLNode, node SubPar return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8943,6 +11644,8 @@ func (a *application) rewriteSubPartitionDefinitions(parent SQLNode, node SubPar } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSubquery(parent SQLNode, node *Subquery, replacer replacerFunc) bool { if node == nil { return true @@ -8960,11 +11663,17 @@ func (a *application) rewriteRefOfSubquery(parent SQLNode, node *Subquery, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSubquerySelect)) + } if !a.rewriteTableStatement(node, node.Select, func(newNode, parent SQLNode) { parent.(*Subquery).Select = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -8975,6 +11684,8 @@ func (a *application) rewriteRefOfSubquery(parent SQLNode, node *Subquery, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSubstrExpr(parent SQLNode, node *SubstrExpr, replacer replacerFunc) bool { if node == nil { return true @@ -8992,21 +11703,35 @@ func (a *application) rewriteRefOfSubstrExpr(parent SQLNode, node *SubstrExpr, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSubstrExprName)) + } if !a.rewriteExpr(node, node.Name, func(newNode, parent SQLNode) { parent.(*SubstrExpr).Name = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubstrExprFrom)) + } if !a.rewriteExpr(node, node.From, func(newNode, parent SQLNode) { parent.(*SubstrExpr).From = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSubstrExprTo)) + } if !a.rewriteExpr(node, node.To, func(newNode, parent SQLNode) { parent.(*SubstrExpr).To = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9017,6 +11742,8 @@ func (a *application) rewriteRefOfSubstrExpr(parent SQLNode, node *SubstrExpr, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfSum(parent SQLNode, node *Sum, replacer replacerFunc) bool { if node == nil { return true @@ -9034,16 +11761,26 @@ func (a *application) rewriteRefOfSum(parent SQLNode, node *Sum, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfSumArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*Sum).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfSumOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Sum).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9054,6 +11791,8 @@ func (a *application) rewriteRefOfSum(parent SQLNode, node *Sum, replacer replac } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteTableExprs(parent SQLNode, node TableExprs, replacer replacerFunc) bool { if node == nil { return true @@ -9072,6 +11811,13 @@ func (a *application) rewriteTableExprs(parent SQLNode, node TableExprs, replace } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(TableExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteTableExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(TableExprs)[idx] = newNode.(TableExpr) @@ -9080,6 +11826,9 @@ func (a *application) rewriteTableExprs(parent SQLNode, node TableExprs, replace return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9090,6 +11839,8 @@ func (a *application) rewriteTableExprs(parent SQLNode, node TableExprs, replace } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteTableName(parent SQLNode, node TableName, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -9104,16 +11855,26 @@ func (a *application) rewriteTableName(parent SQLNode, node TableName, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(TableNameName)) + } if !a.rewriteIdentifierCS(node, node.Name, func(newNode, parent SQLNode) { panic("[BUG] tried to replace 'Name' on 'TableName'") }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(TableNameQualifier)) + } if !a.rewriteIdentifierCS(node, node.Qualifier, func(newNode, parent SQLNode) { panic("[BUG] tried to replace 'Qualifier' on 'TableName'") }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9124,6 +11885,8 @@ func (a *application) rewriteTableName(parent SQLNode, node TableName, replacer } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteTableNames(parent SQLNode, node TableNames, replacer replacerFunc) bool { if node == nil { return true @@ -9142,6 +11905,13 @@ func (a *application) rewriteTableNames(parent SQLNode, node TableNames, replace } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(TableNamesOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteTableName(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(TableNames)[idx] = newNode.(TableName) @@ -9150,6 +11920,9 @@ func (a *application) rewriteTableNames(parent SQLNode, node TableNames, replace return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9160,6 +11933,8 @@ func (a *application) rewriteTableNames(parent SQLNode, node TableNames, replace } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteTableOptions(parent SQLNode, node TableOptions, replacer replacerFunc) bool { if node == nil { return true @@ -9189,6 +11964,8 @@ func (a *application) rewriteTableOptions(parent SQLNode, node TableOptions, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfTableSpec(parent SQLNode, node *TableSpec, replacer replacerFunc) bool { if node == nil { return true @@ -9207,6 +11984,13 @@ func (a *application) rewriteRefOfTableSpec(parent SQLNode, node *TableSpec, rep } } for x, el := range node.Columns { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfTableSpecColumnsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfColumnDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*TableSpec).Columns[idx] = newNode.(*ColumnDefinition) @@ -9215,7 +11999,17 @@ func (a *application) rewriteRefOfTableSpec(parent SQLNode, node *TableSpec, rep return false } } + if a.collectPaths && len(node.Columns) > 0 { + a.cur.current.Pop() + } for x, el := range node.Indexes { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfTableSpecIndexesOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfIndexDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*TableSpec).Indexes[idx] = newNode.(*IndexDefinition) @@ -9224,7 +12018,17 @@ func (a *application) rewriteRefOfTableSpec(parent SQLNode, node *TableSpec, rep return false } } + if a.collectPaths && len(node.Indexes) > 0 { + a.cur.current.Pop() + } for x, el := range node.Constraints { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfTableSpecConstraintsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfConstraintDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*TableSpec).Constraints[idx] = newNode.(*ConstraintDefinition) @@ -9233,16 +12037,27 @@ func (a *application) rewriteRefOfTableSpec(parent SQLNode, node *TableSpec, rep return false } } + if a.collectPaths && len(node.Constraints) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfTableSpecOptions)) + } if !a.rewriteTableOptions(node, node.Options, func(newNode, parent SQLNode) { parent.(*TableSpec).Options = newNode.(TableOptions) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfTableSpecPartitionOption)) + } if !a.rewriteRefOfPartitionOption(node, node.PartitionOption, func(newNode, parent SQLNode) { parent.(*TableSpec).PartitionOption = newNode.(*PartitionOption) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9253,6 +12068,8 @@ func (a *application) rewriteRefOfTableSpec(parent SQLNode, node *TableSpec, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfTablespaceOperation(parent SQLNode, node *TablespaceOperation, replacer replacerFunc) bool { if node == nil { return true @@ -9282,6 +12099,8 @@ func (a *application) rewriteRefOfTablespaceOperation(parent SQLNode, node *Tabl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfTimestampDiffExpr(parent SQLNode, node *TimestampDiffExpr, replacer replacerFunc) bool { if node == nil { return true @@ -9299,16 +12118,26 @@ func (a *application) rewriteRefOfTimestampDiffExpr(parent SQLNode, node *Timest return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfTimestampDiffExprExpr1)) + } if !a.rewriteExpr(node, node.Expr1, func(newNode, parent SQLNode) { parent.(*TimestampDiffExpr).Expr1 = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfTimestampDiffExprExpr2)) + } if !a.rewriteExpr(node, node.Expr2, func(newNode, parent SQLNode) { parent.(*TimestampDiffExpr).Expr2 = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9319,6 +12148,8 @@ func (a *application) rewriteRefOfTimestampDiffExpr(parent SQLNode, node *Timest } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfTrimFuncExpr(parent SQLNode, node *TrimFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -9336,16 +12167,26 @@ func (a *application) rewriteRefOfTrimFuncExpr(parent SQLNode, node *TrimFuncExp return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfTrimFuncExprTrimArg)) + } if !a.rewriteExpr(node, node.TrimArg, func(newNode, parent SQLNode) { parent.(*TrimFuncExpr).TrimArg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfTrimFuncExprStringArg)) + } if !a.rewriteExpr(node, node.StringArg, func(newNode, parent SQLNode) { parent.(*TrimFuncExpr).StringArg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9356,6 +12197,8 @@ func (a *application) rewriteRefOfTrimFuncExpr(parent SQLNode, node *TrimFuncExp } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfTruncateTable(parent SQLNode, node *TruncateTable, replacer replacerFunc) bool { if node == nil { return true @@ -9373,11 +12216,17 @@ func (a *application) rewriteRefOfTruncateTable(parent SQLNode, node *TruncateTa return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfTruncateTableTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*TruncateTable).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9388,6 +12237,8 @@ func (a *application) rewriteRefOfTruncateTable(parent SQLNode, node *TruncateTa } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUnaryExpr(parent SQLNode, node *UnaryExpr, replacer replacerFunc) bool { if node == nil { return true @@ -9405,11 +12256,17 @@ func (a *application) rewriteRefOfUnaryExpr(parent SQLNode, node *UnaryExpr, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfUnaryExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*UnaryExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9420,6 +12277,8 @@ func (a *application) rewriteRefOfUnaryExpr(parent SQLNode, node *UnaryExpr, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUnion(parent SQLNode, node *Union, replacer replacerFunc) bool { if node == nil { return true @@ -9437,36 +12296,62 @@ func (a *application) rewriteRefOfUnion(parent SQLNode, node *Union, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfUnionWith)) + } if !a.rewriteRefOfWith(node, node.With, func(newNode, parent SQLNode) { parent.(*Union).With = newNode.(*With) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUnionLeft)) + } if !a.rewriteTableStatement(node, node.Left, func(newNode, parent SQLNode) { parent.(*Union).Left = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUnionRight)) + } if !a.rewriteTableStatement(node, node.Right, func(newNode, parent SQLNode) { parent.(*Union).Right = newNode.(TableStatement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUnionOrderBy)) + } if !a.rewriteOrderBy(node, node.OrderBy, func(newNode, parent SQLNode) { parent.(*Union).OrderBy = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUnionLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*Union).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUnionInto)) + } if !a.rewriteRefOfSelectInto(node, node.Into, func(newNode, parent SQLNode) { parent.(*Union).Into = newNode.(*SelectInto) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9477,6 +12362,8 @@ func (a *application) rewriteRefOfUnion(parent SQLNode, node *Union, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUnlockTables(parent SQLNode, node *UnlockTables, replacer replacerFunc) bool { if node == nil { return true @@ -9506,6 +12393,8 @@ func (a *application) rewriteRefOfUnlockTables(parent SQLNode, node *UnlockTable } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUpdate(parent SQLNode, node *Update, replacer replacerFunc) bool { if node == nil { return true @@ -9523,17 +12412,34 @@ func (a *application) rewriteRefOfUpdate(parent SQLNode, node *Update, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfUpdateWith)) + } if !a.rewriteRefOfWith(node, node.With, func(newNode, parent SQLNode) { parent.(*Update).With = newNode.(*With) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*Update).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.TableExprs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfUpdateTableExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteTableExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*Update).TableExprs[idx] = newNode.(TableExpr) @@ -9542,26 +12448,45 @@ func (a *application) rewriteRefOfUpdate(parent SQLNode, node *Update, replacer return false } } + if a.collectPaths && len(node.TableExprs) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateExprs)) + } if !a.rewriteUpdateExprs(node, node.Exprs, func(newNode, parent SQLNode) { parent.(*Update).Exprs = newNode.(UpdateExprs) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateWhere)) + } if !a.rewriteRefOfWhere(node, node.Where, func(newNode, parent SQLNode) { parent.(*Update).Where = newNode.(*Where) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateOrderBy)) + } if !a.rewriteOrderBy(node, node.OrderBy, func(newNode, parent SQLNode) { parent.(*Update).OrderBy = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*Update).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9572,6 +12497,8 @@ func (a *application) rewriteRefOfUpdate(parent SQLNode, node *Update, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUpdateExpr(parent SQLNode, node *UpdateExpr, replacer replacerFunc) bool { if node == nil { return true @@ -9589,16 +12516,26 @@ func (a *application) rewriteRefOfUpdateExpr(parent SQLNode, node *UpdateExpr, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfUpdateExprName)) + } if !a.rewriteRefOfColName(node, node.Name, func(newNode, parent SQLNode) { parent.(*UpdateExpr).Name = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*UpdateExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9609,6 +12546,8 @@ func (a *application) rewriteRefOfUpdateExpr(parent SQLNode, node *UpdateExpr, r } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteUpdateExprs(parent SQLNode, node UpdateExprs, replacer replacerFunc) bool { if node == nil { return true @@ -9627,6 +12566,13 @@ func (a *application) rewriteUpdateExprs(parent SQLNode, node UpdateExprs, repla } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(UpdateExprsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfUpdateExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(UpdateExprs)[idx] = newNode.(*UpdateExpr) @@ -9635,6 +12581,9 @@ func (a *application) rewriteUpdateExprs(parent SQLNode, node UpdateExprs, repla return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9645,6 +12594,8 @@ func (a *application) rewriteUpdateExprs(parent SQLNode, node UpdateExprs, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUpdateXMLExpr(parent SQLNode, node *UpdateXMLExpr, replacer replacerFunc) bool { if node == nil { return true @@ -9662,21 +12613,35 @@ func (a *application) rewriteRefOfUpdateXMLExpr(parent SQLNode, node *UpdateXMLE return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfUpdateXMLExprTarget)) + } if !a.rewriteExpr(node, node.Target, func(newNode, parent SQLNode) { parent.(*UpdateXMLExpr).Target = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateXMLExprXPathExpr)) + } if !a.rewriteExpr(node, node.XPathExpr, func(newNode, parent SQLNode) { parent.(*UpdateXMLExpr).XPathExpr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfUpdateXMLExprNewXML)) + } if !a.rewriteExpr(node, node.NewXML, func(newNode, parent SQLNode) { parent.(*UpdateXMLExpr).NewXML = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9687,6 +12652,8 @@ func (a *application) rewriteRefOfUpdateXMLExpr(parent SQLNode, node *UpdateXMLE } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfUse(parent SQLNode, node *Use, replacer replacerFunc) bool { if node == nil { return true @@ -9704,11 +12671,17 @@ func (a *application) rewriteRefOfUse(parent SQLNode, node *Use, replacer replac return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfUseDBName)) + } if !a.rewriteIdentifierCS(node, node.DBName, func(newNode, parent SQLNode) { parent.(*Use).DBName = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9719,6 +12692,8 @@ func (a *application) rewriteRefOfUse(parent SQLNode, node *Use, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVExplainStmt(parent SQLNode, node *VExplainStmt, replacer replacerFunc) bool { if node == nil { return true @@ -9736,16 +12711,26 @@ func (a *application) rewriteRefOfVExplainStmt(parent SQLNode, node *VExplainStm return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVExplainStmtStatement)) + } if !a.rewriteStatement(node, node.Statement, func(newNode, parent SQLNode) { parent.(*VExplainStmt).Statement = newNode.(Statement) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVExplainStmtComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*VExplainStmt).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9756,6 +12741,8 @@ func (a *application) rewriteRefOfVExplainStmt(parent SQLNode, node *VExplainStm } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVStream(parent SQLNode, node *VStream, replacer replacerFunc) bool { if node == nil { return true @@ -9773,31 +12760,53 @@ func (a *application) rewriteRefOfVStream(parent SQLNode, node *VStream, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVStreamComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*VStream).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVStreamSelectExpr)) + } if !a.rewriteSelectExpr(node, node.SelectExpr, func(newNode, parent SQLNode) { parent.(*VStream).SelectExpr = newNode.(SelectExpr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVStreamTable)) + } if !a.rewriteTableName(node, node.Table, func(newNode, parent SQLNode) { parent.(*VStream).Table = newNode.(TableName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVStreamWhere)) + } if !a.rewriteRefOfWhere(node, node.Where, func(newNode, parent SQLNode) { parent.(*VStream).Where = newNode.(*Where) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVStreamLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*VStream).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9808,6 +12817,8 @@ func (a *application) rewriteRefOfVStream(parent SQLNode, node *VStream, replace } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteValTuple(parent SQLNode, node ValTuple, replacer replacerFunc) bool { if node == nil { return true @@ -9826,6 +12837,13 @@ func (a *application) rewriteValTuple(parent SQLNode, node ValTuple, replacer re } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(ValTupleOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(ValTuple)[idx] = newNode.(Expr) @@ -9834,6 +12852,9 @@ func (a *application) rewriteValTuple(parent SQLNode, node ValTuple, replacer re return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9844,6 +12865,8 @@ func (a *application) rewriteValTuple(parent SQLNode, node ValTuple, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfValidation(parent SQLNode, node *Validation, replacer replacerFunc) bool { if node == nil { return true @@ -9873,6 +12896,8 @@ func (a *application) rewriteRefOfValidation(parent SQLNode, node *Validation, r } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteValues(parent SQLNode, node Values, replacer replacerFunc) bool { if node == nil { return true @@ -9891,6 +12916,13 @@ func (a *application) rewriteValues(parent SQLNode, node Values, replacer replac } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(ValuesOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteValTuple(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(Values)[idx] = newNode.(ValTuple) @@ -9899,6 +12931,9 @@ func (a *application) rewriteValues(parent SQLNode, node Values, replacer replac return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9909,6 +12944,8 @@ func (a *application) rewriteValues(parent SQLNode, node Values, replacer replac } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfValuesFuncExpr(parent SQLNode, node *ValuesFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -9926,11 +12963,17 @@ func (a *application) rewriteRefOfValuesFuncExpr(parent SQLNode, node *ValuesFun return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfValuesFuncExprName)) + } if !a.rewriteRefOfColName(node, node.Name, func(newNode, parent SQLNode) { parent.(*ValuesFuncExpr).Name = newNode.(*ColName) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9941,6 +12984,8 @@ func (a *application) rewriteRefOfValuesFuncExpr(parent SQLNode, node *ValuesFun } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfValuesStatement(parent SQLNode, node *ValuesStatement, replacer replacerFunc) bool { if node == nil { return true @@ -9958,36 +13003,62 @@ func (a *application) rewriteRefOfValuesStatement(parent SQLNode, node *ValuesSt return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfValuesStatementWith)) + } if !a.rewriteRefOfWith(node, node.With, func(newNode, parent SQLNode) { parent.(*ValuesStatement).With = newNode.(*With) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValuesStatementRows)) + } if !a.rewriteValues(node, node.Rows, func(newNode, parent SQLNode) { parent.(*ValuesStatement).Rows = newNode.(Values) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValuesStatementListArg)) + } if !a.rewriteListArg(node, node.ListArg, func(newNode, parent SQLNode) { parent.(*ValuesStatement).ListArg = newNode.(ListArg) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValuesStatementComments)) + } if !a.rewriteRefOfParsedComments(node, node.Comments, func(newNode, parent SQLNode) { parent.(*ValuesStatement).Comments = newNode.(*ParsedComments) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValuesStatementOrder)) + } if !a.rewriteOrderBy(node, node.Order, func(newNode, parent SQLNode) { parent.(*ValuesStatement).Order = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfValuesStatementLimit)) + } if !a.rewriteRefOfLimit(node, node.Limit, func(newNode, parent SQLNode) { parent.(*ValuesStatement).Limit = newNode.(*Limit) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -9998,6 +13069,8 @@ func (a *application) rewriteRefOfValuesStatement(parent SQLNode, node *ValuesSt } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVarPop(parent SQLNode, node *VarPop, replacer replacerFunc) bool { if node == nil { return true @@ -10015,16 +13088,26 @@ func (a *application) rewriteRefOfVarPop(parent SQLNode, node *VarPop, replacer return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVarPopArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*VarPop).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVarPopOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*VarPop).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10035,6 +13118,8 @@ func (a *application) rewriteRefOfVarPop(parent SQLNode, node *VarPop, replacer } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVarSamp(parent SQLNode, node *VarSamp, replacer replacerFunc) bool { if node == nil { return true @@ -10052,16 +13137,26 @@ func (a *application) rewriteRefOfVarSamp(parent SQLNode, node *VarSamp, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVarSampArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*VarSamp).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVarSampOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*VarSamp).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10072,6 +13167,8 @@ func (a *application) rewriteRefOfVarSamp(parent SQLNode, node *VarSamp, replace } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVariable(parent SQLNode, node *Variable, replacer replacerFunc) bool { if node == nil { return true @@ -10089,11 +13186,17 @@ func (a *application) rewriteRefOfVariable(parent SQLNode, node *Variable, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVariableName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*Variable).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10104,6 +13207,8 @@ func (a *application) rewriteRefOfVariable(parent SQLNode, node *Variable, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVariance(parent SQLNode, node *Variance, replacer replacerFunc) bool { if node == nil { return true @@ -10121,16 +13226,26 @@ func (a *application) rewriteRefOfVariance(parent SQLNode, node *Variance, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVarianceArg)) + } if !a.rewriteExpr(node, node.Arg, func(newNode, parent SQLNode) { parent.(*Variance).Arg = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVarianceOverClause)) + } if !a.rewriteRefOfOverClause(node, node.OverClause, func(newNode, parent SQLNode) { parent.(*Variance).OverClause = newNode.(*OverClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10141,6 +13256,8 @@ func (a *application) rewriteRefOfVariance(parent SQLNode, node *Variance, repla } return true } + +// Function Generation Source: StructMethod func (a *application) rewriteVindexParam(parent SQLNode, node VindexParam, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -10155,11 +13272,17 @@ func (a *application) rewriteVindexParam(parent SQLNode, node VindexParam, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(VindexParamKey)) + } if !a.rewriteIdentifierCI(node, node.Key, func(newNode, parent SQLNode) { panic("[BUG] tried to replace 'Key' on 'VindexParam'") }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10170,6 +13293,8 @@ func (a *application) rewriteVindexParam(parent SQLNode, node VindexParam, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVindexSpec(parent SQLNode, node *VindexSpec, replacer replacerFunc) bool { if node == nil { return true @@ -10187,17 +13312,34 @@ func (a *application) rewriteRefOfVindexSpec(parent SQLNode, node *VindexSpec, r return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVindexSpecName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*VindexSpec).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfVindexSpecType)) + } if !a.rewriteIdentifierCI(node, node.Type, func(newNode, parent SQLNode) { parent.(*VindexSpec).Type = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.Params { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfVindexSpecParamsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteVindexParam(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*VindexSpec).Params[idx] = newNode.(VindexParam) @@ -10206,6 +13348,9 @@ func (a *application) rewriteRefOfVindexSpec(parent SQLNode, node *VindexSpec, r return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10216,6 +13361,8 @@ func (a *application) rewriteRefOfVindexSpec(parent SQLNode, node *VindexSpec, r } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfWeightStringFuncExpr(parent SQLNode, node *WeightStringFuncExpr, replacer replacerFunc) bool { if node == nil { return true @@ -10233,16 +13380,26 @@ func (a *application) rewriteRefOfWeightStringFuncExpr(parent SQLNode, node *Wei return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfWeightStringFuncExprExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*WeightStringFuncExpr).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfWeightStringFuncExprAs)) + } if !a.rewriteRefOfConvertType(node, node.As, func(newNode, parent SQLNode) { parent.(*WeightStringFuncExpr).As = newNode.(*ConvertType) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10253,6 +13410,8 @@ func (a *application) rewriteRefOfWeightStringFuncExpr(parent SQLNode, node *Wei } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfWhen(parent SQLNode, node *When, replacer replacerFunc) bool { if node == nil { return true @@ -10270,16 +13429,26 @@ func (a *application) rewriteRefOfWhen(parent SQLNode, node *When, replacer repl return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfWhenCond)) + } if !a.rewriteExpr(node, node.Cond, func(newNode, parent SQLNode) { parent.(*When).Cond = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfWhenVal)) + } if !a.rewriteExpr(node, node.Val, func(newNode, parent SQLNode) { parent.(*When).Val = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10290,6 +13459,8 @@ func (a *application) rewriteRefOfWhen(parent SQLNode, node *When, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfWhere(parent SQLNode, node *Where, replacer replacerFunc) bool { if node == nil { return true @@ -10307,11 +13478,17 @@ func (a *application) rewriteRefOfWhere(parent SQLNode, node *Where, replacer re return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfWhereExpr)) + } if !a.rewriteExpr(node, node.Expr, func(newNode, parent SQLNode) { parent.(*Where).Expr = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10322,6 +13499,8 @@ func (a *application) rewriteRefOfWhere(parent SQLNode, node *Where, replacer re } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfWindowDefinition(parent SQLNode, node *WindowDefinition, replacer replacerFunc) bool { if node == nil { return true @@ -10339,16 +13518,26 @@ func (a *application) rewriteRefOfWindowDefinition(parent SQLNode, node *WindowD return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfWindowDefinitionName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*WindowDefinition).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfWindowDefinitionWindowSpec)) + } if !a.rewriteRefOfWindowSpecification(node, node.WindowSpec, func(newNode, parent SQLNode) { parent.(*WindowDefinition).WindowSpec = newNode.(*WindowSpecification) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10359,6 +13548,8 @@ func (a *application) rewriteRefOfWindowDefinition(parent SQLNode, node *WindowD } return true } + +// Function Generation Source: SliceMethod func (a *application) rewriteWindowDefinitions(parent SQLNode, node WindowDefinitions, replacer replacerFunc) bool { if node == nil { return true @@ -10377,6 +13568,13 @@ func (a *application) rewriteWindowDefinitions(parent SQLNode, node WindowDefini } } for x, el := range node { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(WindowDefinitionsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfWindowDefinition(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(WindowDefinitions)[idx] = newNode.(*WindowDefinition) @@ -10385,6 +13583,9 @@ func (a *application) rewriteWindowDefinitions(parent SQLNode, node WindowDefini return false } } + if a.collectPaths && len(node) > 0 { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10395,6 +13596,8 @@ func (a *application) rewriteWindowDefinitions(parent SQLNode, node WindowDefini } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfWindowSpecification(parent SQLNode, node *WindowSpecification, replacer replacerFunc) bool { if node == nil { return true @@ -10412,12 +13615,25 @@ func (a *application) rewriteRefOfWindowSpecification(parent SQLNode, node *Wind return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfWindowSpecificationName)) + } if !a.rewriteIdentifierCI(node, node.Name, func(newNode, parent SQLNode) { parent.(*WindowSpecification).Name = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } for x, el := range node.PartitionClause { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfWindowSpecificationPartitionClauseOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*WindowSpecification).PartitionClause[idx] = newNode.(Expr) @@ -10426,16 +13642,27 @@ func (a *application) rewriteRefOfWindowSpecification(parent SQLNode, node *Wind return false } } + if a.collectPaths && len(node.PartitionClause) > 0 { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfWindowSpecificationOrderClause)) + } if !a.rewriteOrderBy(node, node.OrderClause, func(newNode, parent SQLNode) { parent.(*WindowSpecification).OrderClause = newNode.(OrderBy) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfWindowSpecificationFrameClause)) + } if !a.rewriteRefOfFrameClause(node, node.FrameClause, func(newNode, parent SQLNode) { parent.(*WindowSpecification).FrameClause = newNode.(*FrameClause) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10446,6 +13673,8 @@ func (a *application) rewriteRefOfWindowSpecification(parent SQLNode, node *Wind } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfWith(parent SQLNode, node *With, replacer replacerFunc) bool { if node == nil { return true @@ -10464,6 +13693,13 @@ func (a *application) rewriteRefOfWith(parent SQLNode, node *With, replacer repl } } for x, el := range node.CTEs { + if a.collectPaths { + if x == 0 { + a.cur.current.AddStepWithOffset(uint16(RefOfWithCTEsOffset)) + } else { + a.cur.current.ChangeOffset(x) + } + } if !a.rewriteRefOfCommonTableExpr(node, el, func(idx int) replacerFunc { return func(newNode, parent SQLNode) { parent.(*With).CTEs[idx] = newNode.(*CommonTableExpr) @@ -10472,6 +13708,9 @@ func (a *application) rewriteRefOfWith(parent SQLNode, node *With, replacer repl return false } } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10482,6 +13721,8 @@ func (a *application) rewriteRefOfWith(parent SQLNode, node *With, replacer repl } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfXorExpr(parent SQLNode, node *XorExpr, replacer replacerFunc) bool { if node == nil { return true @@ -10499,16 +13740,26 @@ func (a *application) rewriteRefOfXorExpr(parent SQLNode, node *XorExpr, replace return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfXorExprLeft)) + } if !a.rewriteExpr(node, node.Left, func(newNode, parent SQLNode) { parent.(*XorExpr).Left = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfXorExprRight)) + } if !a.rewriteExpr(node, node.Right, func(newNode, parent SQLNode) { parent.(*XorExpr).Right = newNode.(Expr) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -10519,6 +13770,8 @@ func (a *application) rewriteRefOfXorExpr(parent SQLNode, node *XorExpr, replace } return true } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteAggrFunc(parent SQLNode, node AggrFunc, replacer replacerFunc) bool { if node == nil { return true @@ -10569,6 +13822,8 @@ func (a *application) rewriteAggrFunc(parent SQLNode, node AggrFunc, replacer re return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteAlterOption(parent SQLNode, node AlterOption, replacer replacerFunc) bool { if node == nil { return true @@ -10623,6 +13878,8 @@ func (a *application) rewriteAlterOption(parent SQLNode, node AlterOption, repla return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteCallable(parent SQLNode, node Callable, replacer replacerFunc) bool { if node == nil { return true @@ -10789,6 +14046,8 @@ func (a *application) rewriteCallable(parent SQLNode, node Callable, replacer re return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteColTuple(parent SQLNode, node ColTuple, replacer replacerFunc) bool { if node == nil { return true @@ -10805,6 +14064,8 @@ func (a *application) rewriteColTuple(parent SQLNode, node ColTuple, replacer re return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteConstraintInfo(parent SQLNode, node ConstraintInfo, replacer replacerFunc) bool { if node == nil { return true @@ -10819,6 +14080,8 @@ func (a *application) rewriteConstraintInfo(parent SQLNode, node ConstraintInfo, return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteDBDDLStatement(parent SQLNode, node DBDDLStatement, replacer replacerFunc) bool { if node == nil { return true @@ -10835,6 +14098,8 @@ func (a *application) rewriteDBDDLStatement(parent SQLNode, node DBDDLStatement, return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteDDLStatement(parent SQLNode, node DDLStatement, replacer replacerFunc) bool { if node == nil { return true @@ -10861,6 +14126,8 @@ func (a *application) rewriteDDLStatement(parent SQLNode, node DDLStatement, rep return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteExplain(parent SQLNode, node Explain, replacer replacerFunc) bool { if node == nil { return true @@ -10875,6 +14142,8 @@ func (a *application) rewriteExplain(parent SQLNode, node Explain, replacer repl return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteExpr(parent SQLNode, node Expr, replacer replacerFunc) bool { if node == nil { return true @@ -11119,6 +14388,8 @@ func (a *application) rewriteExpr(parent SQLNode, node Expr, replacer replacerFu return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteInsertRows(parent SQLNode, node InsertRows, replacer replacerFunc) bool { if node == nil { return true @@ -11137,6 +14408,8 @@ func (a *application) rewriteInsertRows(parent SQLNode, node InsertRows, replace return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteSelectExpr(parent SQLNode, node SelectExpr, replacer replacerFunc) bool { if node == nil { return true @@ -11153,6 +14426,8 @@ func (a *application) rewriteSelectExpr(parent SQLNode, node SelectExpr, replace return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteSelectStatement(parent SQLNode, node SelectStatement, replacer replacerFunc) bool { if node == nil { return true @@ -11167,6 +14442,8 @@ func (a *application) rewriteSelectStatement(parent SQLNode, node SelectStatemen return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteShowInternal(parent SQLNode, node ShowInternal, replacer replacerFunc) bool { if node == nil { return true @@ -11185,6 +14462,8 @@ func (a *application) rewriteShowInternal(parent SQLNode, node ShowInternal, rep return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteSimpleTableExpr(parent SQLNode, node SimpleTableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -11199,6 +14478,8 @@ func (a *application) rewriteSimpleTableExpr(parent SQLNode, node SimpleTableExp return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteStatement(parent SQLNode, node Statement, replacer replacerFunc) bool { if node == nil { return true @@ -11309,6 +14590,8 @@ func (a *application) rewriteStatement(parent SQLNode, node Statement, replacer return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteTableExpr(parent SQLNode, node TableExpr, replacer replacerFunc) bool { if node == nil { return true @@ -11327,6 +14610,8 @@ func (a *application) rewriteTableExpr(parent SQLNode, node TableExpr, replacer return true } } + +// Function Generation Source: InterfaceMethod func (a *application) rewriteTableStatement(parent SQLNode, node TableStatement, replacer replacerFunc) bool { if node == nil { return true @@ -11343,6 +14628,8 @@ func (a *application) rewriteTableStatement(parent SQLNode, node TableStatement, return true } } + +// Function Generation Source: BasicMethod func (a *application) rewriteAlgorithmValue(parent SQLNode, node AlgorithmValue, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -11369,6 +14656,8 @@ func (a *application) rewriteAlgorithmValue(parent SQLNode, node AlgorithmValue, } return true } + +// Function Generation Source: BasicMethod func (a *application) rewriteBoolVal(parent SQLNode, node BoolVal, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -11395,6 +14684,8 @@ func (a *application) rewriteBoolVal(parent SQLNode, node BoolVal, replacer repl } return true } + +// Function Generation Source: BasicMethod func (a *application) rewriteListArg(parent SQLNode, node ListArg, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -11421,6 +14712,8 @@ func (a *application) rewriteListArg(parent SQLNode, node ListArg, replacer repl } return true } + +// Function Generation Source: BasicMethod func (a *application) rewriteMatchAction(parent SQLNode, node MatchAction, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -11447,6 +14740,8 @@ func (a *application) rewriteMatchAction(parent SQLNode, node MatchAction, repla } return true } + +// Function Generation Source: BasicMethod func (a *application) rewriteReferenceAction(parent SQLNode, node ReferenceAction, replacer replacerFunc) bool { if a.pre != nil { a.cur.replacer = replacer @@ -11473,6 +14768,8 @@ func (a *application) rewriteReferenceAction(parent SQLNode, node ReferenceActio } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIdentifierCI(parent SQLNode, node *IdentifierCI, replacer replacerFunc) bool { if node == nil { return true @@ -11502,6 +14799,8 @@ func (a *application) rewriteRefOfIdentifierCI(parent SQLNode, node *IdentifierC } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfIdentifierCS(parent SQLNode, node *IdentifierCS, replacer replacerFunc) bool { if node == nil { return true @@ -11531,6 +14830,8 @@ func (a *application) rewriteRefOfIdentifierCS(parent SQLNode, node *IdentifierC } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfRootNode(parent SQLNode, node *RootNode, replacer replacerFunc) bool { if node == nil { return true @@ -11548,11 +14849,17 @@ func (a *application) rewriteRefOfRootNode(parent SQLNode, node *RootNode, repla return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfRootNodeSQLNode)) + } if !a.rewriteSQLNode(node, node.SQLNode, func(newNode, parent SQLNode) { parent.(*RootNode).SQLNode = newNode.(SQLNode) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -11563,6 +14870,8 @@ func (a *application) rewriteRefOfRootNode(parent SQLNode, node *RootNode, repla } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfTableName(parent SQLNode, node *TableName, replacer replacerFunc) bool { if node == nil { return true @@ -11580,16 +14889,26 @@ func (a *application) rewriteRefOfTableName(parent SQLNode, node *TableName, rep return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfTableNameName)) + } if !a.rewriteIdentifierCS(node, node.Name, func(newNode, parent SQLNode) { parent.(*TableName).Name = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + a.cur.current.AddStep(uint16(RefOfTableNameQualifier)) + } if !a.rewriteIdentifierCS(node, node.Qualifier, func(newNode, parent SQLNode) { parent.(*TableName).Qualifier = newNode.(IdentifierCS) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent @@ -11600,6 +14919,8 @@ func (a *application) rewriteRefOfTableName(parent SQLNode, node *TableName, rep } return true } + +// Function Generation Source: PtrToStructMethod func (a *application) rewriteRefOfVindexParam(parent SQLNode, node *VindexParam, replacer replacerFunc) bool { if node == nil { return true @@ -11617,11 +14938,17 @@ func (a *application) rewriteRefOfVindexParam(parent SQLNode, node *VindexParam, return true } } + if a.collectPaths { + a.cur.current.AddStep(uint16(RefOfVindexParamKey)) + } if !a.rewriteIdentifierCI(node, node.Key, func(newNode, parent SQLNode) { parent.(*VindexParam).Key = newNode.(IdentifierCI) }) { return false } + if a.collectPaths { + a.cur.current.Pop() + } if a.post != nil { a.cur.replacer = replacer a.cur.parent = parent diff --git a/go/vt/sqlparser/ast_visit.go b/go/vt/sqlparser/ast_visit.go index b8ece9e3ae3..c2cc02887f0 100644 --- a/go/vt/sqlparser/ast_visit.go +++ b/go/vt/sqlparser/ast_visit.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/sqlparser/pathbuilder/builder.go b/go/vt/sqlparser/pathbuilder/builder.go new file mode 100644 index 00000000000..321c1d217e7 --- /dev/null +++ b/go/vt/sqlparser/pathbuilder/builder.go @@ -0,0 +1,71 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pathbuilder + +import ( + "encoding/binary" +) + +// ASTPathBuilder is used to build +// paths for an AST. The steps are uints. +type ASTPathBuilder struct { + path []byte + sizes []int +} + +const initialCap = 16 + +// NewASTPathBuilder creates a new ASTPathBuilder +func NewASTPathBuilder() *ASTPathBuilder { + return &ASTPathBuilder{ + path: make([]byte, 0, initialCap), + } +} + +// ToPath returns the current path as a string of the used bytes. +func (apb *ASTPathBuilder) ToPath() string { + return string(apb.path) +} + +// AddStep appends a single step (2 bytes) to path. +func (apb *ASTPathBuilder) AddStep(step uint16) { + apb.sizes = append(apb.sizes, len(apb.path)) + apb.path = binary.BigEndian.AppendUint16(apb.path, step) +} + +// AddStepWithOffset appends a single step (2 bytes) + varint offset with value 0 to path. +func (apb *ASTPathBuilder) AddStepWithOffset(step uint16) { + apb.sizes = append(apb.sizes, len(apb.path)) + apb.path = binary.BigEndian.AppendUint16(apb.path, step) + apb.path = binary.AppendUvarint(apb.path, 0) // 0 offset +} + +// ChangeOffset modifies the offset of the last step (which must have included an offset). +func (apb *ASTPathBuilder) ChangeOffset(newOffset int) { + pos := apb.sizes[len(apb.sizes)-1] + 2 + apb.path = binary.AppendUvarint(apb.path[:pos], uint64(newOffset)) +} + +// Pop removes the last step (including offset, if any) from the path. +func (apb *ASTPathBuilder) Pop() { + if len(apb.sizes) == 0 { + return + } + n := len(apb.sizes) - 1 + apb.path = apb.path[:apb.sizes[n]] + apb.sizes = apb.sizes[:n] +} diff --git a/go/vt/sqlparser/pathbuilder/builder_test.go b/go/vt/sqlparser/pathbuilder/builder_test.go new file mode 100644 index 00000000000..3164922efc4 --- /dev/null +++ b/go/vt/sqlparser/pathbuilder/builder_test.go @@ -0,0 +1,134 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package pathbuilder + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestASTPathBuilderAddStep(t *testing.T) { + tests := []struct { + name string + steps []uint16 + wantPath string + }{ + { + name: "single step", + steps: []uint16{1}, + wantPath: "\x00\x01", + }, + { + name: "multiple steps", + steps: []uint16{1, 0x24, 0x913}, + wantPath: "\x00\x01\x00\x24\x09\x13", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + apb := NewASTPathBuilder() + for _, step := range tt.steps { + apb.AddStep(step) + } + require.Equal(t, tt.wantPath, apb.ToPath()) + }) + } +} + +func TestASTPathBuilderAddStepOffset(t *testing.T) { + tests := []struct { + name string + steps []uint16 + offsets []int + wantPath string + }{ + { + name: "single step", + steps: []uint16{1}, + offsets: []int{0}, + wantPath: "\x00\x01\x00", + }, + { + name: "multiple steps", + steps: []uint16{1, 0x24, 0x913, 0x913}, + offsets: []int{0, -1, 0, 1}, // the 0 is overwritten by the last offset + wantPath: "\x00\x01\x00\x00\x24\x09\x13\x01", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + apb := NewASTPathBuilder() + for idx, step := range tt.steps { + switch { + case tt.offsets[idx] == -1: + apb.AddStep(step) + case tt.offsets[idx] == 0: + apb.AddStepWithOffset(step) + default: + apb.ChangeOffset(tt.offsets[idx]) + } + } + require.Equal(t, tt.wantPath, apb.ToPath()) + }) + } +} + +func TestASTPathBuilderPop(t *testing.T) { + tests := []struct { + name string + steps []uint16 + offsets []int + wantPath string + }{ + { + name: "single step", + steps: []uint16{1}, + offsets: []int{0}, + wantPath: "", + }, + { + name: "multiple steps - final step with offset", + steps: []uint16{1, 0x24, 0x913}, + offsets: []int{0, -1, 0, 1}, + wantPath: "\x00\x01\x00\x00\x24", + }, + { + name: "multiple steps - final step without offset", + steps: []uint16{1, 0x24, 0x913}, + offsets: []int{0, -1, -1}, + wantPath: "\x00\x01\x00\x00\x24", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + apb := NewASTPathBuilder() + for idx, step := range tt.steps { + switch { + case tt.offsets[idx] == -1: + apb.AddStep(step) + case tt.offsets[idx] == 0: + apb.AddStepWithOffset(step) + default: + apb.ChangeOffset(tt.offsets[idx]) + } + } + apb.Pop() + require.Equal(t, tt.wantPath, apb.ToPath()) + }) + } +} diff --git a/go/vt/sqlparser/paths.go b/go/vt/sqlparser/paths.go new file mode 100644 index 00000000000..0e9020dc07b --- /dev/null +++ b/go/vt/sqlparser/paths.go @@ -0,0 +1,88 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sqlparser + +import ( + "fmt" + "strings" +) + +// ASTPath is stored as a string. +// Each 2 bytes => one step (big-endian). +// Some steps (e.g., referencing a slice) consume *additional* bytes for an index +type ASTPath string + +// nextPathOffset is an implementation of binary.Uvarint that works directly on +// the ASTPath without having to cast and allocate a byte slice +func (path ASTPath) nextPathOffset() (uint64, int) { + var x uint64 + var s uint + for i := 0; i < len(path); i++ { + b := path[i] + if b < 0x80 { + return x | uint64(b)<= 2 { + // If this isn't the very first step in the path, prepend a separator + if stepCount > 0 { + sb.WriteString("->") + } + stepCount++ + + // Read the step code (2 bytes) + step := path.nextPathStep() + path = path[2:] + + // Write the step name + stepStr := step.DebugString() + sb.WriteString(stepStr) + + // Check suffix to see if we need to read an offset + switch { + case strings.HasSuffix(stepStr, "Offset"): + if len(path) < 1 { + sb.WriteString("(ERR-no-offset-byte)") + return sb.String() + } + offset, readBytes := path.nextPathOffset() + path = path[readBytes:] + sb.WriteString(fmt.Sprintf("(%d)", offset)) + } + } + + // If there's leftover data that doesn't fit into 2 (or more) bytes, you could note it: + if len(path) != 0 { + sb.WriteString("->(ERR-unaligned-extra-bytes)") + } + + return sb.String() +} diff --git a/go/vt/sqlparser/paths_test.go b/go/vt/sqlparser/paths_test.go new file mode 100644 index 00000000000..14de7101854 --- /dev/null +++ b/go/vt/sqlparser/paths_test.go @@ -0,0 +1,51 @@ +/* +Copyright 2025 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sqlparser + +import ( + "encoding/binary" + "testing" + + "github.com/stretchr/testify/assert" +) + +// AddStep appends a single step (2 bytes) to path. +func AddStep(path ASTPath, step ASTStep) ASTPath { + b := make([]byte, 2) + binary.BigEndian.PutUint16(b, uint16(step)) + return path + ASTPath(b) +} + +func AddStepWithOffset(path ASTPath, step ASTStep, offset int) ASTPath { + var buf [10]byte + binary.BigEndian.PutUint16(buf[0:], uint16(step)) + n := binary.PutUvarint(buf[2:], uint64(offset)) + + return path + ASTPath(buf[:2+n]) +} + +func TestASTPathDebugString(t *testing.T) { + // select * from t where func(1,2,x) = 10 + // path to X + p := ASTPath("") + p = AddStep(p, RefOfSelectWhere) + p = AddStep(p, RefOfWhereExpr) + p = AddStep(p, RefOfBinaryExprLeft) + p = AddStepWithOffset(p, RefOfFuncExprExprsOffset, 2) + expected := "(*Select).Where->(*Where).Expr->(*BinaryExpr).Left->(*FuncExpr).ExprsOffset(2)" + assert.Equal(t, expected, p.DebugString()) +} diff --git a/go/vt/sqlparser/rewriter_api.go b/go/vt/sqlparser/rewriter_api.go index 5dc4b30cc59..e159987e8e1 100644 --- a/go/vt/sqlparser/rewriter_api.go +++ b/go/vt/sqlparser/rewriter_api.go @@ -16,7 +16,7 @@ limitations under the License. package sqlparser -// The rewriter was heavily inspired by https://github.com/golang/tools/blob/master/go/ast/astutil/rewrite.go +import "vitess.io/vitess/go/vt/sqlparser/pathbuilder" // Rewrite traverses a syntax tree recursively, starting with root, // and calling pre and post for each node as described below. @@ -34,6 +34,10 @@ package sqlparser // Only fields that refer to AST nodes are considered children; // i.e., fields of basic types (strings, []byte, etc.) are ignored. func Rewrite(node SQLNode, pre, post ApplyFunc) (result SQLNode) { + return rewriteNode(node, pre, post, false) +} + +func rewriteNode(node SQLNode, pre ApplyFunc, post ApplyFunc, collectPaths bool) SQLNode { parent := &RootNode{node} // this is the root-replacer, used when the user replaces the root of the ast @@ -42,8 +46,13 @@ func Rewrite(node SQLNode, pre, post ApplyFunc) (result SQLNode) { } a := &application{ - pre: pre, - post: post, + pre: pre, + post: post, + collectPaths: collectPaths, + } + + if collectPaths { + a.cur.current = pathbuilder.NewASTPathBuilder() } a.rewriteSQLNode(parent, node, replacer) @@ -51,6 +60,10 @@ func Rewrite(node SQLNode, pre, post ApplyFunc) (result SQLNode) { return parent.SQLNode } +func RewriteWithPath(node SQLNode, pre, post ApplyFunc) (result SQLNode) { + return rewriteNode(node, pre, post, true) +} + // SafeRewrite does not allow replacing nodes on the down walk of the tree walking // Long term this is the only Rewrite functionality we want func SafeRewrite( @@ -97,6 +110,7 @@ type Cursor struct { // marks that the node has been replaced, and the new node should be visited revisit bool + current *pathbuilder.ASTPathBuilder } // Node returns the current Node. @@ -130,10 +144,17 @@ func (c *Cursor) ReplaceAndRevisit(newNode SQLNode) { c.revisit = true } +// Path returns the current path that got us to the current location in the AST +// Only works if the AST walk was configured to collect path as walking +func (c *Cursor) Path() ASTPath { + return ASTPath(c.current.ToPath()) +} + type replacerFunc func(newNode, parent SQLNode) // application carries all the shared data so we can pass it around cheaply. type application struct { - pre, post ApplyFunc - cur Cursor + pre, post ApplyFunc + cur Cursor + collectPaths bool } diff --git a/go/vt/sqlparser/rewriter_test.go b/go/vt/sqlparser/rewriter_test.go index b7d24406677..5811c672b7a 100644 --- a/go/vt/sqlparser/rewriter_test.go +++ b/go/vt/sqlparser/rewriter_test.go @@ -65,6 +65,45 @@ func TestReplaceWorksInLaterCalls(t *testing.T) { assert.Equal(t, 2, count) } +func TestFindColNamesWithPaths(t *testing.T) { + // this is the tpch query #1 + q := ` +select l_returnflag, + l_linestatus, + sum(l_quantity) as sum_qty, + sum(l_extendedprice) as sum_base_price, + sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, + sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, + avg(l_quantity) as avg_qty, + avg(l_extendedprice) as avg_price, + avg(l_discount) as avg_disc, + count(*) as count_order +from lineitem +where l_shipdate <= '1998-12-01' - interval '108' day +group by l_returnflag, l_linestatus +order by l_returnflag, l_linestatus` + ast, err := NewTestParser().Parse(q) + require.NoError(t, err) + + var foundColNamePaths []ASTPath + var foundColNames []*ColName + RewriteWithPath(ast, + func(cursor *Cursor) bool { + colName, ok := cursor.Node().(*ColName) + if ok { + foundColNames = append(foundColNames, colName) + foundColNamePaths = append(foundColNamePaths, cursor.Path()) + } + + return true + }, nil) + + for idx, path := range foundColNamePaths { + node := GetNodeFromPath(ast, path) + require.Same(t, foundColNames[idx], node) + } +} + func TestReplaceAndRevisitWorksInLaterCalls(t *testing.T) { q := "select * from tbl1" parser := NewTestParser() diff --git a/go/vt/vtgate/planbuilder/operators/join.go b/go/vt/vtgate/planbuilder/operators/join.go index ff4915527a7..5e8dbc4eabd 100644 --- a/go/vt/vtgate/planbuilder/operators/join.go +++ b/go/vt/vtgate/planbuilder/operators/join.go @@ -103,7 +103,7 @@ func createLeftOuterJoin(ctx *plancontext.PlanningContext, join *sqlparser.JoinT // for outer joins we have to be careful with the predicates we use var op Operator - subq, _ := getSubQuery(join.Condition.On) + subq, _, _ := getSubQuery(join.Condition.On) if subq != nil { panic(vterrors.VT12001("subquery in outer join predicate")) } diff --git a/go/vt/vtgate/planbuilder/operators/subquery_builder.go b/go/vt/vtgate/planbuilder/operators/subquery_builder.go index cc7dc9afe69..d9c29d936ab 100644 --- a/go/vt/vtgate/planbuilder/operators/subquery_builder.go +++ b/go/vt/vtgate/planbuilder/operators/subquery_builder.go @@ -53,22 +53,23 @@ func (sqb *SubQueryBuilder) handleSubquery( expr sqlparser.Expr, outerID semantics.TableSet, ) *SubQuery { - subq, parentExpr := getSubQuery(expr) + subq, parentExpr, path := getSubQuery(expr) if subq == nil { return nil } argName := ctx.GetReservedArgumentFor(subq) - sqInner := createSubqueryOp(ctx, parentExpr, expr, subq, outerID, argName) + sqInner := createSubqueryOp(ctx, parentExpr, expr, subq, outerID, argName, path) sqb.Inner = append(sqb.Inner, sqInner) return sqInner } -func getSubQuery(expr sqlparser.Expr) (subqueryExprExists *sqlparser.Subquery, parentExpr sqlparser.Expr) { +func getSubQuery(expr sqlparser.Expr) (subqueryExprExists *sqlparser.Subquery, parentExpr sqlparser.Expr, path sqlparser.ASTPath) { flipped := false - _ = sqlparser.Rewrite(expr, func(cursor *sqlparser.Cursor) bool { + _ = sqlparser.RewriteWithPath(expr, func(cursor *sqlparser.Cursor) bool { if subq, ok := cursor.Node().(*sqlparser.Subquery); ok { subqueryExprExists = subq + path = cursor.Path() parentExpr = subq if expr, ok := cursor.Parent().(sqlparser.Expr); ok { parentExpr = expr @@ -95,21 +96,22 @@ func createSubqueryOp( subq *sqlparser.Subquery, outerID semantics.TableSet, name string, + path sqlparser.ASTPath, ) *SubQuery { switch parent := parent.(type) { case *sqlparser.NotExpr: switch parent.Expr.(type) { case *sqlparser.ExistsExpr: - return createSubquery(ctx, original, subq, outerID, parent, name, opcode.PulloutNotExists, false) + return createSubqueryFromPath(ctx, original, subq, path, outerID, parent, name, opcode.PulloutNotExists, false) case *sqlparser.ComparisonExpr: panic("should have been rewritten") } case *sqlparser.ExistsExpr: - return createSubquery(ctx, original, subq, outerID, parent, name, opcode.PulloutExists, false) + return createSubqueryFromPath(ctx, original, subq, path, outerID, parent, name, opcode.PulloutExists, false) case *sqlparser.ComparisonExpr: - return createComparisonSubQuery(ctx, parent, original, subq, outerID, name) + return createComparisonSubQuery(ctx, parent, original, subq, path, outerID, name) } - return createSubquery(ctx, original, subq, outerID, parent, name, opcode.PulloutValue, false) + return createSubqueryFromPath(ctx, original, subq, path, outerID, parent, name, opcode.PulloutValue, false) } // inspectStatement goes through all the predicates contained in the AST @@ -188,6 +190,44 @@ func createSubquery( } } +func createSubqueryFromPath( + ctx *plancontext.PlanningContext, + original sqlparser.Expr, + subq *sqlparser.Subquery, + path sqlparser.ASTPath, + outerID semantics.TableSet, + parent sqlparser.Expr, + argName string, + filterType opcode.PulloutOpcode, + isArg bool, +) *SubQuery { + topLevel := ctx.SemTable.EqualsExpr(original, parent) + original = cloneASTAndSemState(ctx, original) + originalSq := sqlparser.GetNodeFromPath(original, path).(*sqlparser.Subquery) + subqID := findTablesContained(ctx, originalSq.Select) + totalID := subqID.Merge(outerID) + sqc := &SubQueryBuilder{totalID: totalID, subqID: subqID, outerID: outerID} + + predicates, joinCols := sqc.inspectStatement(ctx, subq.Select) + correlated := !ctx.SemTable.RecursiveDeps(subq).IsEmpty() + + opInner := translateQueryToOp(ctx, subq.Select) + + opInner = sqc.getRootOperator(opInner, nil) + return &SubQuery{ + FilterType: filterType, + Subquery: opInner, + Predicates: predicates, + Original: original, + ArgName: argName, + originalSubquery: originalSq, + IsArgument: isArg, + TopLevel: topLevel, + JoinColumns: joinCols, + correlated: correlated, + } +} + func (sqb *SubQueryBuilder) inspectWhere( ctx *plancontext.PlanningContext, in *sqlparser.Where, @@ -260,6 +300,7 @@ func createComparisonSubQuery( parent *sqlparser.ComparisonExpr, original sqlparser.Expr, subFromOutside *sqlparser.Subquery, + path sqlparser.ASTPath, outerID semantics.TableSet, name string, ) *SubQuery { @@ -276,7 +317,7 @@ func createComparisonSubQuery( filterType = opcode.PulloutNotIn } - subquery := createSubquery(ctx, original, subq, outerID, parent, name, filterType, false) + subquery := createSubqueryFromPath(ctx, original, subq, path, outerID, parent, name, filterType, false) // if we are comparing with a column from the inner subquery, // we add this extra predicate to check if the two sides are mergable or not diff --git a/go/vt/vtgate/semantics/semantic_table.go b/go/vt/vtgate/semantics/semantic_table.go index efe574501c1..c8e4ca35350 100644 --- a/go/vt/vtgate/semantics/semantic_table.go +++ b/go/vt/vtgate/semantics/semantic_table.go @@ -654,6 +654,21 @@ func (st *SemTable) GetExprAndEqualities(expr sqlparser.Expr) []sqlparser.Expr { return result } +// ForEachExprEquality returns a slice containing the given expression, and it's known equalities if any +func (st *SemTable) ForEachExprEquality(in sqlparser.Expr, forEach func(sqlparser.Expr) error) error { + switch expr := in.(type) { + case *sqlparser.ColName: + table := st.DirectDeps(expr) + k := columnName{Table: table, ColumnName: expr.Name.String()} + for _, expr := range st.ColumnEqualities[k] { + if err := forEach(expr); err != nil { + return err + } + } + } + return nil +} + // TableInfoForExpr returns the table info of the table that this expression depends on. // Careful: this only works for expressions that have a single table dependency func (st *SemTable) TableInfoForExpr(expr sqlparser.Expr) (TableInfo, error) { From 67d081a7a33cac32d1639f22afad91b9a52d999c Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Sun, 16 Feb 2025 13:10:46 +0100 Subject: [PATCH 10/19] Remove bits of unused code across various packages (#17785) --- go/bytes2/buffer.go | 5 ----- go/bytes2/buffer_test.go | 2 +- go/cache/theine/bf/bf.go | 10 ---------- go/cache/theine/bf/bf_test.go | 5 +---- go/cmd/vtctldclient/command/framework_test.go | 8 -------- go/sqltypes/value_test.go | 15 ++------------- go/test/vschemawrapper/vschema_wrapper.go | 14 -------------- go/vt/schemadiff/table.go | 10 ---------- go/vt/sqlparser/rewriter_api.go | 9 --------- go/vt/sqlparser/tracked_buffer.go | 6 ------ go/vt/vttablet/onlineddl/executor.go | 5 ----- go/vt/vttablet/onlineddl/vrepl.go | 13 ------------- go/vt/wrangler/testlib/fake_tablet.go | 8 -------- 13 files changed, 4 insertions(+), 106 deletions(-) diff --git a/go/bytes2/buffer.go b/go/bytes2/buffer.go index 48561c5e493..ba0b1ec2265 100644 --- a/go/bytes2/buffer.go +++ b/go/bytes2/buffer.go @@ -28,11 +28,6 @@ type Buffer struct { bytes []byte } -// NewBuffer is equivalent to bytes.NewBuffer. -func NewBuffer(b []byte) *Buffer { - return &Buffer{bytes: b} -} - // Write is equivalent to bytes.Buffer.Write. func (buf *Buffer) Write(b []byte) (int, error) { buf.bytes = append(buf.bytes, b...) diff --git a/go/bytes2/buffer_test.go b/go/bytes2/buffer_test.go index 1652f176df4..5171059d375 100644 --- a/go/bytes2/buffer_test.go +++ b/go/bytes2/buffer_test.go @@ -23,7 +23,7 @@ import ( ) func TestBuffer(t *testing.T) { - b := NewBuffer(nil) + var b Buffer // Test Write function b.Write([]byte("ab")) diff --git a/go/cache/theine/bf/bf.go b/go/cache/theine/bf/bf.go index 97b27a5c217..3549d709d97 100644 --- a/go/cache/theine/bf/bf.go +++ b/go/cache/theine/bf/bf.go @@ -19,16 +19,6 @@ func New(falsePositiveRate float64) *Bloomfilter { return d } -// create new bloomfilter with given size in bytes -func NewWithSize(size uint32) *Bloomfilter { - d := &Bloomfilter{} - bits := size * 8 - m := nextPowerOfTwo(uint32(bits)) - d.M = m - d.Filter = newbv(m) - return d -} - func (d *Bloomfilter) EnsureCapacity(capacity int) { if capacity <= d.Capacity { return diff --git a/go/cache/theine/bf/bf_test.go b/go/cache/theine/bf/bf_test.go index 135826195ac..12999cdcbc9 100644 --- a/go/cache/theine/bf/bf_test.go +++ b/go/cache/theine/bf/bf_test.go @@ -7,11 +7,8 @@ import ( ) func TestBloom(t *testing.T) { - bf := NewWithSize(5) - bf.FalsePositiveRate = 0.1 - bf.EnsureCapacity(5) + bf := New(0.1) bf.EnsureCapacity(500) - bf.EnsureCapacity(200) exist := bf.Insert(123) require.False(t, exist) diff --git a/go/cmd/vtctldclient/command/framework_test.go b/go/cmd/vtctldclient/command/framework_test.go index 3e4a6753411..351356ea3a0 100644 --- a/go/cmd/vtctldclient/command/framework_test.go +++ b/go/cmd/vtctldclient/command/framework_test.go @@ -101,14 +101,6 @@ func TabletKeyspaceShard(t *testing.T, keyspace, shard string) TabletOption { } } -// ForceInitTablet is the tablet option to set the 'force' flag during InitTablet -func ForceInitTablet() TabletOption { - return func(tablet *topodatapb.Tablet) { - // set the force_init field into the portmap as a hack - tablet.PortMap["force_init"] = 1 - } -} - // StartHTTPServer is the tablet option to start the HTTP server when // starting a tablet. func StartHTTPServer() TabletOption { diff --git a/go/sqltypes/value_test.go b/go/sqltypes/value_test.go index f6360c8b5c4..e71e866c9f5 100644 --- a/go/sqltypes/value_test.go +++ b/go/sqltypes/value_test.go @@ -20,7 +20,6 @@ import ( "math" "strings" "testing" - "time" "github.com/stretchr/testify/assert" @@ -612,16 +611,6 @@ func TestToUint32(t *testing.T) { } } -var randomLocation = time.FixedZone("Nowhere", 3*60*60) - -func DatetimeValue(str string) Value { - return TestValue(Datetime, str) -} - -func DateValue(str string) Value { - return TestValue(Date, str) -} - func TestEncodeSQLStringBuilder(t *testing.T) { testcases := []struct { in Value @@ -680,9 +669,9 @@ func TestEncodeSQLBytes2(t *testing.T) { outSQL: "\x89\x02\x011\x950\x03foo", }} for _, tcase := range testcases { - buf := bytes2.NewBuffer([]byte{}) + var buf bytes2.Buffer - tcase.in.EncodeSQLBytes2(buf) + tcase.in.EncodeSQLBytes2(&buf) assert.Equal(t, tcase.outSQL, buf.String()) } } diff --git a/go/test/vschemawrapper/vschema_wrapper.go b/go/test/vschemawrapper/vschema_wrapper.go index 02daa646bf8..b48d7f5d0b7 100644 --- a/go/test/vschemawrapper/vschema_wrapper.go +++ b/go/test/vschemawrapper/vschema_wrapper.go @@ -288,20 +288,6 @@ func (vw *VSchemaWrapper) FindTableOrVindex(tab sqlparser.TableName) (*vindexes. return vw.Vcursor.FindTableOrVindex(tab) } -func (vw *VSchemaWrapper) getActualKeyspace() string { - if vw.Keyspace == nil { - return "" - } - if !sqlparser.SystemSchema(vw.Keyspace.Name) { - return vw.Keyspace.Name - } - ks, err := vw.AnyKeyspace() - if err != nil { - return "" - } - return ks.Name -} - func (vw *VSchemaWrapper) SelectedKeyspace() (*vindexes.Keyspace, error) { return vw.AnyKeyspace() } diff --git a/go/vt/schemadiff/table.go b/go/vt/schemadiff/table.go index 88f8e7d4ce8..182aa9537e7 100644 --- a/go/vt/schemadiff/table.go +++ b/go/vt/schemadiff/table.go @@ -1099,16 +1099,6 @@ func (c *CreateTableEntity) TableDiff(other *CreateTableEntity, hints *DiffHints return parentAlterTableEntityDiff, nil } -func (c *CreateTableEntity) diffTableCharset( - t1cc *charsetCollate, - t2cc *charsetCollate, -) string { - if t1cc.charset != t2cc.charset { - return t2cc.charset - } - return "" -} - // isDefaultTableOptionValue sees if the value for a TableOption is also its default value func isDefaultTableOptionValue(option *sqlparser.TableOption) bool { var value string diff --git a/go/vt/sqlparser/rewriter_api.go b/go/vt/sqlparser/rewriter_api.go index e159987e8e1..5641681b447 100644 --- a/go/vt/sqlparser/rewriter_api.go +++ b/go/vt/sqlparser/rewriter_api.go @@ -126,15 +126,6 @@ func (c *Cursor) Replace(newNode SQLNode) { c.node = newNode } -// ReplacerF returns a replace func that will work even when the cursor has moved to a different node. -func (c *Cursor) ReplacerF() func(newNode SQLNode) { - replacer := c.replacer - parent := c.parent - return func(newNode SQLNode) { - replacer(newNode, parent) - } -} - // ReplaceAndRevisit replaces the current node in the parent field with this new object. // When used, this will abort the visitation of the current node - no post or children visited, // and the new node visited. diff --git a/go/vt/sqlparser/tracked_buffer.go b/go/vt/sqlparser/tracked_buffer.go index 9ef0cfd1f93..7fdb741aed6 100644 --- a/go/vt/sqlparser/tracked_buffer.go +++ b/go/vt/sqlparser/tracked_buffer.go @@ -430,12 +430,6 @@ func CanonicalString(node SQLNode) string { return buf.String() } -func FormatSlice[T SQLNode](buf *TrackedBuffer, valueExprs []T) { - for _, expr := range valueExprs { - buf.Myprintf("%v", expr) - } -} - func SliceString[T SQLNode](valueExprs []T) string { return SliceStringWithSep(valueExprs, ", ") } diff --git a/go/vt/vttablet/onlineddl/executor.go b/go/vt/vttablet/onlineddl/executor.go index ea6ea8732d2..3a3d1a9906e 100644 --- a/go/vt/vttablet/onlineddl/executor.go +++ b/go/vt/vttablet/onlineddl/executor.go @@ -25,7 +25,6 @@ import ( "errors" "fmt" "os" - "path" "strconv" "strings" "sync" @@ -425,10 +424,6 @@ func (e *Executor) isAnyConflictingMigrationRunning(onlineDDL *schema.OnlineDDL) return (conflictingMigration != nil), conflictingMigration } -func (e *Executor) ptPidFileName(uuid string) string { - return path.Join(os.TempDir(), fmt.Sprintf("pt-online-schema-change.%s.pid", uuid)) -} - // tableExists checks if a given table exists. func (e *Executor) tableExists(ctx context.Context, tableName string) (bool, error) { tableName = strings.ReplaceAll(tableName, `_`, `\_`) diff --git a/go/vt/vttablet/onlineddl/vrepl.go b/go/vt/vttablet/onlineddl/vrepl.go index 7423b05a574..52ac775adfe 100644 --- a/go/vt/vttablet/onlineddl/vrepl.go +++ b/go/vt/vttablet/onlineddl/vrepl.go @@ -226,19 +226,6 @@ func (v *VRepl) readTableStatus(ctx context.Context, conn *dbconnpool.DBConnecti return tableRows, err } -// formalizeColumns -func formalizeColumns(columnsLists ...*schemadiff.ColumnDefinitionEntityList) error { - for _, colList := range columnsLists { - for _, col := range colList.Entities { - col.SetExplicitDefaultAndNull() - if err := col.SetExplicitCharsetCollate(); err != nil { - return err - } - } - } - return nil -} - func (v *VRepl) analyzeAlter() error { if v.alterTableAnalysis.IsRenameTable { return fmt.Errorf("renaming the table is not supported in ALTER TABLE") diff --git a/go/vt/wrangler/testlib/fake_tablet.go b/go/vt/wrangler/testlib/fake_tablet.go index 97d74edf3f7..9649d717d73 100644 --- a/go/vt/wrangler/testlib/fake_tablet.go +++ b/go/vt/wrangler/testlib/fake_tablet.go @@ -102,14 +102,6 @@ func TabletKeyspaceShard(t *testing.T, keyspace, shard string) TabletOption { } } -// ForceInitTablet is the tablet option to set the 'force' flag during InitTablet -func ForceInitTablet() TabletOption { - return func(tablet *topodatapb.Tablet) { - // set the force_init field into the portmap as a hack - tablet.PortMap["force_init"] = 1 - } -} - // StartHTTPServer is the tablet option to start the HTTP server when // starting a tablet. func StartHTTPServer() TabletOption { From c88ac785d668fe244a5f756b297aa92c8a99f19b Mon Sep 17 00:00:00 2001 From: Arthur Schreiber Date: Mon, 17 Feb 2025 15:26:50 +0100 Subject: [PATCH 11/19] Fix a potential connection pool leak. (#17807) Signed-off-by: Arthur Schreiber --- go/pools/smartconnpool/stack.go | 1 + go/pools/smartconnpool/stack_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 go/pools/smartconnpool/stack_test.go diff --git a/go/pools/smartconnpool/stack.go b/go/pools/smartconnpool/stack.go index 8d656ee4e8d..af86fa354bd 100644 --- a/go/pools/smartconnpool/stack.go +++ b/go/pools/smartconnpool/stack.go @@ -51,6 +51,7 @@ func (s *connStack[C]) Pop() (*Pooled[C], bool) { newHead := oldHead.next.Load() if s.top.CompareAndSwap(oldHead, popCount, newHead, popCount+1) { + oldHead.next.Store(nil) return oldHead, true } runtime.Gosched() diff --git a/go/pools/smartconnpool/stack_test.go b/go/pools/smartconnpool/stack_test.go new file mode 100644 index 00000000000..a8150bd8186 --- /dev/null +++ b/go/pools/smartconnpool/stack_test.go @@ -0,0 +1,26 @@ +package smartconnpool + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +type testPooled struct { + Connection +} + +func TestStackPop(t *testing.T) { + s := &connStack[testPooled]{} + + first := &Pooled[testPooled]{} + s.Push(first) + + second := &Pooled[testPooled]{} + s.Push(second) + + c, ok := s.Pop() + assert.True(t, ok) + + assert.Nil(t, c.next.Load()) +} From 0c6ad63126012a7bb3daa6b86b2736dd30e65a9d Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Tue, 18 Feb 2025 11:16:52 +0100 Subject: [PATCH 12/19] Update to Go 1.24.0 (#17790) Signed-off-by: Dirkjan Bussink Signed-off-by: Florent Poinsard Signed-off-by: Vicent Marti Co-authored-by: Florent Poinsard Co-authored-by: Vicent Marti --- .github/workflows/static_checks_etc.yml | 2 +- .../upgrade_downgrade_test_backups_e2e.yml | 2 +- .../upgrade_downgrade_test_backups_manual.yml | 2 +- .../upgrade_downgrade_test_onlineddl_flow.yml | 2 +- ...e_downgrade_test_query_serving_queries.yml | 2 +- ...downgrade_test_query_serving_queries_2.yml | 2 +- ...de_downgrade_test_query_serving_schema.yml | 2 +- ...rade_downgrade_test_reparent_old_vtctl.yml | 2 +- ...e_downgrade_test_reparent_old_vttablet.yml | 2 +- .../upgrade_downgrade_test_semi_sync.yml | 2 +- .golangci.yml | 4 +- Makefile | 2 +- build.env | 2 +- docker/bootstrap/CHANGELOG.md | 5 +- docker/bootstrap/Dockerfile.common | 2 +- docker/lite/Dockerfile | 2 +- docker/lite/Dockerfile.mysql84 | 2 +- docker/lite/Dockerfile.percona80 | 2 +- docker/vttestserver/Dockerfile.mysql80 | 2 +- docker/vttestserver/Dockerfile.mysql84 | 2 +- go.mod | 2 +- go/hack/ensure_swiss_map.go | 39 +++++++ go/hack/hack_test.go | 46 ++++++++ go/hack/msize.go | 102 ++++++++++++++++++ go/mysql/collations/cached_size.go | 55 ++-------- go/mysql/collations/colldata/cached_size.go | 2 +- go/mysql/decimal/cached_size.go | 2 +- go/mysql/json/cached_size.go | 2 +- go/pools/smartconnpool/cached_size.go | 2 +- go/sqltypes/cached_size.go | 2 +- go/tools/sizegen/integration/cached_size.go | 37 +------ .../sizegen/integration/integration_test.go | 23 ++-- go/tools/sizegen/integration/types.go | 2 + go/tools/sizegen/sizegen.go | 59 +++------- go/vt/key/cached_size.go | 2 +- go/vt/proto/query/cached_size.go | 2 +- go/vt/proto/topodata/cached_size.go | 2 +- go/vt/proto/vttime/cached_size.go | 2 +- go/vt/schema/cached_size.go | 2 +- go/vt/sqlparser/cached_size.go | 19 +--- go/vt/srvtopo/cached_size.go | 2 +- go/vt/tableacl/cached_size.go | 2 +- go/vt/vtenv/cached_size.go | 2 +- go/vt/vtgate/engine/cached_size.go | 91 ++-------------- go/vt/vtgate/evalengine/cached_size.go | 2 +- go/vt/vtgate/vindexes/cached_size.go | 64 ++--------- go/vt/vttablet/tabletserver/cached_size.go | 2 +- .../tabletserver/planbuilder/cached_size.go | 2 +- .../tabletserver/rules/cached_size.go | 2 +- .../tabletserver/schema/cached_size.go | 2 +- go/vt/vttablet/tabletserver/schema/schema.go | 11 +- .../tabletserver/schema/schemaz_test.go | 4 +- misc/git/hooks/golangci-lint | 4 +- test.go | 2 +- test/templates/dockerfile.tpl | 2 +- 55 files changed, 301 insertions(+), 342 deletions(-) create mode 100644 go/hack/ensure_swiss_map.go diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml index b7f14688b95..8af08fbb9eb 100644 --- a/.github/workflows/static_checks_etc.yml +++ b/.github/workflows/static_checks_etc.yml @@ -197,7 +197,7 @@ jobs: - name: Install golangci-lint if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true' - run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.60.2 + run: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.64.5 - name: Clean Env if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml index 9fc4c00e18e..6363811f5b5 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_e2e.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_e2e.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_backups_manual.yml b/.github/workflows/upgrade_downgrade_test_backups_manual.yml index 7ca2c3ebbea..6175883c1b7 100644 --- a/.github/workflows/upgrade_downgrade_test_backups_manual.yml +++ b/.github/workflows/upgrade_downgrade_test_backups_manual.yml @@ -78,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml index 03dd28c2e2a..91062f46211 100644 --- a/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml +++ b/.github/workflows/upgrade_downgrade_test_onlineddl_flow.yml @@ -86,7 +86,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml index e155be9f389..17b73a9dca4 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries.yml @@ -78,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml index 2d58d4c8fae..adff191250c 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_queries_2.yml @@ -78,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml index 8c82838594d..41861a063c9 100644 --- a/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml +++ b/.github/workflows/upgrade_downgrade_test_query_serving_schema.yml @@ -78,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml index b3e2cf6451e..6ed7293a1d4 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vtctl.yml @@ -78,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml index fe0702b2fff..17467c5d57c 100644 --- a/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml +++ b/.github/workflows/upgrade_downgrade_test_reparent_old_vttablet.yml @@ -78,7 +78,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.github/workflows/upgrade_downgrade_test_semi_sync.yml b/.github/workflows/upgrade_downgrade_test_semi_sync.yml index cb950d43e4e..50863df04d2 100644 --- a/.github/workflows/upgrade_downgrade_test_semi_sync.yml +++ b/.github/workflows/upgrade_downgrade_test_semi_sync.yml @@ -74,7 +74,7 @@ jobs: if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' uses: actions/setup-go@0a12ed9d6a96ab950c8f026ed9f722fe0da7ef32 # v5.0.2 with: - go-version: 1.23.5 + go-version: 1.24.0 - name: Set up python if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' diff --git a/.golangci.yml b/.golangci.yml index e907f56743b..63c547fcee9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,5 @@ run: - go: 1.23 + go: 1.24 timeout: 10m linters-settings: @@ -191,4 +191,4 @@ issues: # https://github.com/golangci/golangci/wiki/Configuration service: - golangci-lint-version: 1.52.2 # use the fixed version to not introduce new linters unexpectedly + golangci-lint-version: 1.64.5 # use the fixed version to not introduce new linters unexpectedly diff --git a/Makefile b/Makefile index aeb1955bf18..2ed645315c1 100644 --- a/Makefile +++ b/Makefile @@ -286,7 +286,7 @@ $(PROTO_GO_OUTS): minimaltools install_protoc-gen-go proto/*.proto # This rule builds the bootstrap images for all flavors. DOCKER_IMAGES_FOR_TEST = mysql80 mysql84 percona80 DOCKER_IMAGES = common $(DOCKER_IMAGES_FOR_TEST) -BOOTSTRAP_VERSION=41 +BOOTSTRAP_VERSION=42 ensure_bootstrap_version: find docker/ -type f -exec sed -i "s/^\(ARG bootstrap_version\)=.*/\1=${BOOTSTRAP_VERSION}/" {} \; sed -i 's/\(^.*flag.String(\"bootstrap-version\",\) *\"[^\"]\+\"/\1 \"${BOOTSTRAP_VERSION}\"/' test.go diff --git a/build.env b/build.env index 6818975103f..9f513ec8f54 100755 --- a/build.env +++ b/build.env @@ -17,7 +17,7 @@ source ./tools/shell_functions.inc go version >/dev/null 2>&1 || fail "Go is not installed or is not in \$PATH. See https://vitess.io/contributing/build-from-source for install instructions." -goversion_min 1.23.5 || echo "Go version reported: `go version`. Version 1.23.5+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." +goversion_min 1.24.0 || echo "Go version reported: `go version`. Version 1.24.0+ recommended. See https://vitess.io/contributing/build-from-source for install instructions." mkdir -p dist mkdir -p bin diff --git a/docker/bootstrap/CHANGELOG.md b/docker/bootstrap/CHANGELOG.md index 9728dffbab8..176540c0430 100644 --- a/docker/bootstrap/CHANGELOG.md +++ b/docker/bootstrap/CHANGELOG.md @@ -162,4 +162,7 @@ List of changes between bootstrap image versions. ## [41] - 2025-01-15 ### Changes - Update base image to bookworm -- Add MySQL84 image \ No newline at end of file +- Add MySQL84 image + +## [42] - 2025-02-14 +- Update build to golang 1.24.0 diff --git a/docker/bootstrap/Dockerfile.common b/docker/bootstrap/Dockerfile.common index e0866fe4bda..fcbe8b0c629 100644 --- a/docker/bootstrap/Dockerfile.common +++ b/docker/bootstrap/Dockerfile.common @@ -1,4 +1,4 @@ -FROM --platform=linux/amd64 golang:1.23.5-bookworm +FROM --platform=linux/amd64 golang:1.24.0-bookworm # Install Vitess build dependencies RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index c75a0a5ad4c..70d4787686c 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 index e2836ca3047..047e3d1f90c 100644 --- a/docker/lite/Dockerfile.mysql84 +++ b/docker/lite/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index 16e1da78627..011f20c4022 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql80 b/docker/vttestserver/Dockerfile.mysql80 index 989aebe8740..ec01244e7a7 100644 --- a/docker/vttestserver/Dockerfile.mysql80 +++ b/docker/vttestserver/Dockerfile.mysql80 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/docker/vttestserver/Dockerfile.mysql84 b/docker/vttestserver/Dockerfile.mysql84 index ad944f500a0..9ddc78b640f 100644 --- a/docker/vttestserver/Dockerfile.mysql84 +++ b/docker/vttestserver/Dockerfile.mysql84 @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM --platform=linux/amd64 golang:1.23.5-bookworm AS builder +FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER diff --git a/go.mod b/go.mod index d4e98fda37a..3e73e0a74ef 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module vitess.io/vitess -go 1.23.5 +go 1.24.0 require ( cloud.google.com/go/storage v1.50.0 diff --git a/go/hack/ensure_swiss_map.go b/go/hack/ensure_swiss_map.go new file mode 100644 index 00000000000..b09bde1121c --- /dev/null +++ b/go/hack/ensure_swiss_map.go @@ -0,0 +1,39 @@ +//go:build !goexperiment.swissmap + +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +// This is invalid Go code, and it will fail to compile if you disable +// Swiss maps when building Vitess. Our runtime memory accounting system +// expects the map implementation in Go 1.24 to be Swiss. + +package hack + +var EnsureSwissMapIsAlwaysEnabled = [-1]struct{}{} diff --git a/go/hack/hack_test.go b/go/hack/hack_test.go index 9f71d82cf11..094bd14f5df 100644 --- a/go/hack/hack_test.go +++ b/go/hack/hack_test.go @@ -19,6 +19,7 @@ limitations under the License. package hack import ( + "runtime" "testing" "github.com/stretchr/testify/assert" @@ -47,3 +48,48 @@ func TestStringToByte(t *testing.T) { b = StringBytes(s) assert.Nil(t, b) } + +func testMapSize[K comparable, V any](t *testing.T, gen func(i int) (K, V)) { + for _, size := range []int{16 * 1024, 128 * 1024, 256 * 1024, 512 * 1024, 1024 * 1024} { + var before, after runtime.MemStats + runtime.GC() + runtime.ReadMemStats(&before) + + m := make(map[K]V, size) + for i := 0; i < size; i++ { + k, v := gen(i) + m[k] = v + } + + runtime.GC() + runtime.ReadMemStats(&after) + + heapDiff := after.HeapAlloc - before.HeapAlloc + calcSize := RuntimeMapSize(m) + + assert.InEpsilonf(t, heapDiff, calcSize, 0.1, "%Tx%v heapDiff = %v, calcSize = %v", m, size, heapDiff, calcSize) + runtime.KeepAlive(m) + } +} + +func TestMapSize(t *testing.T) { + testMapSize(t, func(i int) (int, int) { + return i, i + }) + + testMapSize(t, func(i int) (uint32, uint32) { + return uint32(i), uint32(i) + }) + + testMapSize(t, func(i int) ([32]uint32, uint32) { + return [32]uint32{0: uint32(i)}, uint32(i) + }) + + testMapSize(t, func(i int) (uint32, [32]uint32) { + return uint32(i), [32]uint32{0: uint32(i)} + }) + + testMapSize(t, func(i int) ([32]uint32, [32]uint32) { + return [32]uint32{0: uint32(i)}, [32]uint32{0: uint32(i)} + }) +} diff --git a/go/hack/msize.go b/go/hack/msize.go index aead790e627..04024a2a282 100644 --- a/go/hack/msize.go +++ b/go/hack/msize.go @@ -32,6 +32,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package hack +import ( + "unsafe" +) + const ( _MaxSmallSize = 32768 smallSizeDiv = 8 @@ -74,3 +78,101 @@ func roundupsize(size uintptr) uintptr { func RuntimeAllocSize(size int64) int64 { return int64(roundupsize(uintptr(size))) } + +// RuntimeMapSize returns the size of the internal data structures of a Map. +// This is an internal implementation detail based on the Swiss Map implementation +// as of Go 1.24 and needs to be kept up-to-date after every Go release. +func RuntimeMapSize[K comparable, V any](themap map[K]V) (internalSize int64) { + // The following are copies of internal data structures as of Go 1.24 + // THEY MUST BE KEPT UP TO DATE + + // internal/abi/type.go + const SizeofType = 48 + + // internal/abi/map_swiss.go + type SwissMapType struct { + pad [SizeofType]uint8 + Key unsafe.Pointer + Elem unsafe.Pointer + Group unsafe.Pointer + Hasher func(unsafe.Pointer, uintptr) uintptr + GroupSize uintptr // == Group.Size_ + SlotSize uintptr // size of key/elem slot + ElemOff uintptr // offset of elem in key/elem slot + Flags uint32 + } + + // internal/runtime/maps/map.go + type Map struct { + used uint64 + seed uintptr + dirPtr unsafe.Pointer + dirLen int + globalDepth uint8 + globalShift uint8 + writing uint8 + clearSeq uint64 + } + + // internal/runtime/maps/groups.go + type groupsReference struct { + data unsafe.Pointer // data *[length]typ.Group + lengthMask uint64 + } + + // internal/runtime/maps/table.go + type table struct { + used uint16 + capacity uint16 + growthLeft uint16 + localDepth uint8 + index int + groups groupsReference + } + + directoryAt := func(m *Map, i uintptr) *table { + const PtrSize = 4 << (^uintptr(0) >> 63) + return *(**table)(unsafe.Pointer(uintptr(m.dirPtr) + PtrSize*i)) + } + + // Converting the map to an interface will result in two ptr-sized words; + // like all interfaces, the first word points to an *abi.Type instance, + // which is specialized as SwissMapType for maps, and to the actual + // memory allocation, which is `*Map` + type MapInterface struct { + Type *SwissMapType + Data *Map + } + + mapiface := any(themap) + iface := (*MapInterface)(unsafe.Pointer(&mapiface)) + m := iface.Data + + var groupSize = int64(iface.Type.GroupSize) + internalSize = int64(unsafe.Sizeof(Map{})) + + if m.dirLen <= 0 { + // Small map optimization: we don't allocate tables at all if all the + // entries in a map fit in a single group + if m.dirPtr != nil { + internalSize += RuntimeAllocSize(groupSize) + } + } else { + // For normal maps, we iterate each table and add the size of all the + // groups it contains. + // See: internal/runtime/maps/export_test.go + var lastTab *table + for i := range m.dirLen { + t := directoryAt(m, uintptr(i)) + if t == lastTab { + continue + } + lastTab = t + + gc := int64(t.groups.lengthMask + 1) + internalSize += RuntimeAllocSize(groupSize * gc) + } + } + + return internalSize +} diff --git a/go/mysql/collations/cached_size.go b/go/mysql/collations/cached_size.go index 630bf41230a..407c02c4ee9 100644 --- a/go/mysql/collations/cached_size.go +++ b/go/mysql/collations/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,7 @@ limitations under the License. package collations -import ( - "math" - "reflect" - "unsafe" - - hack "vitess.io/vitess/go/hack" -) +import hack "vitess.io/vitess/go/hack" //go:nocheckptr func (cached *Environment) CachedSize(alloc bool) int64 { @@ -36,28 +30,14 @@ func (cached *Environment) CachedSize(alloc bool) int64 { } // field byName map[string]vitess.io/vitess/go/mysql/collations.ID if cached.byName != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.byName) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 160)) - if len(cached.byName) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 160)) - } + size += hack.RuntimeMapSize(cached.byName) for k := range cached.byName { size += hack.RuntimeAllocSize(int64(len(k))) } } // field byCharset map[string]*vitess.io/vitess/go/mysql/collations.colldefaults if cached.byCharset != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.byCharset) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.byCharset) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.byCharset) for k, v := range cached.byCharset { size += hack.RuntimeAllocSize(int64(len(k))) if v != nil { @@ -67,42 +47,21 @@ func (cached *Environment) CachedSize(alloc bool) int64 { } // field byCharsetName map[vitess.io/vitess/go/mysql/collations.ID]string if cached.byCharsetName != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.byCharsetName) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 160)) - if len(cached.byCharsetName) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 160)) - } + size += hack.RuntimeMapSize(cached.byCharsetName) for _, v := range cached.byCharsetName { size += hack.RuntimeAllocSize(int64(len(v))) } } // field unsupported map[string]vitess.io/vitess/go/mysql/collations.ID if cached.unsupported != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.unsupported) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 160)) - if len(cached.unsupported) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 160)) - } + size += hack.RuntimeMapSize(cached.unsupported) for k := range cached.unsupported { size += hack.RuntimeAllocSize(int64(len(k))) } } // field byID map[vitess.io/vitess/go/mysql/collations.ID]string if cached.byID != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.byID) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 160)) - if len(cached.byID) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 160)) - } + size += hack.RuntimeMapSize(cached.byID) for _, v := range cached.byID { size += hack.RuntimeAllocSize(int64(len(v))) } diff --git a/go/mysql/collations/colldata/cached_size.go b/go/mysql/collations/colldata/cached_size.go index 190e1731651..a82cacc073b 100644 --- a/go/mysql/collations/colldata/cached_size.go +++ b/go/mysql/collations/colldata/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/mysql/decimal/cached_size.go b/go/mysql/decimal/cached_size.go index 87f6c201b80..10c5b15381d 100644 --- a/go/mysql/decimal/cached_size.go +++ b/go/mysql/decimal/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/mysql/json/cached_size.go b/go/mysql/json/cached_size.go index 27fd511dafc..0d57d9000d8 100644 --- a/go/mysql/json/cached_size.go +++ b/go/mysql/json/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/pools/smartconnpool/cached_size.go b/go/pools/smartconnpool/cached_size.go index 8c985349db3..2c794c46eca 100644 --- a/go/pools/smartconnpool/cached_size.go +++ b/go/pools/smartconnpool/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/sqltypes/cached_size.go b/go/sqltypes/cached_size.go index 53bc407278d..67bf017ed83 100644 --- a/go/sqltypes/cached_size.go +++ b/go/sqltypes/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/tools/sizegen/integration/cached_size.go b/go/tools/sizegen/integration/cached_size.go index 6023b29b7e4..619e77ad817 100644 --- a/go/tools/sizegen/integration/cached_size.go +++ b/go/tools/sizegen/integration/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,7 @@ limitations under the License. package integration -import ( - "math" - "reflect" - "unsafe" - - hack "vitess.io/vitess/go/hack" -) +import hack "vitess.io/vitess/go/hack" type cachedObject interface { CachedSize(alloc bool) int64 @@ -89,14 +83,7 @@ func (cached *Map1) CachedSize(alloc bool) int64 { } // field field1 map[uint8]uint8 if cached.field1 != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.field1) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 32)) - if len(cached.field1) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 32)) - } + size += hack.RuntimeMapSize(cached.field1) } return size } @@ -112,14 +99,7 @@ func (cached *Map2) CachedSize(alloc bool) int64 { } // field field1 map[uint64]vitess.io/vitess/go/tools/sizegen/integration.A if cached.field1 != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.field1) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.field1) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.field1) } return size } @@ -135,14 +115,7 @@ func (cached *Map3) CachedSize(alloc bool) int64 { } // field field1 map[uint64]vitess.io/vitess/go/tools/sizegen/integration.B if cached.field1 != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.field1) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.field1) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.field1) for _, v := range cached.field1 { if cc, ok := v.(cachedObject); ok { size += cc.CachedSize(true) diff --git a/go/tools/sizegen/integration/integration_test.go b/go/tools/sizegen/integration/integration_test.go index f394f019b5a..cc2b269924e 100644 --- a/go/tools/sizegen/integration/integration_test.go +++ b/go/tools/sizegen/integration/integration_test.go @@ -20,6 +20,8 @@ import ( "fmt" "testing" + "github.com/stretchr/testify/assert" + "vitess.io/vitess/go/hack" ) @@ -27,9 +29,6 @@ func TestTypeSizes(t *testing.T) { var PtrSize = hack.RuntimeAllocSize(8) var SliceHeaderSize = hack.RuntimeAllocSize(3 * PtrSize) var FatPointerSize = hack.RuntimeAllocSize(2 * PtrSize) - var BucketHeaderSize = hack.RuntimeAllocSize(8) - var BucketSize = hack.RuntimeAllocSize(8) - var HashMapHeaderSize = hack.RuntimeAllocSize(48) cases := []struct { obj cachedObject @@ -60,17 +59,17 @@ func TestTypeSizes(t *testing.T) { {&Slice3{field1: []*Bimpl{{}, {}, {}, {}}}, SliceHeaderSize + PtrSize*4 + 8*4}, {&Map1{field1: nil}, PtrSize}, - {&Map1{field1: map[uint8]uint8{}}, PtrSize + HashMapHeaderSize}, - {&Map1{field1: map[uint8]uint8{0: 0}}, PtrSize + HashMapHeaderSize + BucketHeaderSize + 1*BucketSize + 1*BucketSize + PtrSize}, + {&Map1{field1: map[uint8]uint8{}}, 56}, + {&Map1{field1: map[uint8]uint8{0: 0}}, 80}, {&Map2{field1: nil}, PtrSize}, - {&Map2{field1: map[uint64]A{}}, PtrSize + HashMapHeaderSize}, - {&Map2{field1: map[uint64]A{0: {}}}, PtrSize + HashMapHeaderSize + BucketHeaderSize + 8*BucketSize + 16*BucketSize + PtrSize}, + {&Map2{field1: map[uint64]A{}}, 56}, + {&Map2{field1: map[uint64]A{0: {}}}, 264}, {&Map3{field1: nil}, PtrSize}, - {&Map3{field1: map[uint64]B{}}, PtrSize + HashMapHeaderSize}, - {&Map3{field1: map[uint64]B{0: &Bimpl{}}}, PtrSize + HashMapHeaderSize + BucketHeaderSize + 8*BucketSize + FatPointerSize*BucketSize + PtrSize + 8}, - {&Map3{field1: map[uint64]B{0: nil}}, PtrSize + HashMapHeaderSize + BucketHeaderSize + 8*BucketSize + FatPointerSize*BucketSize + PtrSize}, + {&Map3{field1: map[uint64]B{}}, 56}, + {&Map3{field1: map[uint64]B{0: &Bimpl{}}}, 272}, + {&Map3{field1: map[uint64]B{0: nil}}, 264}, {&String1{}, hack.RuntimeAllocSize(PtrSize*2 + 8)}, {&String1{field1: "1234"}, hack.RuntimeAllocSize(PtrSize*2+8) + hack.RuntimeAllocSize(4)}, @@ -79,9 +78,7 @@ func TestTypeSizes(t *testing.T) { for _, tt := range cases { t.Run(fmt.Sprintf("sizeof(%T)", tt.obj), func(t *testing.T) { size := tt.obj.CachedSize(true) - if size != tt.size { - t.Errorf("expected %T to be %d bytes, got %d", tt.obj, tt.size, size) - } + assert.Equalf(t, tt.size, size, "expected %T to be %d bytes, got %d", tt.obj, tt.size, size) }) } } diff --git a/go/tools/sizegen/integration/types.go b/go/tools/sizegen/integration/types.go index ff2a676b998..f38e66e690c 100644 --- a/go/tools/sizegen/integration/types.go +++ b/go/tools/sizegen/integration/types.go @@ -14,6 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ +//go:generate go run ../sizegen.go --in . --gen vitess.io/vitess/go/tools/sizegen/integration.* + // nolint package integration diff --git a/go/tools/sizegen/sizegen.go b/go/tools/sizegen/sizegen.go index cc733c8826d..32a22ea186f 100644 --- a/go/tools/sizegen/sizegen.go +++ b/go/tools/sizegen/sizegen.go @@ -34,7 +34,7 @@ import ( "vitess.io/vitess/go/tools/codegen" ) -const licenseFileHeader = `Copyright 2021 The Vitess Authors. +const licenseFileHeader = `Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -340,7 +340,7 @@ func (sizegen *sizegen) sizeImplForSlice(name *types.TypeName, st *types.Slice) } func (sizegen *sizegen) sizeImplForMap(name *types.TypeName, st *types.Map) (jen.Code, codeFlag) { - stmt := sizegen.sizeStmtForMap(jen.Op("*").Add(jen.Id("cached")), st) + stmt := sizegen.sizeStmtForMap(jen.Op("*").Add(jen.Id("cached"))) f := jen.Func() f.Params(jen.Id("cached").Op("*").Id(name.Name())) @@ -388,49 +388,9 @@ func (sizegen *sizegen) sizeImplForSignature(name *types.TypeName, _ *types.Sign return f, 0 } -func (sizegen *sizegen) sizeStmtForMap(fieldName *jen.Statement, m *types.Map) []jen.Code { - const bucketCnt = 8 - const sizeofHmap = int64(6 * 8) - - /* - type bmap struct { - // tophash generally contains the top byte of the hash value - // for each key in this bucket. If tophash[0] < minTopHash, - // tophash[0] is a bucket evacuation state instead. - tophash [bucketCnt]uint8 - // Followed by bucketCnt keys and then bucketCnt elems. - // NOTE: packing all the keys together and then all the elems together makes the - // code a bit more complicated than alternating key/elem/key/elem/... but it allows - // us to eliminate padding which would be needed for, e.g., map[int64]int8. - // Followed by an overflow pointer. - } - */ - sizeOfBucket := int( - bucketCnt + // tophash - bucketCnt*sizegen.sizes.Sizeof(m.Key()) + - bucketCnt*sizegen.sizes.Sizeof(m.Elem()) + - 8, // overflow pointer - ) - +func (sizegen *sizegen) sizeStmtForMap(fieldName *jen.Statement) []jen.Code { return []jen.Code{ - jen.Id("size").Op("+=").Lit(hack.RuntimeAllocSize(sizeofHmap)), - - jen.Id("hmap").Op(":=").Qual("reflect", "ValueOf").Call(fieldName), - - jen.Id("numBuckets").Op(":=").Id("int").Call( - jen.Qual("math", "Pow").Call(jen.Lit(2), jen.Id("float64").Call( - jen.Parens(jen.Op("*").Parens(jen.Op("*").Id("uint8")).Call( - jen.Qual("unsafe", "Pointer").Call(jen.Id("hmap").Dot("Pointer").Call(). - Op("+").Id("uintptr").Call(jen.Lit(9)))))))), - - jen.Id("numOldBuckets").Op(":=").Parens(jen.Op("*").Parens(jen.Op("*").Id("uint16")).Call( - jen.Qual("unsafe", "Pointer").Call( - jen.Id("hmap").Dot("Pointer").Call().Op("+").Id("uintptr").Call(jen.Lit(10))))), - - jen.Id("size").Op("+=").Do(mallocsize(jen.Int64().Call(jen.Id("numOldBuckets").Op("*").Lit(sizeOfBucket)))), - - jen.If(jen.Id("len").Call(fieldName).Op(">").Lit(0).Op("||").Id("numBuckets").Op(">").Lit(1)).Block( - jen.Id("size").Op("+=").Do(mallocsize(jen.Int64().Call(jen.Id("numBuckets").Op("*").Lit(sizeOfBucket))))), + jen.Id("size").Op("+=").Qual("vitess.io/vitess/go/hack", "RuntimeMapSize").Call(fieldName), } } @@ -512,11 +472,16 @@ func (sizegen *sizegen) sizeStmtForType(fieldName *jen.Statement, field types.Ty return nil, 0 case *types.Map: - keySize, keyFlag := sizegen.sizeStmtForType(jen.Id("k"), node.Key(), false) - valSize, valFlag := sizegen.sizeStmtForType(jen.Id("v"), node.Elem(), false) + const ( + SwissMapMaxKeyBytes = 128 + SwissMapMaxElemBytes = 128 + ) + + keySize, keyFlag := sizegen.sizeStmtForType(jen.Id("k"), node.Key(), sizegen.sizes.Sizeof(node.Key()) > SwissMapMaxKeyBytes) + valSize, valFlag := sizegen.sizeStmtForType(jen.Id("v"), node.Elem(), sizegen.sizes.Sizeof(node.Elem()) > SwissMapMaxElemBytes) return jen.If(fieldName.Clone().Op("!=").Nil()).BlockFunc(func(block *jen.Group) { - for _, stmt := range sizegen.sizeStmtForMap(fieldName, node) { + for _, stmt := range sizegen.sizeStmtForMap(fieldName) { block.Add(stmt) } diff --git a/go/vt/key/cached_size.go b/go/vt/key/cached_size.go index ef4e6e79896..1f20a8404d9 100644 --- a/go/vt/key/cached_size.go +++ b/go/vt/key/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/proto/query/cached_size.go b/go/vt/proto/query/cached_size.go index 58054d3c445..1f3d69513aa 100644 --- a/go/vt/proto/query/cached_size.go +++ b/go/vt/proto/query/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/proto/topodata/cached_size.go b/go/vt/proto/topodata/cached_size.go index 165c9ee4226..0fda6448975 100644 --- a/go/vt/proto/topodata/cached_size.go +++ b/go/vt/proto/topodata/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/proto/vttime/cached_size.go b/go/vt/proto/vttime/cached_size.go index f2b69dbefae..42252ec9d2c 100644 --- a/go/vt/proto/vttime/cached_size.go +++ b/go/vt/proto/vttime/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/schema/cached_size.go b/go/vt/schema/cached_size.go index 5ed67c01696..6f82d741c38 100644 --- a/go/vt/schema/cached_size.go +++ b/go/vt/schema/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/sqlparser/cached_size.go b/go/vt/sqlparser/cached_size.go index 4f17041bdbe..36bc371c0c8 100644 --- a/go/vt/sqlparser/cached_size.go +++ b/go/vt/sqlparser/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,7 @@ limitations under the License. package sqlparser -import ( - "math" - "reflect" - "unsafe" - - hack "vitess.io/vitess/go/hack" -) +import hack "vitess.io/vitess/go/hack" type cachedObject interface { CachedSize(alloc bool) int64 @@ -814,14 +808,7 @@ func (cached *CommentDirectives) CachedSize(alloc bool) int64 { } // field m map[string]string if cached.m != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.m) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 272)) - if len(cached.m) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 272)) - } + size += hack.RuntimeMapSize(cached.m) for k, v := range cached.m { size += hack.RuntimeAllocSize(int64(len(k))) size += hack.RuntimeAllocSize(int64(len(v))) diff --git a/go/vt/srvtopo/cached_size.go b/go/vt/srvtopo/cached_size.go index 03dd1ceb0da..06a908fee70 100644 --- a/go/vt/srvtopo/cached_size.go +++ b/go/vt/srvtopo/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/tableacl/cached_size.go b/go/vt/tableacl/cached_size.go index 0bc5cc6c042..aa8c1511d54 100644 --- a/go/vt/tableacl/cached_size.go +++ b/go/vt/tableacl/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vtenv/cached_size.go b/go/vt/vtenv/cached_size.go index 808cc4cdca3..44a982db830 100644 --- a/go/vt/vtenv/cached_size.go +++ b/go/vt/vtenv/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vtgate/engine/cached_size.go b/go/vt/vtgate/engine/cached_size.go index 50d3a4b6bbf..23412990b0a 100644 --- a/go/vt/vtgate/engine/cached_size.go +++ b/go/vt/vtgate/engine/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,7 @@ limitations under the License. package engine -import ( - "math" - "reflect" - "unsafe" - - hack "vitess.io/vitess/go/hack" -) +import hack "vitess.io/vitess/go/hack" type cachedObject interface { CachedSize(alloc bool) int64 @@ -102,14 +96,7 @@ func (cached *Concatenate) CachedSize(alloc bool) int64 { } // field NoNeedToTypeCheck map[int]any if cached.NoNeedToTypeCheck != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.NoNeedToTypeCheck) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.NoNeedToTypeCheck) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.NoNeedToTypeCheck) } return size } @@ -222,14 +209,7 @@ func (cached *DMLWithInput) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(cap(cached.BVList)) * int64(8)) for _, elem := range cached.BVList { if elem != nil { - size += int64(48) - hmap := reflect.ValueOf(elem) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(elem) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(elem) for k := range elem { size += hack.RuntimeAllocSize(int64(len(k))) } @@ -589,14 +569,7 @@ func (cached *Join) CachedSize(alloc bool) int64 { } // field Vars map[string]int if cached.Vars != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.Vars) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.Vars) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.Vars) for k := range cached.Vars { size += hack.RuntimeAllocSize(int64(len(k))) } @@ -881,14 +854,7 @@ func (cached *RecurseCTE) CachedSize(alloc bool) int64 { } // field Vars map[string]int if cached.Vars != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.Vars) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.Vars) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.Vars) for k := range cached.Vars { size += hack.RuntimeAllocSize(int64(len(k))) } @@ -1002,14 +968,7 @@ func (cached *RoutingParameters) CachedSize(alloc bool) int64 { } // field SysTableTableName map[string]vitess.io/vitess/go/vt/vtgate/evalengine.Expr if cached.SysTableTableName != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.SysTableTableName) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 272)) - if len(cached.SysTableTableName) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 272)) - } + size += hack.RuntimeMapSize(cached.SysTableTableName) for k, v := range cached.SysTableTableName { size += hack.RuntimeAllocSize(int64(len(k))) if cc, ok := v.(cachedObject); ok { @@ -1124,14 +1083,7 @@ func (cached *SemiJoin) CachedSize(alloc bool) int64 { } // field Vars map[string]int if cached.Vars != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.Vars) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.Vars) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.Vars) for k := range cached.Vars { size += hack.RuntimeAllocSize(int64(len(k))) } @@ -1381,14 +1333,7 @@ func (cached *Update) CachedSize(alloc bool) int64 { size += cached.DML.CachedSize(true) // field ChangedVindexValues map[string]*vitess.io/vitess/go/vt/vtgate/engine.VindexValues if cached.ChangedVindexValues != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.ChangedVindexValues) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.ChangedVindexValues) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.ChangedVindexValues) for k, v := range cached.ChangedVindexValues { size += hack.RuntimeAllocSize(int64(len(k))) size += v.CachedSize(true) @@ -1570,14 +1515,7 @@ func (cached *VindexValues) CachedSize(alloc bool) int64 { } // field EvalExprMap map[string]vitess.io/vitess/go/vt/vtgate/evalengine.Expr if cached.EvalExprMap != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.EvalExprMap) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 272)) - if len(cached.EvalExprMap) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 272)) - } + size += hack.RuntimeMapSize(cached.EvalExprMap) for k, v := range cached.EvalExprMap { size += hack.RuntimeAllocSize(int64(len(k))) if cc, ok := v.(cachedObject); ok { @@ -1635,14 +1573,7 @@ func (cached *shardRoute) CachedSize(alloc bool) int64 { size += cached.rs.CachedSize(true) // field bv map[string]*vitess.io/vitess/go/vt/proto/query.BindVariable if cached.bv != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.bv) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.bv) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.bv) for k, v := range cached.bv { size += hack.RuntimeAllocSize(int64(len(k))) size += v.CachedSize(true) diff --git a/go/vt/vtgate/evalengine/cached_size.go b/go/vt/vtgate/evalengine/cached_size.go index b953afda95c..fc7a02e84c1 100644 --- a/go/vt/vtgate/evalengine/cached_size.go +++ b/go/vt/vtgate/evalengine/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vtgate/vindexes/cached_size.go b/go/vt/vtgate/vindexes/cached_size.go index ac68887c00d..94f6daa0c05 100644 --- a/go/vt/vtgate/vindexes/cached_size.go +++ b/go/vt/vtgate/vindexes/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,13 +17,7 @@ limitations under the License. package vindexes -import ( - "math" - "reflect" - "unsafe" - - hack "vitess.io/vitess/go/hack" -) +import hack "vitess.io/vitess/go/hack" type cachedObject interface { CachedSize(alloc bool) int64 @@ -327,14 +321,7 @@ func (cached *MultiCol) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.name))) // field columnVdx map[int]vitess.io/vitess/go/vt/vtgate/vindexes.Hashing if cached.columnVdx != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.columnVdx) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.columnVdx) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.columnVdx) for _, v := range cached.columnVdx { if cc, ok := v.(cachedObject); ok { size += cc.CachedSize(true) @@ -343,14 +330,7 @@ func (cached *MultiCol) CachedSize(alloc bool) int64 { } // field columnBytes map[int]int if cached.columnBytes != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.columnBytes) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 144)) - if len(cached.columnBytes) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 144)) - } + size += hack.RuntimeMapSize(cached.columnBytes) } return size } @@ -400,14 +380,7 @@ func (cached *NumericLookupTable) CachedSize(alloc bool) int64 { if alloc { size += int64(8) } - size += int64(48) - hmap := reflect.ValueOf(*cached) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 144)) - if len(*cached) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 144)) - } + size += hack.RuntimeMapSize(*cached) return size } @@ -428,14 +401,7 @@ func (cached *NumericStaticMap) CachedSize(alloc bool) int64 { } // field lookup vitess.io/vitess/go/vt/vtgate/vindexes.NumericLookupTable if cached.lookup != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.lookup) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 144)) - if len(cached.lookup) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 144)) - } + size += hack.RuntimeMapSize(cached.lookup) } // field unknownParams []string { @@ -479,14 +445,7 @@ func (cached *RegionJSON) CachedSize(alloc bool) int64 { size += hack.RuntimeAllocSize(int64(len(cached.name))) // field regionMap vitess.io/vitess/go/vt/vtgate/vindexes.RegionMap if cached.regionMap != nil { - size += int64(48) - hmap := reflect.ValueOf(cached.regionMap) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(cached.regionMap) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(cached.regionMap) for k := range cached.regionMap { size += hack.RuntimeAllocSize(int64(len(k))) } @@ -508,14 +467,7 @@ func (cached *RegionMap) CachedSize(alloc bool) int64 { if alloc { size += int64(8) } - size += int64(48) - hmap := reflect.ValueOf(*cached) - numBuckets := int(math.Pow(2, float64((*(*uint8)(unsafe.Pointer(hmap.Pointer() + uintptr(9))))))) - numOldBuckets := (*(*uint16)(unsafe.Pointer(hmap.Pointer() + uintptr(10)))) - size += hack.RuntimeAllocSize(int64(numOldBuckets * 208)) - if len(*cached) > 0 || numBuckets > 1 { - size += hack.RuntimeAllocSize(int64(numBuckets * 208)) - } + size += hack.RuntimeMapSize(*cached) return size } func (cached *ReverseBits) CachedSize(alloc bool) int64 { diff --git a/go/vt/vttablet/tabletserver/cached_size.go b/go/vt/vttablet/tabletserver/cached_size.go index 96d09826356..5d357738d7b 100644 --- a/go/vt/vttablet/tabletserver/cached_size.go +++ b/go/vt/vttablet/tabletserver/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vttablet/tabletserver/planbuilder/cached_size.go b/go/vt/vttablet/tabletserver/planbuilder/cached_size.go index 7e7f2f3ef4b..e10fce93cb6 100644 --- a/go/vt/vttablet/tabletserver/planbuilder/cached_size.go +++ b/go/vt/vttablet/tabletserver/planbuilder/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vttablet/tabletserver/rules/cached_size.go b/go/vt/vttablet/tabletserver/rules/cached_size.go index d06a31ab8cb..5ea45661e27 100644 --- a/go/vt/vttablet/tabletserver/rules/cached_size.go +++ b/go/vt/vttablet/tabletserver/rules/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vttablet/tabletserver/schema/cached_size.go b/go/vt/vttablet/tabletserver/schema/cached_size.go index 4db9f313644..13132e6acb2 100644 --- a/go/vt/vttablet/tabletserver/schema/cached_size.go +++ b/go/vt/vttablet/tabletserver/schema/cached_size.go @@ -1,5 +1,5 @@ /* -Copyright 2021 The Vitess Authors. +Copyright 2025 The Vitess Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/go/vt/vttablet/tabletserver/schema/schema.go b/go/vt/vttablet/tabletserver/schema/schema.go index e800477da3b..d5d1a6d29bc 100644 --- a/go/vt/vttablet/tabletserver/schema/schema.go +++ b/go/vt/vttablet/tabletserver/schema/schema.go @@ -17,12 +17,11 @@ limitations under the License. package schema import ( + "fmt" "sync" "time" "vitess.io/vitess/go/sqltypes" - "vitess.io/vitess/go/vt/log" - "vitess.io/vitess/go/vt/sqlparser" querypb "vitess.io/vitess/go/vt/proto/query" @@ -85,10 +84,10 @@ func (seq *SequenceInfo) Reset() { seq.LastVal = 0 } -func (seq *SequenceInfo) String() { +func (seq *SequenceInfo) String() string { seq.Lock() defer seq.Unlock() - log.Infof("SequenceInfo: NextVal: %d, LastVal: %d", seq.NextVal, seq.LastVal) + return fmt.Sprintf("SequenceInfo: NextVal: %d, LastVal: %d", seq.NextVal, seq.LastVal) } // MessageInfo contains info specific to message tables. @@ -131,6 +130,10 @@ type MessageInfo struct { IDType sqltypes.Type } +func (mi *MessageInfo) String() string { + return fmt.Sprintf("MessageInfo: AckWaitDuration: %v, PurgeAfterDuration: %v, BatchSize: %v, CacheSize: %v, PollInterval: %v, MinBackoff: %v, MaxBackoff: %v, IDType: %v", mi.AckWaitDuration, mi.PurgeAfterDuration, mi.BatchSize, mi.CacheSize, mi.PollInterval, mi.MinBackoff, mi.MaxBackoff, mi.IDType) +} + // NewTable creates a new Table. func NewTable(name string, tableType int) *Table { return &Table{ diff --git a/go/vt/vttablet/tabletserver/schema/schemaz_test.go b/go/vt/vttablet/tabletserver/schema/schemaz_test.go index 0127c796f67..c41d34bc82d 100644 --- a/go/vt/vttablet/tabletserver/schema/schemaz_test.go +++ b/go/vt/vttablet/tabletserver/schema/schemaz_test.go @@ -28,7 +28,7 @@ import ( "github.com/stretchr/testify/require" ) -func TestSchamazHandler1(t *testing.T) { +func TestSchemazHandler1(t *testing.T) { resp := httptest.NewRecorder() req, _ := http.NewRequest("GET", "/schemaz", nil) tables := initialSchema() @@ -50,7 +50,7 @@ func TestSchamazHandler1(t *testing.T) { `id: INT32
next_id: INT64
cache: INT64
increment: INT64
`, `id
`, `sequence`, - `{{0 0} 0 0}<nil>`, + `SequenceInfo: NextVal: 0, LastVal: 0<nil>`, } matched, err = regexp.Match(strings.Join(seq, `\s*`), body) require.NoError(t, err) diff --git a/misc/git/hooks/golangci-lint b/misc/git/hooks/golangci-lint index 21313316a12..3fd30f65533 100755 --- a/misc/git/hooks/golangci-lint +++ b/misc/git/hooks/golangci-lint @@ -14,7 +14,7 @@ # limitations under the License. # Required version of golangci-lint -REQUIRED_VERSION="v1.60.2" +REQUIRED_VERSION="v1.64.5" # Function to compare versions in pure Bash version_greater_or_equal() { @@ -67,4 +67,4 @@ gopackages=$(echo "$gofiles" | xargs -n1 dirname | sort -u | paste -sd ' ' -) # Lint the Go packages echo "Linting $gopackages" -golangci-lint run $gopackages \ No newline at end of file +golangci-lint run $gopackages diff --git a/test.go b/test.go index 247541009a6..e3d9222a96d 100755 --- a/test.go +++ b/test.go @@ -77,7 +77,7 @@ For example: // Flags var ( flavor = flag.String("flavor", "mysql80", "comma-separated bootstrap flavor(s) to run against (when using Docker mode). Available flavors: all,"+flavors) - bootstrapVersion = flag.String("bootstrap-version", "41", "the version identifier to use for the docker images") + bootstrapVersion = flag.String("bootstrap-version", "42", "the version identifier to use for the docker images") runCount = flag.Int("runs", 1, "run each test this many times") retryMax = flag.Int("retry", 3, "max number of retries, to detect flaky tests") logPass = flag.Bool("log-pass", false, "log test output even if it passes") diff --git a/test/templates/dockerfile.tpl b/test/templates/dockerfile.tpl index 733377418f8..b3138a30f08 100644 --- a/test/templates/dockerfile.tpl +++ b/test/templates/dockerfile.tpl @@ -1,4 +1,4 @@ -ARG bootstrap_version=41 +ARG bootstrap_version=42 ARG image="vitess/bootstrap:${bootstrap_version}-{{.Platform}}" FROM "${image}" From 83e2a4f5b117641c76fd43723ad62375edc65b14 Mon Sep 17 00:00:00 2001 From: Noble Mittal <62551163+beingnoble03@users.noreply.github.com> Date: Wed, 19 Feb 2025 20:14:51 +0530 Subject: [PATCH 13/19] VReplication: Support for `BETWEEN`/`NOT BETWEEN` filter in VStream (#17721) Signed-off-by: Noble Mittal Signed-off-by: Rohit Nayak Co-authored-by: Rohit Nayak --- go/test/endtoend/vreplication/vstream_test.go | 38 +++--- .../tabletserver/vstreamer/planbuilder.go | 107 ++++++++++++++-- .../vstreamer/planbuilder_test.go | 100 ++++++++++++++- .../vstreamer/rowstreamer_test.go | 79 ++++++++++++ .../tabletserver/vstreamer/vstreamer_test.go | 121 ++++++++++++++++++ 5 files changed, 414 insertions(+), 31 deletions(-) diff --git a/go/test/endtoend/vreplication/vstream_test.go b/go/test/endtoend/vreplication/vstream_test.go index 7ce0e7dbd63..f37ba1750f0 100644 --- a/go/test/endtoend/vreplication/vstream_test.go +++ b/go/test/endtoend/vreplication/vstream_test.go @@ -1130,7 +1130,7 @@ func TestVStreamPushdownFilters(t *testing.T) { require.NoError(t, err) // Coordinate go-routines. - streamCtx, streamCancel := context.WithTimeout(context.Background(), 1*time.Minute) + streamCtx, streamCancel := context.WithTimeout(context.Background(), 10*time.Second) defer streamCancel() done := make(chan struct{}) @@ -1176,19 +1176,31 @@ func TestVStreamPushdownFilters(t *testing.T) { Filter: "select * from customer where name = 'påul'", }}, } - flags := &vtgatepb.VStreamFlags{} vstreamConn, err := vtgateconn.Dial(ctx, fmt.Sprintf("%s:%d", vc.ClusterConfig.hostname, vc.ClusterConfig.vtgateGrpcPort)) require.NoError(t, err) defer vstreamConn.Close() - // So we should have at least one paul row event in the copy phase. - copyPhaseRowEvents := 0 - // And we should have many paul row events in the running phase. - runningPhaseRowEvents := 0 - copyPhase := true + // So we should have at least one paul row event in the copy phase, and + // we should have many paul row events in the running phase. + copyPhaseRowEvents, runningPhaseRowEvents := runVStreamAndGetNumOfRowEvents(t, ctx, vstreamConn, vgtid, filter, done) + + require.NotZero(t, createdPauls) + require.NotZero(t, createdNonPauls) + require.Greater(t, createdNonPauls, createdPauls) + require.NotZero(t, copyPhaseRowEvents) + require.NotZero(t, runningPhaseRowEvents) + + t.Logf("Created pauls: %d, pauls copied: %d, pauls replicated: %d", createdPauls, copyPhaseRowEvents, runningPhaseRowEvents) + require.Equal(t, createdPauls, copyPhaseRowEvents+runningPhaseRowEvents) +} +// runVStreamAndGetNumOfRowEvents runs VStream with the specified filter and +// returns number of copy phase and running phase row events. +func runVStreamAndGetNumOfRowEvents(t *testing.T, ctx context.Context, vstreamConn *vtgateconn.VTGateConn, + vgtid *binlogdatapb.VGtid, filter *binlogdatapb.Filter, done chan struct{}) (copyPhaseRowEvents int, runningPhaseRowEvents int) { + copyPhase := true func() { - reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, flags) + reader, err := vstreamConn.VStream(ctx, topodatapb.TabletType_PRIMARY, vgtid, filter, &vtgatepb.VStreamFlags{}) require.NoError(t, err) for { evs, err := reader.Recv() @@ -1217,13 +1229,5 @@ func TestVStreamPushdownFilters(t *testing.T) { } } }() - - require.NotZero(t, createdPauls) - require.NotZero(t, createdNonPauls) - require.Greater(t, createdNonPauls, createdPauls) - require.NotZero(t, copyPhaseRowEvents) - require.NotZero(t, runningPhaseRowEvents) - - t.Logf("Created pauls: %d, pauls copied: %d, pauls replicated: %d", createdPauls, copyPhaseRowEvents, runningPhaseRowEvents) - require.Equal(t, createdPauls, copyPhaseRowEvents+runningPhaseRowEvents) + return } diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go index 6416c5c87de..c35208be93e 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go @@ -101,6 +101,10 @@ const ( IsNotNull // In is used to filter a comparable column if equals any of the values from a specific tuple In + // Note that we do not implement filtering for BETWEEN because + // in the plan we rewrite `x BETWEEN a AND b` to `x >= a AND x <= b` + // NotBetween is used to filter a comparable column if it doesn't lie within a specific range + NotBetween ) // Filter contains opcodes for filtering. @@ -273,6 +277,26 @@ func (plan *Plan) filter(values, result []sqltypes.Value, charsets []collations. if !found { return false, nil } + case NotBetween: + // Note that we do not implement filtering for BETWEEN because + // in the plan we rewrite `x BETWEEN a AND b` to `x >= a AND x <= b` + // This is the filtering for NOT BETWEEN since we don't have support + // for OR yet. + if filter.Values == nil || len(filter.Values) != 2 { + return false, vterrors.Errorf(vtrpcpb.Code_INTERNAL, "expected 2 filter values when performing NOT BETWEEN") + } + leftFilterValue, rightFilterValue := filter.Values[0], filter.Values[1] + isValueLessThanLeftFilter, err := compare(LessThan, values[filter.ColNum], leftFilterValue, plan.env.CollationEnv(), charsets[filter.ColNum]) + if err != nil { + return false, err + } + if isValueLessThanLeftFilter { + continue + } + isValueGreaterThanRightFilter, err := compare(GreaterThan, values[filter.ColNum], rightFilterValue, plan.env.CollationEnv(), charsets[filter.ColNum]) + if err != nil || !isValueGreaterThanRightFilter { + return false, err + } default: match, err := compare(filter.Opcode, values[filter.ColNum], filter.Value, plan.env.CollationEnv(), charsets[filter.ColNum]) if err != nil { @@ -570,6 +594,23 @@ func (plan *Plan) appendTupleFilter(values sqlparser.ValTuple, opcode Opcode, co return nil } +func (plan *Plan) getEvalResultForLiteral(expr sqlparser.Expr) (*evalengine.EvalResult, error) { + literalExpr, ok := expr.(*sqlparser.Literal) + if !ok { + return nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } + pv, err := evalengine.Translate(literalExpr, &evalengine.Config{ + Collation: plan.env.CollationEnv().DefaultConnectionCharset(), + Environment: plan.env, + }) + if err != nil { + return nil, err + } + env := evalengine.EmptyExpressionEnv(plan.env) + resolved, err := env.Evaluate(pv) + return &resolved, err +} + func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) error { if where == nil { return nil @@ -606,21 +647,11 @@ func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) er if err != nil { return err } + // Add it to the expressions that get pushed down to mysqld. + plan.whereExprsToPushDown = append(plan.whereExprsToPushDown, expr) continue } - val, ok := expr.Right.(*sqlparser.Literal) - if !ok { - return fmt.Errorf("unexpected: %v", sqlparser.String(expr)) - } - pv, err := evalengine.Translate(val, &evalengine.Config{ - Collation: plan.env.CollationEnv().DefaultConnectionCharset(), - Environment: plan.env, - }) - if err != nil { - return err - } - env := evalengine.EmptyExpressionEnv(plan.env) - resolved, err := env.Evaluate(pv) + resolved, err := plan.getEvalResultForLiteral(expr.Right) if err != nil { return err } @@ -661,6 +692,56 @@ func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) er }) // Add it to the expressions that get pushed down to mysqld. plan.whereExprsToPushDown = append(plan.whereExprsToPushDown, expr) + case *sqlparser.BetweenExpr: + qualifiedName, ok := expr.Left.(*sqlparser.ColName) + if !ok { + return fmt.Errorf("unexpected: %v", sqlparser.String(expr)) + } + if !qualifiedName.Qualifier.IsEmpty() { + return fmt.Errorf("unsupported qualifier for column: %v", sqlparser.String(qualifiedName)) + } + colnum, err := findColumn(plan.Table, qualifiedName.Name) + if err != nil { + return err + } + fromResolved, err := plan.getEvalResultForLiteral(expr.From) + if err != nil { + return err + } + toResolved, err := plan.getEvalResultForLiteral(expr.To) + if err != nil { + return err + } + + if !expr.IsBetween { + // `x NOT BETWEEN a AND b` means: `x < a OR x > b` + // Also, since we do not have OR implemented yet, + // NOT BETWEEN needs to be handled separately. + plan.Filters = append(plan.Filters, Filter{ + Opcode: NotBetween, + ColNum: colnum, + Values: []sqltypes.Value{ + fromResolved.Value(plan.env.CollationEnv().DefaultConnectionCharset()), + toResolved.Value(plan.env.CollationEnv().DefaultConnectionCharset()), + }, + }) + // Add it to the expressions that get pushed down to mysqld. + plan.whereExprsToPushDown = append(plan.whereExprsToPushDown, expr) + continue + } + + // `x BETWEEN a AND b` means: `x >= a AND x <= b` + plan.Filters = append(plan.Filters, Filter{ + Opcode: GreaterThanEqual, + ColNum: colnum, + Value: fromResolved.Value(plan.env.CollationEnv().DefaultConnectionCharset()), + }, Filter{ + Opcode: LessThanEqual, + ColNum: colnum, + Value: toResolved.Value(plan.env.CollationEnv().DefaultConnectionCharset()), + }) + // Add it to the expressions that get pushed down to mysqld. + plan.whereExprsToPushDown = append(plan.whereExprsToPushDown, expr) default: return fmt.Errorf("unsupported constraint: %v", sqlparser.String(expr)) } diff --git a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go index 3c9e19349e4..b2b48db216d 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/planbuilder_test.go @@ -571,6 +571,89 @@ func TestPlanBuilder(t *testing.T) { }}, env: vtenv.NewTestEnv(), }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select val, id from t1 where id between 2 and 5"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 1, + Field: &querypb.Field{ + Name: "val", + Type: sqltypes.VarChar, + Charset: unicodeCollationID, + }, + }, { + ColNum: 0, + Field: &querypb.Field{ + Name: "id", + Type: sqltypes.Int64, + Charset: collations.CollationBinaryID, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG), + }, + }}, + Filters: []Filter{{ + Opcode: GreaterThanEqual, + ColNum: 0, + Value: sqltypes.NewInt64(2), + Vindex: nil, + VindexColumns: nil, + KeyRange: nil, + }, { + Opcode: LessThanEqual, + ColNum: 0, + Value: sqltypes.NewInt64(5), + Vindex: nil, + VindexColumns: nil, + KeyRange: nil, + }}, + whereExprsToPushDown: []sqlparser.Expr{ + &sqlparser.BetweenExpr{ + IsBetween: true, + Left: sqlparser.NewColName("id"), + From: sqlparser.NewIntLiteral("2"), + To: sqlparser.NewIntLiteral("5"), + }, + }, + env: vtenv.NewTestEnv(), + }, + }, { + inTable: t1, + inRule: &binlogdatapb.Rule{Match: "t1", Filter: "select val, id from t1 where id not between 2 and 5"}, + outPlan: &Plan{ + ColExprs: []ColExpr{{ + ColNum: 1, + Field: &querypb.Field{ + Name: "val", + Type: sqltypes.VarChar, + Charset: unicodeCollationID, + }, + }, { + ColNum: 0, + Field: &querypb.Field{ + Name: "id", + Type: sqltypes.Int64, + Charset: collations.CollationBinaryID, + Flags: uint32(querypb.MySqlFlag_NUM_FLAG), + }, + }}, + Filters: []Filter{{ + Opcode: NotBetween, + ColNum: 0, + Values: []sqltypes.Value{sqltypes.NewInt64(2), sqltypes.NewInt64(5)}, + Vindex: nil, + VindexColumns: nil, + KeyRange: nil, + }}, + whereExprsToPushDown: []sqlparser.Expr{ + &sqlparser.BetweenExpr{ + IsBetween: false, + Left: sqlparser.NewColName("id"), + From: sqlparser.NewIntLiteral("2"), + To: sqlparser.NewIntLiteral("5"), + }, + }, + env: vtenv.NewTestEnv(), + }, }, { inTable: t1, inRule: &binlogdatapb.Rule{Match: "/*/"}, @@ -752,9 +835,22 @@ func TestPlanBuilderFilterComparison(t *testing.T) { outFilters: []Filter{ {Opcode: In, ColNum: 0, Values: []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(2)}}, }, + }, { + name: "between-operator", + inFilter: "select * from t1 where id between 1 and 5", + outFilters: []Filter{ + {Opcode: GreaterThanEqual, ColNum: 0, Value: sqltypes.NewInt64(1)}, + {Opcode: LessThanEqual, ColNum: 0, Value: sqltypes.NewInt64(5)}, + }, + }, { + name: "not-between-operator", + inFilter: "select * from t1 where id not between 1 and 5", + outFilters: []Filter{ + {Opcode: NotBetween, ColNum: 0, Values: []sqltypes.Value{sqltypes.NewInt64(1), sqltypes.NewInt64(5)}}, + }, }, { name: "vindex-and-operators", - inFilter: "select * from t1 where in_keyrange(id, 'hash', '-80') and id = 2 and val <> 'xyz' and id in (100, 30)", + inFilter: "select * from t1 where in_keyrange(id, 'hash', '-80') and id = 2 and val <> 'xyz' and id in (100, 30) and id between 20 and 60", outFilters: []Filter{ { Opcode: VindexMatch, @@ -770,6 +866,8 @@ func TestPlanBuilderFilterComparison(t *testing.T) { {Opcode: Equal, ColNum: 0, Value: sqltypes.NewInt64(2)}, {Opcode: NotEqual, ColNum: 1, Value: sqltypes.NewVarChar("xyz")}, {Opcode: In, ColNum: 0, Values: []sqltypes.Value{sqltypes.NewInt64(100), sqltypes.NewInt64(30)}}, + {Opcode: GreaterThanEqual, ColNum: 0, Value: sqltypes.NewInt64(20)}, + {Opcode: LessThanEqual, ColNum: 0, Value: sqltypes.NewInt64(60)}, }, }} diff --git a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go index 97ed4093c8f..f2c1c226c73 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/rowstreamer_test.go @@ -351,6 +351,85 @@ func TestStreamRowsFilterInt(t *testing.T) { require.Less(t, int64(0), engine.vstreamerPacketSize.Get()) } +func TestStreamRowsFilterBetween(t *testing.T) { + if testing.Short() { + t.Skip() + } + engine.rowStreamerNumPackets.Reset() + engine.rowStreamerNumRows.Reset() + + if err := env.SetVSchema(shardedVSchema); err != nil { + t.Fatal(err) + } + defer env.SetVSchema("{}") + + execStatements(t, []string{ + "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", + "insert into t1 values (1, 100, 'aaa'), (2, 200, 'bbb'), (3, 200, 'ccc'), (4, 100, 'ddd'), (5, 200, 'eee')", + }) + + defer execStatements(t, []string{ + "drop table t1", + }) + + // Test for BETWEEN + wantStream := []string{ + `fields:{name:"id1" type:INT32 table:"t1" org_table:"t1" database:"vttest" org_name:"id1" column_length:11 charset:63 column_type:"int(11)"} fields:{name:"val" type:VARBINARY table:"t1" org_table:"t1" database:"vttest" org_name:"val" column_length:128 charset:63 column_type:"varbinary(128)"} pkfields:{name:"id1" type:INT32 charset:63}`, + `rows:{lengths:1 lengths:3 values:"2bbb"} rows:{lengths:1 lengths:3 values:"3ccc"} rows:{lengths:1 lengths:3 values:"4ddd"} lastpk:{lengths:1 values:"4"}`, + } + wantQuery := "select /*+ MAX_EXECUTION_TIME(3600000) */ id1, id2, val from t1 where (id1 between 2 and 4) order by id1" + checkStream(t, "select id1, val from t1 where (id1 between 2 and 4)", nil, wantQuery, wantStream) + require.Equal(t, int64(0), engine.rowStreamerNumPackets.Get()) + require.Equal(t, int64(3), engine.rowStreamerNumRows.Get()) + require.NotZero(t, engine.vstreamerPacketSize.Get()) + + engine.rowStreamerNumPackets.Reset() + engine.rowStreamerNumRows.Reset() + + // Test for NOT BETWEEN + wantStream = []string{ + `fields:{name:"id1" type:INT32 table:"t1" org_table:"t1" database:"vttest" org_name:"id1" column_length:11 charset:63 column_type:"int(11)"} fields:{name:"val" type:VARBINARY table:"t1" org_table:"t1" database:"vttest" org_name:"val" column_length:128 charset:63 column_type:"varbinary(128)"} pkfields:{name:"id1" type:INT32 charset:63}`, + `rows:{lengths:1 lengths:3 values:"1aaa"} rows:{lengths:1 lengths:3 values:"5eee"} lastpk:{lengths:1 values:"5"}`, + } + wantQuery = "select /*+ MAX_EXECUTION_TIME(3600000) */ id1, id2, val from t1 where (id1 not between 2 and 4) order by id1" + checkStream(t, "select id1, val from t1 where (id1 not between 2 and 4)", nil, wantQuery, wantStream) + require.Equal(t, int64(0), engine.rowStreamerNumPackets.Get()) + require.Equal(t, int64(2), engine.rowStreamerNumRows.Get()) + require.NotZero(t, engine.vstreamerPacketSize.Get()) +} + +func TestStreamRowsFilterIn(t *testing.T) { + if testing.Short() { + t.Skip() + } + engine.rowStreamerNumPackets.Reset() + engine.rowStreamerNumRows.Reset() + + if err := env.SetVSchema(shardedVSchema); err != nil { + t.Fatal(err) + } + defer env.SetVSchema("{}") + + execStatements(t, []string{ + "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", + "insert into t1 values (1, 100, 'aaa'), (2, 200, 'bbb'), (3, 200, 'ccc'), (4, 100, 'ddd'), (5, 200, 'eee')", + }) + + defer execStatements(t, []string{ + "drop table t1", + }) + + wantStream := []string{ + `fields:{name:"id1" type:INT32 table:"t1" org_table:"t1" database:"vttest" org_name:"id1" column_length:11 charset:63 column_type:"int(11)"} fields:{name:"val" type:VARBINARY table:"t1" org_table:"t1" database:"vttest" org_name:"val" column_length:128 charset:63 column_type:"varbinary(128)"} pkfields:{name:"id1" type:INT32 charset:63}`, + `rows:{lengths:1 lengths:3 values:"1aaa"} rows:{lengths:1 lengths:3 values:"2bbb"} rows:{lengths:1 lengths:3 values:"3ccc"} lastpk:{lengths:1 values:"3"}`, + } + wantQuery := "select /*+ MAX_EXECUTION_TIME(3600000) */ id1, id2, val from t1 where (id1 in (1, 2, 3)) order by id1" + checkStream(t, "select id1, val from t1 where id1 in (1, 2, 3)", nil, wantQuery, wantStream) + require.Equal(t, int64(0), engine.rowStreamerNumPackets.Get()) + require.Equal(t, int64(3), engine.rowStreamerNumRows.Get()) + require.NotZero(t, engine.vstreamerPacketSize.Get()) +} + func TestStreamRowsFilterVarBinary(t *testing.T) { if testing.Short() { t.Skip() diff --git a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go index 7281be1d60c..0fb7d4cd62d 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go +++ b/go/vt/vttablet/tabletserver/vstreamer/vstreamer_test.go @@ -2115,3 +2115,124 @@ func TestFilteredInOperator(t *testing.T) { }} ts.Run() } + +func TestFilteredBetweenOperator(t *testing.T) { + testCases := []struct { + name string + filter string + testQueries []*TestQuery + }{ + { + name: "between-int", + filter: "select id1, val from t1 where id1 between 2 and 5", + testQueries: []*TestQuery{ + {"begin", nil}, + {"insert into t1 values (1, 100, 'aaa')", noEvents}, + {"insert into t1 values (2, 200, 'bbb')", nil}, + {"insert into t1 values (3, 100, 'ccc')", nil}, + {"insert into t1 values (4, 200, 'ddd')", nil}, + {"insert into t1 values (5, 200, 'eee')", nil}, + {"insert into t1 values (6, 200, 'fff')", noEvents}, + {"commit", nil}, + }, + }, + { + name: "between-varchar", + filter: "select id1, val from t1 where val between 'c' and 'e'", + testQueries: []*TestQuery{ + {"begin", nil}, + {"insert into t1 values (1, 100, 'a')", noEvents}, + {"insert into t1 values (2, 200, 'b')", noEvents}, + {"insert into t1 values (3, 100, 'c')", nil}, + {"insert into t1 values (4, 200, 'd')", nil}, + {"insert into t1 values (5, 200, 'e')", nil}, + {"insert into t1 values (6, 200, 'f')", noEvents}, + {"commit", nil}, + }, + }, + { + name: "not-between-int", + filter: "select id1, val from t1 where id1 not between 3 and 5", + testQueries: []*TestQuery{ + {"begin", nil}, + {"insert into t1 values (1, 100, 'aaa')", nil}, + {"insert into t1 values (2, 200, 'bbb')", nil}, + {"insert into t1 values (3, 100, 'ccc')", noEvents}, + {"insert into t1 values (4, 200, 'ddd')", noEvents}, + {"insert into t1 values (5, 200, 'eee')", noEvents}, + {"insert into t1 values (6, 200, 'fff')", nil}, + {"commit", nil}, + }, + }, + { + name: "not-between-varchar", + filter: "select id1, val from t1 where val not between 'b' and 'e'", + testQueries: []*TestQuery{ + {"begin", nil}, + {"insert into t1 values (1, 100, 'a')", nil}, + {"insert into t1 values (2, 200, 'b')", noEvents}, + {"insert into t1 values (3, 100, 'c')", noEvents}, + {"insert into t1 values (4, 200, 'd')", noEvents}, + {"insert into t1 values (5, 200, 'e')", noEvents}, + {"insert into t1 values (6, 200, 'f')", nil}, + {"insert into t1 values (7, 100, 'g')", nil}, + {"commit", nil}, + }, + }, + { + name: "between-and-not-between", + filter: "select id1, val from t1 where id1 between 2 and 6 and val not between 'd' and 'f'", + testQueries: []*TestQuery{ + {"begin", nil}, + {"insert into t1 values (1, 100, 'a')", noEvents}, + {"insert into t1 values (2, 200, 'b')", nil}, + {"insert into t1 values (3, 100, 'c')", nil}, + {"insert into t1 values (4, 200, 'd')", noEvents}, + {"insert into t1 values (5, 200, 'e')", noEvents}, + {"insert into t1 values (6, 200, 'f')", noEvents}, + {"insert into t1 values (7, 100, 'g')", noEvents}, + {"commit", nil}, + }, + }, + { + name: "between-and-not-between-and-additional-compare", + filter: "select id1, val from t1 where id1 between 2 and 10 and id1 != 9 and val not between 'd' and 'f' and val in ('a','e')", + testQueries: []*TestQuery{ + {"begin", nil}, + {"insert into t1 values (1, 100, 'a')", noEvents}, + {"insert into t1 values (2, 200, 'b')", noEvents}, + {"insert into t1 values (3, 100, 'c')", noEvents}, + {"insert into t1 values (4, 200, 'd')", noEvents}, + {"insert into t1 values (5, 200, 'e')", noEvents}, + {"insert into t1 values (6, 200, 'f')", noEvents}, + {"insert into t1 values (7, 100, 'g')", noEvents}, + {"insert into t1 values (8, 100, 'a')", nil}, + {"insert into t1 values (9, 100, 'a')", noEvents}, + {"commit", nil}, + }, + }, + } + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ts := &TestSpec{ + t: t, + ddls: []string{ + "create table t1(id1 int, id2 int, val varbinary(128), primary key(id1))", + }, + options: &TestSpecOptions{ + filter: &binlogdatapb.Filter{ + Rules: []*binlogdatapb.Rule{{ + Match: "t1", + Filter: tc.filter, + }}, + }, + }, + } + defer ts.Close() + ts.Init() + ts.fieldEvents["t1"].cols[1].skip = true + ts.tests = [][]*TestQuery{tc.testQueries} + ts.Run() + }) + } +} From 5c27b400a81fca6023e809985826e01976632e6a Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Wed, 19 Feb 2025 10:59:24 -0500 Subject: [PATCH 14/19] VReplication: Align VReplication and VTGate VStream Retry Logic (#17783) Signed-off-by: Matt Lord --- go/vt/vtgate/vstream_manager.go | 32 ++++++++++++++----- go/vt/vtgate/vstream_manager_test.go | 11 +++++-- .../tabletmanager/vreplication/utils.go | 3 +- .../tabletmanager/vreplication/utils_test.go | 3 +- .../tabletserver/vstreamer/uvstreamer.go | 8 ++--- 5 files changed, 40 insertions(+), 17 deletions(-) diff --git a/go/vt/vtgate/vstream_manager.go b/go/vt/vtgate/vstream_manager.go index dc7a77ed62d..2a48fa9fc6d 100644 --- a/go/vt/vtgate/vstream_manager.go +++ b/go/vt/vtgate/vstream_manager.go @@ -27,6 +27,7 @@ import ( "golang.org/x/exp/maps" + "vitess.io/vitess/go/mysql/sqlerror" "vitess.io/vitess/go/stats" "vitess.io/vitess/go/vt/discovery" "vitess.io/vitess/go/vt/key" @@ -798,20 +799,35 @@ func (vs *vstream) streamFromTablet(ctx context.Context, sgtid *binlogdatapb.Sha // An error should be retried if it is expected to be transient. // A tablet should be ignored upon retry if it's likely another tablet will not // produce the same error. -func (vs *vstream) shouldRetry(err error) (bool, bool) { +func (vs *vstream) shouldRetry(err error) (retry bool, ignoreTablet bool) { errCode := vterrors.Code(err) - + // In this context, where we will run the tablet picker again on retry, these + // codes indicate that it's worth a retry as the error is likely a transient + // one with a tablet or within the shard. if errCode == vtrpcpb.Code_FAILED_PRECONDITION || errCode == vtrpcpb.Code_UNAVAILABLE { return true, false } - - // If there is a GTIDSet Mismatch on the tablet, omit it from the candidate - // list in the TabletPicker on retry. - if errCode == vtrpcpb.Code_INVALID_ARGUMENT && strings.Contains(err.Error(), "GTIDSet Mismatch") { - return true, true + // This typically indicates that the user provided invalid arguments for the + // VStream so we should not retry. + if errCode == vtrpcpb.Code_INVALID_ARGUMENT { + // But if there is a GTIDSet Mismatch on the tablet, omit that tablet from + // the candidate list in the TabletPicker and retry. The argument was invalid + // *for that specific *tablet* but it's not generally invalid. + if strings.Contains(err.Error(), "GTIDSet Mismatch") { + return true, true + } + return false, false + } + // Internal errors such as not having all journaling partipants require a new + // VStream. + if errCode == vtrpcpb.Code_INTERNAL { + return false, false } - return false, false + // For anything else, if this is an ephemeral SQL error -- such as a + // MAX_EXECUTION_TIME SQL error during the copy phase -- or any other + // type of non-SQL error, then retry. + return sqlerror.IsEphemeralError(err), false } // sendAll sends a group of events together while holding the lock. diff --git a/go/vt/vtgate/vstream_manager_test.go b/go/vt/vtgate/vstream_manager_test.go index 4e10e60c758..e209e15fb3d 100644 --- a/go/vt/vtgate/vstream_manager_test.go +++ b/go/vt/vtgate/vstream_manager_test.go @@ -420,12 +420,19 @@ func TestVStreamRetriableErrors(t *testing.T) { ignoreTablet: false, }, { - name: "should not retry", + name: "invalid argument", code: vtrpcpb.Code_INVALID_ARGUMENT, msg: "final error", shouldRetry: false, ignoreTablet: false, }, + { + name: "query interrupted", + code: vtrpcpb.Code_UNKNOWN, + msg: "vttablet: rpc error: code = Unknown desc = Query execution was interrupted, maximum statement execution time exceeded (errno 3024) (sqlstate HY000)", + shouldRetry: true, + ignoreTablet: false, + }, } commit := []*binlogdatapb.VEvent{ @@ -928,7 +935,7 @@ func TestVStreamJournalPartialMatch(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - // Variable names are maintained like in OneToMany, but order is different.1 + // Variable names are maintained like in OneToMany, but order is different. ks := "TestVStream" cell := "aa" _ = createSandbox(ks) diff --git a/go/vt/vttablet/tabletmanager/vreplication/utils.go b/go/vt/vttablet/tabletmanager/vreplication/utils.go index 67b52c56261..cff53ce55ee 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/utils.go +++ b/go/vt/vttablet/tabletmanager/vreplication/utils.go @@ -129,7 +129,8 @@ func insertLogWithParams(dbClient *vdbClient, action string, vreplID int32, para insertLog(dbClient, action, vreplID, params["state"], message) } -// isUnrecoverableError returns true if vreplication cannot recover from the given error and should completely terminate. +// isUnrecoverableError returns true if vreplication cannot recover from the given error and +// should completely terminate. func isUnrecoverableError(err error) bool { if err == nil { return false diff --git a/go/vt/vttablet/tabletmanager/vreplication/utils_test.go b/go/vt/vttablet/tabletmanager/vreplication/utils_test.go index 15093e299fc..2406796aace 100644 --- a/go/vt/vttablet/tabletmanager/vreplication/utils_test.go +++ b/go/vt/vttablet/tabletmanager/vreplication/utils_test.go @@ -22,8 +22,6 @@ import ( "strings" "testing" - vttablet "vitess.io/vitess/go/vt/vttablet/common" - "github.com/stretchr/testify/require" "vitess.io/vitess/go/mysql/sqlerror" @@ -31,6 +29,7 @@ import ( "vitess.io/vitess/go/textutil" "vitess.io/vitess/go/vt/binlog/binlogplayer" "vitess.io/vitess/go/vt/vterrors" + vttablet "vitess.io/vitess/go/vt/vttablet/common" binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" diff --git a/go/vt/vttablet/tabletserver/vstreamer/uvstreamer.go b/go/vt/vttablet/tabletserver/vstreamer/uvstreamer.go index ea475d19676..bf8d4330831 100644 --- a/go/vt/vttablet/tabletserver/vstreamer/uvstreamer.go +++ b/go/vt/vttablet/tabletserver/vstreamer/uvstreamer.go @@ -27,17 +27,17 @@ import ( "time" "vitess.io/vitess/go/mysql/replication" - vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" - "vitess.io/vitess/go/vt/dbconfigs" "vitess.io/vitess/go/vt/key" "vitess.io/vitess/go/vt/log" - binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" - querypb "vitess.io/vitess/go/vt/proto/query" "vitess.io/vitess/go/vt/sqlparser" "vitess.io/vitess/go/vt/vterrors" "vitess.io/vitess/go/vt/vttablet/tabletserver/schema" "vitess.io/vitess/go/vt/vttablet/tabletserver/throttle/throttlerapp" + + binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata" + querypb "vitess.io/vitess/go/vt/proto/query" + vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc" ) var uvstreamerTestMode = false // Only used for testing From 2118bc35d4711f2070b3dd1ae2d14decc28ca060 Mon Sep 17 00:00:00 2001 From: Harshit Gangal Date: Wed, 19 Feb 2025 22:00:58 +0530 Subject: [PATCH 15/19] pool: reopen connection closed by idle timeout (#17818) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Harshit Gangal Signed-off-by: Vicent Martí <42793+vmg@users.noreply.github.com> Co-authored-by: Vicent Martí <42793+vmg@users.noreply.github.com> --- go/pools/smartconnpool/pool.go | 24 ++++++++-- go/pools/smartconnpool/pool_test.go | 73 +++++++++++++++++++++++------ 2 files changed, 78 insertions(+), 19 deletions(-) diff --git a/go/pools/smartconnpool/pool.go b/go/pools/smartconnpool/pool.go index 87a288bec3d..7e4b296e634 100644 --- a/go/pools/smartconnpool/pool.go +++ b/go/pools/smartconnpool/pool.go @@ -136,7 +136,6 @@ type ConnPool[C Connection] struct { connect Connector[C] // refresh is the callback to check whether the pool needs to be refreshed refresh RefreshCheck - // maxCapacity is the maximum value to which capacity can be set; when the pool // is re-opened, it defaults to this capacity maxCapacity int64 @@ -401,6 +400,8 @@ func (pool *ConnPool[C]) put(conn *Pooled[C]) { if conn == nil { var err error + // Using context.Background() is fine since MySQL connection already enforces + // a connect timeout via the `db_connect_timeout_ms` config param. conn, err = pool.connNew(context.Background()) if err != nil { pool.closedConn() @@ -413,6 +414,8 @@ func (pool *ConnPool[C]) put(conn *Pooled[C]) { if lifetime > 0 && conn.timeCreated.elapsed() > lifetime { pool.Metrics.maxLifetimeClosed.Add(1) conn.Close() + // Using context.Background() is fine since MySQL connection already enforces + // a connect timeout via the `db_connect_timeout_ms` config param. if err := pool.connReopen(context.Background(), conn, conn.timeUsed.get()); err != nil { pool.closedConn() return @@ -496,15 +499,22 @@ func (pool *ConnPool[D]) extendedMaxLifetime() time.Duration { return time.Duration(maxLifetime) + time.Duration(rand.Uint32N(uint32(maxLifetime))) } -func (pool *ConnPool[C]) connReopen(ctx context.Context, dbconn *Pooled[C], now time.Duration) error { - var err error +func (pool *ConnPool[C]) connReopen(ctx context.Context, dbconn *Pooled[C], now time.Duration) (err error) { dbconn.Conn, err = pool.config.connect(ctx) if err != nil { return err } - dbconn.timeUsed.set(now) + if setting := dbconn.Conn.Setting(); setting != nil { + err = dbconn.Conn.ApplySetting(ctx, setting) + if err != nil { + dbconn.Close() + return err + } + } + dbconn.timeCreated.set(now) + dbconn.timeUsed.set(now) return nil } @@ -764,7 +774,11 @@ func (pool *ConnPool[C]) closeIdleResources(now time.Time) { if conn.timeUsed.expired(mono, timeout) { pool.Metrics.idleClosed.Add(1) conn.Close() - pool.closedConn() + // Using context.Background() is fine since MySQL connection already enforces + // a connect timeout via the `db_connect_timeout_ms` config param. + if err := pool.connReopen(context.Background(), conn, mono); err != nil { + pool.closedConn() + } } } } diff --git a/go/pools/smartconnpool/pool_test.go b/go/pools/smartconnpool/pool_test.go index 202261e6f3b..4e249622fb0 100644 --- a/go/pools/smartconnpool/pool_test.go +++ b/go/pools/smartconnpool/pool_test.go @@ -36,12 +36,11 @@ var ( type TestState struct { lastID, open, close, reset atomic.Int64 - waits []time.Time mu sync.Mutex - - chaos struct { + waits []time.Time + chaos struct { delayConnect time.Duration - failConnect bool + failConnect atomic.Bool failApply bool } } @@ -109,7 +108,7 @@ func newConnector(state *TestState) Connector[*TestConn] { if state.chaos.delayConnect != 0 { time.Sleep(state.chaos.delayConnect) } - if state.chaos.failConnect { + if state.chaos.failConnect.Load() { return nil, fmt.Errorf("failed to connect: forced failure") } return &TestConn{ @@ -586,6 +585,45 @@ func TestUserClosing(t *testing.T) { } } +func TestConnReopen(t *testing.T) { + var state TestState + + p := NewPool(&Config[*TestConn]{ + Capacity: 1, + IdleTimeout: 200 * time.Millisecond, + MaxLifetime: 10 * time.Millisecond, + LogWait: state.LogWait, + }).Open(newConnector(&state), nil) + + defer p.Close() + + conn, err := p.Get(context.Background(), nil) + require.NoError(t, err) + assert.EqualValues(t, 1, state.lastID.Load()) + assert.EqualValues(t, 1, p.Active()) + + // wait enough to reach maxlifetime. + time.Sleep(50 * time.Millisecond) + + p.put(conn) + assert.EqualValues(t, 2, state.lastID.Load()) + assert.EqualValues(t, 1, p.Active()) + + // wait enough to reach idle timeout. + time.Sleep(300 * time.Millisecond) + assert.GreaterOrEqual(t, state.lastID.Load(), int64(3)) + assert.EqualValues(t, 1, p.Active()) + assert.GreaterOrEqual(t, p.Metrics.IdleClosed(), int64(1)) + + // mark connect to fail + state.chaos.failConnect.Store(true) + // wait enough to reach idle timeout and connect to fail. + time.Sleep(300 * time.Millisecond) + // no active connection should be left. + assert.Zero(t, p.Active()) + +} + func TestIdleTimeout(t *testing.T) { testTimeout := func(t *testing.T, setting *Setting) { var state TestState @@ -608,6 +646,7 @@ func TestIdleTimeout(t *testing.T) { conns = append(conns, r) } + assert.GreaterOrEqual(t, state.open.Load(), int64(5)) // wait a long while; ensure that none of the conns have been closed time.Sleep(1 * time.Second) @@ -628,9 +667,15 @@ func TestIdleTimeout(t *testing.T) { t.Fatalf("Connections remain open after 1 second") } } + // At least 5 connections should have been closed by now. + assert.GreaterOrEqual(t, p.Metrics.IdleClosed(), int64(5), "At least 5 connections should have been closed by now.") + + // At any point, at least 4 connections should be open, with 1 either in the process of opening or already opened. + // The idle connection closer shuts down one connection at a time. + assert.GreaterOrEqual(t, state.open.Load(), int64(4)) - // no need to assert anything: all the connections in the pool should are idle-closed - // now and if they're not the test will timeout and fail + // The number of available connections in the pool should remain at 5. + assert.EqualValues(t, 5, p.Available()) } t.Run("WithoutSettings", func(t *testing.T) { testTimeout(t, nil) }) @@ -656,7 +701,7 @@ func TestIdleTimeoutCreateFail(t *testing.T) { // Change the factory before putting back // to prevent race with the idle closer, who will // try to use it. - state.chaos.failConnect = true + state.chaos.failConnect.Store(true) p.put(r) timeout := time.After(1 * time.Second) for p.Active() != 0 { @@ -667,7 +712,7 @@ func TestIdleTimeoutCreateFail(t *testing.T) { } } // reset factory for next run. - state.chaos.failConnect = false + state.chaos.failConnect.Store(false) } } @@ -803,7 +848,7 @@ func TestMaxIdleCount(t *testing.T) { func TestCreateFail(t *testing.T) { var state TestState - state.chaos.failConnect = true + state.chaos.failConnect.Store(true) ctx := context.Background() p := NewPool(&Config[*TestConn]{ @@ -850,12 +895,12 @@ func TestCreateFailOnPut(t *testing.T) { require.NoError(t, err) // change factory to fail the put. - state.chaos.failConnect = true + state.chaos.failConnect.Store(true) p.put(nil) assert.Zero(t, p.Active()) // change back for next iteration. - state.chaos.failConnect = false + state.chaos.failConnect.Store(false) } } @@ -873,7 +918,7 @@ func TestSlowCreateFail(t *testing.T) { LogWait: state.LogWait, }).Open(newConnector(&state), nil) - state.chaos.failConnect = true + state.chaos.failConnect.Store(true) for i := 0; i < 3; i++ { go func() { @@ -892,7 +937,7 @@ func TestSlowCreateFail(t *testing.T) { default: } - state.chaos.failConnect = false + state.chaos.failConnect.Store(false) conn, err := p.Get(ctx, setting) require.NoError(t, err) From 22988df39562f0b4a7ce218d52252e4de9d604d3 Mon Sep 17 00:00:00 2001 From: Matt Lord Date: Thu, 20 Feb 2025 16:31:44 -0500 Subject: [PATCH 16/19] VReplication: Support excluding lagging tablets and use this in vstream manager (#17835) Signed-off-by: Matt Lord --- go/vt/discovery/tablet_picker.go | 17 ++++---- go/vt/discovery/tablet_picker_test.go | 60 +++++++++++++++++++++++++++ go/vt/vtgate/vstream_manager.go | 4 ++ 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/go/vt/discovery/tablet_picker.go b/go/vt/discovery/tablet_picker.go index cfe1ba2e964..34c7178c350 100644 --- a/go/vt/discovery/tablet_picker.go +++ b/go/vt/discovery/tablet_picker.go @@ -100,9 +100,10 @@ func SetTabletPickerRetryDelay(delay time.Duration) { } type TabletPickerOptions struct { - CellPreference string - TabletOrder string - IncludeNonServingTablets bool + CellPreference string + TabletOrder string + IncludeNonServingTablets bool + ExcludeTabletsWithMaxReplicationLag time.Duration } func parseTabletPickerCellPreferenceString(str string) (TabletPickerCellPreference, error) { @@ -356,8 +357,8 @@ func (tp *TabletPicker) PickForStreaming(ctx context.Context) (*topodatapb.Table if len(candidates) == 0 { // If no viable candidates were found, sleep and try again. tp.incNoTabletFoundStat() - log.Infof("No healthy serving tablet found for streaming, shard %s.%s, cells %v, tabletTypes %v, sleeping for %.3f seconds.", - tp.keyspace, tp.shard, tp.cells, tp.tabletTypes, float64(GetTabletPickerRetryDelay().Milliseconds())/1000.0) + log.Infof("No healthy serving tablet found for streaming, shard %s.%s, cells %v, tabletTypes %v, maxReplicationLag: %v, sleeping for %.3f seconds.", + tp.keyspace, tp.shard, tp.cells, tp.tabletTypes, tp.options.ExcludeTabletsWithMaxReplicationLag, float64(GetTabletPickerRetryDelay().Milliseconds())/1000.0) timer := time.NewTimer(GetTabletPickerRetryDelay()) select { case <-ctx.Done(): @@ -471,8 +472,10 @@ func (tp *TabletPicker) GetMatchingTablets(ctx context.Context) []*topo.TabletIn if err := conn.StreamHealth(shortCtx, func(shr *querypb.StreamHealthResponse) error { if shr != nil && (shr.Serving || tp.options.IncludeNonServingTablets) && - shr.RealtimeStats != nil && - shr.RealtimeStats.HealthError == "" { + (shr.RealtimeStats != nil && shr.RealtimeStats.HealthError == "" && + (tabletInfo.Tablet.Type == topodatapb.TabletType_PRIMARY /* lag is not relevant */ || + (tp.options.ExcludeTabletsWithMaxReplicationLag == 0 /* not set */ || + shr.RealtimeStats.ReplicationLagSeconds <= uint32(tp.options.ExcludeTabletsWithMaxReplicationLag.Seconds())))) { return io.EOF // End the stream } return vterrors.New(vtrpcpb.Code_INTERNAL, "tablet is not healthy and serving") diff --git a/go/vt/discovery/tablet_picker_test.go b/go/vt/discovery/tablet_picker_test.go index 27c4d8bf7b1..b44ae9adbd1 100644 --- a/go/vt/discovery/tablet_picker_test.go +++ b/go/vt/discovery/tablet_picker_test.go @@ -685,6 +685,61 @@ func TestPickNonServingTablets(t *testing.T) { assert.True(t, picked3) } +// TestPickNonLaggingTablets validates that lagging tablets are excluded when the +// ExcludeTabletsWithMaxReplicationLag option is set. +func TestPickNonLaggingTablets(t *testing.T) { + ctx := utils.LeakCheckContext(t) + cells := []string{"cell1"} + defaultCell := cells[0] + tabletTypes := "replica" + options := TabletPickerOptions{ + ExcludeTabletsWithMaxReplicationLag: lowReplicationLag.Default(), + } + replLag := options.ExcludeTabletsWithMaxReplicationLag + (5 * time.Second) + te := newPickerTestEnv(t, ctx, cells) + + // Tablet should not be selected as we only want replicas. + primaryTablet := addTablet(ctx, te, 100, topodatapb.TabletType_PRIMARY, defaultCell, true, true) + defer deleteTablet(t, te, primaryTablet) + + // Tablet should not be selected as it is lagging. + laggingReplicaTablet := addTabletWithLag(ctx, te, 200, topodatapb.TabletType_REPLICA, defaultCell, true, true, uint32(replLag.Seconds())) + defer deleteTablet(t, te, laggingReplicaTablet) + + // Tablet should be selected because it's a non-lagging replica. + nonLaggingReplicaTablet := addTablet(ctx, te, 300, topodatapb.TabletType_REPLICA, defaultCell, true, true) + defer deleteTablet(t, te, nonLaggingReplicaTablet) + + _, err := te.topoServ.UpdateShardFields(ctx, te.keyspace, te.shard, func(si *topo.ShardInfo) error { + si.PrimaryAlias = primaryTablet.Alias + return nil + }) + require.NoError(t, err) + + tp, err := NewTabletPicker(ctx, te.topoServ, cells, defaultCell, te.keyspace, te.shard, tabletTypes, options) + require.NoError(t, err) + ctx, cancel := context.WithTimeout(ctx, contextTimeout) + defer cancel() + + var pickedPrimary, pickedLaggingReplica, pickedNonLaggingReplica int + for i := 0; i < numTestIterations; i++ { + tablet, err := tp.PickForStreaming(ctx) + require.NoError(t, err) + if proto.Equal(tablet, primaryTablet) { + pickedPrimary++ + } + if proto.Equal(tablet, laggingReplicaTablet) { + pickedLaggingReplica++ + } + if proto.Equal(tablet, nonLaggingReplicaTablet) { + pickedNonLaggingReplica++ + } + } + require.Zero(t, pickedPrimary) + require.Zero(t, pickedLaggingReplica) + require.Equal(t, numTestIterations, pickedNonLaggingReplica) +} + type pickerTestEnv struct { t *testing.T keyspace string @@ -720,6 +775,10 @@ func newPickerTestEnv(t *testing.T, ctx context.Context, cells []string, extraCe } func addTablet(ctx context.Context, te *pickerTestEnv, id int, tabletType topodatapb.TabletType, cell string, serving, healthy bool) *topodatapb.Tablet { + return addTabletWithLag(ctx, te, id, tabletType, cell, serving, healthy, 0) +} + +func addTabletWithLag(ctx context.Context, te *pickerTestEnv, id int, tabletType topodatapb.TabletType, cell string, serving, healthy bool, replLagSecs uint32) *topodatapb.Tablet { tablet := &topodatapb.Tablet{ Alias: &topodatapb.TabletAlias{ Cell: cell, @@ -748,6 +807,7 @@ func addTablet(ctx context.Context, te *pickerTestEnv, id int, tabletType topoda if healthy { shr.RealtimeStats.HealthError = "" } + shr.RealtimeStats.ReplicationLagSeconds = replLagSecs _ = createFixedHealthConn(tablet, shr) diff --git a/go/vt/vtgate/vstream_manager.go b/go/vt/vtgate/vstream_manager.go index 2a48fa9fc6d..ada1ddb131c 100644 --- a/go/vt/vtgate/vstream_manager.go +++ b/go/vt/vtgate/vstream_manager.go @@ -194,6 +194,10 @@ func (vsm *vstreamManager) VStream(ctx context.Context, tabletType topodatapb.Ta tabletPickerOptions: discovery.TabletPickerOptions{ CellPreference: flags.GetCellPreference(), TabletOrder: flags.GetTabletOrder(), + // This is NOT configurable via the API because we check the + // discovery.GetLowReplicationLag().Seconds() value in the tablet + // health stream. + ExcludeTabletsWithMaxReplicationLag: discovery.GetLowReplicationLag(), }, flags: flags, } From c9c227db69b8f30cc90a43fa023e0d545964713b Mon Sep 17 00:00:00 2001 From: Tim Vaillancourt Date: Thu, 20 Feb 2025 23:24:11 +0100 Subject: [PATCH 17/19] Allow build git envs to be set in `docker/lite` (#17827) Signed-off-by: Tim Vaillancourt --- docker/lite/Dockerfile | 9 +++++++++ docker/lite/Dockerfile.mysql84 | 9 +++++++++ docker/lite/Dockerfile.percona80 | 9 +++++++++ 3 files changed, 27 insertions(+) diff --git a/docker/lite/Dockerfile b/docker/lite/Dockerfile index 70d4787686c..beeb0cfef8c 100644 --- a/docker/lite/Dockerfile +++ b/docker/lite/Dockerfile @@ -17,6 +17,15 @@ FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER +# Allows docker builds to set the BUILD_GIT_BRANCH +ARG BUILD_GIT_BRANCH + +# Allows docker builds to set the BUILD_GIT_REV +ARG BUILD_GIT_REV + +# Allows docker builds to set the BUILD_TIME +ARG BUILD_TIME + WORKDIR /vt/src/vitess.io/vitess # Create vitess user diff --git a/docker/lite/Dockerfile.mysql84 b/docker/lite/Dockerfile.mysql84 index 047e3d1f90c..f47758754ae 100644 --- a/docker/lite/Dockerfile.mysql84 +++ b/docker/lite/Dockerfile.mysql84 @@ -17,6 +17,15 @@ FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER +# Allows docker builds to set the BUILD_GIT_BRANCH +ARG BUILD_GIT_BRANCH + +# Allows docker builds to set the BUILD_GIT_REV +ARG BUILD_GIT_REV + +# Allows docker builds to set the BUILD_TIME +ARG BUILD_TIME + WORKDIR /vt/src/vitess.io/vitess # Create vitess user diff --git a/docker/lite/Dockerfile.percona80 b/docker/lite/Dockerfile.percona80 index 011f20c4022..9a7626244ec 100644 --- a/docker/lite/Dockerfile.percona80 +++ b/docker/lite/Dockerfile.percona80 @@ -17,6 +17,15 @@ FROM --platform=linux/amd64 golang:1.24.0-bookworm AS builder # Allows docker builds to set the BUILD_NUMBER ARG BUILD_NUMBER +# Allows docker builds to set the BUILD_GIT_BRANCH +ARG BUILD_GIT_BRANCH + +# Allows docker builds to set the BUILD_GIT_REV +ARG BUILD_GIT_REV + +# Allows docker builds to set the BUILD_TIME +ARG BUILD_TIME + WORKDIR /vt/src/vitess.io/vitess # Create vitess user From db77d81d7ca5f919dd48c1a3b923aa0adb65e9c6 Mon Sep 17 00:00:00 2001 From: Manan Gupta <35839558+GuptaManan100@users.noreply.github.com> Date: Fri, 21 Feb 2025 11:55:59 +0530 Subject: [PATCH 18/19] Clear `demotePrimaryStalled` field after the function ends (#17823) Signed-off-by: Manan Gupta --- .../vttablet/tabletmanager/rpc_replication.go | 9 +++++- .../tabletmanager/rpc_replication_test.go | 28 +++++++++++++------ go/vt/vttablet/tabletserver/controller.go | 4 +-- go/vt/vttablet/tabletserver/tabletserver.go | 6 ++-- go/vt/vttablet/tabletservermock/controller.go | 2 +- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/go/vt/vttablet/tabletmanager/rpc_replication.go b/go/vt/vttablet/tabletmanager/rpc_replication.go index 7ac37515b67..070eab9a38a 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication.go @@ -535,6 +535,7 @@ func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure return nil, err } defer tm.unlock() + defer tm.QueryServiceControl.SetDemotePrimaryStalled(false) finishCtx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -546,10 +547,16 @@ func (tm *TabletManager) demotePrimary(ctx context.Context, revertPartialFailure // We waited for over 10 times of remote operation timeout, but DemotePrimary is still not done. // Collect more information and signal demote primary is indefinitely stalled. log.Errorf("DemotePrimary seems to be stalled. Collecting more information.") - tm.QueryServiceControl.SetDemotePrimaryStalled() + tm.QueryServiceControl.SetDemotePrimaryStalled(true) buf := make([]byte, 1<<16) // 64 KB buffer size stackSize := runtime.Stack(buf, true) log.Errorf("Stack trace:\n%s", string(buf[:stackSize])) + // This condition check is only to handle the race, where we start to set the demote primary stalled + // but then the function finishes. So, after we set demote primary stalled, we check if the + // function has finished and if it has, we clear the demote primary stalled. + if finishCtx.Err() != nil { + tm.QueryServiceControl.SetDemotePrimaryStalled(false) + } } }() diff --git a/go/vt/vttablet/tabletmanager/rpc_replication_test.go b/go/vt/vttablet/tabletmanager/rpc_replication_test.go index b388235811b..4efb7b13081 100644 --- a/go/vt/vttablet/tabletmanager/rpc_replication_test.go +++ b/go/vt/vttablet/tabletmanager/rpc_replication_test.go @@ -50,16 +50,16 @@ func TestWaitForGrantsToHaveApplied(t *testing.T) { type demotePrimaryStallQS struct { tabletserver.Controller - waitTime time.Duration + qsWaitChan chan any primaryStalled atomic.Bool } -func (d *demotePrimaryStallQS) SetDemotePrimaryStalled() { - d.primaryStalled.Store(true) +func (d *demotePrimaryStallQS) SetDemotePrimaryStalled(val bool) { + d.primaryStalled.Store(val) } func (d *demotePrimaryStallQS) IsServing() bool { - time.Sleep(d.waitTime) + <-d.qsWaitChan return false } @@ -74,7 +74,7 @@ func TestDemotePrimaryStalled(t *testing.T) { // Create a fake query service control to intercept calls from DemotePrimary function. qsc := &demotePrimaryStallQS{ - waitTime: 2 * time.Second, + qsWaitChan: make(chan any), } // Create a tablet manager with a replica type tablet. tm := &TabletManager{ @@ -88,8 +88,20 @@ func TestDemotePrimaryStalled(t *testing.T) { QueryServiceControl: qsc, } - // We make IsServing stall for over 2 seconds, which is longer than 10 * remote operation timeout. + go func() { + tm.demotePrimary(context.Background(), false) + }() + // We make IsServing stall by making it wait on a channel. // This should cause the demote primary operation to be stalled. - tm.demotePrimary(context.Background(), false) - require.True(t, qsc.primaryStalled.Load()) + require.Eventually(t, func() bool { + return qsc.primaryStalled.Load() + }, 5*time.Second, 100*time.Millisecond) + + // Unblock the DemotePrimary call by closing the channel. + close(qsc.qsWaitChan) + + // Eventually demote primary will succeed, and we want the stalled field to be cleared. + require.Eventually(t, func() bool { + return !qsc.primaryStalled.Load() + }, 5*time.Second, 100*time.Millisecond) } diff --git a/go/vt/vttablet/tabletserver/controller.go b/go/vt/vttablet/tabletserver/controller.go index ab2875ae27b..94bffd7d84d 100644 --- a/go/vt/vttablet/tabletserver/controller.go +++ b/go/vt/vttablet/tabletserver/controller.go @@ -120,8 +120,8 @@ type Controller interface { // WaitForPreparedTwoPCTransactions waits for all prepared transactions to be resolved. WaitForPreparedTwoPCTransactions(ctx context.Context) error - // SetDemotePrimaryStalled marks that demote primary is stalled in the state manager. - SetDemotePrimaryStalled() + // SetDemotePrimaryStalled sets the demote primary stalled field to the provided value in the state manager. + SetDemotePrimaryStalled(val bool) // IsDiskStalled returns if the disk is stalled. IsDiskStalled() bool diff --git a/go/vt/vttablet/tabletserver/tabletserver.go b/go/vt/vttablet/tabletserver/tabletserver.go index e09e04a9679..b12a3588db2 100644 --- a/go/vt/vttablet/tabletserver/tabletserver.go +++ b/go/vt/vttablet/tabletserver/tabletserver.go @@ -761,10 +761,10 @@ func (tsv *TabletServer) WaitForPreparedTwoPCTransactions(ctx context.Context) e } } -// SetDemotePrimaryStalled marks that demote primary is stalled in the state manager. -func (tsv *TabletServer) SetDemotePrimaryStalled() { +// SetDemotePrimaryStalled sets the demote primary stalled field to the provided value in the state manager. +func (tsv *TabletServer) SetDemotePrimaryStalled(val bool) { tsv.sm.mu.Lock() - tsv.sm.demotePrimaryStalled = true + tsv.sm.demotePrimaryStalled = val tsv.sm.mu.Unlock() tsv.BroadcastHealth() } diff --git a/go/vt/vttablet/tabletservermock/controller.go b/go/vt/vttablet/tabletservermock/controller.go index 21b38755302..0d35d8e280f 100644 --- a/go/vt/vttablet/tabletservermock/controller.go +++ b/go/vt/vttablet/tabletservermock/controller.go @@ -275,7 +275,7 @@ func (tqsc *Controller) WaitForPreparedTwoPCTransactions(context.Context) error } // SetDemotePrimaryStalled is part of the tabletserver.Controller interface -func (tqsc *Controller) SetDemotePrimaryStalled() { +func (tqsc *Controller) SetDemotePrimaryStalled(bool) { tqsc.MethodCalled["SetDemotePrimaryStalled"] = true } From 0a6f982bca73269042f5809ed7ee53c7acc836eb Mon Sep 17 00:00:00 2001 From: Kyle Johnson Date: Fri, 21 Feb 2025 03:54:24 -0700 Subject: [PATCH 19/19] Fix vtclient vtgate missing flags (specifically --grpc_*) (#17800) Signed-off-by: Kyle Johnson Co-authored-by: Kyle Johnson --- go/cmd/vtclient/cli/vtclient.go | 2 +- go/cmd/vtclient/cli/vtclient_test.go | 2 ++ go/cmd/vtclient/vtclient.go | 1 + go/vt/servenv/servenv.go | 4 ++-- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/go/cmd/vtclient/cli/vtclient.go b/go/cmd/vtclient/cli/vtclient.go index e8bcd9b7ff2..4f3ac6ede27 100644 --- a/go/cmd/vtclient/cli/vtclient.go +++ b/go/cmd/vtclient/cli/vtclient.go @@ -82,7 +82,7 @@ var ( seqChan = make(chan int, 10) ) -func init() { +func InitializeFlags() { servenv.MoveFlagsToCobraCommand(Main) Main.Flags().StringVar(&server, "server", server, "vtgate server to connect to") diff --git a/go/cmd/vtclient/cli/vtclient_test.go b/go/cmd/vtclient/cli/vtclient_test.go index bf0c1206167..83a9d2a3339 100644 --- a/go/cmd/vtclient/cli/vtclient_test.go +++ b/go/cmd/vtclient/cli/vtclient_test.go @@ -121,6 +121,8 @@ func TestVtclient(t *testing.T) { }, } + // initialize the vtclient flags before running any commands + InitializeFlags() for _, q := range queries { // Run main function directly and not as external process. To achieve this, // overwrite os.Args which is used by pflag.Parse(). diff --git a/go/cmd/vtclient/vtclient.go b/go/cmd/vtclient/vtclient.go index 4201d25c882..ccfd31a0ac3 100644 --- a/go/cmd/vtclient/vtclient.go +++ b/go/cmd/vtclient/vtclient.go @@ -22,6 +22,7 @@ import ( ) func main() { + cli.InitializeFlags() if err := cli.Main.Execute(); err != nil { log.Exit(err) } diff --git a/go/vt/servenv/servenv.go b/go/vt/servenv/servenv.go index 22bf3523dfc..42ce4a9cf12 100644 --- a/go/vt/servenv/servenv.go +++ b/go/vt/servenv/servenv.go @@ -336,7 +336,7 @@ func ParseFlagsForTests(cmd string) { // the given cobra command, then copies over the glog flags that otherwise // require manual transferring. func MoveFlagsToCobraCommand(cmd *cobra.Command) { - moveFlags(cmd.Use, cmd.Flags()) + moveFlags(cmd.Name(), cmd.Flags()) } // MovePersistentFlagsToCobraCommand functions exactly like MoveFlagsToCobraCommand, @@ -347,7 +347,7 @@ func MoveFlagsToCobraCommand(cmd *cobra.Command) { // Useful for transferring flags to a parent command whose subcommands should // inherit the servenv-registered flags. func MovePersistentFlagsToCobraCommand(cmd *cobra.Command) { - moveFlags(cmd.Use, cmd.PersistentFlags()) + moveFlags(cmd.Name(), cmd.PersistentFlags()) } func moveFlags(name string, fs *pflag.FlagSet) {