internal void ExecuteWhere(string From_TableName, object[,] Where_NameCondValue, out Set ROWIDS) { string TableName=From_TableName; if(Where_NameCondValue==null) Where_NameCondValue=new object[0,0]; Field[] flds = GetFields(TableName); // Assertion if(true) { Index DELNDX = GetIndex(From_TableName,flds[0]); int __rows1 = DELNDX.GetRowCountForKey(false); // non-deleted rows count for(int k=1;k<flds.Length;k++) { if(flds[k].bIndexed) { Index _NDX = GetIndex(From_TableName,flds[k]); if(_NDX.ReverseCount()!=__rows1) throw new Exception("Corruption error."); } } } // map of fields in table Hashtable FieldMap = new Hashtable(); foreach(Field f in flds) { FieldMap[f.Name]=f; } // Values in names with same type as field ArrayList Where = new ArrayList(); Hashtable UsedFieldMap = new Hashtable(); for(int n=0;n<Where_NameCondValue.GetLength(0);n++) { string fieldname = Where_NameCondValue[n,0].ToString(); string op = Where_NameCondValue[n,1].ToString(); object val = Where_NameCondValue[n,2]; bool oprec = (op=="=")||(op==">")||(op=="<")||(op=="!=")||(op==">=")||(op=="<="); if(!oprec) throw new Exception("Operand '"+op+"' unrecognized"); if(!FieldMap.ContainsKey(fieldname)) throw new Exception("Column "+fieldname+" unrecognized"); Field f = FieldMap[fieldname] as Field; UsedFieldMap[f]=f; int priority=0; if(f.bIndexed&&f.bUnique&&(op=="=")) priority=-4; else if(f.bIndexed&&(op=="=")) priority=-3; else if(f.bIndexed&&f.bUnique&&((op=="<")||(op==">")||(op==">=")||(op=="<="))) priority=-2; else if(f.bIndexed&&((op=="<")||(op==">")||(op==">=")||(op=="<="))) priority=-1; object v=Variant.Object2Variant(val,f.type).obj; Where.Add(new object[]{f,op,v,priority}); } // Sorting of fields to make search faster if(true) { // Order: // Indexed-unique with = condition -4 // Indexed with = condition -3 // Indexed-unique with < or > condition -2 // Indexed with < or > condition -1 // The rest 0 Where.Sort(new WhereComp()); } // Let's do the search if(Where.Count>0) { ROWIDS = null; for(int n=0;(n<Where.Count);n++) { Field f = (Where[n] as object[])[0] as Field; string op = (Where[n] as object[])[1] as string; object val = (Where[n] as object[])[2] as object; if(f.bIndexed) { if(f.bUnique) { if(op=="=") { Index ndx = this.GetIndex(TableName,f); if(ndx.ExistsKey(val)) { long row = ndx.PeekOne(val); if(ROWIDS==null) { ROWIDS = new SortedSet(); ROWIDS.Add( row ); continue; } else if(ROWIDS.Contains( row )) { ROWIDS = new SortedSet(); ROWIDS.Add( row ); continue; } else { ROWIDS = new SortedSet(); break; } } else { ROWIDS = new SortedSet(); break; } } //// beta begin // if(op=="!=") // { // Index ndx = this.GetIndex(TableName,f); // if(ndx.ExistsUnique(val)) // {// the value exists in the index // // If the rowids collection do not exist already // if(ROWIDS==null) // { // // Fill a rowid collection without the removed rowid // rowids = new ArrayList( ndx.ht.Values ); // rowids.Remove(ndx.ht[val]); // continue; // } // // If the rowids collection already exists // else // { // // If contains the value to exclude // if(rowids.Contains(val)) // { // rowids.Remove(ndx.ht[val]); // if(rowids.Count==0) break; // continue; // } // // If do not contains the value to exclude // else // { // continue; // } // } // } // else // {// the value do not exist in the index // continue; // } // } ////end beta } else {// clave no única if(ROWIDS==null) { Index ndx = this.GetIndex(TableName,flds[0]); ROWIDS = new SortedSet( ndx.GetRowSet(false) ); } // begin op = if(op=="=") { Index ndx = this.GetIndex(TableName,f); Set hs = ndx.GetRowSet(val); if(hs.Count<ROWIDS.Count) {// hs is smaller than ROWIDS Set newSet = new SortedSet(); foreach(long row in hs) { if(ROWIDS.Contains(row)) newSet.Add(row); } ROWIDS=newSet; } else {// ROWIDS is smaller than hs Set newSet = new SortedSet(); foreach(long row in ROWIDS) { if(hs.Contains(row)) newSet.Add(row); } ROWIDS=newSet; } //ROWIDS = ROWIDS.Intersect( hs); if(ROWIDS.Count==0) break; else continue; } // end of op = // begin op != if(op=="!=") { Index ndx = this.GetIndex(TableName,f); Set hs = ndx.GetRowSet(val); ROWIDS = ROWIDS.Minus( hs); if(ROWIDS.Count==0) break; else continue; } // end of op != // begin op > if((op=="<")||(op==">")||(op=="<=")||(op==">=")) { Index ndx = this.GetIndex(TableName,f); // Metemos en un set todos los ids de fila que llevamos hasta ahora // para luego irlas poniendo en una lista de seleccionadas Set nSet = new SortedSet(); IComparable v = (IComparable)val; foreach(object key in ndx.Keys) { IComparable o = (IComparable)key; bool bAdd=false; if((op==">")&&(o.CompareTo(v)>0)) bAdd=true; else if((op=="<")&&(o.CompareTo(v)<0)) bAdd=true; else if((op==">=")&&(o.CompareTo(v)>=0)) bAdd=true; else if((op=="<=")&&(o.CompareTo(v)<=0)) bAdd=true; if(bAdd) nSet = nSet.Union( ndx.GetRowSet(key) ); } ROWIDS = ROWIDS.Intersect( nSet ); if(ROWIDS.Count==0) break; continue; } else { throw new Exception("Unsupported operator"); } // end of op > } } // Linear search if(ROWIDS==null) { Index ndx = this.GetIndex(TableName,flds[0]); ROWIDS = new SortedSet( ndx.GetRowSet(false) ); } if(true) { int tid = (int)TableName2TID[TableName]; TableNameDef tnd = TID2Def[tid] as TableNameDef; int valSize = (int)f.DataSize(); int Capacity = (PageSize-ContentPageDataOffset)/valSize; ArrayList pages = f.DataFID; if((pages.Count*Capacity)<tnd.rownum) throw new Exception("Row num corrupted."); ArrayList new_rowids = new ArrayList(); for(int row=0;row<tnd.rownum;row++) { long rowid = (long)row; if(ROWIDS.Contains(rowid)) { int npage = row / Capacity; int offset = row % Capacity; int page = (int)pages[npage]; //br.BaseStream.Position = (page*PageSize)+ContentPageDataOffset+offset*valSize; //object data = f.ReadData(br); object data = f.ReadData( this.PageReader(page,ContentPageDataOffset+offset*valSize) ); IComparable o = (IComparable)data; IComparable v = (IComparable)val; if((op=="=")&&(o.CompareTo(v)==0)) {} else if((op==">")&&(o.CompareTo(v)>0)) {} else if((op=="<")&&(o.CompareTo(v)<0)) {} else if((op=="!=")&&(o.CompareTo(v)!=0)) {} else if((op==">=")&&(o.CompareTo(v)>=0)) {} else if((op=="<=")&&(o.CompareTo(v)<=0)) {} else ROWIDS.Remove( rowid ); } } if(ROWIDS.Count==0) break; } } } else { Index ndx = this.GetIndex(TableName,flds[0]); ROWIDS = new SortedSet( ndx.GetRowSet(false) ); } // Assertion if(true) { Index DELNDX = GetIndex(From_TableName,flds[0]); int __rows1 = DELNDX.GetRowCountForKey(false); // non-deleted rows count for(int k=1;k<flds.Length;k++) { if(flds[k].bIndexed) { Index _NDX = GetIndex(From_TableName,flds[k]); if(_NDX.ReverseCount()!=__rows1) throw new Exception("Corruption error."); } } } }