(t *testing.T, txn *sql.Tx, query string)
| 65 | } |
| 66 | |
| 67 | func queryColumnRows(t *testing.T, txn *sql.Tx, query string) []columnQueryRow { |
| 68 | t.Helper() |
| 69 | rows, err := txn.Query(query) |
| 70 | require.NoError(t, err) |
| 71 | defer rows.Close() |
| 72 | |
| 73 | var result []columnQueryRow |
| 74 | for rows.Next() { |
| 75 | var r columnQueryRow |
| 76 | require.NoError(t, rows.Scan( |
| 77 | &r.TableSchema, |
| 78 | &r.TableName, |
| 79 | &r.ColumnName, |
| 80 | &r.DataType, |
| 81 | &r.CharacterMaxLength, |
| 82 | &r.NumericPrecision, |
| 83 | &r.NumericScale, |
| 84 | &r.DatetimePrecision, |
| 85 | &r.OrdinalPosition, |
| 86 | &r.ColumnDefault, |
| 87 | &r.IsNullable, |
| 88 | &r.CollationName, |
| 89 | &r.UdtSchema, |
| 90 | &r.UdtName, |
| 91 | &r.IdentityGeneration, |
| 92 | &r.ColumnComment, |
| 93 | )) |
| 94 | result = append(result, r) |
| 95 | } |
| 96 | require.NoError(t, rows.Err()) |
| 97 | |
| 98 | // The two queries may order rows differently for exotic identifier names |
| 99 | // (information_schema sorts varchar with the database collation, pg_catalog sorts |
| 100 | // the name type with C collation), so normalize the order before comparing. |
| 101 | slices.SortFunc(result, func(a, b columnQueryRow) int { |
| 102 | if c := strings.Compare(a.TableSchema, b.TableSchema); c != 0 { |
| 103 | return c |
| 104 | } |
| 105 | if c := strings.Compare(a.TableName, b.TableName); c != 0 { |
| 106 | return c |
| 107 | } |
| 108 | return int(a.OrdinalPosition - b.OrdinalPosition) |
| 109 | }) |
| 110 | return result |
| 111 | } |
| 112 | |
| 113 | // TestListColumnQueryMatchesInformationSchema verifies that the pg_catalog-based column |
| 114 | // query produces exactly the same rows as the previous INFORMATION_SCHEMA.COLUMNS-based |
no test coverage detected