@@ -500,13 +500,13 @@ func (i *inspect) addIndexes(s *schema.Schema, rows *sql.Rows, scope queryScope)
500
500
names := make (map [string ]* schema.Index )
501
501
for rows .Next () {
502
502
var (
503
- table , name , typ string
504
- uniq , primary , included , nullsnotdistinct bool
505
- desc , nullsfirst , nullslast , opcdefault sql.NullBool
506
- column , constraints , pred , expr , comment , options , opcname , opcparams sql.NullString
503
+ table , name , typ string
504
+ uniq , primary , included , nullsnotdistinct bool
505
+ desc , nullsfirst , nullslast , opcdefault sql.NullBool
506
+ column , constraints , pred , expr , comment , options , opcname , opcparams , exoper sql.NullString
507
507
)
508
508
if err := rows .Scan (
509
- & table , & name , & typ , & column , & included , & primary , & uniq , & constraints , & pred , & expr , & desc ,
509
+ & table , & name , & typ , & column , & included , & primary , & uniq , & exoper , & constraints , & pred , & expr , & desc ,
510
510
& nullsfirst , & nullslast , & comment , & options , & opcname , & opcdefault , & opcparams , & nullsnotdistinct ,
511
511
); err != nil {
512
512
return fmt .Errorf ("postgres: scanning indexes for schema %q: %w" , s .Name , err )
@@ -566,6 +566,9 @@ func (i *inspect) addIndexes(s *schema.Schema, rows *sql.Rows, scope queryScope)
566
566
NullsLast : nullslast .Bool ,
567
567
})
568
568
}
569
+ if sqlx .ValidString (exoper ) {
570
+ part .AddAttrs (NewOperator (i .schema , exoper .String ))
571
+ }
569
572
switch {
570
573
case included :
571
574
c , ok := scope .column (table , column .String )
@@ -991,6 +994,21 @@ type (
991
994
T string // c, f, p, u, t, x.
992
995
}
993
996
997
+ // Operator describes an operator.
998
+ // https://www.postgresql.org/docs/current/sql-createoperator.html
999
+ Operator struct {
1000
+ schema.Attr
1001
+ schema.Object
1002
+ // Schema where the operator is defined. If nil, the operator
1003
+ // is not managed by the current scope.
1004
+ Schema * schema.Schema
1005
+ // Operator name. Might include the schema name if the schema
1006
+ // is not managed by the current scope or extension based.
1007
+ // e.g., "public.&&".
1008
+ Name string
1009
+ Attrs []schema.Attr
1010
+ }
1011
+
994
1012
// Sequence defines (the supported) sequence options.
995
1013
// https://postgresql.org/docs/current/sql-createsequence.html
996
1014
Sequence struct {
@@ -1206,14 +1224,35 @@ func (o *ReferenceOption) Scan(v any) error {
1206
1224
return nil
1207
1225
}
1208
1226
1209
- // IsUnique reports if the type is unique constraint.
1227
+ // IsUnique reports if the type is a unique constraint.
1210
1228
func (c Constraint ) IsUnique () bool { return strings .ToLower (c .T ) == "u" }
1211
1229
1230
+ // IsExclude reports if the type is an exclude constraint.
1231
+ func (c Constraint ) IsExclude () bool { return strings .ToLower (c .T ) == "x" }
1232
+
1212
1233
// UniqueConstraint returns constraint with type "u".
1213
1234
func UniqueConstraint (name string ) * Constraint {
1214
1235
return & Constraint {T : "u" , N : name }
1215
1236
}
1216
1237
1238
+ // ExcludeConstraint returns constraint with type "x".
1239
+ func ExcludeConstraint (name string ) * Constraint {
1240
+ return & Constraint {T : "x" , N : name }
1241
+ }
1242
+
1243
+ // NewOperator returns the string representation of the operator.
1244
+ func NewOperator (scope string , name string ) * Operator {
1245
+ // When scanned from the database, the operator is returned as: "<schema>.<operator>".
1246
+ // The common case is that operators are the default and defined in pg_catalog, or are
1247
+ // installed by extensions.
1248
+ if parts := strings .FieldsFunc (name , func (r rune ) bool {
1249
+ return r == '.'
1250
+ }); len (parts ) == 2 && scope == "" || parts [0 ] == "pg_catalog" || parts [0 ] == scope {
1251
+ return & Operator {Name : parts [1 ]}
1252
+ }
1253
+ return & Operator {Name : name }
1254
+ }
1255
+
1217
1256
// IntegerType returns the underlying integer type this serial type represents.
1218
1257
func (s * SerialType ) IntegerType () * schema.IntegerType {
1219
1258
t := & schema.IntegerType {T : TypeInteger }
@@ -1615,6 +1654,7 @@ SELECT
1615
1654
%s AS included,
1616
1655
idx.indisprimary AS primary,
1617
1656
idx.indisunique AS unique,
1657
+ (CASE WHEN idx.indisexclusion THEN (SELECT conexclop[idx.ord]::regoper FROM pg_constraint WHERE conindid = idx.indexrelid) END) AS excoper,
1618
1658
con.nametypes AS constraints,
1619
1659
pg_get_expr(idx.indpred, idx.indrelid) AS predicate,
1620
1660
pg_get_indexdef(idx.indexrelid, idx.ord, false) AS expression,
0 commit comments