Repository: go-gorm/gorm
Pull request #6761 (2023-12-21 09:30:17)

fix: join and select mytable.* not working
<!--
Make sure these boxes checked before submitting your pull request.

For significant changes, please open an issue to make an agreement on an implementation design/plan first before starting it.
-->

- [ x ] Do only one thing
- [ x ] Non breaking API changes
- [ x ] Tested

### What did this pull request do?

<!--
provide a general description of the code changes in your pull request
-->

Fixes bug:

Code:

```go
db.InnerJoins("User.Company", db.Select("User__Company.*")).Take(&order)
```

Expected:

```sql
SELECT order.id, order.time, ..., User__Company.id, User__Company.name, User_Company... FROM ...
```

Actually before:

```sql
SELECT order.id, order.time, order... FROM
```

### User Case Description

<!-- Your use case -->


jinzhu: Hi @StephanoGeorge 

Could you please add some additional tests to help prevent future breaks?  Thank you.
StephanoGeorge: @jinzhu Sure, already done, and also made some improvements

Patch:
diff --git a/statement.go b/statement.go
index 59c0b77..b24228b 100644
--- a/statement.go
+++ b/statement.go
@@ -665,7 +665,21 @@ func (stmt *Statement) Changed(fields ...string) bool {
 	return false
 }
 
-var nameMatcher = regexp.MustCompile(`^(?:\W?(\w+?)\W?\.)?\W?(\w+?)\W?$`)
+var matchName = func() func(tableColumn string) (table, column string) {
+	nameMatcher := regexp.MustCompile(`^(?:\W?(\w+?)\W?\.)?(?:(\*)|\W?(\w+?)\W?)$`)
+	return func(tableColumn string) (table, column string) {
+		if matches := nameMatcher.FindStringSubmatch(tableColumn); len(matches) == 4 {
+			table = matches[1]
+			star := matches[2]
+			columnName := matches[3]
+			if star != "" {
+				return table, star
+			}
+			return table, columnName
+		}
+		return "", ""
+	}
+}()
 
 // SelectAndOmitColumns get select and omit columns, select -> true, omit -> false
 func (stmt *Statement) SelectAndOmitColumns(requireCreate, requireUpdate bool) (map[string]bool, bool) {
@@ -686,13 +700,13 @@ func (stmt *Statement) SelectAndOmitColumns(requireCreate, requireUpdate bool) (
 			}
 		} else if field := stmt.Schema.LookUpField(column); field != nil && field.DBName != "" {
 			results[field.DBName] = result
-		} else if matches := nameMatcher.FindStringSubmatch(column); len(matches) == 3 && (matches[1] == stmt.Table || matches[1] == "") {
-			if matches[2] == "*" {
+		} else if table, col := matchName(column); col != "" && (table == stmt.Table || table == "") {
+			if col == "*" {
 				for _, dbName := range stmt.Schema.DBNames {
 					results[dbName] = result
 				}
 			} else {
-				results[matches[2]] = result
+				results[col] = result
 			}
 		} else {
 			results[column] = result


Test patch:
diff --git a/statement_test.go b/statement_test.go
index 648bc87..0995d54 100644
--- a/statement_test.go
+++ b/statement_test.go
@@ -56,9 +56,15 @@ func TestNameMatcher(t *testing.T) {
 		"`name_1`":           {"", "name_1"},
 		"`Name_1`":           {"", "Name_1"},
 		"`Table`.`nAme`":     {"Table", "nAme"},
+		"my_table.*":         {"my_table", "*"},
+		"`my_table`.*":       {"my_table", "*"},
+		"User__Company.*":    {"User__Company", "*"},
+		"`User__Company`.*":  {"User__Company", "*"},
+		`"User__Company".*`:  {"User__Company", "*"},
+		`"table"."*"`:        {"", ""},
 	} {
-		if matches := nameMatcher.FindStringSubmatch(k); len(matches) < 3 || matches[1] != v[0] || matches[2] != v[1] {
-			t.Errorf("failed to match value: %v, got %v, expect: %v", k, matches, v)
+		if table, column := matchName(k); table != v[0] || column != v[1] {
+			t.Errorf("failed to match value: %v, got %v, expect: %v", k, []string{table, column}, v)
 		}
 	}
 }