Repository: vitessio/vitess
Pull request #11482 (2022-10-13 06:37:10)

Move vtorc runners back to normal github runners


<!--
  Thank you for your contribution to the Vitess project.
  How to contribute: https://vitess.io/docs/contributing/
  Please first make sure there is an open Issue to discuss the feature/fix suggested in this PR.
  If this is a new feature, please mark the Issue as "RFC".
 -->

<!-- if this PR is Work in Progress please create it as a Draft Pull Request -->

## Description

<!-- A few sentences describing the overall goals of the pull request's commits. -->
<!-- If this is a bug fix and you think the fix should be backported, please write so. -->

There have been no failures in the past 24 hours on the self-hosted runners for VTOrc. This PR moves them back given that the flakiness has been fixed.

## Related Issue(s)

<!-- List related issues and pull requests. If this PR fixes an issue, please add it using Fixes #????  -->

## Checklist

-   [x] "Backport me!" label has been added if this change should be backported
-   [x] Tests were added or are not required
-   [x] Documentation was added or is not required

## Deployment Notes

<!-- Notes regarding deployment of the contained body of work. These should note any db migrations, etc. -->


vitess-bot[bot]: ### Review Checklist
            
Hello reviewers! :wave: Please follow this checklist when reviewing this Pull Request.

#### General
- [ ] Ensure that the Pull Request has a descriptive title.
- [ ] If this is a change that users need to know about, please apply the `release notes (needs details)` label so that merging is blocked unless the summary release notes document is included.

#### If a new flag is being introduced:
- [ ] Is it really necessary to add this flag?
- [ ] Flag names should be clear and intuitive (as far as possible)
- [ ] Help text should be descriptive.
- [ ] Flag names should use dashes (`-`) as word separators rather than underscores (`_`).

#### If a workflow is added or modified:
- [ ] Each item in `Jobs` should be named in order to mark it as `required`.
- [ ] If the workflow should be required, the maintainer team should be notified.

#### Bug fixes
- [ ] There should be at least one unit or end-to-end test.
- [ ] The Pull Request description should include a link to an issue that describes the bug.

#### Non-trivial changes
- [ ] There should be some code comments as to why things are implemented the way they are.

#### New/Existing features
- [ ] Should be documented, either by modifying the existing documentation or creating new documentation.
- [ ] New features should have a link to a feature request issue or an RFC that documents the use cases, corner cases and test cases.

#### Backward compatibility            
- [ ] Protobuf changes should be wire-compatible.
- [ ] Changes to `_vt` tables and RPCs need to be backward compatible.
- [ ] `vtctl` command output order should be stable and `awk`-able.
- [ ] RPC changes should be compatible with vitess-operator
- [ ] If a flag is removed, then it should also be removed from VTop, if used there.


Patch:
diff --git a/.github/workflows/cluster_endtoend_vtorc.yml b/.github/workflows/cluster_endtoend_vtorc.yml
index 981446f607..6eb41b7cd6 100644
--- a/.github/workflows/cluster_endtoend_vtorc.yml
+++ b/.github/workflows/cluster_endtoend_vtorc.yml
@@ -1,76 +1,126 @@
 # DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
 
-name: Cluster (vtorc)(mysql80)
+name: Cluster (vtorc)
 on: [push, pull_request]
 concurrency:
-  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtorc)(mysql80)')
+  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtorc)')
   cancel-in-progress: true
 
+env:
+  LAUNCHABLE_ORGANIZATION: "vitess"
+  LAUNCHABLE_WORKSPACE: "vitess-app"
+  GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"
+
 jobs:
   build:
-    name: Run endtoend tests on Cluster (vtorc)(mysql80)
-    runs-on: self-hosted
+    name: Run endtoend tests on Cluster (vtorc)
+    runs-on: ubuntu-20.04
 
     steps:
-      - name: Check if workflow needs to be skipped
-        id: skip-workflow
-        run: |
-          skip='false'
-          if [[ "${{github.event.pull_request}}" ==  "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
-            skip='true'
-          fi
-          echo Skip ${skip}
-          echo "::set-output name=skip-workflow::${skip}"
-
-      - name: Check out code
-        if: steps.skip-workflow.outputs.skip-workflow == 'false'
-        uses: actions/checkout@v2
-
-      - name: Check for changes in relevant files
-        if: steps.skip-workflow.outputs.skip-workflow == 'false'
-        uses: frouioui/paths-filter@main
-        id: changes
-        with:
-          token: ''
-          filters: |
-            end_to_end:
-              - 'go/**/*.go'
-              - 'test.go'
-              - 'Makefile'
-              - 'build.env'
-              - 'go.[sumod]'
-              - 'proto/*.proto'
-              - 'tools/**'
-              - 'config/**'
-              - '.github/docker/**'
-              - 'bootstrap.sh'
-              - '.github/workflows/cluster_endtoend_vtorc.yml'
-
-      - name: Build Docker Image
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: docker build -f ./.github/docker/cluster_test_vtorc/Dockerfile -t cluster_test_vtorc:$GITHUB_SHA  .
-
-      - name: Run test
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        timeout-minutes: 30
-        run: docker run --name "cluster_test_vtorc_$GITHUB_SHA" cluster_test_vtorc:$GITHUB_SHA /bin/bash -c 'source build.env && go run test.go -keep-data=true -docker=false -print-log -follow -shard vtorc -- -- --keep-data=true'
-
-      - name: Print Volume Used
-        if: always() && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker inspect -f '{{ (index .Mounts 0).Name }}' cluster_test_vtorc_$GITHUB_SHA
-
-      - name: Cleanup Docker Volume
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker rm -v cluster_test_vtorc_$GITHUB_SHA
-
-      - name: Cleanup Docker Container
-        if: always() && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker rm -f cluster_test_vtorc_$GITHUB_SHA
-
-      - name: Cleanup Docker Image
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker image rm cluster_test_vtorc:$GITHUB_SHA
+    - name: Check if workflow needs to be skipped
+      id: skip-workflow
+      run: |
+        skip='false'
+        if [[ "${{github.event.pull_request}}" ==  "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
+          skip='true'
+        fi
+        echo Skip ${skip}
+        echo "::set-output name=skip-workflow::${skip}"
+
+    - name: Check out code
+      if: steps.skip-workflow.outputs.skip-workflow == 'false'
+      uses: actions/checkout@v2
+
+    - name: Check for changes in relevant files
+      if: steps.skip-workflow.outputs.skip-workflow == 'false'
+      uses: frouioui/paths-filter@main
+      id: changes
+      with:
+        token: ''
+        filters: |
+          end_to_end:
+            - 'go/**/*.go'
+            - 'test.go'
+            - 'Makefile'
+            - 'build.env'
+            - 'go.[sumod]'
+            - 'proto/*.proto'
+            - 'tools/**'
+            - 'config/**'
+            - 'bootstrap.sh'
+            - '.github/workflows/cluster_endtoend_vtorc.yml'
+
+    - name: Set up Go
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      uses: actions/setup-go@v2
+      with:
+        go-version: 1.18.5
+
+    - name: Set up python
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      uses: actions/setup-python@v2
+
+    - name: Tune the OS
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      run: |
+        echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range
+        # Increase the asynchronous non-blocking I/O. More information at https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_use_native_aio
+        echo "fs.aio-max-nr = 1048576" | sudo tee -a /etc/sysctl.conf
+        sudo sysctl -p /etc/sysctl.conf
+
+    - name: Get dependencies
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      run: |
+        # Setup Percona Server for MySQL 8.0
+        sudo apt-get update
+        sudo apt-get install -y lsb-release gnupg2 curl
+        wget https://repo.percona.com/apt/percona-release_latest.$(lsb_release -sc)_all.deb
+        sudo DEBIAN_FRONTEND="noninteractive" dpkg -i percona-release_latest.$(lsb_release -sc)_all.deb
+        sudo percona-release setup ps80
+        sudo apt-get update
+
+        # Install everything else we need, and configure
+        sudo apt-get install -y percona-server-server percona-server-client make unzip g++ etcd git wget eatmydata xz-utils
+        sudo service mysql stop
+        sudo service etcd stop
+        sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
+        sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
+        go mod download
+
+        # install JUnit report formatter
+        go install github.com/vitessio/go-junit-report@HEAD
+
+    - name: Setup launchable dependencies
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      run: |
+        # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up
+        pip3 install --user launchable~=1.0 > /dev/null
+
+        # verify that launchable setup is all correct.
+        launchable verify || true
+
+        # Tell Launchable about the build you are producing and testing
+        launchable record build --name "$GITHUB_RUN_ID" --source .
+
+    - name: Run cluster endtoend test
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      timeout-minutes: 45
+      run: |
+        # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
+        # which musn't be more than 107 characters long.
+        export VTDATAROOT="/tmp/"
+        source build.env
+
+        set -x
+
+        # run the tests however you normally do, then produce a JUnit XML file
+        eatmydata -- go run test.go -docker=false -follow -shard vtorc | tee -a output.txt | go-junit-report -set-exit-code > report.xml
+
+    - name: Print test output and Record test result in launchable
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always()
+      run: |
+        # send recorded tests to launchable
+        launchable record tests --build "$GITHUB_RUN_ID" go-test . || true
+
+        # print test output
+        cat output.txt
diff --git a/.github/workflows/cluster_endtoend_vtorc_mysql57.yml b/.github/workflows/cluster_endtoend_vtorc_mysql57.yml
index cebe62cbe7..04486afc83 100644
--- a/.github/workflows/cluster_endtoend_vtorc_mysql57.yml
+++ b/.github/workflows/cluster_endtoend_vtorc_mysql57.yml
@@ -1,76 +1,140 @@
 # DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
 
-name: Cluster (vtorc)(mysql57)
+name: Cluster (vtorc) mysql57
 on: [push, pull_request]
 concurrency:
-  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtorc)(mysql57)')
+  group: format('{0}-{1}', ${{ github.ref }}, 'Cluster (vtorc) mysql57')
   cancel-in-progress: true
 
+env:
+  LAUNCHABLE_ORGANIZATION: "vitess"
+  LAUNCHABLE_WORKSPACE: "vitess-app"
+  GITHUB_PR_HEAD_SHA: "${{ github.event.pull_request.head.sha }}"
+
 jobs:
   build:
-    name: Run endtoend tests on Cluster (vtorc)(mysql57)
-    runs-on: self-hosted
+    name: Run endtoend tests on Cluster (vtorc) mysql57
+    runs-on: ubuntu-20.04
 
     steps:
-      - name: Check if workflow needs to be skipped
-        id: skip-workflow
-        run: |
-          skip='false'
-          if [[ "${{github.event.pull_request}}" ==  "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
-            skip='true'
-          fi
-          echo Skip ${skip}
-          echo "::set-output name=skip-workflow::${skip}"
-
-      - name: Check out code
-        if: steps.skip-workflow.outputs.skip-workflow == 'false'
-        uses: actions/checkout@v2
-
-      - name: Check for changes in relevant files
-        if: steps.skip-workflow.outputs.skip-workflow == 'false'
-        uses: frouioui/paths-filter@main
-        id: changes
-        with:
-          token: ''
-          filters: |
-            end_to_end:
-              - 'go/**/*.go'
-              - 'test.go'
-              - 'Makefile'
-              - 'build.env'
-              - 'go.[sumod]'
-              - 'proto/*.proto'
-              - 'tools/**'
-              - 'config/**'
-              - '.github/docker/**'
-              - 'bootstrap.sh'
-              - '.github/workflows/cluster_endtoend_vtorc_mysql57.yml'
-
-      - name: Build Docker Image
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: docker build -f ./.github/docker/cluster_test_vtorc_mysql57/Dockerfile -t cluster_test_vtorc_mysql57:$GITHUB_SHA  .
-
-      - name: Run test
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        timeout-minutes: 30
-        run: docker run --name "cluster_test_vtorc_mysql57_$GITHUB_SHA" cluster_test_vtorc_mysql57:$GITHUB_SHA /bin/bash -c 'source build.env && go run test.go -keep-data=true -docker=false -print-log -follow -shard vtorc -- -- --keep-data=true'
-
-      - name: Print Volume Used
-        if: always() && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker inspect -f '{{ (index .Mounts 0).Name }}' cluster_test_vtorc_mysql57_$GITHUB_SHA
-
-      - name: Cleanup Docker Volume
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker rm -v cluster_test_vtorc_mysql57_$GITHUB_SHA
-
-      - name: Cleanup Docker Container
-        if: always() && steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker rm -f cluster_test_vtorc_mysql57_$GITHUB_SHA
-
-      - name: Cleanup Docker Image
-        if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
-        run: |
-          docker image rm cluster_test_vtorc_mysql57:$GITHUB_SHA
+    - name: Check if workflow needs to be skipped
+      id: skip-workflow
+      run: |
+        skip='false'
+        if [[ "${{github.event.pull_request}}" ==  "" ]] && [[ "${{github.ref}}" != "refs/heads/main" ]] && [[ ! "${{github.ref}}" =~ ^refs/heads/release-[0-9]+\.[0-9]$ ]] && [[ ! "${{github.ref}}" =~ "refs/tags/.*" ]]; then
+          skip='true'
+        fi
+        echo Skip ${skip}
+        echo "::set-output name=skip-workflow::${skip}"
+
+    - name: Check out code
+      if: steps.skip-workflow.outputs.skip-workflow == 'false'
+      uses: actions/checkout@v2
+
+    - name: Check for changes in relevant files
+      if: steps.skip-workflow.outputs.skip-workflow == 'false'
+      uses: frouioui/paths-filter@main
+      id: changes
+      with:
+        token: ''
+        filters: |
+          end_to_end:
+            - 'go/**/*.go'
+            - 'test.go'
+            - 'Makefile'
+            - 'build.env'
+            - 'go.[sumod]'
+            - 'proto/*.proto'
+            - 'tools/**'
+            - 'config/**'
+            - 'bootstrap.sh'
+            - '.github/workflows/cluster_endtoend_vtorc_mysql57.yml'
+
+    - name: Set up Go
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      uses: actions/setup-go@v2
+      with:
+        go-version: 1.18.5
+
+    - name: Set up python
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      uses: actions/setup-python@v2
+
+    - name: Tune the OS
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      run: |
+        echo '1024 65535' | sudo tee -a /proc/sys/net/ipv4/ip_local_port_range
+        # Increase the asynchronous non-blocking I/O. More information at https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_use_native_aio
+        echo "fs.aio-max-nr = 1048576" | sudo tee -a /etc/sysctl.conf
+        sudo sysctl -p /etc/sysctl.conf
+
+    - name: Get dependencies
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      run: |
+        sudo apt-get update
+
+        # Uninstall any previously installed MySQL first
+        sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/
+        sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.mysqld
+
+        sudo systemctl stop apparmor
+        sudo DEBIAN_FRONTEND="noninteractive" apt-get remove -y --purge mysql-server mysql-client mysql-common
+        sudo apt-get -y autoremove
+        sudo apt-get -y autoclean
+        sudo deluser mysql
+        sudo rm -rf /var/lib/mysql
+        sudo rm -rf /etc/mysql
+
+        # Get key to latest MySQL repo
+        sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 467B942D3A79BD29
+
+        wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.14-1_all.deb
+        # Bionic packages are still compatible for Focal since there's no MySQL 5.7
+        # packages for Focal.
+        echo mysql-apt-config mysql-apt-config/repo-codename select bionic | sudo debconf-set-selections
+        echo mysql-apt-config mysql-apt-config/select-server select mysql-5.7 | sudo debconf-set-selections
+        sudo DEBIAN_FRONTEND="noninteractive" dpkg -i mysql-apt-config*
+        sudo apt-get update
+        sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y mysql-client=5.7* mysql-community-server=5.7* mysql-server=5.7*
+
+        sudo apt-get install -y make unzip g++ etcd curl git wget eatmydata
+        sudo service mysql stop
+        sudo service etcd stop
+
+        # install JUnit report formatter
+        go install github.com/vitessio/go-junit-report@HEAD
+
+    - name: Setup launchable dependencies
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      run: |
+        # Get Launchable CLI installed. If you can, make it a part of the builder image to speed things up
+        pip3 install --user launchable~=1.0 > /dev/null
+
+        # verify that launchable setup is all correct.
+        launchable verify || true
+
+        # Tell Launchable about the build you are producing and testing
+        launchable record build --name "$GITHUB_RUN_ID" --source .
+
+    - name: Run cluster endtoend test
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
+      timeout-minutes: 45
+      run: |
+        # We set the VTDATAROOT to the /tmp folder to reduce the file path of mysql.sock file
+        # which musn't be more than 107 characters long.
+        export VTDATAROOT="/tmp/"
+        source build.env
+
+        set -x
+
+        # run the tests however you normally do, then produce a JUnit XML file
+        eatmydata -- go run test.go -docker=false -follow -shard vtorc | tee -a output.txt | go-junit-report -set-exit-code > report.xml
+
+    - name: Print test output and Record test result in launchable
+      if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true' && always()
+      run: |
+        # send recorded tests to launchable
+        launchable record tests --build "$GITHUB_RUN_ID" go-test . || true
+
+        # print test output
+        cat output.txt
diff --git a/.github/workflows/static_checks_etc.yml b/.github/workflows/static_checks_etc.yml
index 2f62e4c2c6..ed00729fc5 100644
--- a/.github/workflows/static_checks_etc.yml
+++ b/.github/workflows/static_checks_etc.yml
@@ -135,17 +135,17 @@ jobs:
       - name: check_make_parser
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.parser_changes == 'true'
         run: |
-          tools/check_make_parser.sh
+          tools/check_make_parser.sh || exit 1
 
       - name: check_make_sizegen
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.sizegen == 'true'
         run: |
-          tools/check_make_sizegen.sh
+          tools/check_make_sizegen.sh || exit 1
 
       - name: check_make_visitor
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.visitor == 'true'
         run: |
-          misc/git/hooks/asthelpers
+          misc/git/hooks/asthelpers || exit 1
 
       - name: run ensure_bootstrap_version
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.end_to_end == 'true'
@@ -168,7 +168,7 @@ jobs:
 
       - name: Run golangci-lint
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true'
-        run: $(go env GOPATH)/bin/golangci-lint run go/...
+        run: $(go env GOPATH)/bin/golangci-lint run go/... || exit 1
 
       - name: Run go mod tidy
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.go_files == 'true'
@@ -187,4 +187,4 @@ jobs:
       - name: check_make_proto
         if: steps.skip-workflow.outputs.skip-workflow == 'false' && steps.changes.outputs.proto_changes == 'true'
         run: |
-          tools/check_make_proto.sh
+          tools/check_make_proto.sh || exit 1
diff --git a/go/mysql/collations/coercion.go b/go/mysql/collations/coercion.go
index 3087975f23..edd1a6289e 100644
--- a/go/mysql/collations/coercion.go
+++ b/go/mysql/collations/coercion.go
@@ -208,9 +208,16 @@ func (env *Environment) MergeCollations(left, right TypedCollation, opt Coercion
 	if leftColl == nil || rightColl == nil {
 		return TypedCollation{}, nil, nil, fmt.Errorf("unsupported TypeCollationID: %v / %v", left.Collation, right.Collation)
 	}
+
 	leftCS := leftColl.Charset()
 	rightCS := rightColl.Charset()
 
+	if left.Coercibility == CoerceExplicit && right.Coercibility == CoerceExplicit {
+		if left.Collation != right.Collation {
+			goto cannotCoerce
+		}
+	}
+
 	if leftCS.Name() == rightCS.Name() {
 		switch {
 		case left.Coercibility < right.Coercibility:
diff --git a/go/vt/vtgate/planbuilder/abstract/queryprojection.go b/go/vt/vtgate/planbuilder/abstract/queryprojection.go
index 14572b117b..f3acdd3693 100644
--- a/go/vt/vtgate/planbuilder/abstract/queryprojection.go
+++ b/go/vt/vtgate/planbuilder/abstract/queryprojection.go
@@ -314,39 +314,6 @@ func checkForInvalidAggregations(exp *sqlparser.AliasedExpr) error {
 	}, exp.Expr)
 }
 
-func (qp *QueryProjection) getNonAggrExprNotMatchingGroupByExprs() sqlparser.SelectExpr {
-	for _, expr := range qp.SelectExprs {
-		if expr.Aggr {
-			continue
-		}
-		if !qp.isExprInGroupByExprs(expr) {
-			return expr.Col
-		}
-	}
-	for _, order := range qp.OrderExprs {
-		if !qp.isOrderByExprInGroupBy(order) {
-			return &sqlparser.AliasedExpr{
-				Expr: order.Inner.Expr,
-			}
-		}
-	}
-	return nil
-}
-
-func (qp *QueryProjection) isOrderByExprInGroupBy(order OrderBy) bool {
-	// ORDER BY NULL or Aggregation functions need not be present in group by
-	_, isAggregate := order.WeightStrExpr.(sqlparser.AggrFunc)
-	if sqlparser.IsNull(order.Inner.Expr) || isAggregate {
-		return true
-	}
-	for _, groupByExpr := range qp.groupByExprs {
-		if sqlparser.EqualsExpr(groupByExpr.WeightStrExpr, order.WeightStrExpr) {
-			return true
-		}
-	}
-	return false
-}
-
 func (qp *QueryProjection) isExprInGroupByExprs(expr SelectExpr) bool {
 	for _, groupByExpr := range qp.groupByExprs {
 		exp, err := expr.GetExpr()
@@ -457,10 +424,7 @@ func (qp *QueryProjection) NeedsDistinct() bool {
 func (qp *QueryProjection) AggregationExpressions() (out []Aggr, err error) {
 orderBy:
 	for _, orderExpr := range qp.OrderExprs {
-		if qp.isOrderByExprInGroupBy(orderExpr) {
-			continue orderBy
-		}
-		orderExpr := orderExpr.Inner.Expr
+		orderExpr := orderExpr.WeightStrExpr
 		for _, expr := range qp.SelectExprs {
 			col, ok := expr.Col.(*sqlparser.AliasedExpr)
 			if !ok {
diff --git a/go/vt/vtgate/semantics/analyzer.go b/go/vt/vtgate/semantics/analyzer.go
index ba30f0392c..39e97a307f 100644
--- a/go/vt/vtgate/semantics/analyzer.go
+++ b/go/vt/vtgate/semantics/analyzer.go
@@ -56,7 +56,11 @@ func newAnalyzer(dbName string, si SchemaInformation) *analyzer {
 
 	b := newBinder(s, a, a.tables, a.typer)
 	a.binder = b
-	a.rewriter = &earlyRewriter{scoper: s, binder: b}
+	a.rewriter = &earlyRewriter{
+		scoper:          s,
+		binder:          b,
+		expandedColumns: map[sqlparser.TableName][]*sqlparser.ColName{},
+	}
 	s.binder = b
 	return a
 }
@@ -98,6 +102,7 @@ func (a analyzer) newSemTable(statement sqlparser.Statement, coll collations.ID)
 		SubqueryRef:       a.binder.subqueryRef,
 		ColumnEqualities:  map[columnName][]sqlparser.Expr{},
 		Collation:         coll,
+		ExpandedColumns:   a.rewriter.expandedColumns,
 	}
 }
 
diff --git a/go/vt/vtgate/semantics/early_rewriter.go b/go/vt/vtgate/semantics/early_rewriter.go
index 6f006efd41..206a0d89db 100644
--- a/go/vt/vtgate/semantics/early_rewriter.go
+++ b/go/vt/vtgate/semantics/early_rewriter.go
@@ -25,10 +25,11 @@ import (
 )
 
 type earlyRewriter struct {
-	binder  *binder
-	scoper  *scoper
-	clause  string
-	warning string
+	binder          *binder
+	scoper          *scoper
+	clause          string
+	warning         string
+	expandedColumns map[sqlparser.TableName][]*sqlparser.ColName
 }
 
 func (r *earlyRewriter) down(cursor *sqlparser.Cursor) error {
@@ -92,7 +93,7 @@ func (r *earlyRewriter) expandStar(cursor *sqlparser.Cursor, node sqlparser.Sele
 			selExprs = append(selExprs, selectExpr)
 			continue
 		}
-		starExpanded, colNames, err := expandTableColumns(starExpr, currentScope.tables, r.binder.usingJoinInfo, r.scoper.org)
+		starExpanded, colNames, err := r.expandTableColumns(starExpr, currentScope.tables, r.binder.usingJoinInfo, r.scoper.org)
 		if err != nil {
 			return err
 		}
@@ -254,7 +255,7 @@ func rewriteJoinUsing(
 	return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "did not find WHERE clause")
 }
 
-func expandTableColumns(
+func (r *earlyRewriter) expandTableColumns(
 	starExpr *sqlparser.StarExpr,
 	tables []TableInfo,
 	joinUsing map[TableSet]map[string]TableSet,
@@ -263,6 +264,7 @@ func expandTableColumns(
 	unknownTbl := true
 	var colNames sqlparser.SelectExprs
 	starExpanded := true
+	expandedColumns := map[sqlparser.TableName][]*sqlparser.ColName{}
 	for _, tbl := range tables {
 		if !starExpr.TableName.IsEmpty() && !tbl.matches(starExpr.TableName) {
 			continue
@@ -277,8 +279,9 @@ func expandTableColumns(
 			return false, nil, err
 		}
 
-		withAlias := len(tables) > 1
-		withQualifier := withAlias || !tbl.getExpr().As.IsEmpty()
+		needsQualifier := len(tables) > 1
+		tableAliased := !tbl.getExpr().As.IsEmpty()
+		withQualifier := needsQualifier || tableAliased
 		currTable := tbl.getTableSet(org)
 		usingCols := joinUsing[currTable]
 		if usingCols == nil {
@@ -293,10 +296,23 @@ func expandTableColumns(
 			} else {
 				colName = sqlparser.NewColName(col.Name)
 			}
-			if withAlias {
+			if needsQualifier {
 				alias = sqlparser.NewIdentifierCI(col.Name)
 			}
 			colNames = append(colNames, &sqlparser.AliasedExpr{Expr: colName, As: alias})
+			vt := tbl.GetVindexTable()
+			if vt != nil {
+				keyspace := vt.Keyspace
+				var ks sqlparser.IdentifierCS
+				if keyspace != nil {
+					ks = sqlparser.NewIdentifierCS(keyspace.Name)
+				}
+				tblName := sqlparser.TableName{
+					Name:      tblName.Name,
+					Qualifier: ks,
+				}
+				expandedColumns[tblName] = append(expandedColumns[tblName], colName)
+			}
 		}
 
 		/*
@@ -338,5 +354,8 @@ func expandTableColumns(
 		// This will only happen for case when starExpr has qualifier.
 		return false, nil, vterrors.NewErrorf(vtrpcpb.Code_INVALID_ARGUMENT, vterrors.BadDb, "Unknown table '%s'", sqlparser.String(starExpr.TableName))
 	}
+	if starExpanded {
+		r.expandedColumns = expandedColumns
+	}
 	return starExpanded, colNames, nil
 }
diff --git a/go/vt/vtgate/semantics/semantic_state.go b/go/vt/vtgate/semantics/semantic_state.go
index c96fbc4d81..3573d0eb2a 100644
--- a/go/vt/vtgate/semantics/semantic_state.go
+++ b/go/vt/vtgate/semantics/semantic_state.go
@@ -101,6 +101,9 @@ type (
 		Collation collations.ID
 
 		Warning string
+
+		// ExpandedColumns is a map of all the added columns for a given table.
+		ExpandedColumns map[sqlparser.TableName][]*sqlparser.ColName
 	}
 
 	columnName struct {
diff --git a/tools/check_make_sizegen.sh b/tools/check_make_sizegen.sh
index 787ed43da4..8443c6d8e4 100755
--- a/tools/check_make_sizegen.sh
+++ b/tools/check_make_sizegen.sh
@@ -1,49 +1,22 @@
 #!/bin/bash
+
 #
 # Validate that the current version of the generated cache_size files match the output
 # generated by sizegen.
 #
-# This is used in Travis to verify that the currently committed version was
-# generated with the proper cache_size files.
 
 source build.env
 
-TMP="/tmp/cached_size.$$.go"
-ALL_FILES=$(find . -name "cached_size.go")
-
-set +e
-
-goimports -local vitess.io/vitess -w $ALL_FILES
-
-for SRC in $ALL_FILES
-do
-  TMP="/tmp/"$(echo "$SRC" | sed 's/\//_/g' | sed "s/cached_size.go/cached_size_$$.go/g")
-  mv "$SRC" "$TMP"
-done
+first_output=$(git status --porcelain)
 
 make sizegen
 
-STATUS=0
-
-for SRC in $ALL_FILES
-do
-  TMP="/tmp/"$(echo "$SRC" | sed 's/\//_/g' | sed "s/cached_size.go/cached_size_$$.go/g")
-
-  if [ ! -f "$SRC" ]; then
-    mv "$TMP" "$SRC"
-    continue
-  fi
-
-  if ! diff -q "$SRC" "$TMP" > /dev/null ; then
-    echo "ERROR: Regenerated file for $SRC does not match the current version:"
-    diff -u "$SRC" "$TMP"
-
-    echo
-    echo "Please re-run 'make sizegen' to generate."
-    STATUS=1
-  fi
-  mv "$TMP" "$SRC"
-done
+second_output=$(git status --porcelain)
 
-exit $STATUS
+diff=$(diff <( echo "$first_output") <( echo "$second_output"))
 
+if [[ "$diff" != "" ]]; then
+  echo "ERROR: Regenerated cached_size files do not match the current version."
+  echo -e "List of files containing differences:\n$diff"
+  exit 1
+fi


Test patch:
diff --git a/.github/docker/cluster_test_vtorc/Dockerfile b/.github/docker/cluster_test_vtorc/Dockerfile
deleted file mode 100644
index 8042d96eb1..0000000000
--- a/.github/docker/cluster_test_vtorc/Dockerfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
-
-ARG bootstrap_version=11
-ARG image="vitess/bootstrap:${bootstrap_version}-mysql80"
-
-FROM "${image}"
-
-USER root
-
-# Re-copy sources from working tree
-RUN rm -rf /vt/src/vitess.io/vitess/*
-COPY . /vt/src/vitess.io/vitess
-
-# Set the working directory
-WORKDIR /vt/src/vitess.io/vitess
-
-# Fix permissions
-RUN chown -R vitess:vitess /vt
-
-USER vitess
-
-# Set environment variables
-ENV VTROOT /vt/src/vitess.io/vitess
-# Set the vtdataroot such that it uses the volume mount
-ENV VTDATAROOT /vt/vtdataroot
-
-# create the vtdataroot directory
-RUN mkdir -p $VTDATAROOT
-
-# install goimports
-RUN go install golang.org/x/tools/cmd/goimports@latest
-
-# sleep for 50 minutes
-CMD sleep 3000
diff --git a/.github/docker/cluster_test_vtorc_mysql57/Dockerfile b/.github/docker/cluster_test_vtorc_mysql57/Dockerfile
deleted file mode 100644
index 0497e4112d..0000000000
--- a/.github/docker/cluster_test_vtorc_mysql57/Dockerfile
+++ /dev/null
@@ -1,34 +0,0 @@
-# DO NOT MODIFY: THIS FILE IS GENERATED USING "make generate_ci_workflows"
-
-ARG bootstrap_version=11
-ARG image="vitess/bootstrap:${bootstrap_version}-mysql57"
-
-FROM "${image}"
-
-USER root
-
-# Re-copy sources from working tree
-RUN rm -rf /vt/src/vitess.io/vitess/*
-COPY . /vt/src/vitess.io/vitess
-
-# Set the working directory
-WORKDIR /vt/src/vitess.io/vitess
-
-# Fix permissions
-RUN chown -R vitess:vitess /vt
-
-USER vitess
-
-# Set environment variables
-ENV VTROOT /vt/src/vitess.io/vitess
-# Set the vtdataroot such that it uses the volume mount
-ENV VTDATAROOT /vt/vtdataroot
-
-# create the vtdataroot directory
-RUN mkdir -p $VTDATAROOT
-
-# install goimports
-RUN go install golang.org/x/tools/cmd/goimports@latest
-
-# sleep for 50 minutes
-CMD sleep 3000
diff --git a/go/mysql/collations/integration/coercion_test.go b/go/mysql/collations/integration/coercion_test.go
index dbc039d952..58aae5aa97 100644
--- a/go/mysql/collations/integration/coercion_test.go
+++ b/go/mysql/collations/integration/coercion_test.go
@@ -135,8 +135,8 @@ func TestComparisonSemantics(t *testing.T) {
 	conn := mysqlconn(t)
 	defer conn.Close()
 
-	if strings.HasPrefix(conn.ServerVersion, "8.0.31") {
-		t.Skipf("Coercion semantics have changed in 8.0.31")
+	if v, err := conn.ServerVersionAtLeast(8, 0, 31); err != nil || !v {
+		t.Skipf("The behavior of Coercion Semantics is not correct before 8.0.31")
 	}
 
 	for _, coll := range collations.Local().AllCollations() {
diff --git a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go
index dfcfcc0c42..820e6ad36e 100644
--- a/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go
+++ b/go/test/endtoend/vtgate/queries/aggregation/aggregation_test.go
@@ -33,7 +33,7 @@ func start(t *testing.T) (utils.MySQLCompare, func()) {
 	deleteAll := func() {
 		_, _ = utils.ExecAllowError(t, mcmp.VtConn, "set workload = oltp")
 
-		tables := []string{"aggr_test", "t3", "t7_xxhash", "aggr_test_dates", "t7_xxhash_idx", "t1", "t2"}
+		tables := []string{"t9", "aggr_test", "t3", "t7_xxhash", "aggr_test_dates", "t7_xxhash_idx", "t1", "t2"}
 		for _, table := range tables {
 			_, _ = mcmp.ExecAndIgnore("delete from " + table)
 		}
@@ -352,7 +352,7 @@ func TestEmptyTableAggr(t *testing.T) {
 		})
 	}
 
-	mcmp.Exec("insert into t1(t1_id, `name`, `value`, shardkey) values(1,'a1','foo',100), (2,'b1','foo',200), (3,'c1','foo',300), (3,'a1','foo',100), (3,'b1','bar',200)")
+	mcmp.Exec("insert into t1(t1_id, `name`, `value`, shardkey) values(1,'a1','foo',100), (2,'b1','foo',200), (3,'c1','foo',300), (4,'a1','foo',100), (5,'b1','bar',200)")
 
 	for _, workload := range []string{"oltp", "olap"} {
 		t.Run(workload, func(t *testing.T) {
@@ -365,3 +365,12 @@ func TestEmptyTableAggr(t *testing.T) {
 	}
 
 }
+
+func TestOrderByCount(t *testing.T) {
+	mcmp, closer := start(t)
+	defer closer()
+
+	mcmp.Exec("insert into t9(id1, id2, id3) values(1, '1', '1'), (2, '2', '2'), (3, '2', '2'), (4, '3', '3'), (5, '3', '3'), (6, '3', '3')")
+
+	mcmp.AssertMatches("SELECT /*vt+ PLANNER=gen4 */ t9.id2 FROM t9 GROUP BY t9.id2 ORDER BY COUNT(t9.id2) DESC", `[[VARCHAR("3")] [VARCHAR("2")] [VARCHAR("1")]]`)
+}
diff --git a/go/test/endtoend/vtgate/queries/aggregation/main_test.go b/go/test/endtoend/vtgate/queries/aggregation/main_test.go
index 65cf3a0343..a859002f44 100644
--- a/go/test/endtoend/vtgate/queries/aggregation/main_test.go
+++ b/go/test/endtoend/vtgate/queries/aggregation/main_test.go
@@ -33,8 +33,8 @@ var (
 	clusterInstance *cluster.LocalProcessCluster
 	vtParams        mysql.ConnParams
 	mysqlParams     mysql.ConnParams
-	keyspaceName    = "ks_union"
-	cell            = "test_union"
+	keyspaceName    = "ks_aggr"
+	cell            = "test_aggr"
 
 	//go:embed schema.sql
 	schemaSQL string
diff --git a/go/test/endtoend/vtgate/queries/aggregation/schema.sql b/go/test/endtoend/vtgate/queries/aggregation/schema.sql
index fb7a508fa3..a538a3dafe 100644
--- a/go/test/endtoend/vtgate/queries/aggregation/schema.sql
+++ b/go/test/endtoend/vtgate/queries/aggregation/schema.sql
@@ -70,3 +70,4 @@ CREATE TABLE t2 (
     shardKey bigint,
     PRIMARY KEY (id)
 ) ENGINE InnoDB;
+
diff --git a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json
index 1fc9db15e7..45a6cb7238 100644
--- a/go/vt/vtgate/planbuilder/testdata/aggr_cases.json
+++ b/go/vt/vtgate/planbuilder/testdata/aggr_cases.json
@@ -4779,5 +4779,45 @@
         "user.user"
       ]
     }
+  },
+  {
+    "comment": "Group By X Order By X",
+    "query": "SELECT user.intcol FROM user GROUP BY user.intcol ORDER BY COUNT(user.intcol)",
+    "v3-plan": "unsupported: in scatter query: complex order by expression: count(`user`.intcol)",
+    "gen4-plan": {
+      "QueryType": "SELECT",
+      "Original": "SELECT user.intcol FROM user GROUP BY user.intcol ORDER BY COUNT(user.intcol)",
+      "Instructions": {
+        "OperatorType": "Sort",
+        "Variant": "Memory",
+        "OrderBy": "1 ASC",
+        "ResultColumns": 1,
+        "Inputs": [
+          {
+            "OperatorType": "Aggregate",
+            "Variant": "Ordered",
+            "Aggregates": "sum_count(1) AS count(`user`.intcol)",
+            "GroupBy": "0",
+            "Inputs": [
+              {
+                "OperatorType": "Route",
+                "Variant": "Scatter",
+                "Keyspace": {
+                  "Name": "user",
+                  "Sharded": true
+                },
+                "FieldQuery": "select `user`.intcol, count(`user`.intcol) from `user` where 1 != 1 group by `user`.intcol",
+                "OrderBy": "0 ASC",
+                "Query": "select `user`.intcol, count(`user`.intcol) from `user` group by `user`.intcol order by `user`.intcol asc",
+                "Table": "`user`"
+              }
+            ]
+          }
+        ]
+      },
+      "TablesUsed": [
+        "user.user"
+      ]
+    }
   }
 ]
\ No newline at end of file
diff --git a/go/vt/vtgate/semantics/early_rewriter_test.go b/go/vt/vtgate/semantics/early_rewriter_test.go
index 9b40227af9..79e64e1b29 100644
--- a/go/vt/vtgate/semantics/early_rewriter_test.go
+++ b/go/vt/vtgate/semantics/early_rewriter_test.go
@@ -28,10 +28,15 @@ import (
 )
 
 func TestExpandStar(t *testing.T) {
+	ks := &vindexes.Keyspace{
+		Name:    "main",
+		Sharded: false,
+	}
 	schemaInfo := &FakeSI{
 		Tables: map[string]*vindexes.Table{
 			"t1": {
-				Name: sqlparser.NewIdentifierCS("t1"),
+				Keyspace: ks,
+				Name:     sqlparser.NewIdentifierCS("t1"),
 				Columns: []vindexes.Column{{
 					Name: sqlparser.NewIdentifierCI("a"),
 					Type: sqltypes.VarChar,
@@ -45,7 +50,8 @@ func TestExpandStar(t *testing.T) {
 				ColumnListAuthoritative: true,
 			},
 			"t2": {
-				Name: sqlparser.NewIdentifierCS("t2"),
+				Keyspace: ks,
+				Name:     sqlparser.NewIdentifierCS("t2"),
 				Columns: []vindexes.Column{{
 					Name: sqlparser.NewIdentifierCI("c1"),
 					Type: sqltypes.VarChar,
@@ -56,7 +62,8 @@ func TestExpandStar(t *testing.T) {
 				ColumnListAuthoritative: true,
 			},
 			"t3": { // non authoritative table.
-				Name: sqlparser.NewIdentifierCS("t3"),
+				Keyspace: ks,
+				Name:     sqlparser.NewIdentifierCS("t3"),
 				Columns: []vindexes.Column{{
 					Name: sqlparser.NewIdentifierCI("col"),
 					Type: sqltypes.VarChar,
@@ -64,7 +71,8 @@ func TestExpandStar(t *testing.T) {
 				ColumnListAuthoritative: false,
 			},
 			"t4": {
-				Name: sqlparser.NewIdentifierCS("t4"),
+				Keyspace: ks,
+				Name:     sqlparser.NewIdentifierCS("t4"),
 				Columns: []vindexes.Column{{
 					Name: sqlparser.NewIdentifierCI("c1"),
 					Type: sqltypes.VarChar,
@@ -75,7 +83,8 @@ func TestExpandStar(t *testing.T) {
 				ColumnListAuthoritative: true,
 			},
 			"t5": {
-				Name: sqlparser.NewIdentifierCS("t5"),
+				Keyspace: ks,
+				Name:     sqlparser.NewIdentifierCS("t5"),
 				Columns: []vindexes.Column{{
 					Name: sqlparser.NewIdentifierCI("a"),
 					Type: sqltypes.VarChar,
@@ -89,9 +98,10 @@ func TestExpandStar(t *testing.T) {
 	}
 	cDB := "db"
 	tcases := []struct {
-		sql    string
-		expSQL string
-		expErr string
+		sql               string
+		expSQL            string
+		expErr            string
+		colExpandedNumber int
 	}{{
 		sql:    "select * from t1",
 		expSQL: "select a, b, c from t1",
@@ -99,8 +109,9 @@ func TestExpandStar(t *testing.T) {
 		sql:    "select t1.* from t1",
 		expSQL: "select a, b, c from t1",
 	}, {
-		sql:    "select *, 42, t1.* from t1",
-		expSQL: "select a, b, c, 42, a, b, c from t1",
+		sql:               "select *, 42, t1.* from t1",
+		expSQL:            "select a, b, c, 42, a, b, c from t1",
+		colExpandedNumber: 6,
 	}, {
 		sql:    "select 42, t1.* from t1",
 		expSQL: "select 42, a, b, c from t1",
@@ -111,8 +122,9 @@ func TestExpandStar(t *testing.T) {
 		sql:    "select t1.* from t1, t2",
 		expSQL: "select t1.a as a, t1.b as b, t1.c as c from t1, t2",
 	}, {
-		sql:    "select *, t1.* from t1, t2",
-		expSQL: "select t1.a as a, t1.b as b, t1.c as c, t2.c1 as c1, t2.c2 as c2, t1.a as a, t1.b as b, t1.c as c from t1, t2",
+		sql:               "select *, t1.* from t1, t2",
+		expSQL:            "select t1.a as a, t1.b as b, t1.c as c, t2.c1 as c1, t2.c2 as c2, t1.a as a, t1.b as b, t1.c as c from t1, t2",
+		colExpandedNumber: 6,
 	}, { // aliased table
 		sql:    "select * from t1 a, t2 b",
 		expSQL: "select a.a as a, a.b as b, a.c as c, b.c1 as c1, b.c2 as c2 from t1 as a, t2 as b",
@@ -158,6 +170,30 @@ func TestExpandStar(t *testing.T) {
 			require.True(t, isSelectStatement, "analyzer expects a select statement")
 			st, err := Analyze(selectStatement, cDB, schemaInfo)
 			if tcase.expErr == "" {
+				found := 0
+			outer:
+				for _, selExpr := range selectStatement.SelectExprs {
+					aliasedExpr, isAliased := selExpr.(*sqlparser.AliasedExpr)
+					if !isAliased {
+						continue
+					}
+					for _, tbl := range st.ExpandedColumns {
+						for _, col := range tbl {
+							if sqlparser.EqualsExpr(aliasedExpr.Expr, col) {
+								found++
+								continue outer
+							}
+						}
+					}
+				}
+				if tcase.colExpandedNumber == 0 {
+					for _, tbl := range st.ExpandedColumns {
+						found -= len(tbl)
+					}
+					require.Zero(t, found)
+				} else {
+					require.Equal(t, tcase.colExpandedNumber, found)
+				}
 				require.NoError(t, err)
 				require.NoError(t, st.NotUnshardedErr)
 				require.NoError(t, st.NotSingleRouteErr)
diff --git a/test/ci_workflow_gen.go b/test/ci_workflow_gen.go
index 2612c0fede..7476d5bba8 100644
--- a/test/ci_workflow_gen.go
+++ b/test/ci_workflow_gen.go
@@ -115,6 +115,7 @@ var (
 		"vtgate_vschema",
 		"vtgate_queries",
 		"vtgate_schema_tracker",
+		"vtorc",
 		"xb_recovery",
 		"mysql80",
 		"vreplication_across_db_versions",
@@ -128,9 +129,7 @@ var (
 		"vttablet_prscomplex",
 	}
 
-	clusterSelfHostedList = []string{
-		"vtorc",
-	}
+	clusterSelfHostedList       = []string{}
 	clusterDockerList           = []string{}
 	clustersRequiringXtraBackup = []string{
 		"xb_backup",