resolveDatabaseJoins executes queries against target databases for cross-DB relationships.
( ctx context.Context, from []jsn.Field, sfmap map[string]*qcode.Select, )
| 54 | |
| 55 | // resolveDatabaseJoins executes queries against target databases for cross-DB relationships. |
| 56 | func (s *gstate) resolveDatabaseJoins( |
| 57 | ctx context.Context, |
| 58 | from []jsn.Field, |
| 59 | sfmap map[string]*qcode.Select, |
| 60 | ) ([]jsn.Field, error) { |
| 61 | selects := s.cs.st.qc.Selects |
| 62 | |
| 63 | // Replacement data for the marked insertion points |
| 64 | to := make([]jsn.Field, len(from)) |
| 65 | |
| 66 | var wg sync.WaitGroup |
| 67 | wg.Add(len(from)) |
| 68 | |
| 69 | var cerr error |
| 70 | var cerrMutex sync.Mutex |
| 71 | |
| 72 | for i, id := range from { |
| 73 | // Use the json key to find the related Select object |
| 74 | sel, ok := sfmap[string(id.Key)] |
| 75 | if !ok { |
| 76 | return nil, fmt.Errorf("invalid database join field key") |
| 77 | } |
| 78 | p := selects[sel.ParentID] |
| 79 | |
| 80 | // Get the target database context |
| 81 | targetDB := sel.Database |
| 82 | if targetDB == "" { |
| 83 | targetDB = sel.Ti.Database |
| 84 | } |
| 85 | |
| 86 | dbCtx, ok := s.gj.databases[targetDB] |
| 87 | if !ok { |
| 88 | return nil, fmt.Errorf("database not found: %s", targetDB) |
| 89 | } |
| 90 | |
| 91 | // Extract parent ID value. Keep the raw JSON token around so a string |
| 92 | // primary key like "null" is not confused with a JSON null. |
| 93 | rawIDVal := bytes.TrimSpace(id.Value) |
| 94 | idVal := jsn.Value(rawIDVal) |
| 95 | |
| 96 | go func(n int, idVal, rawIDVal []byte, sel *qcode.Select, dbCtx *dbContext, parentTable string) { |
| 97 | defer wg.Done() |
| 98 | |
| 99 | // Handle null/empty parent IDs gracefully |
| 100 | if len(idVal) == 0 || bytes.Equal(rawIDVal, []byte("null")) { |
| 101 | to[n] = jsn.Field{Key: []byte(sel.FieldName), Value: []byte("null")} |
| 102 | return |
| 103 | } |
| 104 | |
| 105 | ctx1, span := s.gj.spanStart(ctx, "Execute Database Join") |
| 106 | if span.IsRecording() { |
| 107 | span.SetAttributesString( |
| 108 | StringAttr{"join.database", dbCtx.name}, |
| 109 | StringAttr{"join.table", sel.Table}, |
| 110 | StringAttr{"join.parent_table", parentTable}, |
| 111 | ) |
| 112 | } |
| 113 |