mongodb 记录字段不致密,新结构和老结构合并之后,报错数组越界

imagepng

集算器扩展包 extlib\MongoCli\scu-mongo-cli-xxx.jar 存在的问题。
驱动包类 com.scudata.lib.mongo.function.ImCursor, 方法 mergeTable。

(ImCursorHncFind 是重写 ImCursor,主要修改读数据 command 命令变成 mongodb 官方游标读取方式,其他逻辑保持不变)

下面是方法 mergeTable 具体代码逻辑

// 序表与序表合并,字段不一致时字段数据对齐
// 将 bufTbl 合并到 vTbls 中, 先将两表结构调整为一致,再过滤数据。
private boolean mergeTable(Table[] vTbls, Table bufTbl, int n) {
boolean bBreak = false;
Table vTbl = vTbls[0];
//A. 相同结构合并
if (Arrays.equals(vTbl.dataStruct().getFieldNames(), bufTbl.dataStruct().getFieldNames())){
;//skip
//B. 包括结构合并 (vTbl>bufTbl),只处理 bufTbl 数据
}else if(isColumnContain(vTbl.dataStruct().getFieldNames(), bufTbl.dataStruct().getFieldNames())){
Table tmpTable = new Table(vTbl.dataStruct());
modifyTableData(tmpTable, bufTbl);
bufTbl.clear();
bufTbl.addAll(tmpTable);
tmpTable.clear();
//C. 不同结构合并
}else{
String[] newCols = mergeColumns(vTbl.dataStruct().getFieldNames(),
bufTbl.dataStruct().getFieldNames());
Table tmpTable = new Table(newCols);
IArray mems = vTbl.getMems();

		// oldData
		Record r = null;
		for(int i=0; i<mems.size(); i++){
			r = (Record)mems.get(i+1);
			tmpTable.newLast(r.getFieldValues());
		}
		vTbl.clear();
		vTbl=new Table(newCols);
		vTbl.addAll(tmpTable);
		tmpTable.clear();
		// tmpTable经过上面逻辑变成了60个字段,bufTbl结构还是58个字段,两个表的字段结构不一致。
		modifyTableData(tmpTable, bufTbl);
		bufTbl.clear();
		bufTbl.addAll(tmpTable);
		tmpTable.clear();
	}
	
	if (bufTbl.length()>n){ //2.1 有足够缓存
		for(int i=0; i<n; i++){
			BaseRecord r = bufTbl.getRecord(i+1);
			vTbl.newLast(r.getFieldValues());
		}
		for(int i=n; i>0; i--){
			bufTbl.delete(i);
		}
		//2.2 剩余存入缓冲.这个是bufTbl参数,可能有58个字段,字段不全。

// m_bufTable = new Table(bufTbl.dataStruct());

		//vTbl是经过字段合并动作,字段会比bufTbl只多不少,所以这里用bufTbl
		m_bufTable = new Table(vTbl.dataStruct());
		m_bufTable.addAll(bufTbl);
		//return vTbl;
		bBreak = true;
	}else{			//2.3  缓存数不足	
		vTbl.addAll(bufTbl);
		n -= bufTbl.length();
		bufTbl.clear();				
	}
	
	vTbls[0] = vTbl;
	return bBreak;
}

上面逻辑如果进入到 else 逻辑,新老结构进行合并。合并之后 vTbl 结构是最全的,bufTbl 对象结构还是之前的,不是合并之后的结构。

源代码 m_bufTable = new Table(bufTbl.dataStruct()); 这行有点问题

//vTbl 是经过字段合并动作,字段会比 bufTbl 只多不少,所以这里用 vTbl
m_bufTable = new Table(vTbl.dataStruct());