The column undoubtedly does exist in your database, but if you haven't added the column to a thing called the projection map, you'll get the "invalid column" error you're seeing. You can add the projection map via a query builder object, like this:
// The projection map is a hashmap of strings
HashMap<String, String> MyProjectionMap;
MyProjectionMap = new HashMap<String, String>();
// Add column mappings to the projection map
MyProjectionMap.put(Tasks._ID, Tasks._ID);
MyProjectionMap.put(Tasks.TITLE, Tasks.TITLE);
[...]
SQLiteQueryBuilder qb;
qb.setTables("tasks");
qb.setProjectionMap(MyProjectionMap)
// Then do your query
Cursor c = qb.query(db, projection, ...)
To understand what happens, look in the source for the SQLiteQueryBuilder class, and you'll see the following:
private String[] computeProjection(String[] projectionIn) {
if (projectionIn != null && projectionIn.length > 0) {
if (mProjectionMap != null) {
[...]
for (int i = 0; i < length; i++) {
String userColumn = projectionIn[i];
String column = mProjectionMap.get(userColumn);
[...]
if (!mStrictProjectionMap && ( userColumn.contains(" AS ") || userColumn.contains(" as "))) {
/* A column alias already exist */
projection[i] = userColumn;
continue;
}
throw new IllegalArgumentException("Invalid column " + projectionIn[i]);
}
}
[...]
Basically it's checking the columns you requested in your projection against a list of "allowed" columns, and you can see that if the map does not contain the column from your projection, it will throw an IllegalArgumentException, just as you saw. (I imagine this checking against the map is a security feature to prevent SQL-based attacks from people abusing your content provider, but that's just a guess.)
Note also that if you set "strict" projection maps in your query builder:
qb.setStrictProjectionMap(true);
Then in that case it expects you to know the exact column names... If you don't set it, it checks for the "AS" column alias -- I think that explains the "weird fix" you discovered.
Hope this helps.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…