Browse Source

Fix parsing of certain internal-use queries. Fixes issue #142

git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1102 f203690c-595d-4dc9-a70b-905162fa7fd2
tags/jackcess-2.1.8
James Ahlborn 7 years ago
parent
commit
3193d76ffd

+ 6
- 0
src/changes/changes.xml View File

@@ -4,6 +4,12 @@
<author email="javajedi@users.sf.net">Tim McCune</author>
</properties>
<body>
<release version="2.1.8" date="TBD">
<action dev="jahlborn" type="fix" system="SourceForge2" issue="142">
Fix parsing of certain internal-use queries (such as those used as the
data source for the fields in a form).
</action>
</release>
<release version="2.1.7" date="2017-05-17">
<action dev="jahlborn" type="update">
Implement support for partial index lookups. Efficient IndexCursor

+ 12
- 1
src/main/java/com/healthmarketscience/jackcess/impl/query/QueryFormat.java View File

@@ -21,6 +21,7 @@ import java.util.Map;
import java.util.regex.Pattern;

import com.healthmarketscience.jackcess.DataType;
import com.healthmarketscience.jackcess.query.Query;
import org.apache.commons.lang.SystemUtils;

/**
@@ -48,7 +49,7 @@ public class QueryFormat
// dbQAction = 240

// mask which removes superfluous flags from object flags
static final int OBJECT_FLAG_MASK = 0XF0;
static final int OBJECT_FLAG_MASK = 0xF0;

public static final String COL_ATTRIBUTE = "Attribute";
public static final String COL_EXPRESSION = "Expression";
@@ -130,4 +131,14 @@ public class QueryFormat
JOIN_TYPE_MAP.put((short)3, " RIGHT JOIN ");
}

public static final Map<Short,Query.Type> TYPE_MAP =
new HashMap<Short,Query.Type>();
static {
for(Query.Type type : Query.Type.values()) {
if(type != Query.Type.UNKNOWN) {
TYPE_MAP.put(type.getValue(), type);
}
}
}

}

+ 25
- 5
src/main/java/com/healthmarketscience/jackcess/impl/query/QueryImpl.java View File

@@ -387,9 +387,20 @@ public abstract class QueryImpl implements Query
int objectId)
{
// remove other object flags before testing for query type
int typeFlag = objectFlag & OBJECT_FLAG_MASK;
int objTypeFlag = objectFlag & OBJECT_FLAG_MASK;

if(objTypeFlag == 0) {
// sometimes the query rows tell a different story
short rowTypeFlag = getShortValue(getQueryType(rows), objTypeFlag);
Type rowType = TYPE_MAP.get(rowTypeFlag);
if((rowType != null) && (rowType.getObjectFlag() != objTypeFlag)) {
// use row type instead of object flag type
objTypeFlag = rowType.getObjectFlag();
}
}

try {
switch(typeFlag) {
switch(objTypeFlag) {
case SELECT_QUERY_OBJECT_FLAG:
return new SelectQueryImpl(name, rows, objectId, objectFlag);
case MAKE_TABLE_QUERY_OBJECT_FLAG:
@@ -411,7 +422,7 @@ public abstract class QueryImpl implements Query
default:
// unknown querytype
throw new IllegalStateException(withErrorContext(
"unknown query object flag " + typeFlag, name));
"unknown query object flag " + objTypeFlag, name));
}
} catch(IllegalStateException e) {
LOG.warn(withErrorContext("Failed parsing query", name), e);
@@ -421,9 +432,9 @@ public abstract class QueryImpl implements Query
return new UnknownQueryImpl(name, rows, objectId, objectFlag);
}

private Short getQueryType(List<Row> rows)
private static Short getQueryType(List<Row> rows)
{
return getUniqueRow(getRowsByAttribute(rows, TYPE_ATTRIBUTE)).flag;
return getFirstRowByAttribute(rows, TYPE_ATTRIBUTE).flag;
}

private static List<Row> getRowsByAttribute(List<Row> rows, Byte attribute) {
@@ -436,6 +447,15 @@ public abstract class QueryImpl implements Query
return result;
}

private static Row getFirstRowByAttribute(List<Row> rows, Byte attribute) {
for(Row row : rows) {
if(attribute.equals(row.attribute)) {
return row;
}
}
return EMPTY_ROW;
}

protected Row getUniqueRow(List<Row> rows) {
if(rows.size() == 1) {
return rows.get(0);

Loading…
Cancel
Save