@@ -134,6 +134,98 @@ func JoinParamsCall(
134134 return joinParamsCall (params , engPkg , targetMethod , targetStructs , sourceStructs )
135135}
136136
137+ // findSourceField finds a matching field in source struct using multiple strategies:
138+ // 1. Exact name match
139+ // 2. Case-insensitive match
140+ // 3. Snake_case match
141+ // 4. Position-based match (fallback when structs have same field count).
142+ func findSourceField (
143+ targetField FieldInfo ,
144+ targetIdx int ,
145+ targetStruct StructInfo ,
146+ sourceStruct StructInfo ,
147+ ) (FieldInfo , bool ) {
148+ // Strategy 1: Exact name match
149+ for _ , sf := range sourceStruct .Fields {
150+ if sf .Name == targetField .Name {
151+ return sf , true
152+ }
153+ }
154+
155+ // Strategy 2: Case-insensitive match
156+ for _ , sf := range sourceStruct .Fields {
157+ if strings .EqualFold (sf .Name , targetField .Name ) {
158+ return sf , true
159+ }
160+ }
161+
162+ // Strategy 3: Snake_case match
163+ targetSnake := toSnakeCase (targetField .Name )
164+ for _ , sf := range sourceStruct .Fields {
165+ if toSnakeCase (sf .Name ) == targetSnake {
166+ return sf , true
167+ }
168+ }
169+
170+ // Strategy 4: Position-based match (fallback when structs have same field count)
171+ // Only use position matching if the structs have the same number of fields
172+ if len (sourceStruct .Fields ) == len (targetStruct .Fields ) && len (sourceStruct .Fields ) > 0 {
173+ // Match by position - use the field at the same index in source
174+ if targetIdx < len (sourceStruct .Fields ) {
175+ sf := sourceStruct .Fields [targetIdx ]
176+ // Verify types are compatible
177+ if fieldsCompatible (sf .Type , targetField .Type ) {
178+ return sf , true
179+ }
180+ }
181+ }
182+
183+ return FieldInfo {}, false
184+ }
185+
186+ // fieldsCompatible checks if two field types are compatible for mapping.
187+ func fieldsCompatible (sourceType , targetType string ) bool {
188+ // Normalize types for comparison
189+ sourceBase := normalizeType (sourceType )
190+ targetBase := normalizeType (targetType )
191+
192+ return sourceBase == targetBase
193+ }
194+
195+ // normalizeType normalizes a type string for comparison.
196+ func normalizeType (t string ) string {
197+ // Remove common prefixes/suffixes
198+ t = strings .TrimPrefix (t , "[]" )
199+ t = strings .TrimPrefix (t , "*" )
200+
201+ // Handle time types
202+ if strings .Contains (t , "time.Time" ) || strings .Contains (t , "NullTime" ) {
203+ return "time"
204+ }
205+
206+ // Handle numeric types
207+ switch t {
208+ case typeInt , "int8" , "int16" , "int32" , "int64" ,
209+ "uint" , "uint8" , "uint16" , "uint32" , "uint64" ,
210+ sqlNullInt32 , sqlNullInt64 :
211+ return typeInt
212+ case "float32" , "float64" , sqlNullFloat64 :
213+ return "float"
214+ case typeString , sqlNullString , typeBytes :
215+ return typeString
216+ case typeBool , sqlNullBool :
217+ return typeBool
218+ }
219+
220+ // Remove package prefix if present
221+ parts := strings .Split (t , "." )
222+ if len (parts ) > 1 {
223+ return parts [len (parts )- 1 ]
224+ }
225+
226+ return t
227+ }
228+
137229func joinDomainStructParam (
138230 param Param ,
139231 i int ,
@@ -153,23 +245,22 @@ func joinDomainStructParam(
153245
154246 if targetParamType != "" {
155247 sourceStruct := sourceStructs [param .Type ]
156- targetStruct := targetStructs [targetParamType ]
157-
158- var fields []string
159-
160- for _ , targetField := range targetStruct .Fields {
161- var sourceField FieldInfo
248+ // Target struct keys may include the package prefix (e.g., "mysqldb.GetStuckNarFilesParams")
249+ // Try with prefix first, then without
250+ targetStructKey := targetParamType
251+ if engPkg != "" {
252+ if _ , ok := targetStructs [engPkg + "." + targetParamType ]; ok {
253+ targetStructKey = engPkg + "." + targetParamType
254+ }
255+ // Otherwise keep using targetParamType (no prefix)
256+ }
162257
163- found := false
258+ targetStruct := targetStructs [ targetStructKey ]
164259
165- for _ , sf := range sourceStruct .Fields {
166- if sf .Name == targetField .Name {
167- sourceField = sf
168- found = true
260+ var fields []string
169261
170- break
171- }
172- }
262+ for targetIdx , targetField := range targetStruct .Fields {
263+ sourceField , found := findSourceField (targetField , targetIdx , targetStruct , sourceStruct )
173264
174265 if found {
175266 conversion := generateFieldConversion (
0 commit comments