Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.scudata.dm.query.SimpleJoin Maven / Gradle / Ivy
Go to download
SPL(Structured Process Language) A programming language specially for structured data computing.
package com.scudata.dm.query;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.scudata.cellset.ICellSet;
import com.scudata.common.IOUtils;
import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.common.UUID;
import com.scudata.dm.BaseRecord;
import com.scudata.dm.Context;
import com.scudata.dm.DataStruct;
import com.scudata.dm.Env;
import com.scudata.dm.FileObject;
import com.scudata.dm.Record;
import com.scudata.dm.Sequence;
import com.scudata.dm.Table;
import com.scudata.dm.cursor.ICursor;
import com.scudata.dm.cursor.IMultipath;
import com.scudata.dm.cursor.JoinxCursor;
import com.scudata.dm.cursor.MemoryCursor;
import com.scudata.dm.cursor.SubCursor;
import com.scudata.dm.cursor.SyncCursor;
import com.scudata.dm.cursor.XJoinxCursor;
import com.scudata.dm.op.Join;
import com.scudata.dm.op.New;
import com.scudata.dm.op.Operation;
import com.scudata.dm.op.Select;
import com.scudata.dm.query.utils.ExpressionTranslator;
import com.scudata.dw.PhyTable;
import com.scudata.excel.ExcelTool;
import com.scudata.expression.Expression;
import com.scudata.resources.ParseMessage;
public class SimpleJoin
{
private List parameterList;
private Context ctx;
private DataStruct ds;
private ICursor icur;
private JoinNode rootNode;
private Set whereList;
private Set selectList;
private List recycleList;
private String intoFileName;
private Boolean singleTable;
private Map withTableMap;
private ICellSet ics;
private int parallelNumber;
private List> subQueryOfExistsEntryList;
private List> subQueryOfSelectEntryList;
private List> subQueryOfInEntryList;
private List> subQueryOfWhereEntryList;
private Map subQueryOfExistsMap;
private Map subQueryOfSelectMap;
private Map subQueryOfInMap;
private Map subQueryOfWhereMap;
private boolean isMemory;
private JoinTable fromTable;
public static final int Memory_Join = 0;
public static final int External_Join = 1;
abstract class JoinNode
{
protected JoinNode nodeParent = null;
protected JoinNode nodeLeft = null;
protected JoinNode nodeRight = null;
protected Set joinFilter = new HashSet();
protected Set whereFilter = new HashSet();
protected Set selectFields = null;
protected String filterBuffer = null;
protected Set tableNameList = new HashSet();
protected ICursor nodeCursor = null;
protected DataStruct nodeStruct = null;
protected boolean isMemoryNode = false;
protected int stamp = Memory_Join;
protected boolean parallel = false;
protected String tableFile = null;
protected PhyTable metaData = null;
protected String topFilter = null;
public JoinNode getLeft()
{
return this.nodeLeft;
}
public JoinNode getRight()
{
return this.nodeRight;
}
public JoinNode getParent()
{
return this.nodeParent;
}
public void setLeft(JoinNode left)
{
this.nodeLeft = left;
addTableNames(left.getTableNames());
}
public void setRight(JoinNode right)
{
this.nodeRight = right;
addTableNames(right.getTableNames());
}
public void setParent(JoinNode parent)
{
this.nodeParent = parent;
}
public String getTableFile()
{
return null;
}
public void setTableFile(String file)
{
}
public PhyTable getTableMetaData()
{
return null;
}
public void setTableMetaData(PhyTable metaData)
{
}
public boolean hasTableName(String table)
{
for(String tableName : this.tableNameList)
{
if(tableName.equalsIgnoreCase(table))
{
return true;
}
}
return false;
}
public void addTableName(String table)
{
if(!hasTableName(table))
{
this.tableNameList.add(table);
}
}
public Set getTableNames()
{
return this.tableNameList;
}
public void addTableNames(Set tableList)
{
this.tableNameList.addAll(tableList);
}
public String getFilter()
{
String filter = "";
for(String joinFilter : this.joinFilter)
{
if(!filter.isEmpty())
{
filter += " AND ";
}
filter += addSmartParen(joinFilter);
}
this.joinFilter.clear();
return filter;
}
public void setFilter(String filter)
{
this.joinFilter.add(filter.trim());
}
public String getBuffer()
{
return this.filterBuffer;
}
public void setBuffer(String buffer)
{
this.filterBuffer = buffer;
}
public void moveBuffer(int sign)
{
if(sign == 1)
{
setWhere(this.filterBuffer);
this.filterBuffer = null;
}
else if(sign == 0)
{
setFilter(this.filterBuffer);
this.filterBuffer = null;
}
else if(sign == -1)
{
if(this.selectFields != null)
{
this.selectFields.add(this.filterBuffer.trim());
}
this.filterBuffer = null;
}
}
public boolean analyzeBuffer(String filter)
{
if(filter == null || filter.trim().isEmpty())
{
this.filterBuffer = "1=1";
return true;
}
String tableName = null;
Token[] tokens = Tokenizer.parse(filter);
String newName = null;
StringBuffer sb = new StringBuffer();
boolean inFlag = false;
for(int i = 0, len = tokens.length; i < len; i++)
{
if(tokens[i].isKeyWord("NOT") && i + 3 < len && tokens[i + 1].isKeyWord("EXISTS") && tokens[i + 2].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 2, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 3, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
Set tableNames = rootNode.getTableNames();
Set containsList = new HashSet();
for(String select : selectList)
{
containsList.add(select.toLowerCase());
}
boolean needDelayed = false;
Set nameSet = new LinkedHashSet();
for(int n = 0, l = subQueryTokens.length; n < l; n++)
{
boolean contains= false;
String tempName = null;
for(String name : tableNames)
{
if(name.equalsIgnoreCase(subQueryTokens[n].getString()))
{
contains = true;
tempName = name;
break;
}
}
if(n < l - 2 && contains
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n].getString() + subQueryTokens[n + 1].getString() + subQueryTokens[n + 2].getString();
if(!containsList.contains(theFieldName.toLowerCase()))
{
selectList.add(theFieldName);
containsList.add(theFieldName.toLowerCase());
}
n += 2;
nameSet.add(tempName);
needDelayed = true;
}
}
if(needDelayed)
{
for(String name : nameSet)
{
if(!getTableNames().contains(name))
{
return false;
}
}
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!subQueryOfExistsMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfExistsEntryList.add(subQueryMap.entrySet().iterator().next());
sb.append("$" + uuid + " IS NULL");
sb.append(tokens[end].getSpaces());
subQueryOfExistsMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfExistsMap.get(checkList.toString());
sb.append(dollar_uuid + " IS NULL");
sb.append(tokens[end].getSpaces());
}
}
else
{
SimpleSQL lq = new SimpleSQL(ics, subQueryTokens, 0, subQueryTokens.length, parameterList, ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
Sequence seq = cursor.peek(1);
if(seq == null)
{
sb.append("1=1");
sb.append(tokens[end].getSpaces());
}
else
{
sb.append("1=0");
sb.append(tokens[end].getSpaces());
}
}
i = end;
continue;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":executeJoin, EXISTS?ؼ??ֺ????????Ӳ?ѯ");
}
}
else if(tokens[i].isKeyWord("EXISTS") && i + 2 < len && tokens[i + 1].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 1, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 2, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
Set tableNames = rootNode.getTableNames();
Set containsList = new HashSet();
for(String select : selectList)
{
containsList.add(select.toLowerCase());
}
boolean needDelayed = false;
Set nameSet = new LinkedHashSet();
for(int n = 0, l = subQueryTokens.length; n < l; n++)
{
boolean contains = false;
String tempName = null;
for(String name : tableNames)
{
if(name.equalsIgnoreCase(subQueryTokens[n].getString()))
{
contains = true;
tempName = name;
break;
}
}
if(n < l - 2 && contains
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n].getString() + subQueryTokens[n + 1].getString() + subQueryTokens[n + 2].getString();
if(!containsList.contains(theFieldName.toLowerCase()))
{
selectList.add(theFieldName);
containsList.add(theFieldName.toLowerCase());
}
n += 2;
nameSet.add(tempName);
needDelayed = true;
}
}
if(needDelayed)
{
for(String name : nameSet)
{
if(!getTableNames().contains(name))
{
return false;
}
}
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!subQueryOfExistsMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfExistsEntryList.add(subQueryMap.entrySet().iterator().next());
sb.append("$" + uuid + " IS NOT NULL");
sb.append(tokens[end].getSpaces());
subQueryOfExistsMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfExistsMap.get(checkList.toString());
sb.append(dollar_uuid + " IS NOT NULL");
sb.append(tokens[end].getSpaces());
}
}
else
{
SimpleSQL lq = new SimpleSQL(ics, subQueryTokens, 0, subQueryTokens.length, parameterList, ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
Sequence seq = cursor.peek(1);
if(seq == null)
{
sb.append("1=0");
sb.append(tokens[end].getSpaces());
}
else
{
sb.append("1=1");
sb.append(tokens[end].getSpaces());
}
}
i = end;
continue;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":executeJoin, EXISTS?ؼ??ֺ????????Ӳ?ѯ");
}
}
newName = tokens[i].getOriginString();
if(tokens[i].getType() == Tokenizer.IDENT && i + 2 < len && tokens[i + 1].getType() == Tokenizer.DOT)
{
if(tokens[i + 2].getType() == Tokenizer.IDENT && tokens[i+2].getString().equals("COUNT"))
{
tableName = tokens[i].getString();
if(!hasTableName(tableName))
{
return false;
}
else
{
//ͳһ???µı???Ϊ??????.???????????ֲ?ͬ????ͬ???ֶ?
newName = "\"" + tokens[i].getString()+ "." + "1" + "\"";
i += 2;
}
}
else if(tokens[i + 2].getString().equals("*"))
{
tableName = tokens[i].getString();
if(!hasTableName(tableName))
{
return false;
}
else
{
//ͳһ???µı???Ϊ??????.???????????ֲ?ͬ????ͬ???ֶ?
newName = "\"" + tokens[i].getString() + "." + tokens[i+2].getString() + "\"";
i += 2;
}
}
else if(tokens[i + 2].getType() == Tokenizer.IDENT)
{
tableName = tokens[i].getString();
if(!hasTableName(tableName))
{
return false;
}
else
{
//˳???¼WHERE??ON?Ӿ??е?ԭʼ?ֶ????Ƶ?SELECT?ֶμ?¼?б??Ա?ʹ??
String oldName = tokens[i].getString() + tokens[i+1].getString() + tokens[i+2].getString();
selectList.add(oldName);
//ͳһ???µı???Ϊ??????.???????????ֲ?ͬ????ͬ???ֶ?
newName = "\"" + tokens[i].getString()+"."+tokens[i+2].getString() + "\"";
i += 2;
}
}
}
else if(tokens[i].getType() == Tokenizer.IDENT && tokens[i].getString().equals("COUNT"))
{
if(this instanceof JoinTable)
{
tableName = getTableNames().iterator().next();
//ͳһ???µı???Ϊ??????.???????????ֲ?ͬ????ͬ???ֶ?
newName = "\"" + tableName + "." + "1" + "\"";
}
}
else if(tokens[i].getString().equals("*"))
{
if(this instanceof JoinTable)
{
tableName = getTableNames().iterator().next();
//ͳһ???µı???Ϊ??????.???????????ֲ?ͬ????ͬ???ֶ?
newName = "\"" + tableName + "." + tokens[i].getString() + "\"";
}
}
else if(tokens[i].getType() == Tokenizer.LPAREN)
{
int finish = Tokenizer.scanParen(tokens, i, len);
int begin = i;
int end = finish;
while(true)
{
begin++;
end--;
if(end > begin && tokens[begin].getType() == Tokenizer.LPAREN && tokens[end].getType() == Tokenizer.RPAREN)
{
int pos = Tokenizer.scanParen(tokens, begin, end + 1);
if(pos == end)
{
continue;
}
}
begin--;
end++;
break;
}
Token[] subQueryTokens = Arrays.copyOfRange(tokens, begin + 1, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
ICursor icur = null;
if(isSubQuery) //?Ӳ?ѯ
{
Set tableNames = rootNode.getTableNames();
Set containsList = new HashSet();
for(String select : selectList)
{
containsList.add(select.toLowerCase());
}
boolean needDelayed = false;
Set nameSet = new LinkedHashSet();
for(int n = 0, l = subQueryTokens.length; n < l; n++)
{
boolean contains = false;
String tempName = null;
for(String name : tableNames)
{
if(name.equalsIgnoreCase(subQueryTokens[n].getString()))
{
contains = true;
tempName = name;
break;
}
}
if(n < l - 2 && contains
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n].getString() + subQueryTokens[n + 1].getString() + subQueryTokens[n + 2].getString();
if(!containsList.contains(theFieldName.toLowerCase()))
{
selectList.add(theFieldName);
containsList.add(theFieldName.toLowerCase());
}
n += 2;
nameSet.add(tempName);
needDelayed = true;
}
}
if(inFlag)
{
if(needDelayed)
{
for(String name : nameSet)
{
if(!getTableNames().contains(name))
{
return false;
}
}
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!subQueryOfInMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfInEntryList.add(subQueryMap.entrySet().iterator().next());
newName = "$" + uuid;
subQueryOfInMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfInMap.get(checkList.toString());
newName = dollar_uuid;
}
}
else
{
SimpleSQL lq = new SimpleSQL(ics, subQueryTokens, 0, subQueryTokens.length, parameterList, ctx, true);
lq.setMemory(true);
icur = lq.query();
Sequence seq = null;
if(icur != null)
{
seq = icur.fetch();
}
if(seq == null || seq.length() == 0)
{
newName = "(1=0)";
}
else
{
if(!(seq.get(1) instanceof BaseRecord) || seq.dataStruct() == null || seq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":executeJoin, IN???Ӳ?ѯ????쳣");
}
newName = "(";
for(int m = 1, n = seq.length(); m <= n; m++)
{
if(m > 1)
{
newName += ",";
}
Object value = ((BaseRecord)seq.get(m)).getFieldValue(0);
newName += getSQLValue(value);
}
newName += ")";
}
inFlag = false;
}
}
else
{
if(needDelayed)
{
for(String name : nameSet)
{
if(!getTableNames().contains(name))
{
return false;
}
}
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!subQueryOfWhereMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfWhereEntryList.add(subQueryMap.entrySet().iterator().next());
newName = "$" + uuid;
subQueryOfWhereMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfWhereMap.get(checkList.toString());
newName = dollar_uuid;
}
}
else
{
SimpleSQL lq = new SimpleSQL(ics, subQueryTokens, 0, subQueryTokens.length, parameterList, ctx, true);
lq.setMemory(true);
icur = lq.query();
Sequence seq = null;
if(icur != null)
{
seq = icur.fetch();
if(seq == null || seq.length() != 1 || !(seq.get(1) instanceof BaseRecord) || seq.dataStruct() == null || seq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":executeJoin, WHERE???Ӳ?ѯ????쳣");
}
}
newName = getSQLValue(((BaseRecord)seq.get(1)).getFieldValue(0));
}
}
i = finish;
}
}
else if(tokens[i].isKeyWord("IN"))
{
inFlag = true;
}
else if(inFlag)
{
inFlag = false;
}
sb.append(newName);
sb.append(tokens[i].getSpaces());
}
this.filterBuffer = sb.toString();
return true;
}
public String getWhere()
{
String filter = "";
for(String whereFilter : this.whereFilter)
{
if(!filter.isEmpty())
{
filter += " AND ";
}
filter += addSmartParen(whereFilter);
}
this.whereFilter.clear();
return filter;
}
public void setWhere(String filter)
{
this.whereFilter.add(filter.trim());
}
public Set getSelect()
{
return this.selectFields;
}
public ICursor getCursor()
{
return this.nodeCursor;
}
public void setCursor(ICursor cursor)
{
this.nodeCursor = cursor;
}
public DataStruct getStruct()
{
return this.nodeStruct;
}
public void setStruct(DataStruct struct)
{
this.nodeStruct = struct;
}
public void executeJoin()
{
if(this instanceof JoinTable)
{
boolean needRename = false;
String tableName = this.getTableNames().iterator().next();
String prefix = "\"" + tableName + ".";
StringBuffer sb = new StringBuffer();
int index = 0;
for(String selectField : this.selectFields)
{
if(selectField != null)
{
selectField = selectField.trim();
}
if(index > 0)
{
sb.append(", ");
}
if(selectField.startsWith(prefix))
{
String fieldName = selectField.substring(prefix.length(), selectField.length() - 1); //ע??Ҫ??ȥ""
sb.append(fieldName);//ԭ?ֶ???
sb.append(" ");
if(fieldName.equals("1"))
{
sb.append(prefix + "COUNT\"");
}
else if(fieldName.equals("*"))
{
needRename = true;//?????????ֶ???
}
else
{
sb.append(selectField);//???ֶ??????б???
}
}
index++;
}
String topFilter = ((JoinTable)this).getTopFilter();
if(this.nodeStruct == null && this.metaData == null)
{
if(this.tableFile == null || this.tableFile.isEmpty())
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":executeJoin, ??Ч???????ӱ??ڵ?");
}
SimpleSelect ss = new SimpleSelect(ics, ctx);
ss.setMemory(isMemory || this.isMemoryNode);
if(this.parallel && parallelNumber > 1)
{
ss.setParallel(parallelNumber);
}
if(topFilter != null)
{
ss.setTopFilter(topFilter);
}
String sql = String.format("SELECT %s FROM %s %s", sb.toString(), this.getTableFile(), this.getTableNames().iterator().next());
ICursor icur = ss.query(sql);
if(icur != null)
{
String whereStr = getWhere();
if(whereStr != null && !whereStr.trim().isEmpty())
{
whereStr = " WHERE " + whereStr;
}
DataStruct ds = ss.getDataStruct();
for(String fieldName : ds.getFieldNames())
{
if(fieldName.startsWith(prefix))
{
whereStr = whereStr.replaceAll("(?i)" + fieldName, fieldName.substring(prefix.length(), fieldName.length() - 1));
}
else
{
whereStr = whereStr.replaceAll("(?i)" + prefix + fieldName + "\"", fieldName);
}
}
whereStr = whereStr.trim();
List> newSubQueryOfExistsEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfExistsEntryList.isEmpty())
{
for(Map.Entry subQueryOfExistsEntry : subQueryOfExistsEntryList)
{
String ident = subQueryOfExistsEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfExistsEntryList.add(subQueryOfExistsEntry);
}
}
}
List> newSubQueryOfInEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfInEntryList.isEmpty())
{
for(Map.Entry subQueryOfExistsEntry : subQueryOfInEntryList)
{
String ident = subQueryOfExistsEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfInEntryList.add(subQueryOfExistsEntry);
}
}
}
List> newSubQueryOfWhereEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfWhereEntryList.isEmpty())
{
for(Map.Entry subQueryOfExistsEntry : subQueryOfWhereEntryList)
{
String ident = subQueryOfExistsEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfWhereEntryList.add(subQueryOfExistsEntry);
}
}
}
if(!newSubQueryOfExistsEntryList.isEmpty() || !newSubQueryOfInEntryList.isEmpty() || !newSubQueryOfWhereEntryList.isEmpty())
{
this.nodeCursor = icur;
this.nodeStruct = ds;
if(!newSubQueryOfExistsEntryList.isEmpty())
{
icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfExistsEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.Exist_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
}
if(!newSubQueryOfInEntryList.isEmpty())
{
icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfInEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.In_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
}
if(!newSubQueryOfWhereEntryList.isEmpty())
{
icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfWhereEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.Where_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
}
whereStr = SimpleSelect.scanExp(Tokenizer.parse(whereStr.replace("WHERE", "").trim()), parameterList);
Map transMap = new LinkedHashMap();
Next:
for(int p = 0; p < this.nodeStruct.getFieldCount(); p++)
{
String colName = this.nodeStruct.getFieldName(p);
for(Map.Entry newSubQueryOfExistsEntry : newSubQueryOfExistsEntryList)
{
String ident = newSubQueryOfExistsEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
for(Map.Entry newSubQueryOfInEntry : newSubQueryOfInEntryList)
{
String ident = newSubQueryOfInEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
for(Map.Entry newSubQueryOfWhereEntry : newSubQueryOfWhereEntryList)
{
String ident = newSubQueryOfWhereEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
transMap.put("'" + getRealFieldName(colName) + "'", "#" + (p + 1));
}
whereStr = ExpressionTranslator.translateExp(whereStr, transMap);
this.nodeCursor.addOperation(new Select(new Expression(whereStr), null), ctx);
}
else
{
sql = String.format("%s %s", sql, whereStr);
ss = new SimpleSelect(ics, ctx);
ss.setMemory(isMemory || this.isMemoryNode);
if(this.parallel && parallelNumber > 1)
{
ss.setParallel(parallelNumber);
}
if(topFilter != null)
{
ss.setTopFilter(topFilter);
}
ss.setSQLParameters(parameterList);
this.nodeCursor = ss.query(sql);
this.nodeStruct = ss.getDataStruct();
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor.fetch());
}
}
}
}
else
{
SimpleSelect ss = new SimpleSelect(ics, ctx);
ss.setMemory(isMemory || this.isMemoryNode);
String dql = String.format("SELECT %s FROM (?)", sb.toString());
if(this.nodeStruct != null)
{
if(this.nodeCursor == null)
{
this.nodeCursor = new MemoryCursor(new Table(this.nodeStruct));
}
ss.setSQLParameters(this.nodeCursor);
ss.setSQLParameters(this.nodeStruct);
}
else if(this.metaData != null)
{
ss.setSQLParameters(this.metaData);
}
if(topFilter != null)
{
ss.setTopFilter(topFilter);
}
this.nodeCursor = ss.query(dql);
this.nodeStruct = ss.getDataStruct();
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor.fetch());
}
}
if(needRename)//select * from T, ??ѯʱû?????ֶ?????ʱ????
{
String[] fieldNames = this.nodeStruct.getFieldNames();
Expression[] fieldExps = new Expression[fieldNames.length];
for(int i=0, len=fieldNames.length; i> newSubQueryOfExistsEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfExistsEntryList.isEmpty())
{
for(Map.Entry subQueryOfExistsEntry : subQueryOfExistsEntryList)
{
String ident = subQueryOfExistsEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfExistsEntryList.add(subQueryOfExistsEntry);
}
}
}
List> newSubQueryOfInEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfInEntryList.isEmpty())
{
for(Map.Entry subQueryOfInEntry : subQueryOfInEntryList)
{
String ident = subQueryOfInEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfInEntryList.add(subQueryOfInEntry);
}
}
}
List> newSubQueryOfWhereEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfWhereEntryList.isEmpty())
{
for(Map.Entry subQueryOfWhereEntry : subQueryOfWhereEntryList)
{
String ident = subQueryOfWhereEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfWhereEntryList.add(subQueryOfWhereEntry);
}
}
}
if(!newSubQueryOfExistsEntryList.isEmpty() || !newSubQueryOfInEntryList.isEmpty() || !newSubQueryOfWhereEntryList.isEmpty())
{
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor.fetch());
}
if(!newSubQueryOfExistsEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfExistsEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.Exist_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
}
if(!newSubQueryOfInEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfInEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.In_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
}
if(!newSubQueryOfWhereEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfWhereEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.Where_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
}
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor == null ? null : this.nodeCursor.fetch());
}
whereStr = SimpleSelect.scanExp(Tokenizer.parse(whereStr.replace("WHERE", "").trim()), parameterList);
Map transMap = new LinkedHashMap();
Next:
for(int p = 0; p < this.nodeStruct.getFieldCount(); p++)
{
String colName = this.nodeStruct.getFieldName(p);
for(Map.Entry newSubQueryOfExistsEntry : newSubQueryOfExistsEntryList)
{
String ident = newSubQueryOfExistsEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
for(Map.Entry newSubQueryOfInEntry : newSubQueryOfInEntryList)
{
String ident = newSubQueryOfInEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
for(Map.Entry newSubQueryOfWhereEntry : newSubQueryOfWhereEntryList)
{
String ident = newSubQueryOfWhereEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
transMap.put("'" + colName + "'", "#" + (p + 1));
}
whereStr = ExpressionTranslator.translateExp(whereStr, transMap);
this.nodeCursor.addOperation(new Select(new Expression(whereStr), null), ctx);
}
else
{
String sql = String.format("SELECT * FROM (?) %s", whereStr);
SimpleSelect ss = new SimpleSelect(ics, ctx);
ss.setMemory(isMemory || this.isMemoryNode);
ss.setSQLParameters(this.nodeCursor);
ss.setSQLParameters(this.nodeStruct);
ss.setSQLParameters(parameterList);
if(topFilter != null)
{
ss.setTopFilter(topFilter);
}
this.nodeCursor = ss.query(sql);
this.nodeStruct = ss.getDataStruct();
if(this.isMemoryNode && !(this.nodeCursor instanceof MemoryCursor))
{
this.nodeCursor = new MemoryCursor(this.nodeCursor.fetch());
}
}
}
else
{
JoinNode left = getLeft();
JoinNode right = getRight();
if(left == null || right == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":executeJoin, ij???????쳣??JOIN ON?Ӿ?");
}
left.executeJoin();
right.executeJoin();
String option = null;
if(this instanceof LeftJoin)
{
option = "1";
}
else if(this instanceof FullJoin)
{
option = "f";
}
ICursor lCur = left.getCursor();
DataStruct lDst = left.getStruct();
ICursor rCur = right.getCursor();
DataStruct rDst = right.getStruct();
String filter = getFilter();
if(filter == null || filter.isEmpty())
{
filter = "(1=1)";
}
String whereStr = getWhere();
List> newSubQueryOfExistsEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfExistsEntryList.isEmpty())
{
for(Map.Entry subQueryOfExistsEntry : subQueryOfExistsEntryList)
{
String ident = subQueryOfExistsEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfExistsEntryList.add(subQueryOfExistsEntry);
}
}
}
List> newSubQueryOfInEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfInEntryList.isEmpty())
{
for(Map.Entry subQueryOfInEntry : subQueryOfInEntryList)
{
String ident = subQueryOfInEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfInEntryList.add(subQueryOfInEntry);
}
}
}
List> newSubQueryOfWhereEntryList = new ArrayList>();
if(!whereStr.isEmpty() && !subQueryOfWhereEntryList.isEmpty())
{
for(Map.Entry subQueryOfWhereEntry : subQueryOfWhereEntryList)
{
String ident = subQueryOfWhereEntry.getKey();
if(whereStr.contains(ident))
{
newSubQueryOfWhereEntryList.add(subQueryOfWhereEntry);
}
}
}
Token[] filterTokens = null;
filterTokens = optimizeWhere(Tokenizer.parse(filter), parameterList);
filter = SimpleSelect.scanExp(filterTokens, parameterList);
//System.out.println("SimpleJoin 1------------"+filter);
Map n2cMap = new LinkedHashMap();
for(int i = 0, len = lDst.getFieldNames().length; i < len; i++)
{
String fieldName = lDst.getFieldNames()[i];
if(fieldName.startsWith("\"") && fieldName.endsWith("\"")
&& fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
}
n2cMap.put("'" + fieldName + "'", "L." + "#" + (i + 1));
}
for(int j = 0, len = rDst.getFieldNames().length; j < len; j++)
{
String fieldName = rDst.getFieldNames()[j];
if(fieldName.startsWith("\"") && fieldName.endsWith("\"")
&& fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
}
n2cMap.put("'" + fieldName + "'", "~." + "#" + (j + 1));
}
Map trMap = new LinkedHashMap();
trMap.put("L.#", "#");
trMap.put("~.#", "#");
filter = ExpressionTranslator.translateExp(filter, n2cMap);
//xingjl 2020/07/23, correct : date('1980-07-19','yyyy-mm-dd')
filter = filter.replaceAll("'", "\"");
filter = filter.replaceAll("yyyy-mm-dd", "yyyy-MM-dd");
//System.out.println("SimpleJoin 2------------"+filter);
ICursor[] curs = new ICursor[]{lCur, rCur};
DataStruct[] dss = new DataStruct[]{lDst, rDst};
String[] names = new String[]{"L", "R"};
Expression[] exps = new Expression[2];
String[] fps = new String[]{null, null};
exps[0] = new Expression("true");
exps[1] = new Expression(filter);
if(option != null && option.indexOf("f") != -1)
{
String[] subFilters = null;
try
{
subFilters = splitAnd(filter);
}
catch(RQException ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+"JoinNode.executeJoin, FULL JOIN??֧??AND????", ex);
}
List leftExpList = new ArrayList();
List rightExpList = new ArrayList();
for(String subFilter : subFilters)
{
String[] subFilterItems = null;
try
{
subFilterItems = splitEqual(subFilter);
}
catch(RQException ex)
{
subFilterItems = subFilter.split("!=");
if(subFilterItems.length == 2 && subFilterItems[1].equals("null"))
{
continue;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+"JoinNode.executeJoin, FULL JOIN??֧?ֵ?ֵ????", ex);
}
}
if(subFilterItems.length != 2)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+"JoinNode.executeJoin, FULL JOIN??֧?ֵ?ֵ????");
}
if(subFilterItems[0].indexOf("~.") != -1 && subFilterItems[0].indexOf("L.") == -1)
{
rightExpList.add(new Expression(ExpressionTranslator.translateExp(subFilterItems[0], trMap)));
}
else if(subFilterItems[0].indexOf("~.") == -1 && subFilterItems[0].indexOf("L.") != -1)
{
leftExpList.add(new Expression(ExpressionTranslator.translateExp(subFilterItems[0], trMap)));
}
else if(subFilterItems[0].indexOf("~.") == -1 && subFilterItems[0].indexOf("L.") == -1)
{
;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+"JoinNode.executeJoin, FULL JOIN??֧???????ֶ???ͬһ??ĵ?ֵ????");
}
if(subFilterItems[1].indexOf("~.") != -1 && subFilterItems[1].indexOf("L.") == -1)
{
rightExpList.add(new Expression(ExpressionTranslator.translateExp(subFilterItems[1], trMap)));
if(rightExpList.size() > leftExpList.size())
{
leftExpList.add(new Expression(subFilterItems[0]));
}
}
else if(subFilterItems[1].indexOf("~.") == -1 && subFilterItems[1].indexOf("L.") != -1)
{
leftExpList.add(new Expression(ExpressionTranslator.translateExp(subFilterItems[1], trMap)));
if(leftExpList.size() > rightExpList.size())
{
rightExpList.add(new Expression(subFilterItems[0]));
}
}
else if(subFilterItems[1].indexOf("~.") == -1 && subFilterItems[1].indexOf("L.") == -1)
{
if(leftExpList.size() > rightExpList.size())
{
rightExpList.add(new Expression(subFilterItems[1]));
}
else if(rightExpList.size() > leftExpList.size())
{
leftExpList.add(new Expression(subFilterItems[1]));
}
else
{
leftExpList.add(new Expression(subFilterItems[0]));
rightExpList.add(new Expression(subFilterItems[1]));
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+"JoinNode.executeJoin, FULL JOIN??֧???????ֶ???ͬһ??ĵ?ֵ????");
}
}
Expression[][] expss = new Expression[2][];
expss[0] = new Expression[leftExpList.size()];
expss[1] = new Expression[rightExpList.size()];
leftExpList.toArray(expss[0]);
rightExpList.toArray(expss[1]);
if(curs[0] instanceof MemoryCursor && (curs[1] instanceof MemoryCursor || this.stamp == Memory_Join))
{
this.nodeCursor = new SimpleJoinCursor(curs, expss, names, option, ctx, dss);
this.nodeStruct = ((SimpleJoinCursor)this.nodeCursor).getTableDataStruct();
}
else
{
this.nodeCursor = new SimpleJoinxCursor(curs, expss, names, option, ctx, dss);
this.nodeStruct = ((SimpleJoinxCursor)this.nodeCursor).getTableDataStruct();
}
}
else
{
if(curs[0] instanceof MemoryCursor && (curs[1] instanceof MemoryCursor || this.stamp == Memory_Join))
{
this.nodeCursor = new SimpleXJoinCursor(curs, exps, names, fps, option, ctx, dss);
this.nodeStruct = ((SimpleXJoinCursor)this.nodeCursor).getTableDataStruct();
}
else
{
if(curs[1] instanceof IMultipath)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+"JoinNode.executeJoin, xjoinx???ܶ??ڹ???ά????֧?ֶ?·?α?");
}
this.nodeCursor = new SimpleXJoinxCursor(curs, exps, names, fps, option, ctx, dss);
this.nodeStruct = ((SimpleXJoinxCursor)this.nodeCursor).getTableDataStruct();
}
}
if(!newSubQueryOfExistsEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfExistsEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.Exist_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
}
if(!newSubQueryOfInEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfInEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.In_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
}
if(!newSubQueryOfWhereEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(ics, this.nodeCursor, newSubQueryOfWhereEntryList, parameterList, rootNode.getTableNames(), SubQueryCursor.Where_Type, this.nodeStruct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(this.nodeCursor))
{
this.nodeStruct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
this.nodeStruct = icur.getDataStruct();
}
this.nodeCursor = icur;
}
if(!whereStr.isEmpty())
{
whereStr = SimpleSelect.scanExp(Tokenizer.parse(whereStr), parameterList);
Map transMap = new LinkedHashMap();
Next:
for(int p = 0; p < this.nodeStruct.getFieldCount(); p++)
{
String colName = this.nodeStruct.getFieldName(p);
for(Map.Entry newSubQueryOfExistsEntry : newSubQueryOfExistsEntryList)
{
String ident = newSubQueryOfExistsEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
for(Map.Entry newSubQueryOfInEntry : newSubQueryOfInEntryList)
{
String ident = newSubQueryOfInEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
for(Map.Entry newSubQueryOfWhereEntry : newSubQueryOfWhereEntryList)
{
String ident = newSubQueryOfWhereEntry.getKey();
if(colName.equalsIgnoreCase(ident))
{
transMap.put("'" + colName + "'", "#" + (p + 1));
continue Next;
}
}
transMap.put("'" + colName + "'", "#" + (p + 1));
}
whereStr = ExpressionTranslator.translateExp(whereStr, transMap);
this.nodeCursor.addOperation(new Select(new Expression(whereStr), null), ctx);
}
}
}
public int getStamp()
{
return this.stamp;
}
public void setStamp(int stamp)
{
this.stamp = stamp;
}
public boolean getParallel()
{
return this.parallel;
}
public void setParallel(boolean parallel)
{
this.parallel = parallel;
}
}
class JoinTable extends JoinNode
{
private JoinTable()
{
this.selectFields = new HashSet();
}
public JoinTable(String file)
{
this();
this.tableFile = file;
}
public JoinTable(PhyTable metaData)
{
this();
this.metaData = metaData;
}
public JoinTable(ICursor cursor, DataStruct struct)
{
this();
this.nodeStruct = struct;
this.nodeCursor = cursor;
}
public String getTableFile()
{
return this.tableFile;
}
public void setTableFile(String file)
{
this.tableFile = file;
}
public PhyTable getTableMetaData()
{
return this.metaData;
}
public void setTableMetaData(PhyTable metaData)
{
this.metaData = metaData;
}
public void setLeft(JoinNode left)
{
this.nodeLeft = null;
}
public void setRight(JoinNode right)
{
this.nodeRight = null;
}
public int getStamp()
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":JoinTable.getStamp, ???ڵ?û?????ӱ?ǩ");
}
public void setStamp(int stamp)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":JoinTable.getStamp, ???ڵ㲻?????????ӱ?ǩ");
}
public boolean isMemoryNode()
{
return this.isMemoryNode;
}
public void setMemoryNode(boolean isMemoryNode)
{
this.isMemoryNode = isMemoryNode;
}
public String getTopFilter()
{
return this.topFilter;
}
public void setTopFilter(String topFilter)
{
this.topFilter = topFilter;
}
}
class LeftJoin extends JoinNode
{
public LeftJoin()
{
}
public LeftJoin(JoinNode left, JoinNode right)
{
this.nodeLeft = left;
this.nodeRight = right;
}
}
class FullJoin extends JoinNode
{
public FullJoin()
{
}
public FullJoin(JoinNode left, JoinNode right)
{
this.nodeLeft = left;
this.nodeRight = right;
}
}
class InnerJoin extends JoinNode
{
public InnerJoin()
{
}
public InnerJoin(JoinNode left, JoinNode right)
{
this.nodeLeft = left;
this.nodeRight = right;
}
}
class SimpleXJoinxCursor extends XJoinxCursor
{
private DataStruct tabDs;
private DataStruct ds1, ds2, ds;
public SimpleXJoinxCursor(ICursor[] cursors, Expression[] exps, String[] names, String[] fltOpts, String opt, Context ctx, DataStruct[] dss)
{
super(cursors, exps, names, fltOpts, opt, ctx);
this.ds1 = dss[0];
this.ds2 = dss[1];
int l = (ds1 == null ? 0 : ds1.getFieldCount());
int r = (ds2 == null ? 0 : ds2.getFieldCount());
List nameList = new ArrayList();
for(int i = 0; i< l + r; i++)
{
if(i < l)
{
nameList.add(ds1.getFieldName(i));
}
else
{
nameList.add(ds2.getFieldName(i - l));
}
}
String[] colNames = new String[nameList.size()];
nameList.toArray(colNames);
this.tabDs = new DataStruct(colNames);
}
protected Sequence get(int n)
{
if(this.tabDs == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SimpleXJoinxCursor.get, ????Ԥ?????????ݽṹ");
}
Sequence tab = super.get(n);
if(tab != null)
{
Table res = new Table(this.tabDs);
int l = this.ds1.getFieldCount();
int r = this.ds2.getFieldCount();
List valueList = new ArrayList(l+r);
for(int i=1, x=tab.getMems().size(); i<=x; i++)
{
BaseRecord rd = new Record(this.tabDs);
Object obj1 = tab.getMems().get(i);
if(obj1 instanceof BaseRecord)
{
BaseRecord rd1 = (Record) obj1;
for(int j=0, y=2; j nameList = new ArrayList();
for(int i = 0; i< l + r; i++)
{
if(i < l)
{
nameList.add(this.ds1.getFieldName(i));
}
else
{
nameList.add(this.ds2.getFieldName(i - l));
}
}
String[] colNames = new String[nameList.size()];
nameList.toArray(colNames);
this.tabDs = new DataStruct(colNames);
}
protected Sequence get(int n)
{
if(this.tabDs == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SimpleXJoinCursor.get, ????Ԥ?????????ݽṹ");
}
Sequence tab = super.get(n);
if(tab != null)
{
Table res = new Table(this.tabDs);
int l = this.ds1.getFieldCount();
int r = this.ds2.getFieldCount();
List valueList = new ArrayList(l+r);
for(int i=1, x=tab.getMems().size(); i<=x; i++)
{
BaseRecord rd = new Record(this.tabDs);
Object obj1 = tab.getMems().get(i);
if(obj1 instanceof BaseRecord)
{
BaseRecord rd1 = (BaseRecord) obj1;
for(int j=0, y=2; j nameList = new ArrayList();
for(int i = 0; i< l + r; i++)
{
if(i < l)
{
nameList.add(ds1.getFieldName(i));
}
else
{
nameList.add(ds2.getFieldName(i - l));
}
}
String[] colNames = new String[nameList.size()];
nameList.toArray(colNames);
this.tabDs = new DataStruct(colNames);
}
protected Sequence get(int n)
{
if(this.tabDs == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SimpleXJoinxCursor.get, ????Ԥ?????????ݽṹ");
}
Sequence tab = super.get(n);
if(tab != null)
{
Table res = new Table(this.tabDs);
int l = this.ds1.getFieldCount();
int r = this.ds2.getFieldCount();
List valueList = new ArrayList(l+r);
for(int i=1, x=tab.getMems().size(); i<=x; i++)
{
BaseRecord rd = new Record(this.tabDs);
Object obj1 = tab.getMems().get(i);
if(obj1 instanceof BaseRecord)
{
BaseRecord rd1 = (BaseRecord) obj1;
for(int j=0, y=2; j nameList = new ArrayList();
for(int i = 0; i< l + r; i++)
{
if(i < l)
{
nameList.add(this.ds1.getFieldName(i));
}
else
{
nameList.add(this.ds2.getFieldName(i - l));
}
}
String[] colNames = new String[nameList.size()];
nameList.toArray(colNames);
this.tabDs = new DataStruct(colNames);
}
protected Sequence get(int n)
{
if(this.tabDs == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SimpleJoinCursor.get, ????Ԥ?????????ݽṹ");
}
Sequence tab = super.get(n);
if(tab != null)
{
Table res = new Table(this.tabDs);
int l = this.ds1.getFieldCount();
int r = this.ds2.getFieldCount();
List valueList = new ArrayList(l+r);
for(int i=1, x=tab.getMems().size(); i<=x; i++)
{
BaseRecord rd = new Record(this.tabDs);
Object obj1 = tab.getMems().get(i);
if(obj1 instanceof BaseRecord)
{
BaseRecord rd1 = (BaseRecord) obj1;
for(int j=0, y=2; j paramList = null;
private DataStruct ds = null;
private DataStruct tabDs = null;
private List>> subQueryListListList = null;
private List> fieldNameListList = null;
private List colNameList = null;
public SubQueryCursor(ICursor cursor, int type, ICellSet ics, List paramList, List colNameList, List>> subQueryListListList, List> fieldNameListList, Context ctx, DataStruct tabDs)
{
super(cursor);
this.type = type;
if(this.type != Exist_Type && this.type != Select_Type && this.type != In_Type && this.type != Where_Type)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":SubQueryCursor, ?Ӳ?ѯ?α??ʼ??????????");
}
this.ics = ics;
this.paramList = paramList;
this.subQueryListListList = subQueryListListList;
if(this.subQueryListListList == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":SubQueryCursor, ?Ӳ?ѯ?α??ʼ??????????");
}
this.fieldNameListList = fieldNameListList;
if(this.fieldNameListList == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":SubQueryCursor, ?Ӳ?ѯ?α??ʼ??????????");
}
this.colNameList = colNameList;
if(this.colNameList == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":SubQueryCursor, ?Ӳ?ѯ?α??ʼ??????????");
}
this.ctx = ctx;
List finalFieldNameList = new ArrayList();
finalFieldNameList.addAll(Arrays.asList(tabDs.getFieldNames()));
finalFieldNameList.addAll(this.colNameList);
String[] finalFieldNames = new String[finalFieldNameList.size()];
finalFieldNameList.toArray(finalFieldNames);
this.tabDs = new DataStruct(finalFieldNames);
this.colNameList.clear();
}
protected Sequence get(int n)
{
Sequence tab = super.get(n);
if(tab != null && tab.dataStruct() != null)
{
int init = tab.dataStruct().getFieldCount();
int size = this.fieldNameListList.size();
for(int i = 0; i < size; i++)
{
DataStruct struct = new DataStruct(Arrays.copyOfRange(this.tabDs.getFieldNames(), 0, init + i + 1));
Table res = new Table(struct);
List> subQueryListList = this.subQueryListListList.get(i);
List fieldNameList = this.fieldNameListList.get(i);
for(int m = 1; m <= tab.getMems().size(); m++)
{
Object obj = tab.getMems().get(m);
if(!(obj instanceof BaseRecord))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SubQueryCursor.get, ??ѯ??????б????ɼ?¼???");
}
BaseRecord rec = (BaseRecord) obj;
int index = 0;
List subQueryList = new ArrayList();
subQueryList.addAll(subQueryListList.get(index++));
for(String fieldName : fieldNameList)
{
String fieldValue = getSQLValue(rec.getFieldValue(fieldName));
Token[] fieldValueTokens = Tokenizer.parse(fieldValue);
subQueryList.addAll(Arrays.asList(fieldValueTokens));
if(index < subQueryListList.size())
{
subQueryList.addAll(subQueryListList.get(index++));
}
}
Token[] subQuery = new Token[subQueryList.size()];
subQueryList.toArray(subQuery);
SimpleSQL lq = new SimpleSQL(this.ics, subQuery, 0, subQuery.length, this.paramList, this.ctx, false);
lq.setMemory(true);
Object result = lq.execute();
Sequence sq = result instanceof ICursor ? ((ICursor)result).fetch() : (result instanceof Sequence ? (Sequence)result : null);
Object val = null;
if(sq != null)
{
if(this.type == SubQueryCursor.Exist_Type)
{
val = "1";
}
else if(this.type == SubQueryCursor.Select_Type || this.type == SubQueryCursor.Where_Type)
{
if(sq.length() != 1 || !(sq.get(1) instanceof BaseRecord) || sq.dataStruct() == null || sq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SubQueryCursor.get, SELECT/WHERE?Ӿ????Ӳ?ѯ????쳣");
}
val = ((BaseRecord)sq.get(1)).getFieldValue(0);
}
else if(this.type == SubQueryCursor.In_Type)
{
Sequence v = new Sequence();
for(int p = 1, q = sq.length(); p <= q; p++)
{
if(!(sq.get(1) instanceof BaseRecord) || sq.dataStruct() == null || sq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":SubQueryCursor.get, IN?Ӿ????Ӳ?ѯ????쳣");
}
v.add(((BaseRecord)sq.get(p)).getFieldValue(0));
}
val = v;
}
}
BaseRecord newRec = new Record(struct);
newRec.set(rec);
newRec.set(init + i, val);
res.add(newRec);
}
tab = res;
}
}
return tab;
}
/**
* ????ʣ??ļ?¼???ر??α?
* @return Sequence
*/
public Sequence fetch() {
Sequence result = this.get(Integer.MAX_VALUE);
close();
return result;
}
public DataStruct getDataStruct()
{
return this.ds;
}
public void setDataStruct(DataStruct ds)
{
this.ds = ds;
}
public DataStruct getTableDataStruct()
{
return this.tabDs;
}
}
public SimpleJoin(ICellSet ics, Context ctx)
{
this.icur = null;
this.ds = null;
this.ctx = ctx;
this.ics = ics;
init();
}
private void init()
{
this.parameterList = null;
if(this.ctx == null)
{
this.ctx = new Context();
}
this.whereList = new HashSet();
this.selectList = new HashSet();
this.recycleList = new ArrayList();
this.intoFileName = "";
this.singleTable = false;
this.withTableMap = new HashMap();
this.isMemory = false;
this.parallelNumber = 1;
this.subQueryOfExistsEntryList = new ArrayList>();
this.subQueryOfSelectEntryList = new ArrayList>();
this.subQueryOfInEntryList = new ArrayList>();
this.subQueryOfWhereEntryList = new ArrayList>();
this.subQueryOfExistsMap = new HashMap();
this.subQueryOfSelectMap = new HashMap();
this.subQueryOfInMap = new HashMap();
this.subQueryOfWhereMap = new HashMap();
}
private int pos(int p1, int def)
{
if (p1 > 0) return p1;
return def;
}
private int pos(int p1, int p2, int def)
{
if (p1 > 0) return p1;
if (p2 > 0) return p2;
return def;
}
private int pos(int p1, int p2, int p3, int p4, int def)
{
if (p1 > 0) return p1;
if (p2 > 0) return p2;
if (p3 > 0) return p3;
if (p4 > 0) return p4;
return def;
}
private int pos(int p1, int p2, int p3, int p4, int p5, int p6, int def)
{
if (p1 > 0) return p1;
if (p2 > 0) return p2;
if (p3 > 0) return p3;
if (p4 > 0) return p4;
if (p5 > 0) return p5;
if (p6 > 0) return p6;
return def;
}
private int pos(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int def)
{
if (p1 > 0) return p1;
if (p2 > 0) return p2;
if (p3 > 0) return p3;
if (p4 > 0) return p4;
if (p5 > 0) return p5;
if (p6 > 0) return p6;
if (p7 > 0) return p7;
return def;
}
public void setSQLParameters(List paramList)
{
this.parameterList = paramList;
}
private JoinTable scanTable(Token []tokens, int start, int next)
{
String tableName = null;
String aliasName = null;
JoinTable node = null;
if (start < next)
{
int pos = start + 1;
if(tokens[start].getType() == Tokenizer.KEYWORD)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanTable, ????ȱʧ??????????");
}
else if(tokens[start].getType() == Tokenizer.LPAREN)
{
tableName = "";
int end = Tokenizer.scanParen(tokens, start, next);
String[] keywords = new String[]{"SELECT", "WITH", "UNION", "INTERSECT", "EXCEPT", "MINUS"};
int keyPos = Tokenizer.scanKeyWords(keywords, tokens, start+1, end);
boolean isSubQuery = ((keyPos < 0) ? false : true);
if(isSubQuery)
{
Token[] subTokens = Arrays.copyOfRange(tokens, pos, end);
SimpleSQL lq = new SimpleSQL(this.ics, subTokens, 0, subTokens.length, parameterList, ctx, false);
lq.setMemory(this.isMemory);
ICursor icur = lq.query();
DataStruct ds = lq.getDataStruct();
node = new JoinTable(icur, ds);
if(end+1 != next)
{
if(tokens[end+1].isKeyWord("AS"))
{
if(end+2 == next || tokens[end+2].getType() != Tokenizer.IDENT)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
aliasName = tokens[end+2].getString();
}
else if(tokens[end+1].getType() == Tokenizer.IDENT)
{
aliasName = tokens[end+1].getString();
}
}
}
}
else
{
tableName = "";
pos = start;
while(pos < next)
{
tableName = tableName + tokens[pos].getOriginString();
tableName = tableName + tokens[pos].getSpaces();
pos++;
}
tableName = tableName.trim();
if (next - 2 >= start && tokens[next - 1].getType() == Tokenizer.IDENT)
{
int splitPos = tableName.lastIndexOf(" ");
if(splitPos != -1)
{
aliasName = tableName.substring(splitPos + 1);
if(aliasName.equals(tokens[next - 1].getOriginString()))
{
tableName = tableName.substring(0, splitPos).trim();
}
else
{
aliasName = null;
}
}
if(next - 3 >= start && tokens[next - 2].isKeyWord("AS"))
{
splitPos = tableName.lastIndexOf(" ");
if(splitPos != -1)
{
String asKeyWord = tableName.substring(splitPos + 1);
if(asKeyWord.equals(tokens[next - 2].getOriginString()))
{
tableName = tableName.substring(0, splitPos).trim();
}
}
}
}
if(tableName.startsWith("\"") && tableName.endsWith("\"")
&& tableName.substring(1, tableName.length()-1).indexOf("\"") == -1)
{
tableName = tableName.substring(1, tableName.length() - 1);
}
}
}
if(aliasName == null)
{
Token[] tableTokens = Tokenizer.parse(tableName);
if(tableTokens.length == 1 && tableTokens[0].getType() == Tokenizer.IDENT)
{
aliasName = tableName;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanTable, ÿ??ƴ?ӱ?????????һ?????ı????????");
}
}
if(!tableName.isEmpty())
{
FileObject fileObject = new FileObject(tableName, null, "s", ctx);
if(!fileObject.isExists()) //?????????룬????ȥ??
{
int index = tableName.lastIndexOf(":");
if(index != -1)
{
fileObject = new FileObject(tableName.substring(0, index).trim(), null, "s", this.ctx);
}
}
if(!fileObject.isExists())
{
node = this.withTableMap.get(tableName.toLowerCase());
if(node == null)
{
Object obj = null;
try
{
obj = new Expression(this.ics, this.ctx, tableName).calculate(this.ctx);
}
catch(Exception ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanTable, ?쳣?ı???:"+tableName);
}
if(obj instanceof ICursor)
{
ICursor cursor = (ICursor)obj;
DataStruct struct = cursor.getDataStruct();
if(struct == null)
{
Sequence sq = cursor.peek(1);
if(sq != null)
{
struct = sq.dataStruct();
}
//cursor.reset();
}
node = new JoinTable(cursor, struct);
}
else if(obj instanceof Table)
{
ICursor cursor = new MemoryCursor((Table)obj);
DataStruct struct = ((Table)obj).dataStruct();
node = new JoinTable(cursor, struct);
}
else if(obj instanceof PhyTable)
{
node = new JoinTable((PhyTable)obj);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanTable, ??֧?ֵ???ʱ??????????");
}
}
}
else
{
node = new JoinTable(tableName);
}
}
node.addTableName(aliasName);
return node;
}
private JoinNode scanNode(Token []tokens, int start, int next, boolean check)
{
int count = 0;
JoinTable table = null;
JoinNode root = null;
while (start < next)
{
if (start == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanNode, ??ʼλ?ó???????λ??");
}
int end = Tokenizer.scanComma(tokens, start, next);
if (end < 0)
{
end = next;
}
table = scanTable(tokens, start, end);
start = end + 1;
count++;
if(count > 1)
{
if(check)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanJoin, FROM??JOIN?ؼ??ֺ?ı???????????ȷ");
}
JoinNode node = new InnerJoin();
node.setStamp(Memory_Join);
node.setLeft(root);
root.setParent(node);
node.setRight(table);
table.setParent(node);
table.setMemoryNode(true);
root = node;
}
else
{
root = table;
}
}
return root;
}
private JoinNode scanJoin(Token []tokens, int start, int next, boolean hide)
{
JoinNode root = null;
JoinNode node = null;
if(hide)
{
root = scanNode(tokens, start, next, false);
}
else
{
int begin = start;
int stamp = Memory_Join;
int offset = 0;
StringBuffer filter = null;
for(int index = start; index <= next; index++)
{
if(index == next)
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
break;
}
else if(tokens[index].getString().equals("{") && filter == null)
{
int end = Tokenizer.scanBrace(tokens, index, next);
Token[] expTokens = Arrays.copyOfRange(tokens, index + 1, end);
StringBuffer expBuf = new StringBuffer();
for(int i = 0; i < expTokens.length; i++)
{
expBuf.append(expTokens[i].getOriginString());
expBuf.append(expTokens[i].getSpaces());
}
String expStr = expBuf.toString().trim();
Object obj = null;
try
{
obj = new Expression(this.ics, this.ctx, expStr).calculate(this.ctx);
}
catch(Exception ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ?쳣?ı???:"+expStr);
}
if(obj instanceof ICursor)
{
ICursor cursor = (ICursor)obj;
DataStruct struct = cursor.getDataStruct();
if(struct == null)
{
Sequence sq = cursor.peek(1);
if(sq != null)
{
struct = sq.dataStruct();
}
//cursor.reset();
}
node = new JoinTable(cursor, struct);
}
else if(obj instanceof Table)
{
ICursor cursor = new MemoryCursor((Table)obj);
DataStruct struct = ((Table)obj).dataStruct();
node = new JoinTable(cursor, struct);
}
else if(obj instanceof PhyTable)
{
node = new JoinTable((PhyTable)obj);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??֧?ֵ???ʱ??????????");
}
if(end + 1 != next)
{
if(tokens[end + 1].isKeyWord("AS"))
{
if(end + 2 == next || tokens[end + 2].getType() != Tokenizer.IDENT)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
node.addTableName(tokens[end + 2].getString());
}
else if(tokens[end + 1].getType() == Tokenizer.IDENT)
{
node.addTableName(tokens[end + 1].getString());
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
if(root == null)
{
root = node;
}
index = end;
begin = end + 1;
continue;
}
else if(tokens[index].getType() == Tokenizer.LPAREN && filter == null)
{
int end = Tokenizer.scanParen(tokens, index, next);
String[] keywords = new String[]{"SELECT", "WITH", "UNION", "INTERSECT", "EXCEPT", "MINUS"};
int keyPos = Tokenizer.scanKeyWords(keywords, tokens, index + 1, end);
boolean isSubQuery = ((keyPos < 0) ? false : true);
if(isSubQuery)
{
Token[] subTokens = Arrays.copyOfRange(tokens, index + 1, end);
SimpleSQL lq = new SimpleSQL(this.ics, subTokens, 0, subTokens.length, parameterList, ctx, false);
lq.setMemory(this.isMemory);
ICursor icur = lq.query();
DataStruct ds = lq.getDataStruct();
node = new JoinTable(icur, ds);
}
else
{
node = scanJoin(tokens, index + 1, end, false);
}
if(end + 1 != next)
{
if(tokens[end + 1].isKeyWord("AS"))
{
if(end + 2 == next || tokens[end + 2].getType() != Tokenizer.IDENT)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
node.addTableName(tokens[end + 2].getString());
}
else if(tokens[end+1].getType() == Tokenizer.IDENT)
{
node.addTableName(tokens[end + 1].getString());
}
}
if(root == null)
{
root = node;
}
index = end;
begin = end + 1;
continue;
}
else if(index + 5 < next
&& tokens[index + 3].isKeyWord("EXTERNAL")
&& tokens[index].equals("/") && tokens[index + 1].equals("*") && tokens[index + 2].equals("+") && tokens[index + 4].equals("*") && tokens[index + 5].equals("/"))
{
if(tokens[index + 3].isKeyWord("EXTERNAL")) // && Sequence.getFunctionPoint(15)
{
stamp = External_Join; //??SQL??/*+EXTERNAL*/??ǩ?????ڲ?????
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
offset = offset + 6;
index = index + 5;
continue;
}
else if(index + 1 < next && tokens[index].isKeyWord("LEFT") && tokens[index + 1].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new LeftJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setLeft(root);
root = node;
begin = index + 2;
index++;
node = null;
continue;
}
else if(index + 2 < next && tokens[index].isKeyWord("LEFT") && tokens[index + 1].isKeyWord("OUTER") && tokens[index + 2].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new LeftJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setLeft(root);
root = node;
begin = index + 3;
index += 2;
node = null;
continue;
}
else if(index + 1 < next && tokens[index].isKeyWord("FULL") && tokens[index + 1].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new FullJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setLeft(root);
root = node;
begin = index + 2;
index++;
node = null;
continue;
}
else if(index + 2 < next && tokens[index].isKeyWord("FULL") && tokens[index + 1].isKeyWord("OUTER") && tokens[index + 2].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new FullJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setLeft(root);
root = node;
begin = index + 3;
index += 2;
node = null;
continue;
}
else if(tokens[index].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new InnerJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setLeft(root);
root = node;
begin = index + 1;
node = null;
continue;
}
else if(index + 1 < next && tokens[index].isKeyWord("INNER") && tokens[index + 1].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new InnerJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setLeft(root);
root = node;
begin = index + 2;
index++;
node = null;
continue;
}
else if(index + 1 < next && tokens[index].isKeyWord("RIGHT") && tokens[index + 1].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new LeftJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setRight(root);
root = node;
begin = index + 2;
index++;
node = null;
continue;
}
else if(index + 2 < next && tokens[index].isKeyWord("RIGHT") && tokens[index + 1].isKeyWord("OUTER") && tokens[index + 2].isKeyWord("JOIN"))
{
if(root == null)
{
root = scanNode(tokens, begin, index - offset, true);
offset = 0;
}
else
{
if(filter != null)
{
root.setFilter(filter.toString());
filter = null;
}
}
node = new LeftJoin();
node.setStamp(stamp);
stamp = Memory_Join;
root.setParent(node);
node.setRight(root);
root = node;
begin = index + 3;
index += 2;
node = null;
continue;
}
else if(tokens[index].isKeyWord("ON"))
{
if(node == null)
{
node = scanNode(tokens, begin, index, true);
}
if(root != null)
{
if(node != null)
{
node.setParent(root);
if(root.getRight() == null)
{
root.setRight(node);
}
else if(root.getLeft() == null)
{
root.setLeft(node);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
filter = new StringBuffer();
node = null;
continue;
}
if(filter != null)
{
filter.append(tokens[index].getOriginString());
filter.append(tokens[index].getSpaces());
}
}
}
JoinNode point = root;
while(point.getLeft() != null)
{
point = point.getLeft();
}
if(point instanceof JoinTable)
{
this.fromTable = (JoinTable)point;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
setMemoryNodes(root);
setParallelNodes(root, null);
return root;
}
private void setMemoryNodes(JoinNode node)
{
if(!(node instanceof JoinTable) && node.getStamp() == Memory_Join)
{
JoinNode left = node.getLeft();
if(left instanceof JoinTable)
{
if(!left.equals(this.fromTable))
{
((JoinTable)left).setMemoryNode(true);
}
else
{
((JoinTable)left).setMemoryNode(false);
}
}
else if(left != null)
{
setMemoryNodes(left);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
JoinNode right = node.getRight();
if(right instanceof JoinTable)
{
if(!right.equals(this.fromTable))
{
((JoinTable) right).setMemoryNode(true);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
}
else if(right != null)
{
setMemoryNodes(right);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
}
}
private void setParallelNodes(JoinNode node, Integer isAllParallel)
{
if(isAllParallel == null)
{
isAllParallel = checkAllParallel(node);
}
if(node instanceof JoinTable)
{
if(isAllParallel == 1)
{
node.setParallel(true);
}
else if(isAllParallel == 0 && node.equals(this.fromTable))
{
node.setParallel(true);
}
else
{
node.setParallel(false);
}
}
else if(node != null)
{
setParallelNodes(node.getLeft(), isAllParallel);
setParallelNodes(node.getRight(), isAllParallel);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
}
private int checkAllParallel(JoinNode node) //?Ƿ???߳?ȡ???ɱ????????
{
if(node instanceof JoinTable)
{
return 1;
}
else if(node != null)
{
if(node.getStamp() == External_Join)
{
return 0;
}
else
{
if(checkAllParallel(node.getLeft()) < 0 || checkAllParallel(node.getRight()) < 0)
{
return -1;
}
else
{
return checkAllParallel(node.getLeft()) * checkAllParallel(node.getRight());
}
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error"));
}
}
private List scanFrom(Token []tokens, int start, int next, boolean hasJoin)
{
int fromPos = Tokenizer.scanKeyWord("FROM", tokens, start, next);
if(fromPos < 0 || fromPos == start)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, FROM?ؼ???ȱʧ??λ?ò???ȷ");
}
int intoPos = Tokenizer.scanKeyWord("INTO", tokens, start, next);
if(intoPos >= fromPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, INTO?ؼ??ֵ?λ?ò???ȷ");
}
else if(intoPos >= 0)
{
ArrayList tempList = new ArrayList();
for(int i=start; i intoPos && i < fromPos)
{
this.intoFileName += tokens[i].getOriginString();
this.intoFileName += tokens[i].getSpaces();
}
else if(i < intoPos || i >= fromPos)
{
tempList.add(tokens[i]);
}
}
next = next - (fromPos - intoPos);
fromPos = intoPos;
tokens = new Token[tempList.size()];
tempList.toArray(tokens);
}
int minPos = fromPos;
int wherePos = Tokenizer.scanKeyWord("WHERE", tokens, start, next);
if(wherePos >= 0 && wherePos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, WHERE?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(wherePos, minPos);
int groupPos = Tokenizer.scanKeyWord("GROUP", tokens, start, next);
if(groupPos >= 0 && groupPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, GROUP?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(groupPos , minPos);
int havingPos = Tokenizer.scanKeyWord("HAVING", tokens, start, next);
if(havingPos >= 0 && havingPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, HAVING?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(havingPos , minPos);
int orderPos = Tokenizer.scanKeyWord("ORDER", tokens, start, next);
if(orderPos >= 0 && orderPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ORDER?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(orderPos , minPos);
int limitPos = Tokenizer.scanKeyWord("LIMIT", tokens, start, next);
if(limitPos >= 0 && limitPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, LIMIT?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(limitPos , minPos);
int offsetPos = Tokenizer.scanKeyWord("OFFSET", tokens, start, next);
if(offsetPos >= 0 && offsetPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, OFFSET?ؼ??ֵ?λ?ò???ȷ");
}
int byStart = pos(groupPos, wherePos, fromPos);
int byEnd = pos(havingPos, orderPos, limitPos, offsetPos, next);
int byPos = Tokenizer.scanKeyWord("BY", tokens, byStart, byEnd);
if(byPos < 0 && groupPos > 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ?ؼ???GROUP????ȱ?ٹؼ???BY");
}
else if(havingPos > 0 && byPos > havingPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ????ؼ???BYλ??Ӧ????HAVING֮ǰ");
}
int fromEnd = pos(wherePos, groupPos, byPos, havingPos, orderPos, limitPos, offsetPos, next);
if(!hasJoin) //??????JOIN??????Ƿ?????ʽ??????
{
int commaPos = Tokenizer.scanComma(tokens, fromPos, fromEnd);
if(commaPos == -1) //????
{
List resultList = new ArrayList();
resultList.add(tokens);
this.singleTable = true;
return resultList;
}
}
boolean hide = !checkJoinOn(tokens, fromPos+1, fromEnd);
this.rootNode = scanJoin(tokens, fromPos+1, fromEnd, hide);
if(wherePos >= 0)
{
int whereEnd = pos(groupPos, byPos, havingPos, orderPos, next);
boolean fromBetween = false;
StringBuffer sb = new StringBuffer();
for(int i = wherePos; i < whereEnd; i++)
{
if(tokens[i].isKeyWord("WHERE"))
{
continue;
}
else if(tokens[i].getType() == Tokenizer.LPAREN)
{
int j = Tokenizer.scanParen(tokens, i, whereEnd);
for(int k=i; k<=j; k++)
{
sb.append(tokens[k].getOriginString());
sb.append(tokens[k].getSpaces());
}
i = j;
}
else if(tokens[i].isKeyWord("OR"))
{
this.whereList.clear();
break;
}
else if(tokens[i].isKeyWord("BETWEEN"))
{
fromBetween = true;
sb.append(tokens[i].getOriginString());
sb.append(tokens[i].getSpaces());
}
else if(tokens[i].isKeyWord("AND"))
{
if(fromBetween)
{
fromBetween = false;
sb.append(tokens[i].getOriginString());
sb.append(tokens[i].getSpaces());
}
else
{
this.whereList.add(sb.toString());
sb = new StringBuffer();
}
}
else
{
sb.append(tokens[i].getOriginString());
sb.append(tokens[i].getSpaces());
}
if(i == whereEnd-1)
{
this.whereList.add(sb.toString());
}
}
//where?Ӿ??Ǵ?and???ӣ???????ǰ????
if(this.whereList.size() != 0)
{
fromEnd = whereEnd;
}
}
//ȥ???ѷ?????ϵ?into\from\join\on\where(ȫand????ʱ)???Ӿ?
List tokensList = new ArrayList();
List tokenList = new ArrayList();
for(int i=0, len=tokens.length; i= fromEnd)
{
if((tokens[i].isKeyWord("BY") && !tokens[i-1].isKeyWord("GROUP") && !tokens[i-1].isKeyWord("ORDER"))
|| tokens[i].isKeyWord("GROUP") || tokens[i].isKeyWord("HAVING") || tokens[i].isKeyWord("ORDER"))
{
if(tokenList.size() != 0)
{
Token[] newTokens = new Token[tokenList.size()];
tokenList.toArray(newTokens);
tokensList.add(newTokens);
tokenList.clear();
}
}
tokenList.add(tokens[i]);
if(i == len - 1)
{
Token[] newTokens = new Token[tokenList.size()];
tokenList.toArray(newTokens);
tokensList.add(newTokens);
tokenList.clear();
}
}
}
return tokensList;
}
private int scanQuantifies(Token []tokens, int start, int next) //ֻ??????ִ?й???
{
Token t = tokens[start];
if(t.isKeyWord())
{
int c = start;
if (t.getString().equalsIgnoreCase("DISTINCT"))
{
c++;
if (c >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanQuantifies, ??ʼλ?ó???????λ??");
}
t = tokens[c];
}
if(t.isKeyWord() && t.getString().equalsIgnoreCase("TOP"))
{
c += 2;
if (c >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanQuantifies, ??ʼλ?ó???????λ??");
}
}
return c;
}
else
{
return start;
}
}
private void scanSelect(List tokensList)
{
for(Token[] tokens : tokensList)
{
boolean belongSelect = false;
for(int i = 0, len = tokens.length; i < len; i++)
{
if(tokens[i].isKeyWord("SELECT"))
{
int start = i + 1;
start = scanQuantifies(tokens, start, len);
i = start;
belongSelect = true;
}
if(tokens.length == 2 && tokens[i].getString().equalsIgnoreCase("*"))
{
selectList.clear();
selectList.add("*");
return;
}
else if(tokens[i].getType() == Tokenizer.IDENT)
{
if(i+1 != len && tokens[i].getString().equalsIgnoreCase("COUNT") && tokens[i+1].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 1, len);
if(end == i + 3)
{
if(tokens[i + 2].getString().equals("*"))
{
selectList.add("COUNT");
i = end;
}
}
else if(end == i + 5)
{
if(tokens[i + 2].getType() == Tokenizer.IDENT && tokens[i + 3].getType() == Tokenizer.DOT && tokens[i + 4].getString().equals("*"))
{
String oldName = tokens[i+2].getString() + tokens[i+3].getString() + "COUNT";
selectList.add(oldName);
i = end;
}
}
}
else if(i + 1 != len && tokens[i + 1].getType() == Tokenizer.DOT)
{
if(i + 2 != len)
{
if(tokens[i + 2].getType() == Tokenizer.IDENT && Tokenizer.isGatherFunction(tokens[i + 2].getString()) && tokens[i + 3].getType() == Tokenizer.LPAREN)
{
if(i + 3 != len)
{
int end = Tokenizer.scanParen(tokens, i+3, len);
if(end == i + 5)
{
String oldName = null;
if(tokens[i + 2].getString().equalsIgnoreCase("COUNT") && tokens[i + 4].getString().equals("*"))
{
oldName = tokens[i].getString() + tokens[i+1].getString() + "COUNT";
}
else
{
oldName = tokens[i].getString() + tokens[i+1].getString() + tokens[i+4].getString();
}
selectList.add(oldName);
i = end;
}
else if(end == i + 7)
{
if(tokens[i + 4].getType() == Tokenizer.IDENT && tokens[i + 5].getType() == Tokenizer.DOT)
{
if(!tokens[i].getString().equalsIgnoreCase(tokens[i + 4].getString()))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, ?ۺϺ???????????????ۺ??ֶ???????һ??");
}
else
{
String oldName = null;
if(tokens[i + 2].getString().equalsIgnoreCase("COUNT") && tokens[i + 6].getString().equals("*"))
{
oldName = tokens[i].getString() + tokens[i + 1].getString() + "COUNT";
}
else
{
oldName = tokens[i].getString() + tokens[i + 1].getString() + tokens[i + 6].getString();
}
selectList.add(oldName);
i = end;
}
}
}
}
}
else if(tokens[i + 2].getString().equals("*"))
{
String tableName = tokens[i].getString();
if(!this.rootNode.hasTableName(tableName))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, SQL????д???δ֪?ı?");
}
else
{
List deleteList = new ArrayList();
Iterator iter = selectList.iterator();
while(iter.hasNext())
{
String select = iter.next();
if(select.toLowerCase().startsWith(tableName.toLowerCase() + "."))
{
deleteList.add(select);
}
}
for(String delete : deleteList)
{
selectList.remove(delete);
}
selectList.add(tableName + "." + "*");
i += 2;
}
}
else if(tokens[i + 2].getType() == Tokenizer.IDENT)
{
String tableName = tokens[i].getString();
if(!this.rootNode.hasTableName(tableName))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, SQL????д???δ֪?ı?");
}
else
{
boolean selectTableAll = false;
Iterator iter = selectList.iterator();
while(iter.hasNext())
{
String select = iter.next();
if(select.equalsIgnoreCase(tokens[i].getString() + tokens[i+1].getString() + "*"))
{
selectTableAll = true;
}
}
if(!selectTableAll)
{
//??¼ԭʼ?ֶ????Ƶ?SELECT?ֶμ?¼?б??Ա?ʹ??
String oldName = tokens[i].getString() + tokens[i+1].getString() + tokens[i+2].getString();
selectList.add(oldName);
}
i += 2;
}
}
}
}
}
else if(i + 1 < len && tokens[i].isKeyWord("EXISTS") && tokens[i + 1].getType() == Tokenizer.LPAREN || i + 2 < len
&& tokens[i].isKeyWord("NOT") && tokens[i + 1].isKeyWord("EXISTS") && tokens[i + 2].getType() == Tokenizer.LPAREN)
{
int pos = tokens[i].isKeyWord("EXISTS") ? i : i + 1;
int end = Tokenizer.scanParen(tokens, pos + 1, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, pos + 2, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
Set tableNames = rootNode.getTableNames();
Set containsList = new HashSet();
for(String select : selectList)
{
containsList.add(select.toLowerCase());
}
boolean needDelayed = false;
for(int n = 0, l = subQueryTokens.length; n < l; n++)
{
boolean contains= false;
for(String name : tableNames)
{
if(name.equalsIgnoreCase(subQueryTokens[n].getString()))
{
contains = true;
break;
}
}
if(n < l - 2 && contains
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n].getString() + subQueryTokens[n + 1].getString() + subQueryTokens[n + 2].getString();
if(!containsList.contains(theFieldName.toLowerCase()))
{
selectList.add(theFieldName);
containsList.add(theFieldName.toLowerCase());
}
n += 2;
needDelayed = true;
}
}
if(needDelayed)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!subQueryOfExistsMap.containsKey(checkList.toString()))
{
subQueryOfExistsMap.put(checkList.toString(), null);
}
}
i = end;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, EXISTS?Ӿ?????????Ӳ?ѯ???");
}
}
else if(i + 1 < len && tokens[i].isKeyWord("IN") && tokens[i + 1].getType() == Tokenizer.LPAREN || i + 2 < len
&& tokens[i].isKeyWord("NOT") && tokens[i + 1].isKeyWord("IN") && tokens[i + 2].getType() == Tokenizer.LPAREN)
{
int pos = tokens[i].isKeyWord("IN") ? i : i + 1;
int end = Tokenizer.scanParen(tokens, pos + 1, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, pos + 2, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
Set tableNames = rootNode.getTableNames();
Set containsList = new HashSet();
for(String select : selectList)
{
containsList.add(select.toLowerCase());
}
boolean needDelayed = false;
for(int n = 0, l = subQueryTokens.length; n < l; n++)
{
boolean contains= false;
for(String name : tableNames)
{
if(name.equalsIgnoreCase(subQueryTokens[n].getString()))
{
contains = true;
break;
}
}
if(n < l - 2 && contains
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n].getString() + subQueryTokens[n + 1].getString() + subQueryTokens[n + 2].getString();
if(!containsList.contains(theFieldName.toLowerCase()))
{
selectList.add(theFieldName);
containsList.add(theFieldName.toLowerCase());
}
n += 2;
needDelayed = true;
}
}
if(needDelayed)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!subQueryOfInMap.containsKey(checkList.toString()))
{
subQueryOfInMap.put(checkList.toString(), null);
}
}
i = end;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, EXISTS?Ӿ?????????Ӳ?ѯ???");
}
}
else if(tokens[i].getType() == Tokenizer.LPAREN && i + 1 < len) //SELECT/WHERE
{
int end = Tokenizer.scanParen(tokens, i, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 1, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
Set tableNames = this.rootNode.getTableNames();
Set containsList = new HashSet();
for(String select : this.selectList)
{
containsList.add(select.toLowerCase());
}
boolean needDelayed = false;
for(int n = 0, l = subQueryTokens.length; n < l; n++)
{
boolean contains = false;
for(String name : tableNames)
{
if(name.equalsIgnoreCase(subQueryTokens[n].getString()))
{
contains = true;
break;
}
}
if(n < l - 2 && contains && subQueryTokens[n + 1].getType() == Tokenizer.DOT && subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n].getString() + subQueryTokens[n + 1].getString() + subQueryTokens[n + 2].getString();
if(!containsList.contains(theFieldName.toLowerCase()))
{
selectList.add(theFieldName);
containsList.add(theFieldName.toLowerCase());
}
n += 2;
needDelayed = true;
}
}
if(needDelayed)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(belongSelect)
{
if(!subQueryOfSelectMap.containsKey(checkList.toString()))
{
subQueryOfSelectMap.put(checkList.toString(), null);
}
}
else
{
if(!subQueryOfWhereMap.containsKey(checkList.toString()))
{
subQueryOfWhereMap.put(checkList.toString(), null);
}
}
}
i = end;
}
}
}
}
}
private boolean checkJoinOn(Token []tokens, int start, int next)
{
boolean joinFlag = false;
int couple = 0;
for(int i=start; i 1 || couple < -1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":checkJoinOn, ?ؼ???JOIN??ON??ƥ??");
}
}
return joinFlag;
}
private void filterCheck(JoinNode node)
{
if(node == null)
{
node = this.rootNode;
}
if(!(node instanceof JoinTable))
{
String filter = node.getFilter();
if(!node.analyzeBuffer(filter))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":filterBrowse, ON?Ӿ??д???δ֪?ı?");
}
node.moveBuffer(0);
JoinNode left = node.getLeft();
JoinNode right = node.getRight();
if(left == null || right == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":filterCheck, ij???????쳣??JOIN ON?Ӿ?");
}
filterCheck(left);
filterCheck(right);
}
}
private void filterBrowse(JoinNode node, String filter, List recycle)
{
if(node == null)
{
node = this.rootNode;
if(!node.analyzeBuffer(filter))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":filterBrowse, WHERE?Ӿ??д???δ֪?ı?");
}
}
if(node instanceof InnerJoin)//where??InnerJoinʱ???????ҽڵ????????´???
{
JoinNode left = node.getLeft();
if(left != null)
{
if(left.analyzeBuffer(filter))//??where?еı?ȫ??????ڵ???
{
filterBrowse(left, filter, recycle);//????????ڵ???????´???
return;
}
}
if(!(node.getRight() instanceof JoinTable))
{
JoinNode right = node.getRight();
if(right != null)
{
if(right.analyzeBuffer(filter))//??where?еı?ȫ?????ҽڵ???
{
filterBrowse(right, filter, recycle);//???????ҽڵ???????´???
return;
}
}
}
String buffer = node.getBuffer();
boolean contains = false;
for(String ident : this.subQueryOfExistsMap.values())
{
if(contains)
{
break;
}
if(buffer.contains(ident))
{
contains = true;
}
}
for(String ident : this.subQueryOfInMap.values())
{
if(contains)
{
break;
}
if(buffer.contains(ident))
{
contains = true;
}
}
for(String ident : this.subQueryOfWhereMap.values())
{
if(contains)
{
break;
}
if(buffer.contains(ident))
{
contains = true;
}
}
if(contains)
{
node.moveBuffer(1); //??????ѯ?ֶεĹ鲢?ڵ?ǰ?ڵ??where??
}
else
{
node.moveBuffer(0); //??????Թ鲢??on??
}
}
else if(node instanceof LeftJoin)//where??LeftJoinʱֻ??????ڵ????????´??ݲ??ܹ鲢?ڵ?ǰ?ڵ??on??
{
JoinNode left = node.getLeft();
if(left != null)
{
if(left.analyzeBuffer(filter))//??where?еı?ȫ??????ڵ???
{
filterBrowse(left, filter, recycle);//????????ڵ???????´???
return;
}
}
node.moveBuffer(1); //????鲢?ڵ?ǰ?ڵ??where??
}
else if(node instanceof JoinTable)//where????λ???DZ??ڵ㲻?ܹ鲢??on????????ǰ????
{
PerfectWhere pw = new PerfectWhere(Tokenizer.parse(filter), this.parameterList);
String topFilter = pw.getTopFromTokens(null, null, ((JoinTable)node).getTableFile(), ((JoinTable)node).getTableNames().iterator().next());
if(topFilter == null)
{
node.moveBuffer(1);//?鲢?ڵ?ǰ?ڵ??where??
}
else
{
((JoinTable)node).setTopFilter(topFilter);
Token[] filterTokens = pw.getTokens(true);
filter = "";
for(Token filterToken : filterTokens)
{
filter += filterToken.getOriginString();
filter += filterToken.getSpaces();
}
node.setBuffer(filter);
node.moveBuffer(1);//?鲢?ڵ?ǰ?ڵ??where??
}
}
String where = node.getBuffer();
if(where != null && !where.isEmpty())
{
recycle.add(where); //????ǰʹ?õ?where????????ȫ????ƴ?????
node.setBuffer(null);
}
}
private void selectBrowse(JoinNode node, String field)
{
if(node == null)
{
node = this.rootNode;
if(!node.analyzeBuffer(field))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":selectBrowse, SELECT?Ӿ??д???δ֪?ı?");
}
}
if(node instanceof JoinTable)
{
node.moveBuffer(-1);
}
else
{
JoinNode left = node.getLeft();
JoinNode right = node.getRight();
if(left == null || right == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":selectBrowse, ij???????쳣??JOIN ON?Ӿ?");
}
if(left.analyzeBuffer(field))
{
selectBrowse(left, field);
}
if(right.analyzeBuffer(field))
{
selectBrowse(right, field);
}
}
}
private Token[] getNewTokens(List tokensList)
{
List tokenList = new ArrayList();
int index = 0;
for(int k = 0, sz = tokensList.size(); k < sz; k++)
{
Token[] tokens = tokensList.get(k);
boolean belongSelect = false;
for(int i = 0, len = tokens.length; i < len; i++)
{
if(tokens[i].isKeyWord("SELECT"))
{
belongSelect = true;
}
else if(tokens[i].isKeyWord("NOT") && i + 3 < len && tokens[i + 1].isKeyWord("EXISTS") && tokens[i + 2].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 2, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 3, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
boolean needDelayed = false;
if(subQueryOfExistsMap.containsKey(checkList.toString()))
{
needDelayed = true;
}
if(needDelayed)
{
if(subQueryOfExistsMap.get(checkList.toString()) == null)
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfExistsEntryList.add(subQueryMap.entrySet().iterator().next());
Token tk = new Token(Tokenizer.IDENT, "$"+uuid, index++, "$"+uuid);
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IS", index++, "IS");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "NULL", index++, "NULL");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
subQueryOfExistsMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfExistsMap.get(checkList.toString());
Token tk = new Token(Tokenizer.IDENT, dollar_uuid, index++, dollar_uuid);
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IS", index++, "IS");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "NULL", index++, "NULL");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
Sequence seq = null;
if(cursor != null)
{
seq = cursor.peek(1);
}
if(seq == null)
{
Token tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.OPERATOR, "=", index++, "=");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
else
{
Token tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.OPERATOR, "=", index++, "=");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.NUMBER, "0", index++, "0");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
i = end;
continue;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":getNewTokens, exists?ؼ??ֺ????????Ӳ?ѯ");
}
}
else if(tokens[i].isKeyWord("EXISTS") && i + 2 < len && tokens[i + 1].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 1, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 2, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
boolean needDelayed = false;
if(subQueryOfExistsMap.containsKey(checkList.toString()))
{
needDelayed = true;
}
if(needDelayed)
{
if(subQueryOfExistsMap.get(checkList.toString()) == null)
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfExistsEntryList.add(subQueryMap.entrySet().iterator().next());
Token tk = new Token(Tokenizer.IDENT, "$"+uuid, index++, "$"+uuid);
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IS", index++, "IS");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "NOT", index++, "NOT");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "NULL", index++, "NULL");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
subQueryOfExistsMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfExistsMap.get(checkList.toString());
Token tk = new Token(Tokenizer.IDENT, dollar_uuid, index++, dollar_uuid);
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IS", index++, "IS");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "NOT", index++, "NOT");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "NULL", index++, "NULL");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
Sequence seq = null;
if(cursor != null)
{
seq = cursor.peek(1);
}
if(seq == null)
{
Token tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.OPERATOR, "=", index++, "=");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.NUMBER, "0", index++, "0");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
else
{
Token tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.OPERATOR, "=", index++, "=");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
i = end;
continue;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":getNewTokens, exists?ؼ??ֺ????????Ӳ?ѯ");
}
}
else if(tokens[i].isKeyWord("NOT") && i + 3 < len && tokens[i + 1].isKeyWord("IN") && tokens[i + 2].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 2, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 3, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
boolean needDelayed = false;
if(subQueryOfInMap.containsKey(checkList.toString()))
{
needDelayed = true;
}
if(needDelayed)
{
if(subQueryOfInMap.get(checkList.toString()) == null)
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfInEntryList.add(subQueryMap.entrySet().iterator().next());
Token tk = new Token(Tokenizer.KEYWORD, "NOT", index++, "NOT");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IN", index++, "IN");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.IDENT, "$"+uuid, index++, "$"+uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
subQueryOfInMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfInMap.get(checkList.toString());
Token tk = new Token(Tokenizer.KEYWORD, "NOT", index++, "NOT");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IN", index++, "IN");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.IDENT, dollar_uuid, index++, dollar_uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
Sequence seq = null;
if(cursor != null)
{
seq = cursor.fetch();
}
if(seq == null || seq.length() == 0)
{
Token tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.OPERATOR, "=", index++, "=");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
else
{
if(!(seq.get(1) instanceof BaseRecord) || seq.dataStruct() == null || seq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":getNewTokens, IN???Ӳ?ѯ????쳣");
}
Token tk = new Token(Tokenizer.KEYWORD, "NOT", index++, "NOT");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.KEYWORD, "IN", index++, "IN");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.LPAREN, "(", index++, "(");
tk.addSpace();
tokenList.add(tk);
for(int p = 1, q = seq.length(); p <= q; p++)
{
if(p > 1)
{
tk = new Token(Tokenizer.COMMA, ",", index++, ",");
tk.addSpace();
tokenList.add(tk);
}
String valStr = getSQLValue(((BaseRecord)seq.get(p)).getFieldValue(0));
Token[] valTokens = Tokenizer.parse(valStr + " ");
tokenList.addAll(Arrays.asList(valTokens));
}
tk = new Token(Tokenizer.RPAREN, ")", index++, ")");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
i = end;
continue;
}
}
else if(tokens[i].isKeyWord("IN") && i + 2 < len && tokens[i + 1].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i + 1, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 2, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
boolean needDelayed = false;
if(subQueryOfInMap.containsKey(checkList.toString()))
{
needDelayed = true;
}
if(needDelayed)
{
if(subQueryOfInMap.get(checkList.toString()) == null)
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
subQueryOfInEntryList.add(subQueryMap.entrySet().iterator().next());
Token tk = new Token(Tokenizer.KEYWORD, "IN", index++, "IN");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.IDENT, "$" + uuid, index++, "$" + uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
subQueryOfInMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = subQueryOfInMap.get(checkList.toString());
Token tk = new Token(Tokenizer.KEYWORD, "IN", index++, "IN");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.IDENT, dollar_uuid, index++, dollar_uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
Sequence seq = null;
if(cursor != null)
{
seq = cursor.fetch();
}
if(seq == null || seq.length() == 0)
{
Token tk = new Token(Tokenizer.NUMBER, "1", index++, "1");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.OPERATOR, "=", index++, "=");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.NUMBER, "0", index++, "0");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
else
{
if(!(seq.get(1) instanceof BaseRecord) || seq.dataStruct() == null || seq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":getNewTokens, IN???Ӳ?ѯ????쳣");
}
Token tk = new Token(Tokenizer.KEYWORD, "IN", index++, "IN");
tk.addSpace();
tokenList.add(tk);
tk = new Token(Tokenizer.LPAREN, "(", index++, "(");
tk.addSpace();
tokenList.add(tk);
for(int p = 1, q = seq.length(); p <= q; p++)
{
if(p > 1)
{
tk = new Token(Tokenizer.COMMA, ",", index++, ",");
tk.addSpace();
tokenList.add(tk);
}
String valStr = getSQLValue(((BaseRecord)seq.get(p)).getFieldValue(0));
Token[] valTokens = Tokenizer.parse(valStr + " ");
tokenList.addAll(Arrays.asList(valTokens));
}
tk = new Token(Tokenizer.RPAREN, ")", index++, ")");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
i = end;
continue;
}
}
else if(tokens[i].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i, len);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, i + 1, end);
boolean isSubQuery = false;
if(Tokenizer.scanKeyWords(new String[]{"SELECT","UNION","INTERSECT","EXCEPT","MINUS"}, subQueryTokens, 0, subQueryTokens.length - 1) != -1)
{
isSubQuery = true;
}
if(isSubQuery)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
boolean needDelayed = false;
if(belongSelect && subQueryOfSelectMap.containsKey(checkList.toString()))
{
needDelayed = true;
}
else if(!belongSelect && subQueryOfWhereMap.containsKey(checkList.toString()))
{
needDelayed = true;
}
if(needDelayed)
{
if(belongSelect)
{
if(subQueryOfSelectMap.get(checkList.toString()) == null)
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
this.subQueryOfSelectEntryList.add(subQueryMap.entrySet().iterator().next());
Token tk = new Token(Tokenizer.IDENT, "$"+uuid, index++, "$"+uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
this.subQueryOfSelectMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = this.subQueryOfSelectMap.get(checkList.toString());
Token tk = new Token(Tokenizer.IDENT, dollar_uuid, index++, dollar_uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
else
{
if(subQueryOfWhereMap.get(checkList.toString()) == null)
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
this.subQueryOfWhereEntryList.add(subQueryMap.entrySet().iterator().next());
Token tk = new Token(Tokenizer.IDENT, "$"+uuid, index++, "$"+uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
this.subQueryOfWhereMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = this.subQueryOfWhereMap.get(checkList.toString());
Token tk = new Token(Tokenizer.IDENT, dollar_uuid, index++, dollar_uuid);
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
}
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(this.isMemory);
Sequence seq = null;
ICursor cursor = lq.query();
if(cursor != null)
{
seq = cursor.fetch(2);
}
if(seq == null || seq.length() != 1 || !(seq.get(1) instanceof BaseRecord) || seq.dataStruct() == null || seq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":getNewTokens, ??SELECT/WHERE?Ӿ????Ӳ?ѯ????쳣");
}
Object val = ((BaseRecord)seq.get(1)).getFieldValue(0);
Token[] valTokens = Tokenizer.parse(getSQLValue(val) + " ");
tokenList.addAll(Arrays.asList(valTokens));
}
i = end;
continue;
}
}
else if(tokens[i].getType() == Tokenizer.IDENT)
{
if(i+1 != len && tokens[i].getString().equalsIgnoreCase("COUNT") && tokens[i+1].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i+1, len);
if(end == i+5)
{
if(tokens[i+2].getType() == Tokenizer.IDENT && tokens[i+3].getType() == Tokenizer.DOT && tokens[i+4].getString().equals("*"))
{
Token tk = new Token(Tokenizer.IDENT, "COUNT", index++, "COUNT");
tk.setSpaces(tokens[i].getSpaces());
tokenList.add(tk);
tk = new Token(Tokenizer.LPAREN, "(", index++, "(");
tk.setSpaces(tokens[i+1].getSpaces());
tokenList.add(tk);
tk = new Token(Tokenizer.IDENT, tokens[i+2].getString() + ".COUNT", index++, tokens[i+2].getOriginString() + ".COUNT");
tk.setSpaces(tokens[i+4].getSpaces());
tokenList.add(tk);
tk = new Token(Tokenizer.RPAREN, ")", index++, ")");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
i = end;
continue;
}
}
}
else if(i + 1 != len && tokens[i+1].getType() == Tokenizer.DOT)
{
if(i + 2 != len)
{
if(tokens[i + 2].getType() == Tokenizer.IDENT && Tokenizer.isGatherFunction(tokens[i+2].getString()) && tokens[i+3].getType() == Tokenizer.LPAREN)
{
if(i + 3 != len)
{
int end = Tokenizer.scanParen(tokens, i+3, len);
if(end == i + 5)
{
Token tk = new Token(Tokenizer.IDENT, tokens[i+2].getString(), index++, tokens[i+2].getOriginString());
tk.setSpaces(tokens[i+2].getSpaces());
tokenList.add(tk);
tk = new Token(Tokenizer.LPAREN, "(", index++, "(");
tk.setSpaces(tokens[i+3].getSpaces());
tokenList.add(tk);
if(tokens[i+2].getString().equalsIgnoreCase("COUNT") && tokens[i+4].getString().equals("*"))
{
tk = new Token(Tokenizer.IDENT, tokens[i].getString() + ".COUNT", index++, tokens[i].getOriginString() + ".COUNT");
tk.setSpaces(tokens[i+4].getSpaces());
tokenList.add(tk);
}
else
{
tk = new Token(Tokenizer.IDENT, tokens[i].getString() + "." + tokens[i+4].getString(), index++, tokens[i].getOriginString() + "." + tokens[i+4].getOriginString());
tk.setSpaces(tokens[i+4].getSpaces());
tokenList.add(tk);
}
tk = new Token(Tokenizer.RPAREN, ")", index++, ")");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
i = end;
continue;
}
else if(end == i+7)
{
if(tokens[i+4].getType() == Tokenizer.IDENT && tokens[i+5].getType() == Tokenizer.DOT)
{
if(!tokens[i].getString().equalsIgnoreCase(tokens[i+4].getString()))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":getNewTokens, ?ۺϺ???????????????ۺ??ֶ???????һ??");
}
else
{
Token tk = new Token(Tokenizer.IDENT, tokens[i+2].getString(), index++, tokens[i+2].getOriginString());
tk.setSpaces(tokens[i+2].getSpaces());
tokenList.add(tk);
tk = new Token(Tokenizer.LPAREN, "(", index++, "(");
tk.setSpaces(tokens[i+3].getSpaces());
tokenList.add(tk);
if(tokens[i+2].getString().equalsIgnoreCase("COUNT") && tokens[i+6].getString().equals("*"))
{
tk = new Token(Tokenizer.IDENT, tokens[i+4].getString() + ".COUNT", index++, tokens[i+4].getOriginString() + ".COUNT");
tk.setSpaces(tokens[i+6].getSpaces());
tokenList.add(tk);
}
else
{
tk = new Token(Tokenizer.IDENT, tokens[i+4].getString() + "." + tokens[i+6].getString(), index++, tokens[i+4].getOriginString() + "." + tokens[i+6].getOriginString());
tk.setSpaces(tokens[i+6].getSpaces());
tokenList.add(tk);
}
tk = new Token(Tokenizer.RPAREN, ")", index++, ")");
tk.setSpaces(tokens[end].getSpaces());
tokenList.add(tk);
i = end;
continue;
}
}
}
}
}
else if(tokens[i+2].getString().equals("*"))
{
String tableName = tokens[i].getString();
DataStruct struct = this.rootNode.getStruct();
if(struct != null)
{
String[] fieldNames = struct.getFieldNames();
if(fieldNames != null)
{
boolean needComma = false;
for(int j=0, l=fieldNames.length; j tokensList = scanFrom(tokens, start, next, hasJoin); //?ж??Ƿ??Ƕ????ѯ??????????????
if(this.singleTable)
{
SimpleSelect sdql = new SimpleSelect(this.ics, this.ctx);
sdql.setMemory(this.isMemory);
if(this.parallelNumber > 1)
{
sdql.setParallel(this.parallelNumber);
}
sdql.setSQLParameters(this.parameterList);
tokens = tokensList.get(0);
for(String name : this.withTableMap.keySet())
{
JoinTable table = this.withTableMap.get(name);
String tableFile = table.getTableFile();
ICursor cursor = table.getCursor();
DataStruct struct = table.getStruct();
if(tableFile != null)
{
for(Token token : tokens)
{
if(token.getType() == Tokenizer.IDENT && token.getString().equalsIgnoreCase(name))
{
if(tableFile.startsWith("\"") && tableFile.endsWith("\"") && tableFile.substring(1, tableFile.length()-1).indexOf("\"") == -1)
{
tableFile = tableFile.substring(1, tableFile.length() - 1);
}
sdql.setTablePath(name, tableFile);
}
}
}
else
{
if(cursor != null)
{
List tmpList = new ArrayList();
for(int i = 0; i < tokens.length; i++)
{
Token token = tokens[i];
if(token.getType() == Tokenizer.IDENT && token.getString().equalsIgnoreCase(name))
{
if(tmpList.get(tmpList.size() - 1).isKeyWord("FROM"))
{
Token tk = new Token(Tokenizer.LPAREN, "(", tmpList.size(), "(");
tk.addSpace();
tmpList.add(tk);
tk = new Token(Tokenizer.PARAMMARK, "?", tmpList.size(), "?");
tk.addSpace();
tmpList.add(tk);
tk = new Token(Tokenizer.RPAREN, ")", tmpList.size(), ")");
tk.addSpace();
tmpList.add(tk);
sdql.setSQLParameters(cursor);
sdql.setSQLParameters(struct);
}
else if(i + 1 < tokens.length && tokens[i + 1].getType() == Tokenizer.DOT)
{
i++;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":query, ?????????ø?ʽ????");
}
}
else
{
Token tk = new Token(token.getType(), token.getString(), tmpList.size(), token.getOriginString());
tk.setSpaces(token.getSpaces());
tmpList.add(tk);
}
}
tokens = new Token[tmpList.size()];
tmpList.toArray(tokens);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":query, ??Ч?ı??ڵ?");
}
}
}
next = tokens.length;
this.icur = sdql.query(tokens, start, next);
this.ds = sdql.getDataStruct();
if(this.ds != null)
{
boolean needRename = false;
String[] names = new String[this.ds.getFieldCount()];
Expression[] exps = new Expression[this.ds.getFieldCount()];
for(int k = 0; k < this.ds.getFieldCount(); k++)
{
String fieldName = this.ds.getFieldName(k);
if(fieldName.startsWith("\"") && fieldName.endsWith("\"") && fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
needRename = true;
}
Token[] fieldTokens = Tokenizer.parse(fieldName);
if(fieldTokens.length == 3 && fieldTokens[0].getType() == Tokenizer.IDENT
&& fieldTokens[1].getType() == Tokenizer.DOT && fieldTokens[2].getType() == Tokenizer.IDENT)
{
fieldName = fieldTokens[2].getOriginString();
if(fieldName.startsWith("\"") && fieldName.endsWith("\"") && fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
needRename = true;
}
}
names[k] = fieldName;
exps[k] = new Expression("#" + (k + 1));
}
if(this.icur != null && needRename)
{
this.icur.addOperation(new New(exps, names, null), this.ctx);
this.ds = new DataStruct(names);
}
}
}
else
{
filterCheck(null); //????on?Ӿ?
if(this.whereList != null)
{
for(String where : this.whereList) //????where?Ӿ?
{
filterBrowse(null, where, this.recycleList);
}
}
scanSelect(tokensList); //?????????Ӿ?
if(this.selectList != null)
{
for(String select:this.selectList) //ȷ??select?Ӿ??漰?????ֶ?
{
selectBrowse(null, select);
}
}
if(this.rootNode != null)
{
//ִ?????зֱ???ƴ??
this.rootNode.executeJoin();
//?????µ?token????,ע??Ҫ??ƴ??֮???Դ?????T.*??????????ʽ
Token[] newTokens = getNewTokens(tokensList);
//ȡԭʼ?α?????ݽṹ
ICursor icursor = this.rootNode.getCursor();
DataStruct struct = this.rootNode.getStruct();
icursor.setDataStruct(struct);
List> newSubQueryOfExistsEntryList = new ArrayList>();
for(Map.Entry subQueryOfExistsEntry : this.subQueryOfExistsEntryList)
{
String ident = subQueryOfExistsEntry.getKey();
boolean contains = false;
for(Token token : newTokens)
{
if(token.getString().equals(ident))
{
contains = true;
break;
}
}
if(contains)
{
newSubQueryOfExistsEntryList.add(subQueryOfExistsEntry);
}
}
this.subQueryOfExistsEntryList = newSubQueryOfExistsEntryList;
List> newSubQueryOfInEntryList = new ArrayList>();
for(Map.Entry subQueryOfInEntry : this.subQueryOfInEntryList)
{
String ident = subQueryOfInEntry.getKey();
boolean contains = false;
for(Token token : newTokens)
{
if(token.getString().equals(ident))
{
contains = true;
break;
}
}
if(contains)
{
newSubQueryOfInEntryList.add(subQueryOfInEntry);
}
}
this.subQueryOfInEntryList = newSubQueryOfInEntryList;
List> newSubQueryOfWhereEntryList = new ArrayList>();
for(Map.Entry subQueryOfWhereEntry : this.subQueryOfWhereEntryList)
{
String ident = subQueryOfWhereEntry.getKey();
boolean contains = false;
for(Token token : newTokens)
{
if(token.getString().equals(ident))
{
contains = true;
break;
}
}
if(contains)
{
newSubQueryOfWhereEntryList.add(subQueryOfWhereEntry);
}
}
this.subQueryOfWhereEntryList = newSubQueryOfWhereEntryList;
if(!this.subQueryOfExistsEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(this.ics, icursor, this.subQueryOfExistsEntryList, this.parameterList, this.rootNode.getTableNames(), SubQueryCursor.Exist_Type, struct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(icursor))
{
struct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
struct = icur.getDataStruct();
}
icursor = icur;
}
if(!this.subQueryOfInEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(this.ics, icursor, this.subQueryOfInEntryList, this.parameterList, this.rootNode.getTableNames(), SubQueryCursor.In_Type, struct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(icursor))
{
struct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
struct = icur.getDataStruct();
}
icursor = icur;
}
if(!this.subQueryOfWhereEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(this.ics, icursor, this.subQueryOfWhereEntryList, this.parameterList, this.rootNode.getTableNames(), SubQueryCursor.Where_Type, struct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(icursor))
{
struct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
struct = icur.getDataStruct();
}
icursor = icur;
}
if(!this.subQueryOfSelectEntryList.isEmpty())
{
ICursor icur = fillSubQueryField(this.ics, icursor, this.subQueryOfSelectEntryList, this.parameterList, this.rootNode.getTableNames(), SubQueryCursor.Select_Type, struct);
if(icur != null && icur instanceof SubQueryCursor && !icur.equals(icursor))
{
struct = ((SubQueryCursor)icur).getTableDataStruct();
}
else if(icur != null)
{
struct = icur.getDataStruct();
}
icursor = icur;
}
//??ѯ????ѡ????
SimpleSelect sdql = new SimpleSelect(this.ics, this.ctx);
sdql.setMemory(this.isMemory);
if(this.parallelNumber > 1)
{
sdql.setParallel(this.parallelNumber);
}
sdql.setSQLParameters(icursor);
sdql.setSQLParameters(struct);
sdql.setSQLParameters(this.parameterList);
this.icur = sdql.query(newTokens, 0, newTokens.length);
this.ds = sdql.getDataStruct();
}
}
if(!this.intoFileName.isEmpty())
{
ArrayList intoFiles = new ArrayList();
this.intoFileName = this.intoFileName.trim();
if (intoFileName.indexOf("${")>=0){
int lastdot = intoFileName.lastIndexOf(".");
if (lastdot == -1) {
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":query, ????ʶinto?ļ?????");
}
String ext = intoFileName.substring(lastdot);
intoFileName = Expression.replaceMacros(intoFileName.substring(0,lastdot), null, ctx);
String[] fs = intoFileName.split(",");
for (int i=0; i tableMap)
{
if(tableMap == null)
{
return;
}
for(Map.Entry entry : tableMap.entrySet())
{
String tableName = entry.getKey();
Object tableObject = entry.getValue();
JoinTable tableNode = null;
if(tableObject instanceof String) //????֧?ֱ??ļ?·??
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":setWithTableMap, WITH?Ӿ???ֻ??ʹ?ü??????ű????Ӳ?ѯ???");
}
else if(tableObject instanceof Expression)
{
Object obj = ((Expression)tableObject).calculate(this.ctx);
if(obj instanceof ICursor)
{
ICursor cursor = (ICursor)obj;
DataStruct struct = cursor.getDataStruct();
if(struct == null)
{
Sequence sq = cursor.peek(1);
if(sq != null)
{
struct = sq.dataStruct();
}
//cursor.reset();
}
tableNode = new JoinTable(cursor, struct);
}
else if(obj instanceof Table)
{
ICursor cursor = new MemoryCursor((Table)obj);
DataStruct struct = ((Table)obj).dataStruct();
tableNode = new JoinTable(cursor, struct);
}
else if(obj instanceof PhyTable)
{
tableNode = new JoinTable((PhyTable)obj);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":setWithTableMap, ??֧?ֵ???ʱ??????????");
}
}
else if(tableObject instanceof SimpleSQL)
{
((SimpleSQL)tableObject).setMemory(this.isMemory);
ICursor icur = ((SimpleSQL)tableObject).query();
DataStruct ds = ((SimpleSQL)tableObject).getDataStruct();
tableNode = new JoinTable(icur, ds);
}
tableNode.addTableName(tableName);
this.withTableMap.put(tableName.toLowerCase(), tableNode);
}
}
private Token[] optimizeWhere(Token[] whereTokens, List paramList)
{
PerfectWhere pw = new PerfectWhere(whereTokens, paramList);
return pw.getTokens(true);
}
private String getSQLValue(Object value)
{
if(value == null)
{
return "null";
}
else if(value instanceof String)
{
return "'" + value + "'";
}
else if(value instanceof Boolean)
{
return value.toString();
}
else if(value instanceof Number)
{
return value.toString();
}
else if(value instanceof java.sql.Date)
{
return String.format("date(\"%s\",\"yyyy-MM-dd\")", new SimpleDateFormat("yyyy-MM-dd").format((java.sql.Date)value));
}
else if(value instanceof java.sql.Time)
{
return String.format("time(\"%s\",\"HH:mm:ss.SSS\")", new SimpleDateFormat("HH:mm:ss.SSS").format((java.sql.Time)value));
}
else if(value instanceof java.sql.Timestamp)
{
return String.format("timestamp(\"%s\",\"yyyy-MM-dd HH:mm:ss.SSS\")", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format((java.sql.Timestamp)value));
}
else if(value instanceof Date)
{
return String.format("timestamp(\"%s\",\"yyyy-MM-dd HH:mm:ss.SSS\")", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format((Date)value));
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":getSQLValue, ??֧?ֵ?????????");
}
}
private ICursor fillSubQueryField(ICellSet ics, ICursor icur, List> subQueryEntryList, List paramList, Set tableNames, int type, DataStruct ds)
{
if(icur == null)
{
return null;
}
if(ds == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, ??ѯ???????ȱ?????ݽṹ");
}
if(subQueryEntryList.isEmpty())
{
icur.setDataStruct(ds);
return icur;
}
String[] fieldNames = ds.getFieldNames();
List>> subQueryListListList = new ArrayList>>();
List> fieldNameListList = new ArrayList>();
List colNameList = new ArrayList();
for(Map.Entry subQueryEntry : subQueryEntryList)
{
Token[] subQueryTokens = subQueryEntry.getValue();
boolean canUseJoin = false;
if(type != SubQueryCursor.In_Type)
{
int fromPos = Tokenizer.scanKeyWord("FROM", subQueryTokens, 0, subQueryTokens.length);
if(fromPos <= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, FROM?ؼ???ȱʧ");
}
int wherePos = Tokenizer.scanKeyWord("WHERE", subQueryTokens, 0, subQueryTokens.length);
if(wherePos >= 0 && wherePos < fromPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, WHERE?ؼ??ֵ?λ?ò???ȷ");
}
if(wherePos < 0)
{
break;
}
int minPos = wherePos;
int groupPos = Tokenizer.scanKeyWord("GROUP", subQueryTokens, 0, subQueryTokens.length);
if(groupPos >= 0 && groupPos < wherePos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, GROUP?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(groupPos, minPos);
int havingPos = Tokenizer.scanKeyWord("HAVING", subQueryTokens, 0, subQueryTokens.length);
if(havingPos >= 0 && havingPos < groupPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, HAVING?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(havingPos, minPos);
int orderPos = Tokenizer.scanKeyWord("ORDER", subQueryTokens, 0, subQueryTokens.length);
if(orderPos >= 0 && orderPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, ORDER?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(orderPos , minPos);
int limitPos = Tokenizer.scanKeyWord("LIMIT", subQueryTokens, 0, subQueryTokens.length);
if(limitPos >= 0 && limitPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, LIMIT?ؼ??ֵ?λ?ò???ȷ");
}
minPos = pos(limitPos , minPos);
int offsetPos = Tokenizer.scanKeyWord("OFFSET", subQueryTokens, 0, subQueryTokens.length);
if(offsetPos >= 0 && offsetPos < minPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, OFFSET?ؼ??ֵ?λ?ò???ȷ");
}
int byStart = pos(groupPos, wherePos, fromPos);
int byEnd = pos(havingPos, orderPos, limitPos, offsetPos, subQueryTokens.length);
int byPos = Tokenizer.scanKeyWord("BY", subQueryTokens, byStart, byEnd);
if(byPos < 0 && groupPos > 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, ?ؼ???GROUP????ȱ?ٹؼ???BY");
}
else if(havingPos > 0 && byPos > havingPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, ????ؼ???BYλ??Ӧ????HAVING֮ǰ");
}
int whereEnd = pos(groupPos, byPos, havingPos, orderPos, limitPos, offsetPos, subQueryTokens.length);
int intoPos = Tokenizer.scanKeyWord("INTO", subQueryTokens, 0, subQueryTokens.length);
if(intoPos >= fromPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, INTO?ؼ??ֵ?λ?ò???ȷ");
}
int columnEnd = pos(intoPos, fromPos);
int selectPos = Tokenizer.scanKeyWord("SELECT", subQueryTokens, 0, subQueryTokens.length);
if(selectPos < 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, SELECT?ؼ???ȱʧ");
}
int columnStart = selectPos;
int distinctPos = Tokenizer.scanKeyWord("DISTINCT", subQueryTokens, 0, subQueryTokens.length);
if(distinctPos >= 0 && distinctPos < selectPos)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, DISTINCT?ؼ??ֵ?λ?ò???ȷ");
}
columnStart = pos(distinctPos, columnStart);
int topPos = Tokenizer.scanKeyWord("TOP", subQueryTokens, 0, subQueryTokens.length);
if(topPos >= 0 && topPos < columnStart)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, TOP?ؼ??ֵ?λ?ò???ȷ");
}
columnStart = pos(topPos, columnStart);
if(columnStart == topPos)
{
columnStart += 2;
}
else
{
columnStart++;
}
Token[] whereTokens = Arrays.copyOfRange(subQueryTokens, wherePos + 1, whereEnd);
PerfectWhere pw = new PerfectWhere(whereTokens, this.parameterList);
Set outerFieldSet = new LinkedHashSet();
Set innerFieldSet = new LinkedHashSet();
Token[] newOnTokens = pw.getOnFromTokens(tableNames, outerFieldSet, innerFieldSet);
if(newOnTokens != null && newOnTokens.length != 0)
{
canUseJoin = true;
}
if(canUseJoin)
{
whereTokens = pw.getTokens(true);
Token[] columnTokens = Arrays.copyOfRange(subQueryTokens, columnStart, columnEnd);
if(type == SubQueryCursor.Select_Type)
{
if(Tokenizer.scanComma(columnTokens, 0, columnTokens.length) != -1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":fillSubQueryField, ?Ӳ?ѯ??SELECT?ֶα??뵥??");
}
if(columnTokens[columnTokens.length - 1].getSpaces().isEmpty())
{
columnTokens[columnTokens.length - 1].addSpace();
}
}
else if(type == SubQueryCursor.Exist_Type)
{
Token columnToken = new Token(Tokenizer.NUMBER, "1", -1, "1");
columnToken.addSpace();
columnTokens = new Token[]{columnToken};
}
String aliasName = subQueryEntry.getKey();
Token aliasToken = new Token(Tokenizer.IDENT, aliasName, -1, aliasName);
aliasToken.addSpace();
String columnStr = "";
for(Token columnToken : columnTokens)
{
columnStr += columnToken.getOriginString();
columnStr += columnToken.getSpaces();
}
columnStr = columnStr.trim().toLowerCase();
List innerFieldList = new ArrayList();
int index = 2;
Map fn2cnMap = new LinkedHashMap();
for(String innerField : innerFieldSet)
{
if(!innerField.equals(columnStr))
{
innerFieldList.add(innerField);
fn2cnMap.put(innerField, "#"+index);
index++;
}
else
{
fn2cnMap.put(innerField, "#1");
}
}
List newTokenList = new ArrayList();
newTokenList.addAll(Arrays.asList(Arrays.copyOfRange(subQueryTokens, 0, columnStart)));
newTokenList.addAll(Arrays.asList(columnTokens));
newTokenList.add(aliasToken);
index = 2;
for(String innerField : innerFieldList)
{
Token commaToken = new Token(Tokenizer.COMMA, ",", -1, ",");
commaToken.addSpace();
newTokenList.add(commaToken);
newTokenList.addAll(Arrays.asList(Tokenizer.parse(innerField + " " + "_" + index + " ")));
index++;
}
newTokenList.addAll(Arrays.asList(Arrays.copyOfRange(subQueryTokens, columnEnd, wherePos + 1)));
newTokenList.addAll(Arrays.asList(whereTokens));
newTokenList.addAll(Arrays.asList(Arrays.copyOfRange(subQueryTokens, whereEnd, subQueryTokens.length)));
Token[] newTokens = new Token[newTokenList.size()];
newTokenList.toArray(newTokens);
SimpleSQL lq = new SimpleSQL(this.ics, newTokens, 0, newTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
Object obj = lq.execute();
Sequence subSeq = obj instanceof ICursor ? ((ICursor)obj).fetch() : (obj instanceof Sequence ? (Sequence)obj : null);
String onFilter = "";
for(Token newOnToken : newOnTokens)
{
onFilter += newOnToken.getOriginString();
onFilter += newOnToken.getSpaces();
}
List outerExpsList = new ArrayList();
List innerExpsList = new ArrayList();
for(String outerField : outerFieldSet)
{
for(int k = 0, len = fieldNames.length; k < len; k++)
{
String fieldName = fieldNames[k];
if(fieldName.equalsIgnoreCase("\"" + outerField + "\"") || fieldName.equalsIgnoreCase(outerField))
{
fn2cnMap.put(outerField, "#" + (k + 1));
}
}
}
String[] subFilters = onFilter.split("AND");
for(String subFilter : subFilters)
{
String[] fltExps = subFilter.split("=");
if(fltExps.length != 2)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+":fillSubQueryField, ??ֵ????????ʽ?????");
}
if(outerFieldSet.contains(fltExps[0].trim().toLowerCase())) //?ⲿ?ֶ?
{
String numberCode = ExpressionTranslator.translateExp(fltExps[0].toLowerCase(), fn2cnMap);
outerExpsList.add(new Expression(numberCode));
}
else if(innerFieldSet.contains(fltExps[0].trim().toLowerCase())) //?ڲ??ֶ?
{
String numberCode = ExpressionTranslator.translateExp(fltExps[0].toLowerCase(), fn2cnMap);
innerExpsList.add(new Expression(numberCode));
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+":fillSubQueryField, δ֪???ֶ?");
}
if(outerFieldSet.contains(fltExps[1].trim().toLowerCase())) //?ⲿ?ֶ?
{
String numberCode = ExpressionTranslator.translateExp(fltExps[1].toLowerCase(), fn2cnMap);
outerExpsList.add(new Expression(numberCode));
}
else if(innerFieldSet.contains(fltExps[1].trim().toLowerCase())) //?ڲ??ֶ?
{
String numberCode = ExpressionTranslator.translateExp(fltExps[1].toLowerCase(), fn2cnMap);
innerExpsList.add(new Expression(numberCode));
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error")+":fillSubQueryField, δ֪???ֶ?");
}
}
Expression[] outerExps = new Expression[outerExpsList.size()];
outerExpsList.toArray(outerExps);
Expression[] innerExps = new Expression[innerExpsList.size()];
innerExpsList.toArray(innerExps);
String opt = "";
if(icur instanceof MemoryCursor)
{
Sequence res = new Join(null, new Expression[][]{outerExps}, new Sequence[]{subSeq}, new Expression[][]{innerExps}, new Expression[][]{new Expression[]{new Expression("#1")}}, new String[][]{new String[]{aliasName}}, opt).process(icur.fetch(), this.ctx);
icur = new MemoryCursor(res);
}
else
{
icur.addOperation(new Join(null, new Expression[][]{outerExps}, new Sequence[]{subSeq}, new Expression[][]{innerExps}, new Expression[][]{new Expression[]{new Expression("#1")}}, new String[][]{new String[]{aliasName}}, opt), this.ctx);
}
String[] newFieldNames = new String[ds.getFieldCount() + 1];
System.arraycopy(ds.getFieldNames(), 0, newFieldNames, 0, ds.getFieldCount());
newFieldNames[ds.getFieldCount()] = aliasName;
icur.setDataStruct(new DataStruct(newFieldNames));
}
}
if(!canUseJoin)
{
List> subQueryListList = new ArrayList>();
List fieldNameList = new ArrayList