tags:

views:

2159

answers:

4

I want to find out, with an SQL query, whether an index is UNIQUE or not. I'm using SQLite 3.

I have tried two approaches:

SELECT * FROM sqlite_master WHERE name = 'sqlite_autoindex_user_1'

This returns information about the index ("type", "name", "tbl_name", "rootpage" and "sql"). Note that the sql column is empty when the index is automatically created by SQLite.

PRAGMA index_info(sqlite_autoindex_user_1);

This returns the columns in the index ("seqno", "cid" and "name").

Any other suggestions?

Edit: The above example is for an auto-generated index, but my question is about indexes in general. For example, I can create an index with "CREATE UNIQUE INDEX index1 ON visit (user, date)". It seems no SQL command will show if my new index is UNIQUE or not.

+1  A: 

you can programmatically build a select statement to see if any tuples point to more than one row. If you get back three columns, foo, bar and baz, create the following query

select count(*) from t
group by foo, bar, baz
having count(*) > 1

If that returns any rows, your index is not unique, since more than one row maps to the given tuple. If sqlite3 supports derived tables (I've yet to have the need, so I don't know off-hand), you can make this even more succinct:

select count(*) from (
    select count(*) from t
    group by foo, bar, baz
    having count(*) > 1
)

This will return a single row result set, denoting the number of duplicate tuple sets. If positive, your index is not unique.

dland
Yes, that does work in sqlite3.
finnw
Of course, this still won't tell you if the index allows duplicates but there don't happen to be any yet.
finnw
@finnw: ah yes, you have a good point there :)
dland
This only proves if an index is *not* unique, not if it is...
Christian Davén
+2  A: 

Since noone's come up with a good answer, I think the best solution is this:

  • If the index starts with "sqlite_autoindex", it is an auto-generated index for a single UNIQUE column
  • Otherwise, look for the UNIQUE keyword in the sql column in the table sqlite_master, with something like this:

    SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE '%UNIQUE%'

Christian Davén
A: 

You are close:

1) If the index starts with "sqlite_autoindex", it is an auto-generated index for the primary key . However, this will be in the sqlite_master or sqlite_temp_master tables depending depending on whether the table being indexed is temporary.

2) You need to watch out for table names and columns that contain the substring unique, so you want to use:

SELECT * FROM sqlite_master WHERE type = 'index' AND sql LIKE 'CREATE UNIQUE INDEX%'

See the sqlite website documentation on Create Index

Noah
+4  A: 
PRAGMA INDEX_LIST('table_name');

Returns a table with 3 columns:

  1. seq Unique numeric ID of index
  2. name Name of the index
  3. unique Uniqueness flag (nonzero if UNIQUE index.)

Then just loop through the resulting rows until you see the name of the index you wish to query (unfortunately you can't have a WHERE clause in a PRAGMA statement.)

finnw
Thanks, I had missed that PRAGMA statement somehow!
Christian Davén