// ConstraintColumns from selected catalog (or all, if empty), matching schemas and constraints
ConstraintColumns from selected catalog (or all, if empty), matching schemas and constraints
// ConstraintColumns from selected catalog ( or all if empty ) matching schemas and constraints
func (s InformationSchema) ConstraintColumns(f metadata.Filter) (*metadata.ConstraintColumnSet, error) {
	if !s.hasConstraints {
		return nil, metadata.ErrNotSupported
	}
	vals := []interface{}{}
	qstr := ""
	if s.hasCheckConstraints {
		qstr = `SELECT
	  c.constraint_catalog,
	  c.table_schema,
	  c.table_name,
	  c.constraint_name,
	  c.column_name,
	  1 AS ordinal_position,
	  '' AS foreign_catalog,
	  '' AS foreign_schema,
	  '' AS foreign_table,
	  '' AS foreign_name
	FROM information_schema.constraint_column_usage c
	`
		conds, checkVals := s.conditions(len(vals)+1, f, formats{
			catalog:    "c.constraint_catalog LIKE %s",
			schema:     "c.table_schema LIKE %s",
			notSchemas: "c.table_schema NOT IN (%s)",
			parent:     "c.table_name LIKE %s",
			name:       "c.constraint_name LIKE %s",
		})
		if len(conds) != 0 {
			qstr += " WHERE " + strings.Join(conds, " AND ")
			vals = append(vals, checkVals...)
		}
		qstr += `
UNION ALL
`
	}
	qstr += `SELECT
  c.constraint_catalog,
  c.table_schema,
  c.table_name,
  c.constraint_name,
  c.column_name,
  c.ordinal_position,
  COALESCE(f.constraint_catalog, '') AS foreign_catalog,
  COALESCE(f.table_schema, '') AS foreign_schema,
  COALESCE(f.table_name, '') AS foreign_table,
  COALESCE(f.column_name, '') AS foreign_name
FROM information_schema.key_column_usage c
LEFT JOIN information_schema.referential_constraints r ON c.constraint_catalog = r.constraint_catalog
  AND c.constraint_schema = r.constraint_schema
  AND c.constraint_name = r.constraint_name
LEFT JOIN information_schema.key_column_usage f ON r.unique_constraint_catalog = f.constraint_catalog
  AND r.unique_constraint_schema = f.constraint_schema
  AND r.unique_constraint_name = f.constraint_name
  ` + s.clauses[ConstraintJoinCond] + `
  AND c.position_in_unique_constraint = f.ordinal_position
`
	conds, keyVals := s.conditions(len(vals)+1, f, formats{
		catalog:    "c.constraint_catalog LIKE %s",
		schema:     "c.table_schema LIKE %s",
		notSchemas: "c.table_schema NOT IN (%s)",
		parent:     "c.table_name LIKE %s",
		reference:  "f.table_name LIKE %s",
		name:       "c.constraint_name LIKE %s",
	})
	if len(conds) != 0 {
		qstr += " WHERE " + strings.Join(conds, " AND ")
		vals = append(vals, keyVals...)
	}
	rows, closeRows, err := s.query(qstr, []string{}, "constraint_catalog, table_schema, table_name, constraint_name, ordinal_position, column_name", vals...)
	if err != nil {
		if err == sql.ErrNoRows {
			return metadata.NewConstraintColumnSet([]metadata.ConstraintColumn{}), nil
		}
		return nil, err
	}
	defer closeRows()
	results := []metadata.ConstraintColumn{}
	i := 1
	for rows.Next() {
		rec := metadata.ConstraintColumn{OrdinalPosition: i}
		i++
		err = rows.Scan(
			&rec.Catalog,
			&rec.Schema,
			&rec.Table,
			&rec.Constraint,
			&rec.Name,
			&rec.OrdinalPosition,
			&rec.ForeignCatalog,
			&rec.ForeignSchema,
			&rec.ForeignTable,
			&rec.ForeignName,
		)
		if err != nil {
			return nil, err
		}
		results = append(results, rec)
	}
	if rows.Err() != nil {
		return nil, rows.Err()
	}
	return metadata.NewConstraintColumnSet(results), nil
}
func ( s InformationSchema ) ConstraintColumns ( f metadata . Filter ) ( * metadata . ConstraintColumnSet , error ) { if ! s . hasConstraints { return nil , metadata . ErrNotSupported } vals := [ ] interface { } { } qstr := " " if s . hasCheckConstraints { qstr = `SELECT
	  c.constraint_catalog,
	  c.table_schema,
	  c.table_name,
	  c.constraint_name,
	  c.column_name,
	  1 AS ordinal_position,
	  '' AS foreign_catalog,
	  '' AS foreign_schema,
	  '' AS foreign_table,
	  '' AS foreign_name
	FROM information_schema.constraint_column_usage c
	` conds , checkVals := s . conditions ( len ( vals ) + 1 , f , formats { catalog : " " , schema : " " , notSchemas : " " , parent : " " , name : " " , } ) if len ( conds ) != 0 { qstr += " " + strings . Join ( conds , " " ) vals = append ( vals , checkVals ... ) } qstr += `
UNION ALL
` } qstr += `SELECT
  c.constraint_catalog,
  c.table_schema,
  c.table_name,
  c.constraint_name,
  c.column_name,
  c.ordinal_position,
  COALESCE(f.constraint_catalog, '') AS foreign_catalog,
  COALESCE(f.table_schema, '') AS foreign_schema,
  COALESCE(f.table_name, '') AS foreign_table,
  COALESCE(f.column_name, '') AS foreign_name
FROM information_schema.key_column_usage c
LEFT JOIN information_schema.referential_constraints r ON c.constraint_catalog = r.constraint_catalog
  AND c.constraint_schema = r.constraint_schema
  AND c.constraint_name = r.constraint_name
LEFT JOIN information_schema.key_column_usage f ON r.unique_constraint_catalog = f.constraint_catalog
  AND r.unique_constraint_schema = f.constraint_schema
  AND r.unique_constraint_name = f.constraint_name
  ` + s . clauses [ ConstraintJoinCond ] + `
  AND c.position_in_unique_constraint = f.ordinal_position
` conds , keyVals := s . conditions ( len ( vals ) + 1 , f , formats { catalog : " " , schema : " " , notSchemas : " " , parent : " " , reference : " " , name : " " , } ) if len ( conds ) != 0 { qstr += " " + strings . Join ( conds , " " ) vals = append ( vals , keyVals ... ) } rows , closeRows , err := s . query ( qstr , [ ] string { } , " " , vals ... ) if err != nil { if err == sql . ErrNoRows { return metadata . NewConstraintColumnSet ( [ ] metadata . ConstraintColumn { } ) , nil } return nil , err } defer closeRows ( ) results := [ ] metadata . ConstraintColumn { } i := 1 for rows . Next ( ) { rec := metadata . ConstraintColumn { OrdinalPosition : i } i ++ err = rows . Scan ( & rec . Catalog , & rec . Schema , & rec . Table , & rec . Constraint , & rec . Name , & rec . OrdinalPosition , & rec . ForeignCatalog , & rec . ForeignSchema , & rec . ForeignTable , & rec . ForeignName , ) if err != nil { return nil , err } results = append ( results , rec ) } if rows . Err ( ) != nil { return nil , rows . Err ( ) } return metadata . NewConstraintColumnSet ( results ) , nil }
ConstraintColumns from selected catalog (or all, if empty), matching schemas and constraints
ConstraintColumns from selected catalog ( or all if empty ) matching schemas and constraints