]> source.dussan.org Git - jackcess.git/commitdiff
Fix parsing of certain internal-use queries. Fixes issue #142
authorJames Ahlborn <jtahlborn@yahoo.com>
Wed, 31 May 2017 03:53:25 +0000 (03:53 +0000)
committerJames Ahlborn <jtahlborn@yahoo.com>
Wed, 31 May 2017 03:53:25 +0000 (03:53 +0000)
git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1102 f203690c-595d-4dc9-a70b-905162fa7fd2

src/changes/changes.xml
src/main/java/com/healthmarketscience/jackcess/impl/query/QueryFormat.java
src/main/java/com/healthmarketscience/jackcess/impl/query/QueryImpl.java

index f2c0e5ec3b10ff5754f800ab23dd1dd8124bb4ee..94c0767e703c12f7a74ded74dc5b1e63805614d4 100644 (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
index 6986191dc7334e4cbf9f99a459099e8452c06e27..f9513d4a06234a8c8220264b0503e48523730e02 100644 (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);
+      }
+    }
+  }
+
 }
index 0645a810612d61a404db54ec3fca43bb37cdc9dc..a9fd5e696b1856f851cc99afc363f1fa7a471e5d 100644 (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);