[teiid-commits] teiid SVN: r2383 - in trunk: engine/src/main/java/org/teiid/common/buffer and 3 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Jul 28 11:20:08 EDT 2010


Author: shawkins
Date: 2010-07-28 11:20:07 -0400 (Wed, 28 Jul 2010)
New Revision: 2383

Modified:
   trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java
   trunk/engine/src/main/java/org/teiid/common/buffer/TupleBrowser.java
   trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
   trunk/engine/src/main/java/org/teiid/query/tempdata/IndexCondition.java
   trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
   trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
Log:
TEIID-1167 cleaning up index condition logic

Modified: trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java
===================================================================
--- trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java	2010-07-28 04:40:32 UTC (rev 2382)
+++ trunk/common-core/src/main/java/org/teiid/core/types/XMLType.java	2010-07-28 15:20:07 UTC (rev 2383)
@@ -127,6 +127,11 @@
 		} catch (OptionalDataException e) {
 			this.encoding = Streamable.ENCODING;
 		}
+		try {
+			this.type = (Type)in.readObject();
+		} catch (OptionalDataException e) {
+			this.type = Type.UNKNOWN;
+		}
 	}
 	
 	@Override
@@ -136,6 +141,7 @@
 			this.encoding = getEncoding(this);
 		}
 		out.writeObject(this.encoding);
+		out.writeObject(this.type);
 	}
 
 	/**

Modified: trunk/engine/src/main/java/org/teiid/common/buffer/TupleBrowser.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/common/buffer/TupleBrowser.java	2010-07-28 04:40:32 UTC (rev 2382)
+++ trunk/engine/src/main/java/org/teiid/common/buffer/TupleBrowser.java	2010-07-28 15:20:07 UTC (rev 2383)
@@ -31,15 +31,12 @@
 
 /**
  * Implements intelligent browsing over a {@link STree}
- * 
- * TODO: when using other values we can be more efficient 
- * with paging.
  */
 public class TupleBrowser {
 	
 	private final STree tree;
 	
-	private List<List<?>> otherValues;
+	private List<List<Object>> valueSet;
 	
 	private SPage page;
 	private int index;
@@ -50,13 +47,30 @@
 	private TupleBatch values;
 	private boolean updated;
 	private boolean direction;
-	private boolean range;
+
+	/**
+	 * Construct a value based browser
+	 * @param sTree
+	 * @param valueSet
+	 * @param direction
+	 */
+	public TupleBrowser(STree sTree, List<List<Object>> valueSet, boolean direction) {
+		this.tree = sTree;
+		this.direction = direction;
+		this.valueSet = valueSet;
+	}
 	
-	public TupleBrowser(STree sTree, List<?> lowerBound, List<?> upperBound, List<List<?>> otherValues, boolean range, boolean direction) throws TeiidComponentException {
+	/**
+	 * Construct a range based browser
+	 * @param sTree
+	 * @param lowerBound
+	 * @param upperBound
+	 * @param direction
+	 * @throws TeiidComponentException
+	 */
+	public TupleBrowser(STree sTree, List<Object> lowerBound, List<Object> upperBound, boolean direction) throws TeiidComponentException {
 		this.tree = sTree;
 		this.direction = direction;
-		this.otherValues = otherValues;
-		this.range = range;
 		
 		if (lowerBound != null) {
 			setPage(lowerBound);
@@ -81,16 +95,11 @@
 			if (!direction) {
 				values = upper.values;
 			}
-		} else if (range) {
-			//this is a range query
-			//TODO: this could also be signaled with an all null key
+		} else {
 			bound = tree.header[0];
 			while (bound.next != null) {
 				bound = bound.next;
 			}
-		} else {
-			bound = page;
-			boundIndex = index;
 		}
 				
 		if (!direction) {
@@ -107,32 +116,65 @@
 		}
 	}
 
-	private void setPage(List<?> lowerBound) throws TeiidComponentException {
-		if (values != null) {
-			int possibleIndex = Collections.binarySearch(values.getTuples(), lowerBound, tree.comparator);
-			if (possibleIndex != -1 && possibleIndex != -values.getTuples().size() -1) {
-				index = possibleIndex;
-				if (possibleIndex < 0) {
-					index = -index -1;
-				}
-				return;
-			}
-		}
-		resetState();
+	private boolean setPage(List<?> lowerBound) throws TeiidComponentException {
 		LinkedList<SearchResult> places = new LinkedList<SearchResult>();
 		this.tree.find(lowerBound, places);
 		
 		SearchResult sr = places.getLast();
 		page = sr.page;
 		index = sr.index;
+		boolean result = true;
 		if (index < 0) {
+			result = false;
 			index = -index - 1;
 		}
 		values = sr.values;
+		return result;
 	}
 	
+	/**
+	 * Returns the next tuple or null if there are no more results.
+	 * @return
+	 * @throws TeiidComponentException
+	 */
 	public List<?> next() throws TeiidComponentException {
 		for (;;) {
+			//first check for value iteration
+			if (valueSet != null) {
+				if (valueSet.isEmpty()) {
+					resetState();
+					return null;
+				}
+				List<?> newValue = direction?valueSet.remove(0):valueSet.remove(valueSet.size() -1);
+				if (values != null) {
+					int possibleIndex = Collections.binarySearch(values.getTuples(), newValue, tree.comparator);
+					if (possibleIndex >= 0) {
+						//value exists in the current page
+						index = possibleIndex;
+						return values.getTuples().get(possibleIndex);
+					}
+					//check for end/terminal conditions
+					if (direction && possibleIndex == -values.getTuples().size() -1) {
+						if (page.next == null) {
+							resetState();
+							return null;
+						}
+					} else if (!direction && possibleIndex == -1) {
+						if (page.prev == null) {
+							resetState();
+							return null;
+						}
+					} else {
+						//the value simply doesn't exist
+						continue;
+					}
+				}
+				resetState();
+				if (!setPage(newValue)) {
+					continue;
+				}
+				return values.getTuples().get(index);
+			}
 			if (page == null) {
 				return null;
 			}
@@ -149,19 +191,6 @@
 				if (page == bound && index == boundIndex) {
 					resetState();
 					page = null; //terminate
-				} else if (otherValues != null && !range) {
-					if (!otherValues.isEmpty()) {
-						List newBound = direction?otherValues.remove(0):otherValues.remove(otherValues.size() -1);
-						setPage(newBound);
-					} else {
-						otherValues = null;
-						if (page != bound) {
-							resetState();
-						}
-						page = bound;
-						index = boundIndex;
-						values = bound.values;
-					}
 				} else {
 					index+=getOffset();
 				}
@@ -185,6 +214,9 @@
 	}
 	
 	private int getOffset() {
+		if (valueSet != null) {
+			return 0;
+		}
 		return direction?1:-1;
 	}
 	

Modified: trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java	2010-07-28 04:40:32 UTC (rev 2382)
+++ trunk/engine/src/main/java/org/teiid/query/optimizer/relational/PlanToProcessConverter.java	2010-07-28 15:20:07 UTC (rev 2383)
@@ -191,13 +191,9 @@
 	                        pinode.setIntoElements(allIntoElements);
 	                        pinode.setModelName(modelName);
 	                        processNode = pinode;
-	                        if (!metadata.isTemporaryTable(groupID)) {
-	                            SourceCapabilities caps = capFinder.findCapabilities(modelName);
-	                            pinode.setDoBatching(caps.supportsCapability(Capability.BATCHED_UPDATES));
-	                            pinode.setDoBulkInsert(caps.supportsCapability(Capability.BULK_UPDATE));
-	                        } else {
-	                            pinode.setDoBulkInsert(true);
-	                        } 
+                            SourceCapabilities caps = capFinder.findCapabilities(modelName);
+                            pinode.setDoBatching(caps.supportsCapability(Capability.BATCHED_UPDATES));
+                            pinode.setDoBulkInsert(caps.supportsCapability(Capability.BULK_UPDATE));
                         }
                     } catch(QueryMetadataException e) {
                         throw new TeiidComponentException(e);

Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/IndexCondition.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/IndexCondition.java	2010-07-28 04:40:32 UTC (rev 2382)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/IndexCondition.java	2010-07-28 15:20:07 UTC (rev 2383)
@@ -35,13 +35,16 @@
 import org.teiid.query.sql.symbol.ElementSymbol;
 import org.teiid.query.sql.symbol.Expression;
 
+/**
+ * Accumulates information from criteria about a specific index column.
+ */
 class IndexCondition {
 	
 	static IndexCondition[] getIndexConditions(Criteria condition, List<ElementSymbol> keyColumns) {
 		List<Criteria> crits = Criteria.separateCriteriaByAnd(condition);
 		IndexCondition[] conditions = new IndexCondition[keyColumns.size()];
 		for (int i = 0; i < conditions.length; i++) {
-			if (i > 0 && (conditions[i - 1].range || conditions[i -1].upper != null)) {
+			if (i > 0 && conditions[i - 1].valueSet.size() != 1) {
 				break; //don't yet support any other types of composite key lookups
 			}
 			conditions[i] = new IndexCondition();
@@ -122,27 +125,25 @@
 	
 	Constant lower = null;
 	Constant upper = null;
-	boolean range = true;
-	TreeSet<Constant> otherValues = new TreeSet<Constant>();
+	TreeSet<Constant> valueSet = new TreeSet<Constant>();
 	
 	void addCondition(Constant value, int comparisionMode) {
 		switch (comparisionMode) {
 		case CompareCriteria.EQ:
-			otherValues.clear();
-			lower = value;
+			valueSet.clear();
+			valueSet.add(value);
+			lower = null;
 			upper = null;
-			range = false;
 			break;
 		case CompareCriteria.GE:
 		case CompareCriteria.GT:
-			if (lower == null) {
-				range = true;
+			if (valueSet.isEmpty()) {
 				lower = value;
 			} 
 			break;
 		case CompareCriteria.LE:
 		case CompareCriteria.LT:
-			if (upper == null && range) {
+			if (valueSet.isEmpty()) {
 				upper = value;
 			}
 			break;
@@ -150,21 +151,12 @@
 	}
 	
 	void addSet(TreeSet<Constant> values) {
-		if (!range && lower != null) {
+		if (!valueSet.isEmpty()) {
 			return;
 		}
-		Iterator<Constant> iter = values.iterator();
-		Constant lowest = iter.next();
-		iter.remove();
-		lower = lowest;
-		range = false;
-		iter = values.descendingIterator();
-		if (iter.hasNext()) {
-			Constant highest = iter.next();
-			upper = highest;
-			iter.remove();
-		}
-		otherValues.addAll(values);
+		lower = null;
+		upper = null;
+		valueSet.addAll(values);
 	}
 	
 }
\ No newline at end of file

Modified: trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java	2010-07-28 04:40:32 UTC (rev 2382)
+++ trunk/engine/src/main/java/org/teiid/query/tempdata/TempTable.java	2010-07-28 15:20:07 UTC (rev 2383)
@@ -300,18 +300,18 @@
 	}
 
 	private TupleBrowser createTupleBrower(Criteria condition, boolean direction) throws TeiidComponentException {
-		List lower = null;
-		List upper = null;
-		List<List<?>> otherValues = null;
-		boolean range = true;
+		List<Object> lower = null;
+		List<Object> upper = null;
+		List<List<Object>> values = null;
 		if (condition != null && rowId == null) {
 			IndexCondition[] indexConditions = IndexCondition.getIndexConditions(condition, columns.subList(0, tree.getKeyLength()));
 			if (indexConditions.length > 1 && indexConditions[indexConditions.length - 1] != null) {
-				lower = new ArrayList(indexConditions.length);
+				List<Object> value = new ArrayList<Object>(indexConditions.length);
 				for (IndexCondition indexCondition : indexConditions) {
-					lower.add(indexCondition.lower.getValue());
+					value.add(indexCondition.valueSet.iterator().next().getValue());
 				}
-				range = false;
+				values = new ArrayList<List<Object>>(1);
+				values.add(value);
 				//TODO: support other composite key lookups
 			} else {
 				if (indexConditions[0].lower != null) {
@@ -320,14 +320,18 @@
 				if (indexConditions[0].upper != null) {
 					upper = Arrays.asList(indexConditions[0].upper.getValue());
 				}
-				otherValues = new ArrayList<List<?>>();
-				for (Constant constant : indexConditions[0].otherValues) {
-					otherValues.add(Arrays.asList(constant.getValue()));
+				if (!indexConditions[0].valueSet.isEmpty()) {
+					values = new ArrayList<List<Object>>();
+					for (Constant constant : indexConditions[0].valueSet) {
+						values.add(Arrays.asList(constant.getValue()));
+					}
 				}
-				range = indexConditions[0].range;
 			}
 		}
-		return new TupleBrowser(this.tree, lower, upper, otherValues, range, direction);
+		if (values != null) {
+			return new TupleBrowser(this.tree, values, direction);
+		}
+		return new TupleBrowser(this.tree, lower, upper, direction);
 	}
 	
 	public int getRowCount() {

Modified: trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2010-07-28 04:40:32 UTC (rev 2382)
+++ trunk/engine/src/test/java/org/teiid/query/processor/TestTempTables.java	2010-07-28 15:20:07 UTC (rev 2383)
@@ -185,7 +185,25 @@
 		execute("insert into x (e2, e1) values (1, 'c')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
 		execute("insert into x (e2, e1) values (0, 'd')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
 		execute("insert into x (e2, e1) values (-1, 'e')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
-		execute("select * from x where e1 in ('a', 'c', 'e')", new List[] {Arrays.asList("a", 3), Arrays.asList("c", 1), Arrays.asList("e", -1)}); //$NON-NLS-1$
+		execute("select * from x where e1 in ('a', 'c', 'e', 'f', 'g')", new List[] {Arrays.asList("a", 3), Arrays.asList("c", 1), Arrays.asList("e", -1)}); //$NON-NLS-1$
 	}
 	
+	@Test public void testInWithIndexUpdate() throws Exception {
+		execute("create local temporary table x (e1 string, e2 integer, primary key (e1))", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (3, 'a')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (2, 'b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (1, 'c')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (0, 'd')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (-1, 'e')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("update x set e2 = 5 where e1 in ('a', 'c')", new List[] {Arrays.asList(2)}); //$NON-NLS-1$
+	}
+	
+	@Test public void testCompositeKeyCompareEquals() throws Exception {
+		execute("create local temporary table x (e1 string, e2 integer, primary key (e1, e2))", new List[] {Arrays.asList(0)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (3, 'a')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (2, 'b')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("insert into x (e2, e1) values (1, 'c')", new List[] {Arrays.asList(1)}); //$NON-NLS-1$
+		execute("select * from x where e1 = 'b' and e2 = 2", new List[] {Arrays.asList("b", 2)}); //$NON-NLS-1$
+	}
+	
 }



More information about the teiid-commits mailing list