(oid uint32, formatCode int16, target any, depth int)
| 1067 | } |
| 1068 | |
| 1069 | func (m *Map) planScan(oid uint32, formatCode int16, target any, depth int) ScanPlan { |
| 1070 | if depth > 8 { |
| 1071 | return &scanPlanFail{m: m, oid: oid, formatCode: formatCode} |
| 1072 | } |
| 1073 | |
| 1074 | if target == nil { |
| 1075 | return &scanPlanFail{m: m, oid: oid, formatCode: formatCode} |
| 1076 | } |
| 1077 | |
| 1078 | if _, ok := target.(*UndecodedBytes); ok { |
| 1079 | return scanPlanAnyToUndecodedBytes{} |
| 1080 | } |
| 1081 | |
| 1082 | switch formatCode { |
| 1083 | case BinaryFormatCode: |
| 1084 | if _, ok := target.(*string); ok { |
| 1085 | switch oid { |
| 1086 | case TextOID, VarcharOID: |
| 1087 | return scanPlanString{} |
| 1088 | } |
| 1089 | } |
| 1090 | case TextFormatCode: |
| 1091 | switch target.(type) { |
| 1092 | case *string: |
| 1093 | return scanPlanString{} |
| 1094 | case *[]byte: |
| 1095 | if oid != ByteaOID { |
| 1096 | return scanPlanAnyTextToBytes{} |
| 1097 | } |
| 1098 | case TextScanner: |
| 1099 | return scanPlanTextAnyToTextScanner{} |
| 1100 | } |
| 1101 | } |
| 1102 | |
| 1103 | var dt *Type |
| 1104 | |
| 1105 | if dataType, ok := m.TypeForOID(oid); ok { |
| 1106 | dt = dataType |
| 1107 | } else if dataType, ok := m.TypeForValue(target); ok { |
| 1108 | dt = dataType |
| 1109 | oid = dt.OID // Preserve assumed OID in case we are recursively called below. |
| 1110 | } |
| 1111 | |
| 1112 | if dt != nil { |
| 1113 | if plan := dt.Codec.PlanScan(m, oid, formatCode, target); plan != nil { |
| 1114 | return plan |
| 1115 | } |
| 1116 | } |
| 1117 | |
| 1118 | // This needs to happen before trying m.TryWrapScanPlanFuncs. Otherwise, a sql.Scanner would not get called if it was |
| 1119 | // defined on a type that could be unwrapped such as `type myString string`. |
| 1120 | // |
| 1121 | // https://github.com/jackc/pgtype/issues/197 |
| 1122 | if _, ok := target.(sql.Scanner); ok { |
| 1123 | if dt == nil { |
| 1124 | return &scanPlanSQLScanner{formatCode: formatCode} |
| 1125 | } else { |
| 1126 | return &scanPlanCodecSQLScanner{c: dt.Codec, m: m, oid: oid, formatCode: formatCode} |
no test coverage detected