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.SimpleSelect 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.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
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.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import com.scudata.cellset.ICellSet;
import com.scudata.common.MessageManager;
import com.scudata.common.RQException;
import com.scudata.common.UUID;
import com.scudata.dm.BFileWriter;
import com.scudata.dm.BaseRecord;
import com.scudata.dm.ComputeStack;
import com.scudata.dm.Context;
import com.scudata.dm.DataStruct;
import com.scudata.dm.Env;
import com.scudata.dm.FileObject;
import com.scudata.dm.Param;
import com.scudata.dm.Record;
import com.scudata.dm.Sequence;
import com.scudata.dm.Table;
import com.scudata.dm.cursor.BFileCursor;
import com.scudata.dm.cursor.ConjxCursor;
import com.scudata.dm.cursor.FileCursor;
import com.scudata.dm.cursor.ICursor;
import com.scudata.dm.cursor.MemoryCursor;
import com.scudata.dm.cursor.MultipathCursors;
import com.scudata.dm.cursor.SubCursor;
import com.scudata.dm.cursor.SyncCursor;
import com.scudata.dm.op.Derive;
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.SimpleSelect.ParamNode;
import com.scudata.dm.query.utils.ExpressionTranslator;
import com.scudata.dm.query.utils.FileUtil;
import com.scudata.dm.sql.FunInfoManager;
import com.scudata.dw.ComTable;
import com.scudata.dw.PhyTable;
import com.scudata.excel.ExcelTool;
import com.scudata.expression.Expression;
import com.scudata.resources.ParseMessage;
import com.scudata.util.CursorUtil;
import com.scudata.util.EnvUtil;
import com.scudata.util.JSONUtil;
public class SimpleSelect
{
private boolean hasDistinct;
private int topNumber;
private int limitNumber;
private int offsetNumber;
private int parallelNumber;
private String distinctGatherField;
private Map levelMap;
private List finalList;
private List aliasList;
private List columnList;
private List groupList;
private List sortList;
private TableNode tableNode;
private ExpressionNode havingNode;
private ExpressionNode whereNode;
private List selectFieldList;
private List gatherNodeList;
private List parameterList;
private ICursor icur;
private DataStruct ds;
private int columnIndex;
private Context ctx;
private Map tablePathMap;
private ICellSet ics;
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 String password;
private boolean isMemory;
private PhyTable tmd;
private String topFilter;
private Sequence fromSeq; //20240731 xingjl
abstract class Node
{
abstract public boolean hasGather();
abstract public boolean hasField(Boolean isOrder); //????group by??order by?Ӿ??ж??Ƿ?????ֶΣ??ۺϺ?????һ?㺯?????
abstract public boolean hasField(String fieldName); //????select?Ӿ??ж??Ƿ????ij?ֶΣ??ۺϺ???????????һ?㺯??
abstract public boolean hasFieldNotGroup();
abstract public void optimize();
abstract public void collect();
abstract public String toExpression();
abstract public void setFromHaving();
abstract public void setFromWhere();
}
class TableNode extends Node
{
final public static int TYPE_ICR = -1;
final public static int TYPE_BIN = 0;
final public static int TYPE_TXT = 1;
final public static int TYPE_CSV = 2;
final public static int TYPE_XLS = 3;
final public static int TYPE_XLSX = 4;
final public static int TYPE_GTB = 5;
final public static int TYPE_JSON = 6;
private String name;
private String alias;
private FileObject file;
private ArrayList files = new ArrayList();
public ArrayList getFiles() {
return files;
}
public void setFiles(ArrayList files) {
this.files = files;
if (this.files == null || this.files.size()==0 && this.file != null) {
files = new ArrayList();
files.add(file);
}
}
private PhyTable meta;
private ArrayList metas;
private int type;
private ICursor cursor;
private DataStruct struct;
private String[] fields;
private Expression where;
private boolean fileAttrQuery=false;
public boolean isFileAttrQuery() {
return fileAttrQuery;
}
public void setFileAttrQuery(boolean fileAttrQuery) {
this.fileAttrQuery = fileAttrQuery;
}
public TableNode(String tableName, String aliasName, FileObject fileObject, int type)
{
if(tableName != null)
{
this.name = tableName;
}
if(aliasName != null)
{
if(aliasName.startsWith("\"") && aliasName.endsWith("\"") && aliasName.substring(1, aliasName.length() - 1).indexOf("\"") == -1)
{
aliasName = aliasName.substring(1, aliasName.length() - 1);
}
this.alias = aliasName;
}
if(fileObject == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":TableNode.TableNode, ?ļ???????Ϊ??ֵ");
}
if(type == TableNode.TYPE_ICR)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":TableNode.TableNode, ???ļ??????쳣");
}
else
{
this.cursor = null;
this.struct = null;
this.file = fileObject;
this.meta = null;
this.type = type;
this.fields = null;
this.where = null;
}
}
public TableNode(String tableName, String aliasName, ICursor cs, DataStruct ds)
{
if(tableName != null)
{
this.name = tableName;
}
if(aliasName != null)
{
if(aliasName.startsWith("\"") && aliasName.endsWith("\"") && aliasName.substring(1, aliasName.length() - 1).indexOf("\"") == -1)
{
aliasName = aliasName.substring(1, aliasName.length() - 1);
}
this.alias = aliasName;
}
this.cursor = cs;
this.struct = ds;
this.file = null;
this.meta = null;
this.type = TableNode.TYPE_ICR;
this.fields = null;
}
public TableNode(String tableName, String aliasName, PhyTable meta)
{
if(tableName != null)
{
this.name = tableName;
}
if(aliasName != null)
{
if(aliasName.startsWith("\"") && aliasName.endsWith("\"") && aliasName.substring(1, aliasName.length() - 1).indexOf("\"") == -1)
{
aliasName = aliasName.substring(1, aliasName.length() - 1);
}
this.alias = aliasName;
}
this.cursor = null;
this.struct = null;
this.file = null;
this.meta = meta;
this.type = TableNode.TYPE_GTB;
this.fields = null;
}
public String getName()
{
if(this.name == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":TableNode.getName, ??Ч?ı??ڵ?");
}
return this.name;
}
public String getAlias()
{
if(this.alias == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":TableNode.getAlias, ??Ч?ı??ڵ?");
}
return this.alias;
}
public int getType()
{
return this.type;
}
public void setWhere(String whereExp) // ???ר????ǰ????
{
if(whereExp != null && !whereExp.isEmpty())
{
this.where = new Expression(whereExp);
}
}
private String[] getDataField() {
if (this.fields == null || this.fields.length == 0) return this.fields;
String n = "";
for (int i=0; i0) return n.substring(1).split(",");
else return new String[0];
}
private String[] getFileField() {
if (this.fields == null || this.fields.length == 0) return this.fields;
String n = "";
for (int i=0; i0) return n.substring(1).split(",");
else return new String[0];
}
public ICursor getCursor()
{
ICursor icursor = null;
if(this.file != null || this.meta != null)
{
if (this.fileAttrQuery) {
//return new FileCursor(new FileObject("d:/test/fileAttr.txt"), 1, 1, this.fields, null, null, "t", ctx);
}
if(this.type == TableNode.TYPE_GTB) // ????ļ?
{
ICursor []cursors2 = new ICursor[this.files.size()];
metas = new ArrayList();
for (int z=0; z 1)
{
ICursor []cursors = new ICursor[parallelNumber];
for (int i = 0; i < parallelNumber; ++i)
{
cursors[i] = new SyncCursor(icursor);
}
cursors2[z] = new MultipathCursors(cursors, ctx);
}
}
else
{
if(parallelNumber == 1)
{
cursors2[z] = meta.cursor(this.fields, this.where, ctx);
}
else if(parallelNumber > 1)
{
ICursor []cursors = new ICursor[parallelNumber];
for (int i = 0; i < parallelNumber; ++i)
{
cursors[i] = meta.cursor(null, fields, where, null, null, null, i+1, parallelNumber, null, ctx);
}
cursors2[z] = new MultipathCursors(cursors, ctx);
}
}
}
if (this.files.size() == 1) icursor = cursors2[0];
else icursor = new ConjxCursor(cursors2);
}
else if(this.type == TableNode.TYPE_BIN) // ???ļ?
{
ICursor []cursors2 = new ICursor[this.files.size()];
for (int z=0; z0) {
Expression[] exps2 = new Expression[this.fields.length];
for (int p=0; p0) {
Expression[] exps2 = new Expression[this.fields.length];
for (int z=0; z list;
public ExpressionNode(ArrayList nodeList)
{
this.list = nodeList;
}
public ArrayList getNodeList()
{
if(this.list == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":ExpressionNode.getNodeList, ??Ч?ı???ʽ?ڵ?");
}
return this.list;
}
public boolean hasGather()
{
if(this.list == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":ExpressionNode.hasGather, ??Ч?ı???ʽ?ڵ?");
}
for(int i=0,z=this.list.size();i= 2)
{
sb.append(",");
}
sb.append(getProcValue(seq.get(i)));
}
sb.append("]");
sb.append(".pos@b(");
sb.append("$?");
sb.append(")");
if(this.not)
{
sb.append("==");
}
else
{
sb.append("!=");
}
sb.append("null");
sb.append(")");
}
//???coalesce?????ľֲ??Ż?
String expStr = sb.toString();
if(this.node.getNodeList().size() == 1
&& this.node.getNodeList().get(0) instanceof FunctionNode
&& ((FunctionNode)this.node.getNodeList().get(0)).getName().equalsIgnoreCase("coalesce"))
{
FunctionNode coalesce = (FunctionNode) this.node.getNodeList().get(0);
String[] paramsStr = getParams(coalesce.getParamNode().toExpression());
if(paramsStr.length == 2)
{
String tmpExpStr = expStr.replace("$?", paramsStr[1]);
Expression tmpExp = new Expression(tmpExpStr);
try
{
Object objVal = tmpExp.calculate(ctx);
if(objVal != null && objVal.equals(false))
{
expression = paramsStr[0];
}
}
catch(Exception ex)
{
throw new RQException(ex.getMessage(), ex);
}
}
}
//?Ż?????
expStr = expStr.replace("$?", expression);
return expStr;
}
}
else //??ͨ????ʽ??IN?Ӿ䣬??????ѯ?ֶε??Ӳ?ѯ??IN?Ӿ?
{
String paramStr = this.param.toExpression().trim();
//??join??????Ӳ?ѯ?ֶ???Ϊ?Ǻ????ӵ?
//??????ѡ???ֶιʲ???Ҫȥ????????
if(subQueryOfInMap.containsValue(paramStr))
{
//???ַ??????????ʺϣ???Ϊ??Ҫ??????ֵ????
//????????ѯ?ֶ?ֵ??ͬ??????ֵ??ΧҲ??仯
//??ÿ?????ݶ???Ҫ?????????????????˷?ʱ??
StringBuffer sb = new StringBuffer();
if(this.not)
{
sb.append("!");
}
sb.append(paramStr);
sb.append(".contain(");
sb.append(expression);
sb.append(")");
//???coalesce?????ľֲ??Ż?????Ҳ????ʹ??
//??Ϊ??????ѯ?ֶ?ֵ??ͬ???ط?ΧҲ??仯
//?ʲ???ȷ??coalesce?ڶ????????Ƿ???
String expStr = sb.toString();
return expStr;
}
else if(paramStr.startsWith("(") && paramStr.endsWith(")"))
{
//????ʱΪ????????Ӳ?ѯ???̶????һ????????Ҫ?ڴ?ȥ??,
//ͬʱ??Ҳ??Ϊ????????ѯ?ֶε??Ӳ?ѯ?ı?ʶ???ı?־
paramStr = paramStr.substring(1, paramStr.length()-1);
StringBuffer sb = new StringBuffer();
String[] params = paramStr.split(",");
if(params.length <= 2)
{
sb.append("(");
for(int pi = 0, pl = params.length; pi < pl; pi++)
{
sb.append(params[pi].trim());
if(this.not)
{
sb.append("!=");
}
else
{
sb.append("==");
}
sb.append("(");
sb.append("$?");
sb.append(")");
if(pi != pl - 1)
{
if(this.not)
{
sb.append("&&");
}
else
{
sb.append("||");
}
}
}
sb.append(")");
}
else
{
String[] values = getParams(paramStr);
Map valueMap = new LinkedHashMap();
Sequence seq = new Sequence();
for(String value : values)
{
Object obj = new Expression(value).calculate(ctx);
valueMap.put(obj, value);
seq.add(obj);
}
seq.sort("o");//???ö??ַ???????????????
StringBuffer tmp = new StringBuffer();
for(int i = 1; i <= seq.length(); i++)
{
if(i > 1)
{
tmp.append(",");
}
tmp.append(valueMap.get(seq.get(i)));
}
sb.append("(");
sb.append("[");
sb.append(tmp.toString());
sb.append("]");
sb.append(".pos@b(");
sb.append("$?");
sb.append(")");
if(this.not)
{
sb.append("==");
}
else
{
sb.append("!=");
}
sb.append("null");
sb.append(")");
}
//???coalesce?????ľֲ??Ż?
String expStr = sb.toString();
if(this.node.getNodeList().size() == 1
&& this.node.getNodeList().get(0) instanceof FunctionNode
&& ((FunctionNode)this.node.getNodeList().get(0)).getName().equalsIgnoreCase("coalesce"))
{
FunctionNode coalesce = (FunctionNode) this.node.getNodeList().get(0);
String[] paramsStr = getParams(coalesce.getParamNode().toExpression());
if(paramsStr.length == 2)
{
String tmpExpStr = expStr.replace("$?", paramsStr[1]);
Expression tmpExp = new Expression(tmpExpStr);
try
{
Object objVal = tmpExp.calculate(ctx);
if(objVal != null && objVal.equals(false))
{
expression = paramsStr[0];
}
}
catch(Exception ex)
{
throw new RQException(ex.getMessage(), ex);
}
}
}
//?Ż?????
expStr = expStr.replace("$?", expression);
return expStr;
}
else
{
//??join????scanExp????whereʱ?????˴?
//??????Ӳ?ѯ?ֶ???Ϊ?Ѿ?????????????ѡ???ֶ?
if(paramStr.startsWith("'$") && paramStr.endsWith("'"))
{
//???ַ??????????ʺϣ???Ϊ??Ҫ??????ֵ????
//????????ѯ?ֶ?ֵ??ͬ??????ֵ??ΧҲ??仯
//??ÿ?????ݶ???Ҫ?????????????????˷?ʱ??
StringBuffer sb = new StringBuffer();
if(this.not)
{
sb.append("!");
}
sb.append(paramStr);
sb.append(".contain(");
sb.append(expression);
sb.append(")");
//???coalesce?????ľֲ??Ż?????Ҳ????ʹ??
//??Ϊ??????ѯ?ֶ?ֵ??ͬ???ط?ΧҲ??仯
//?ʲ???ȷ??coalesce?ڶ????????Ƿ???
String expStr = sb.toString();
return expStr;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":InNode.toExpression, ??ʶ???IN?Ӿ?");
}
}
}
}
public boolean hasGather() //???ᱻselect??????
{
return false;
}
public boolean hasFieldNotGroup() //???ᱻselect??????
{
return false;
}
public void setFromHaving()
{
this.isFromHaving = true;
}
public void setFromWhere()
{
this.isFromWhere = true;
}
public void collect()
{
if(this.node == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":InNode.collect, ??Ч??In?ڵ?");
}
this.node.collect();
}
public boolean hasField(Boolean isOrder)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":InNode.hasField, In?Ӿ䲻?????ڷ????ֶ?");
}
public boolean hasField(String fieldName)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":InNode.hasField, In?Ӿ䲻?????ڲ?ѯ?ֶ?");
}
}
class LikeNode extends Node
{
private ExpressionNode node;
// private String pattern;
private boolean not;
private boolean isFromHaving;
private boolean isFromWhere;
private Token token;
private SimpleSelect select;
public LikeNode(ExpressionNode expNode, Token token, boolean hasNot, SimpleSelect select)
{
this.node = expNode;
//this.pattern = pattern;
this.not = hasNot;
this.token = token;
this.select = select;
}
public String getPattern()
{
if(this.token == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":LikeNode.getPattern, ??Ч??Like?ڵ?");
}
return this.token.getString();
}
public boolean getNot()
{
return this.not;
}
public void optimize()
{
if(this.node == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":LikeNode.optimize, ??Ч??Like?ڵ?");
}
this.node.optimize();
}
public String toExpression()
{
if(this.node == null || this.token == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":LikeNode.toExpression, ??Ч??Like?ڵ?");
}
//
String tt = this.token.toString();
if (tt.indexOf("'") == 0 && tt.lastIndexOf("'") == tt.length() - 1) tt = tt.substring(1,tt.length()-1);
String pattern = "\""+tt+"\"";
if (token.getType() == Tokenizer.PARAMMARK) {
ParamNode paramNode = new ParamNode();
String strIndex = token.getString().substring(1);
if(strIndex.length() != 0)
{
int paramIndex = Integer.parseInt(strIndex);
paramNode.setIndex(paramIndex);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ռλ??????????");
}
pattern = paramNode.toExpression();
}
pattern = pattern.replace("\\", "\\\\");
pattern = pattern.replace("*", "\\\\*");
pattern = pattern.replace("?", "\\\\?");
pattern = pattern.replace("[_]", "" + (char)18 + (char)19);
pattern = pattern.replace("_", "?");
pattern = pattern.replace("" + (char)18 + (char)19, "_");
pattern = pattern.replace("[%]", "" + (char)18 + (char)19);
pattern = pattern.replace("%", "*");
pattern = pattern.replace("" + (char)18 + (char)19, "%");
pattern = pattern.replace("[[]", "[");
return "like@c(" + this.node.toExpression() +"," + pattern + ")";
}
public boolean hasGather() //???ᱻselect??????
{
return false;
}
public boolean hasFieldNotGroup() //???ᱻselect??????
{
return false;
}
public void setFromHaving()
{
this.isFromHaving = true;
}
public void setFromWhere()
{
this.isFromWhere = true;
}
public void collect()
{
if(this.node == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":LikeNode.collect, ??Ч??Like?ڵ?");
}
this.node.collect();
}
public boolean hasField(Boolean isOrder)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":LikeNode.hasField, Like?Ӿ䲻?????ڷ????ֶ?");
}
public boolean hasField(String fieldName)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":LikeNode.hasField, Like?Ӿ䲻?????ڲ?ѯ?ֶ?");
}
}
class CaseNode extends Node
{
private List list;
public CaseNode(List nodeList)
{
this.list = nodeList;
}
public List getNodeList()
{
if(this.list == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":CaseNode.getNodeList, ??Ч??Case?ڵ?");
}
return this.list;
}
public void optimize()
{
if(this.list == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":CaseNode.optimize, ??Ч??Case?ڵ?");
}
for(int i = 0, z = this.list.size(); i < z; i++)
{
Node node = this.list.get(i);
if(node != null)
{
node.optimize();
}
}
}
public String toExpression()
{
StringBuffer buf = new StringBuffer(this.list.get(0).toExpression());
int sz = this.list.size();
if(this.list.size() % 2 == 0)
{
sz = sz - 1;
}
for(int i = 1; i < sz; i += 2)
{
buf.append(",");
buf.append(String.format("%s:%s", this.list.get(i).toExpression(), this.list.get(i + 1).toExpression()));
}
if(this.list.size() % 2 == 0)
{
buf.append(";");
buf.append(this.list.get(this.list.size() - 1).toExpression());
}
return String.format("case(%s)", buf.toString());
}
public boolean hasGather()
{
if(this.list == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":CaseNode.hasGather, ??Ч?ı???ʽ?ڵ?");
}
for(int i=0,z=this.list.size();i 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.length() == 0 ||!(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;
}
public DataStruct getDataStruct()
{
return this.ds;
}
public void setDataStruct(DataStruct ds)
{
this.ds = ds;
}
public DataStruct getTableDataStruct()
{
return this.tabDs;
}
}
public SimpleSelect(ICellSet ics, Context ctx)
{
this.icur = null;
this.ds = null;
this.ctx = ctx;
this.ics = ics;;
init();
}
private void init()
{
this.hasDistinct = false;
this.topNumber = -1;
this.limitNumber = -1;
this.offsetNumber = -1;
this.parallelNumber = 1;
this.distinctGatherField = null; // must be null when init
this.levelMap = new LinkedHashMap();
this.finalList = new ArrayList();
this.aliasList = new ArrayList();
this.columnList = new ArrayList();
this.groupList = new ArrayList();
this.sortList = new ArrayList();
this.tableNode = null;
this.havingNode = null;
this.whereNode = null;
this.selectFieldList = new ArrayList();
this.gatherNodeList = new ArrayList();
this.parameterList = new ArrayList();
this.columnIndex = 1;
if(this.ctx == null)
{
this.ctx = new Context();
}
this.tablePathMap = new HashMap();
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();
this.password = null;
this.tmd = null;
this.topFilter = null;
}
public void setTablePath(String name, String path)
{
if(name != null)
{
this.tablePathMap.put(name.toLowerCase(), path);
}
}
public void setLevelFunction(String levelName, String levelFunction)
{
if(levelName == null || levelName.trim().isEmpty() || levelFunction == null || levelFunction.trim().isEmpty())
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":setLevelFunction, ????????Ϊ??ֵ");
}
levelName = levelName.toLowerCase();
levelFunction = levelFunction.toLowerCase();
Token[] tokens = Tokenizer.parse(levelFunction);
for(int i=0; i paramList)
{
if(paramList != null && !paramList.isEmpty())
{
for(Object param : paramList)
{
setSQLParameters(param);
}
}
}
private Object getSQLParameters(int paramIndex)
{
if(this.parameterList != null && this.parameterList.size() > paramIndex)
{
Object param = this.parameterList.get(paramIndex);
return param;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("search.lessParam") + ":getDQLParameters");
}
}
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 def)
{
if (p1 > 0) return p1;
if (p2 > 0) return p2;
if (p3 > 0) return p3;
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;
}
public ICursor query(String dql)
{
Token[] dqlTokens = Tokenizer.parse(dql);
return query(dqlTokens, 0, dqlTokens.length);
}
public ICursor query(Token[] tokens, int start, int end)
{
scanSelect(tokens, start, end);
execute();
init();
return this.icur;
}
public void scanSelect(Token []tokens, int start, int next)
{
if(tokens[start].isKeyWord("SELECT"))
{
start++; // skip over "select"
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, SQL????????SELECT?ؼ??ֿ?ͷ");
}
if (start >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanSelect, ??ʼλ?ó???????λ??");
}
start = scanQuantifies(tokens, start, next);
int colPos = start;
int fromPos = -1;
int havePos = -1;
int orderPos = -1;
int limitPos = -1;
int offsetPos = -1;
for (int i = colPos; i < next; ++i)
{
Token token = tokens[i];
if(token.isKeyWord())
{
if (fromPos == -1)
{
if (token.equals("FROM"))
{
fromPos = i;
}
}
else if (havePos == -1 && token.equals("HAVING"))
{
havePos = i;
}
else if (token.equals("ORDER"))
{
orderPos = i;
}
else if (token.equals("LIMIT"))
{
limitPos = i;
}
else if (token.equals("OFFSET"))
{
offsetPos = i;
break;
}
}
else if (token.getType() == Tokenizer.LPAREN) // ????()
{
i = Tokenizer.scanParen(tokens, i, next);
}
}
if (fromPos < 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.lessTable"));
}
int fromEnd = pos(havePos, orderPos, limitPos, offsetPos, next);
scanFrom(tokens, fromPos, fromEnd);
int colEnd = fromPos;
scanColumns(tokens, colPos, colEnd);
if (havePos > 0)
{
int haveEnd = pos(orderPos, limitPos, offsetPos, next);
Token[] havingTokens = Arrays.copyOfRange(tokens, havePos + 1, haveEnd);
havingTokens = optimizeWhere(havingTokens, this.parameterList);
this.havingNode = scanExp(havingTokens, 0, havingTokens.length);
}
if (orderPos > 0)
{
int orderEnd = pos(limitPos, offsetPos, next);
scanOrders(tokens, orderPos, orderEnd);
}
if (limitPos > 0)
{
int limitEnd = pos(offsetPos, next);
scanLimit(tokens, limitPos, limitEnd);
}
if (offsetPos > 0)
{
scanOffset(tokens, offsetPos, next);
}
}
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, ??ʼλ?ó???????λ??");
}
this.hasDistinct = true;
t = tokens[c];
}
if(t.isKeyWord() && t.getString().equalsIgnoreCase("TOP"))
{
c++;
try
{
this.topNumber = Integer.parseInt(tokens[c].getString());
if(this.topNumber < 0)
{
throw new NumberFormatException();
}
}
catch(NumberFormatException nfe)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanQuantifies, TOP?ؼ??ֺ??????ӷǸ?????", nfe);
}
c++;
if (c >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanQuantifies, ??ʼλ?ó???????λ??");
}
}
return c;
}
else
{
return start;
}
}
private void scanLimit(Token []tokens, int start, int next)
{
Token t = tokens[start];
if(t.isKeyWord("LIMIT"))
{
int c = start + 1;
if (c >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanLimit, ??ʼλ?ó???????λ??");
}
try
{
if(tokens[c].isKeyWord("ALL"))
{
this.limitNumber = -1;
}
else
{
this.limitNumber = Integer.parseInt(tokens[c].getString());
if(this.limitNumber < 0)
{
throw new NumberFormatException();
}
}
}
catch(NumberFormatException nfe)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanLimit, Limit?ؼ??ֺ??????ӷǸ?????", nfe);
}
}
}
private void scanOffset(Token []tokens, int start, int next)
{
Token t = tokens[start];
if(t.isKeyWord("OFFSET"))
{
int c = start + 1;
if (c >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanOffset, ??ʼλ?ó???????λ??");
}
try
{
this.offsetNumber = Integer.parseInt(tokens[c].getString());
if(this.offsetNumber < 0)
{
throw new NumberFormatException();
}
}
catch(NumberFormatException nfe)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanOffset, Offset?ؼ??ֺ??????ӷǸ?????", nfe);
}
}
}
private void scanFrom(Token[] tokens, int start, int next)
{
start++; // skip over "from"
if (start < next)
{
int wherePos = Tokenizer.scanKeyWord("WHERE", tokens, start, next);
int byPos = Tokenizer.scanKeyWord("BY", tokens, pos(wherePos, start), next);
int groupPos = Tokenizer.scanKeyWord("GROUP", tokens, pos(wherePos, start), pos(byPos, next));
int tableNext = pos(wherePos, pos(groupPos, byPos), next);
if (start >= tableNext)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??ʼλ?ó???????λ??");
}
if(tokens[start].getString().equals("{"))
{
int pos = start + 1;
if(pos == tableNext)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??????????ʽ??ʼλ?ó???????λ??");
}
int end = Tokenizer.scanBrace(tokens, start, tableNext);
String tableName = null;
String aliasName = null;
if(end + 3 == tableNext && tokens[end + 1].isKeyWord("AS"))
{
tableName = "";
aliasName = tokens[end + 2].getString();
}
else if(end + 2 == tableNext)
{
tableName = "";
aliasName = tokens[end + 1].getString();
}
else if(end + 1 == tableNext)
{
tableName = "";
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??????????ʽ?Ľ?β??????");
}
if(aliasName == null)
{
aliasName = "";
}
Token[] expTokens = Arrays.copyOfRange(tokens, pos, 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
{
//20240731 xingjl
Sequence seq = new Sequence();
seq.add(this.fromSeq);
this.ctx.getComputeStack().pushArg(seq);
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();
}
this.tableNode = new TableNode(tableName, aliasName, cursor, struct);
}
else if(obj instanceof Table)
{
ICursor cursor = new MemoryCursor((Table)obj);
DataStruct struct = ((Table)obj).dataStruct();
this.tableNode = new TableNode(tableName, aliasName, cursor, struct);
}
else if(obj instanceof PhyTable)
{
this.tableNode = new TableNode(tableName, aliasName, (PhyTable)obj);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??֧?ֵı?????????");
}
}
else if(tokens[start].getType() == Tokenizer.LPAREN)
{
int pos = start + 1;
if(pos == tableNext)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??ʱ???Ӿ???ʼλ?ó???????λ??");
}
int end = Tokenizer.scanParen(tokens, start, tableNext);
String tableName = null;
String aliasName = null;
if(end + 2 == tableNext)
{
tableName = "";
aliasName = tokens[end + 1].getString();
}
else if(end + 1 == tableNext)
{
tableName = "";
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??ʱ???Ӿ?Ľ?β??????");
}
if(aliasName == null)
{
aliasName = "";
}
if(tokens[pos].getType() == Tokenizer.PARAMMARK)
{
if(pos + 1 != end)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ??ʱ??ռλ????ʽ????");
}
if(this.ds != null)
{
if(this.icur == null)
{
this.icur = new MemoryCursor(new Table(this.ds));
}
this.tableNode = new TableNode(tableName, aliasName, this.icur, this.ds);
this.icur = null;
this.ds = null;
}
else if(this.tmd != null)
{
this.tableNode = new TableNode(tableName, aliasName, this.tmd);
this.tmd = null;
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, tokens, pos, end, parameterList, this.ctx, false);
lq.setMemory(this.isMemory);
ICursor cursor = lq.query();
DataStruct struct = lq.getDataStruct();
this.tableNode = new TableNode(tableName, aliasName, cursor, struct);
}
}
else
{
String tableName = "";
String aliasName = null;
int pos = start;
while(pos < tableNext)
{
tableName = tableName + tokens[pos].getOriginString();
//xingjl 20230323 from D://test/1??????/emps.txt??ȥ??1????ո?
// 20231106 ȥ??Ӱ?????????????֧?ֱ????????????ֿ?ͷ???ļ????ݲ?֧?֡?
tableName = tableName + tokens[pos].getSpaces();
pos++;
}
tableName = tableName.trim();
if (tableNext - 2 >= start && tokens[tableNext - 1].getType() == Tokenizer.IDENT)
{
int splitPos = tableName.lastIndexOf(" ");
if(splitPos != -1)
{
aliasName = tableName.substring(splitPos + 1);
if(aliasName.equals(tokens[tableNext - 1].getOriginString()))
{
tableName = tableName.substring(0, splitPos).trim();
}
else
{
aliasName = null;
}
}
if(tableNext - 3 >= start && tokens[tableNext - 2].isKeyWord("AS"))
{
splitPos = tableName.lastIndexOf(" ");
if(splitPos != -1)
{
String asKeyWord = tableName.substring(splitPos + 1);
if(asKeyWord.equals(tokens[tableNext - 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);
}
String paramStr = null;
if(tableName.endsWith(")"))
{
int lParenPos = tableName.lastIndexOf("(");
if(lParenPos != -1)
{
paramStr = tableName.substring(lParenPos + 1, tableName.length() - 1).trim();
tableName = tableName.substring(0, lParenPos).trim()+".dfx";
}
}
boolean fileExists = false;
//System.out.println("tableName " + tableName);
File[] fs = FileUtil.getFiles(tableName);
if (fs == null) {
fs = FileUtil.getFiles(Env.getMainPath()+"/"+tableName);
if (fs == null && Env.getPaths() != null) {
for (int i=0; i objs = new ArrayList();
for (int i=0; i 0)
{
int end = pos(groupPos, byPos, next);
Token[] whereTokens = Arrays.copyOfRange(tokens, wherePos + 1, end);
whereTokens = optimizeWhere(whereTokens, this.parameterList);
ExpressionNode expNode = scanExp(whereTokens, 0, whereTokens.length);
this.whereNode = expNode;
}
if (byPos > 0)
{
scanBy(tokens, byPos, next);
}
}
else
{
MessageManager mm = ParseMessage.get();
String n = ":";
try {n += tokens[start].getString();}catch(Exception e){}
throw new RQException(mm.getMessage("syntax.error") + ":scanFrom, ?쳣?ı???(ע?????????Ϊ?ؼ??ֻ??????ֿ?ͷ):"+n);
}
}
private void scanColumns(Token []tokens, int start, int next)
{
while (start < next)
{
int comma = Tokenizer.scanComma(tokens, start, next);
if (comma < 0)
{
scanColumn(tokens, start, next);
break;
}
else
{
scanColumn(tokens, start, comma);
start = comma + 1;
if (start >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumns, ??ʼλ?ó???????λ??");
}
}
}
}
private void scanColumn(Token []tokens, int start, int next)
{
if (start >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, ??ʼλ?ó???????λ??");
}
if (start + 1 == next && tokens[start].equals("*"))
{//select *
String columnName = null;
String aliasName = null;
DataStruct ds = this.tableNode.dataStruct();
if(ds != null)
{
String[] fieldNames = ds.getFieldNames();
for(int i=0, len = fieldNames.length; i=0) continue;
ArrayList expList = new ArrayList();
expList.add(new FieldNode(name));
ExpressionNode expNode = new ExpressionNode(expList);
columnName = name;
aliasName = columnName;
this.finalList.add(aliasName);
this.aliasList.add(aliasName.toLowerCase());
this.columnList.add(expNode);
}
}
}
else if (start + 3 == next
&& this.tableNode.isIdentic(tokens[start].getString())
&& tokens[start + 1].getType() == Tokenizer.DOT
&& tokens[start + 2].equals("*"))
{//select T.*
String columnName = null;
String aliasName = null;
DataStruct ds = this.tableNode.dataStruct();
if(ds != null)
{
String[] fieldNames = ds.getFieldNames();
for(int i=0, len = fieldNames.length; i expList = new ArrayList();
expList.add(new FieldNode(name));
ExpressionNode expNode = new ExpressionNode(expList);
columnName = name;
aliasName = columnName;
this.finalList.add(aliasName);
this.aliasList.add(aliasName.toLowerCase());
this.columnList.add(expNode);
}
}
}
else if(start + 3 < next
&& tokens[start].getType() == Tokenizer.LPAREN
&& tokens[start + 1].isKeyWord("SELECT"))
{//select (select ...from...)
int end = Tokenizer.scanParen(tokens, start, next);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, start + 1, end);
boolean needDelayed = false;
for(int n = 0, len = subQueryTokens.length; n < len; n++)
{
if(n < len - 2
&& subQueryTokens[n].getString().equalsIgnoreCase(this.tableNode.getAlias())
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n + 2].getString();
if(theFieldName.startsWith("\"") && theFieldName.endsWith("\"")
&& theFieldName.substring(1, theFieldName.length() - 1).indexOf("\"") == -1)
{
theFieldName = theFieldName.substring(1, theFieldName.length() - 1);
}
new FieldNode(theFieldName).optimize();
n += 2;
needDelayed = true;
}
}
String aliasName = null;
if(end == next - 1)
{
aliasName = "_" + this.columnIndex;
}
else
{
int begin = end + 1;
if(tokens[end + 1].isKeyWord("AS"))
{
if(end + 2 == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, As?ؼ??ֺ???ȱ???б???");
}
begin = end + 2;
}
aliasName = "";
for(int p = begin; p < next; p++)
{
aliasName += tokens[p].getOriginString();
}
}
this.finalList.add(aliasName);
this.aliasList.add(aliasName.toLowerCase());
if(needDelayed)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!this.subQueryOfSelectMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
ArrayList expList = new ArrayList();
expList.add(new NormalNode("$" + uuid));
ExpressionNode expNode = new ExpressionNode(expList);
this.columnList.add(expNode);
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
this.subQueryOfSelectEntryList.add(subQueryMap.entrySet().iterator().next());
this.subQueryOfSelectMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = this.subQueryOfSelectMap.get(checkList.toString());
ArrayList expList = new ArrayList();
expList.add(new NormalNode(dollar_uuid));
ExpressionNode expNode = new ExpressionNode(expList);
this.columnList.add(expNode);
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
DataStruct ds = lq.getDataStruct();
if(ds.getFieldCount() == 1)
{
Sequence seq = null;
if(cursor != null)
{
seq = cursor.fetch(2);
}
if(seq == null || seq.length() != 1 || seq.dataStruct() == null || seq.dataStruct().getFieldCount() != 1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, ??SELECT?Ӿ??з??س???ֵ???Ӳ?ѯֻ??Ϊ???е???");
}
Object val = seq.get(1);
if(val instanceof BaseRecord)
{
val = ((BaseRecord)val).getFieldValue(0);
}
Token[] valTokens = Tokenizer.parse(getSQLValue(val));
ExpressionNode expNode = scanExp(valTokens, 0, valTokens.length);
this.columnList.add(expNode);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, ???س???ֵ???Ӳ?ѯֻ??Ϊ????");
}
}
this.columnIndex++;
}
else
{
String aliasName = null;
int expNext = next;
if(next - 1 > start)
{
Token alias = tokens[next - 1];
Token prevToken = tokens[next - 2];
if (prevToken.isKeyWord("AS"))
{
if (alias.getType() == Tokenizer.IDENT)
{
expNext = next - 2;
aliasName = alias.getString();
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, ?????б?????ӦΪ?????ֻ??????ַ?");
}
}
else if (!prevToken.canHaveRightExp())
{
if (alias.getType() == Tokenizer.IDENT)
{
expNext = next - 1;
aliasName = alias.getString();
}
else if (alias.getType() != Tokenizer.KEYWORD && alias.getType() != Tokenizer.RPAREN && alias.getType() != Tokenizer.LEVELMARK && alias.getType() != Tokenizer.TABLEMARK)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, ij??????ѯ?еı???ʽ?????");
}
}
}
ExpressionNode expNode = scanExp(tokens, start, expNext);
if(expNode.getNodeList() == null || expNode.getNodeList().size() == 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanColumn, ij??????ѯ?еı???ʽΪ??ֵ");
}
if(aliasName != null)
{
if(aliasName.startsWith("\"") && aliasName.endsWith("\"")
&& aliasName.substring(1, aliasName.length() - 1).indexOf("\"") == -1)
{
aliasName = aliasName.substring(1, aliasName.length() - 1);
}
}
else
{
String columnName = null;
if(expNode.getNodeList().size() == 1 && expNode.getNodeList().get(0) instanceof FieldNode)
{
columnName = ((FieldNode)expNode.getNodeList().get(0)).getOriginal();
}
else
{
columnName = "_" + this.columnIndex;
}
aliasName = columnName;
}
this.columnIndex++;
this.finalList.add(aliasName);
this.aliasList.add(aliasName.toLowerCase());
this.columnList.add(expNode);
}
}
public static String scanExp(Token []tokens, List paramList)
{
SimpleSelect sdql = new SimpleSelect(null, null);//?????ڽ?????????ȡ?α꣬????Ҫ?????Ķ???
sdql.setSQLParameters(paramList);
SimpleSelect.ExpressionNode expNode = sdql.scanExp(tokens, 0, tokens.length);
expNode.setFromWhere();
return expNode.toExpression();
}
private ExpressionNode scanExp(Token []tokens, int start, int next)
{
ArrayList expList = new ArrayList();
boolean hasNot = false;
for (int i = start; i < next; i++)
{
//if (expList.size()>0) System.out.println(expList.get(expList.size()-1).toExpression());
//System.out.println(new ExpressionNode(expList).toExpression());
Token token = tokens[i];
char type = token.getType();
if (type == Tokenizer.IDENT) // F, D, A, T.F, T.fun()
{
int pos = i + 1;
if (pos == next) // F, A
{
int begin = i;
String name = tokens[begin].getString();
if(name.startsWith("\"") && name.endsWith("\"")
&& name.substring(1, name.length() - 1).indexOf("\"") == -1)
{
name = name.substring(1, name.length() - 1);
}
if(aliasList != null && aliasList.size() != 0)
{
if(aliasList.contains(name.toLowerCase()))
{
//System.out.println("4----"+name);
expList.add(new NormalNode("'"+name.toLowerCase()+"'"));
continue;
}
}
expList.add(new FieldNode(name));
}
else if (tokens[pos].getType() == Tokenizer.DOT) //T.F
{
pos++;
if (pos == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ??ʼλ?ó???????λ??");
}
else if (pos + 1 < next && tokens[pos + 1].getType() == Tokenizer.LPAREN) // T.sum(exp)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????????ʽ??֧??????д??");
}
else // T.F
{
int begin = i;
if (tokens[begin + 2].getType() != Tokenizer.IDENT)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ij????ѯ?б?????ӷ??ֶ?????");
}
int fieldNext = begin + 3;
if(begin + 3 < next)
{
if (tokens[begin + 3].getType() == Tokenizer.LEVELMARK)
{
fieldNext = begin + 4;
}
}
String tableName = tokens[begin].getString();
if (this.tableNode != null && !this.tableNode.isIdentic(tableName))
{
MessageManager mm = ParseMessage.get();
throw new RQException(tokens[i].getString() + mm.getMessage("syntax.unknownTable") + ":scanExp");
}
String fieldName = tokens[begin + 2].getString();
if(fieldName.startsWith("\"") && fieldName.endsWith("\"")
&& fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
}
expList.add(new FieldNode(fieldName));
i = fieldNext - 1;
}
}
else if(tokens[pos].getType() == Tokenizer.LPAREN) //sum(exp), year(exp)
{
int end = Tokenizer.scanParen(tokens, pos, next);
String functionName = token.getString();
if(Tokenizer.isGatherFunction(functionName))
{
boolean isCountIf = false;
boolean isFirst = false;
boolean isLast = false;
if(functionName.equalsIgnoreCase("COUNTIF"))
{
isCountIf = true;
functionName = "count";
}
else if(functionName.equalsIgnoreCase("FIRST"))
{
isFirst = true;
functionName = "top@1";
}
else if(functionName.equalsIgnoreCase("LAST"))
{
isLast = true;
functionName = "top@1";
}
ExpressionNode paramNode = null;
int begin = i + 2;
ArrayList tempList = new ArrayList();
if(isFirst || isLast)
{
if(isFirst)
{
tempList.add(new NormalNode("1"));
}
else if(isLast)
{
tempList.add(new NormalNode("-1"));
}
tempList.add(new NormalNode(","));
ExpressionNode expNode = scanExp(tokens, begin, end);
List nodeList = expNode.getNodeList();
List tailList = new ArrayList();
for(int n = nodeList.size() - 1; n >= 0; n--)
{
Node node = nodeList.get(n);
tailList.add(0, node);
nodeList.remove(n);
if(node instanceof NormalNode && ((NormalNode)node).getValue().equals(","))
{
break;
}
}
Node headNode = nodeList.get(0);
Node tailNode = nodeList.get(nodeList.size() - 1);
if(headNode instanceof NormalNode && ((NormalNode)headNode).getValue().equals("[")
&& tailNode instanceof NormalNode && ((NormalNode)tailNode).getValue().equals("]"))
{
tempList.add(headNode);
nodeList.remove(headNode);
tailList.add(0, tailNode);
nodeList.remove(tailNode);
}
ArrayList subNodeList = new ArrayList();
boolean desc = false;
for(int n = 0; n < nodeList.size(); n++)
{
Node node = nodeList.get(n);
if(node instanceof NormalNode && ((NormalNode)node).getValue().equals("desc"))
{
desc = true;
node = new NormalNode("");
}
if(node instanceof NormalNode && ((NormalNode)node).getValue().equals(","))
{
if(desc)
{
tempList.add(new NormalNode("-"));
tempList.add(new ParenNode(new ExpressionNode(subNodeList)));
}
else
{
tempList.addAll(subNodeList);
}
tempList.add(node);
subNodeList = new ArrayList();
desc = false;
}
else
{
subNodeList.add(node);
}
if(n == nodeList.size() - 1)
{
if(desc)
{
tempList.add(new NormalNode("-"));
tempList.add(new ParenNode(new ExpressionNode(subNodeList)));
}
else
{
tempList.addAll(subNodeList);
}
subNodeList = null;
desc = false;
}
}
tempList.addAll(tailList);
}
else
{
while (begin < end)
{
int comma = Tokenizer.scanComma(tokens, begin, end);
if(comma == -1)
{
if(tempList.size() == 0)
{
if(tokens[begin].getString().equals("*") && begin + 1 == end)
{
tokens[begin].setString("1");
tokens[begin].setType(Tokenizer.NUMBER);
}
paramNode = scanExp(tokens, begin, end);
}
else if(isCountIf && tempList.size() > 0)
{
tempList.add(new NormalNode("||"));
tempList.add(new NormalNode("("));
tempList.add(scanExp(tokens, begin, end));
tempList.add(new NormalNode(")"));
}
if(this.distinctGatherField != null)
{
if(isCountIf || !functionName.equalsIgnoreCase("COUNT"))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ??COUNT?ۺϺ????IJ?????֧??DISTINCT");
}
String fieldName = paramNode.toExpression();
if(fieldName == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, COUNT(DISTINCT)?IJ?????ʽ????");
}
functionName = "icount";
this.distinctGatherField = null;
}
break;
}
else
{
if(isCountIf)
{
if(tempList.size() > 0)
{
tempList.add(new NormalNode("||"));
}
tempList.add(new NormalNode("("));
tempList.add(scanExp(tokens, begin, comma));
tempList.add(new NormalNode(")"));
begin = comma + 1;
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ij?ۺϺ????IJ???????????");
}
}
}
}
if((isCountIf || isFirst || isLast) && paramNode == null && tempList.size() != 0)
{
paramNode = new ExpressionNode(tempList);
}
int size = paramNode.getNodeList().size();
if (size == 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":scanExp, ?ۺϺ????IJ????ڵ???????Ϊ??");
}
expList.add(new GatherNode(functionName, paramNode));
}
else
{
ExpressionNode paramNode = null;
int begin = i + 2;
paramNode = scanExp(tokens, begin, end);
expList.add(new FunctionNode(functionName, paramNode));
}
i = end;
}
else if (tokens[pos].getType() == Tokenizer.LEVELMARK) //F#L
{
String fieldName = tokens[i].getString();
String levelName = tokens[pos].getLevelName();
DimNode dimNode = new DimNode(levelName);
dimNode.setField(fieldName);
expList.add(dimNode);
i = pos;
}
else if (tokens[pos].getType() == Tokenizer.OPERATOR) //F+G
{
int begin = i;
String fieldName = tokens[begin].getString();
if(fieldName.startsWith("\"") && fieldName.endsWith("\"")
&& fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
}
if(aliasList != null && aliasList.size() != 0)
{
if(aliasList.contains(fieldName.toLowerCase()))
{
//System.out.println("1----"+fieldName);
expList.add(new NormalNode("'"+fieldName.toLowerCase()+"'"));
continue;
}
}
expList.add(new FieldNode(fieldName));
}
else if (tokens[pos].getType() == Tokenizer.COMMA) //F,
{
int begin = i;
String fieldName = tokens[begin].getString();
if(fieldName.startsWith("\"") && fieldName.endsWith("\"")
&& fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
}
if(aliasList != null && aliasList.size() != 0)
{
if(aliasList.contains(fieldName.toLowerCase()))
{
//System.out.println("2----"+fieldName);
expList.add(new NormalNode("'"+fieldName.toLowerCase()+"'"));
continue;
}
}
//System.out.println("7----"+fieldName+",,,"+new FieldNode(fieldName).toExpression());
expList.add(new FieldNode(fieldName));
}
else if (tokens[pos].getType() == Tokenizer.KEYWORD)//F asc/desc, F order by
{
int begin = i;
String fieldName = tokens[begin].getString();
if(fieldName.startsWith("\"") && fieldName.endsWith("\"")
&& fieldName.substring(1, fieldName.length() - 1).indexOf("\"") == -1)
{
fieldName = fieldName.substring(1, fieldName.length() - 1);
}
if(aliasList != null && aliasList.size() != 0)
{
if(aliasList.contains(fieldName.toLowerCase()))
{
//System.out.println("3----"+fieldName);
expList.add(new NormalNode("'"+fieldName.toLowerCase()+"'"));
continue;
}
}
expList.add(new FieldNode(fieldName));
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ?ֶ???????˷Ƿ????ַ?");
}
}
else if (type == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, i, next);
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)
{
boolean needDelayed = false;
for(int n = 0, len = subQueryTokens.length; n < len; n++)
{
if(n < len - 2
&& subQueryTokens[n].getString().equalsIgnoreCase(this.tableNode.getAlias())
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n + 2].getString();
if(theFieldName.startsWith("\"") && theFieldName.endsWith("\"")
&& theFieldName.substring(1, theFieldName.length() - 1).indexOf("\"") == -1)
{
theFieldName = theFieldName.substring(1, theFieldName.length() - 1);
}
new FieldNode(theFieldName).optimize();
n += 2;
needDelayed = true;
}
}
if(needDelayed)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(i > 0 && tokens[i - 1].isKeyWord("IN"))
{
if(!this.subQueryOfInMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
ArrayList list = new ArrayList();
list.add(new NormalNode("$" + uuid)); //??join??????Ӳ?ѯ?ֶ???Ϊ?Ǻ????ӵIJ?????ѡ???ֶ?
ExpressionNode expNode = new ExpressionNode(list);
expList.add(expNode);
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
this.subQueryOfInEntryList.add(subQueryMap.entrySet().iterator().next());
this.subQueryOfInMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = this.subQueryOfInMap.get(checkList.toString());
ArrayList list = new ArrayList();
list.add(new NormalNode(dollar_uuid));//??join??????Ӳ?ѯ?ֶ???Ϊ?Ǻ????ӵIJ?????ѡ???ֶ?
ExpressionNode expNode = new ExpressionNode(list);
expList.add(expNode);
}
}
else
{
if(!this.subQueryOfWhereMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
ArrayList list = new ArrayList();
list.add(new NormalNode("$" + uuid));//??join??????Ӳ?ѯ?ֶ???Ϊ?Ǻ????ӵIJ?????ѡ???ֶ?
ExpressionNode expNode = new ExpressionNode(list);
expList.add(expNode);
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
this.subQueryOfWhereEntryList.add(subQueryMap.entrySet().iterator().next());
this.subQueryOfWhereMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = this.subQueryOfWhereMap.get(checkList.toString());
ArrayList list = new ArrayList();
list.add(new NormalNode(dollar_uuid));//??join??????Ӳ?ѯ?ֶ???Ϊ?Ǻ????ӵIJ?????ѡ???ֶ?
ExpressionNode expNode = new ExpressionNode(list);
expList.add(expNode);
}
}
}
else
{
SimpleSQL lq = new SimpleSQL(this.ics, subQueryTokens, 0, subQueryTokens.length, this.parameterList, this.ctx, true);
lq.setMemory(true);
ICursor cursor = lq.query();
DataStruct ds = lq.getDataStruct();
if(ds.getFieldCount() == 1)
{
expList.add(new TableNode("", "", cursor, ds));
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ???س???ֵ???Ӳ?ѯֻ??Ϊ????");
}
}
}
else
{
expList.add(new ParenNode(scanExp(subQueryTokens, 0, subQueryTokens.length)));//ʵ???ϲ????Ӳ?ѯ
}
i = end;
}
else if (token.isKeyWord("LEFT") && i+1 != next && tokens[i+1].getType() == Tokenizer.LPAREN)
{
token.setType(Tokenizer.IDENT);
i = i - 1;
}
else if (token.isKeyWord("RIGHT") && i+1 != next && tokens[i+1].getType() == Tokenizer.LPAREN)
{
token.setType(Tokenizer.IDENT);
i = i - 1;
}
else if (token.isKeyWord("FIRST") && i+1 != next && tokens[i+1].getType() == Tokenizer.LPAREN)
{
token.setType(Tokenizer.IDENT);
i = i - 1;
}
else if (token.isKeyWord("ORDER") && i+1 != next && tokens[i+1].isKeyWord("BY"))
{
expList.add(0, new NormalNode(","));
int comma = Tokenizer.scanComma(tokens, i+2, next);
if(comma != -1)
{
expList.add(0, new NormalNode("]"));
}
expList.addAll(0, scanExp(tokens, i+2, next).getNodeList());
if(comma != -1)
{
expList.add(0, new NormalNode("["));
}
i = next;
}
else if (token.isKeyWord("IN"))
{
int pos = i + 1;
if (pos == next || tokens[pos].getType() != Tokenizer.LPAREN && tokens[pos].getType() != Tokenizer.IDENT)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, IN?Ӿ?Ӿ?ĸ?ʽ????");
}
ArrayList tempList = new ArrayList();
for(int x = expList.size() - 1; x >= 0; x--)
{
if(expList.get(x) instanceof NormalNode)
{
NormalNode normal = (NormalNode)expList.get(x);
if(normal.getValue().equalsIgnoreCase("AND") || normal.getValue().equalsIgnoreCase("&&")
|| normal.getValue().equalsIgnoreCase("OR") || normal.getValue().equalsIgnoreCase("||"))
{
break;
}
}
tempList.add(0, expList.get(x));
expList.remove(x);
}
ExpressionNode expNode = new ExpressionNode(tempList);
if(tokens[pos].getType() == Tokenizer.LPAREN)
{
int end = Tokenizer.scanParen(tokens, pos, next);
ExpressionNode paramNode = scanExp(tokens, pos, end + 1);//????????????????Խ????Ӳ?ѯ????
expList.add(new InNode(expNode, paramNode, hasNot));
i = end;
}
else if(tokens[pos].getType() == Tokenizer.IDENT)
{
ArrayList paramList = new ArrayList();
String theFieldName = tokens[pos].getOriginString();
if(theFieldName.startsWith("\"") && theFieldName.endsWith("\"")
&& theFieldName.substring(1, theFieldName.length() - 1).indexOf("\"") == -1)
{
theFieldName = theFieldName.substring(1, theFieldName.length() - 1);
}
paramList.add(new FieldNode(theFieldName));//join??????Ӳ?ѯ?ֶ???Ϊ?Ѿ?????????????ѡ???ֶ?
ExpressionNode paramNode = new ExpressionNode(paramList);
expList.add(new InNode(expNode, paramNode, hasNot));
i = pos;
}
if(hasNot)
{
hasNot = false;
}
}
else if (token.isKeyWord("LIKE"))
{
int pos = i + 1;
if (pos == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Like?Ӿ?ĸ?ʽ????");
}
else
{
// if(tokens[pos].getType() != Tokenizer.STRING)
// {
// if(!tokens[pos].getString().startsWith("\"") || !tokens[pos].getString().endsWith("\"")
// || tokens[pos].getString().substring(1, tokens[pos].getString().length()-1).indexOf("\"") != -1)
// {
// MessageManager mm = ParseMessage.get();
// throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Like?Ӿ????ʽ???ʹ???");
// }
// }
}
// String pattern = tokens[pos].getString().substring(1, tokens[pos].getString().length() - 1);//??""??''?Ա??ڲ???,????ټ???
ArrayList tempList = new ArrayList();
for(int x = expList.size() - 1; x >= 0; x--)
{
if(expList.get(x) instanceof NormalNode)
{
NormalNode normal = (NormalNode)expList.get(x);
if(normal.getValue().equalsIgnoreCase("AND") || normal.getValue().equalsIgnoreCase("&&")
|| normal.getValue().equalsIgnoreCase("OR") || normal.getValue().equalsIgnoreCase("||"))
{
break;
}
}
tempList.add(0, expList.get(x));
expList.remove(x);
}
ExpressionNode expNode = new ExpressionNode(tempList);
expList.add(new LikeNode(expNode, tokens[pos], hasNot,this));
if(hasNot)
{
hasNot = false;
}
i = pos;
}
else if (token.isKeyWord("CASE"))
{
int endPos = Tokenizer.scanCaseEnd(tokens, i, next);
int elsePos = Tokenizer.scanCaseElse(tokens, i, endPos);
List nodeList = new ArrayList();
int pos = i + 1;
boolean needOptimizeFilter = false;
if(!tokens[pos].isKeyWord("WHEN"))
{
int whenPos = Tokenizer.scanCaseWhen(tokens, pos, elsePos == -1 ? endPos : elsePos);
if(whenPos == -1)
{
throw new RQException("CASE???ȱ??WHEN?ؼ???");
}
ExpressionNode caseNode = scanExp(tokens, pos, whenPos);
nodeList.add(caseNode);
pos = whenPos;
}
else
{
nodeList.add(new NormalNode("true"));
needOptimizeFilter = true;
}
while(pos < (elsePos == -1 ? endPos : elsePos))
{
int whenPos = Tokenizer.scanCaseWhen(tokens, pos, elsePos == -1 ? endPos : elsePos);
if(whenPos == -1)
{
whenPos = elsePos == -1 ? endPos : elsePos;
}
int thenPos = Tokenizer.scanCaseThen(tokens, pos, whenPos);
if(needOptimizeFilter)
{
Token[] whenTokens = Arrays.copyOfRange(tokens, pos + 1, thenPos);
PerfectWhere pw = new PerfectWhere(whenTokens, this.parameterList);
whenTokens = pw.getTokens(true);
ExpressionNode whenNode = scanExp(whenTokens, 0, whenTokens.length);
nodeList.add(whenNode);
}
else
{
ExpressionNode whenNode = scanExp(tokens, pos + 1, thenPos);
nodeList.add(whenNode);
}
ExpressionNode thenNode = scanExp(tokens, thenPos+1, whenPos);
nodeList.add(thenNode);
pos = whenPos;
}
if(elsePos != -1)
{
ExpressionNode elseNode = scanExp(tokens, elsePos + 1, endPos);
nodeList.add(elseNode);
}
expList.add(new CaseNode(nodeList));
i = endPos;
}
else if (token.isKeyWord("BETWEEN"))
{
ArrayList tempList = new ArrayList();
for(int x = expList.size() - 1; x >= 0; x--)
{
if(expList.get(x) instanceof NormalNode)
{
NormalNode normal = (NormalNode)expList.get(x);
if(normal.getValue().equalsIgnoreCase("AND") || normal.getValue().equalsIgnoreCase("&&")
|| normal.getValue().equalsIgnoreCase("OR") || normal.getValue().equalsIgnoreCase("||"))
{
break;
}
}
tempList.add(0, expList.get(x));
expList.remove(x);
}
ExpressionNode expNode = new ExpressionNode(tempList);
int andPos = Tokenizer.scanKeyWord("AND", tokens, i + 1, next);
if(andPos == -1)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Between????ȱ?ٹؼ???and");
}
ExpressionNode floorValue = scanExp(tokens, i + 1, andPos);
int endAnd = Tokenizer.scanKeyWord("AND", tokens, andPos + 1, next);
int endOr = Tokenizer.scanKeyWord("OR", tokens, andPos + 1, next);
int end = -1;
if(endAnd == -1 || endOr == -1)
{
end = pos(endAnd, endOr, next);
}
else
{
end = endAnd < endOr ? endAnd : endOr;
}
ExpressionNode ceilValue = scanExp(tokens, andPos + 1, end);
expList.add(new BetweenNode(expNode, floorValue, ceilValue, hasNot));
if(hasNot)
{
hasNot = false;
}
i = end - 1;
}
else if (token.isKeyWord("EXISTS"))
{
int pos = i + 1;
if (pos + 1 >= next || tokens[pos].getType() != Tokenizer.LPAREN || !tokens[pos + 1].isKeyWord("SELECT"))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Exists?Ӿ?Ӿ?ĸ?ʽ????");
}
int end = Tokenizer.scanParen(tokens, pos, next);
Token[] subQueryTokens = Arrays.copyOfRange(tokens, pos + 1, end);
boolean needDelayed = false;
for(int n = 0, len = subQueryTokens.length; n < len; n++)
{
if(n < len - 2
&& subQueryTokens[n].getString().equalsIgnoreCase(this.tableNode.getAlias())
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT
&& subQueryTokens[n + 2].getType() == Tokenizer.IDENT)
{
String theFieldName = subQueryTokens[n + 2].getString();
if(theFieldName.startsWith("\"") && theFieldName.endsWith("\"")
&& theFieldName.substring(1, theFieldName.length() - 1).indexOf("\"") == -1)
{
theFieldName = theFieldName.substring(1, theFieldName.length() - 1);
}
new FieldNode(theFieldName).optimize();
n += 2;
needDelayed = true;
}
}
if(needDelayed)
{
List checkList = new ArrayList();
for(Token subQueryToken : subQueryTokens)
{
checkList.add(subQueryToken.getString().toUpperCase());
}
if(!this.subQueryOfExistsMap.containsKey(checkList.toString()))
{
String uuid = UUID.randomUUID().toString().replace("-", "_");
Map subQueryMap = new HashMap();
subQueryMap.put("$" + uuid, subQueryTokens);
this.subQueryOfExistsEntryList.add(subQueryMap.entrySet().iterator().next());
expList.add(new NormalNode("$" + uuid));
if(hasNot) //not exists : is null
{
expList.add(new NormalNode("=="));
}
else
{
expList.add(new NormalNode("!="));
}
expList.add(new NormalNode("null"));
this.subQueryOfExistsMap.put(checkList.toString(), "$" + uuid);
}
else
{
String dollar_uuid = this.subQueryOfExistsMap.get(checkList.toString());
expList.add(new NormalNode(dollar_uuid));
if(hasNot) //not exists : is null
{
expList.add(new NormalNode("=="));
}
else
{
expList.add(new NormalNode("!="));
}
expList.add(new NormalNode("null"));
}
}
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)
{
if(hasNot)
{
expList.add(new NormalNode("1"));
expList.add(new NormalNode("=="));
expList.add(new NormalNode("1"));
}
else
{
expList.add(new NormalNode("1"));
expList.add(new NormalNode("=="));
expList.add(new NormalNode("0"));
}
}
else
{
if(hasNot)
{
expList.add(new NormalNode("1"));
expList.add(new NormalNode("=="));
expList.add(new NormalNode("0"));
}
else
{
expList.add(new NormalNode("1"));
expList.add(new NormalNode("=="));
expList.add(new NormalNode("1"));
}
}
}
if(hasNot)
{
hasNot = false;
}
i = end;
}
else if (type == Tokenizer.PARAMMARK)
{
ParamNode paramNode = new ParamNode();
String strIndex = tokens[i].getString().substring(1);
if(strIndex.length() != 0)
{
int paramIndex = Integer.parseInt(strIndex);
paramNode.setIndex(paramIndex);
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ռλ??????????");
}
expList.add(paramNode);
}
else
{
String value = token.getString();
if (token.getType() == Tokenizer.OPERATOR)
{
if(value.equalsIgnoreCase("="))
{
if (i == start)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ʽ??????'='?ſ?ͷ");
}
else if(tokens[i-1].getType() != Tokenizer.OPERATOR)
{
if(hasNot)
{
value = "!=";
}
else
{
value = "==";
}
}
}
else if(value.equalsIgnoreCase(">"))
{
if (i + 1 == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ʽ??????'>'?Ž?β");
}
else if(tokens[i + 1].getType() == Tokenizer.OPERATOR)
{
if(tokens[i + 1].getString().equalsIgnoreCase("=") && (i + 1 < next))
{
if(hasNot)
{
value = "<";
i = i + 1;
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ij????ʽ??ʹ???˲?֧?ֵIJ?????");
}
}
else
{
if(hasNot)
{
value = "<=";
}
}
}
else if(value.equalsIgnoreCase("<"))
{
if (i + 1 == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ʽ??????'<'?Ž?β");
}
else if(tokens[i + 1].getType() == Tokenizer.OPERATOR)
{
if(tokens[i + 1].getString().equalsIgnoreCase("=") && (i + 1 < next))
{
if(hasNot)
{
value = ">";
i = i + 1;
}
}
else if(tokens[i + 1].getString().equalsIgnoreCase(">") && (i + 1 < next))
{
if(hasNot)
{
value = "=";
i = i + 1;
}
else
{
value = "!=";
i = i + 1;
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ij????ʽ??ʹ???˲?֧?ֵIJ?????");
}
}
else
{
if(hasNot)
{
value = ">=";
}
}
}
else if(value.equalsIgnoreCase("!"))
{
if (i + 1 == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ʽ??????'!'?Ž?β");
}
else if(tokens[i + 1].getType() == Tokenizer.OPERATOR)
{
if(tokens[i + 1].getString().equalsIgnoreCase("=") && (i + 1 < next))
{
if(hasNot)
{
value = "==";
i = i + 1;
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ij????ʽ??ʹ???˲?֧?ֵIJ?????");
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ????ʽ??'!'???ܵ???ʹ??");
}
}
if(hasNot)
{
hasNot = false;
}
}
else if(token.getType() == Tokenizer.KEYWORD)
{
if(value.equalsIgnoreCase("AND"))
{
value = "&&";
}
else if(value.equalsIgnoreCase("OR"))
{
value = "||";
}
else if(value.equalsIgnoreCase("NOT"))
{
hasNot = true;
value = "";
}
else if(value.equalsIgnoreCase("IS"))
{
if (i + 1 == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Is?ؼ????÷?????");
}
else if(tokens[i + 1].getType() == Tokenizer.KEYWORD)
{
if(tokens[i + 1].getString().equalsIgnoreCase("NOT"))
{
if (i + 2 == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Is Not?ؼ????÷?????");
}
if(tokens[i + 2].getType() == Tokenizer.KEYWORD)
{
if(tokens[i + 2].getString().equalsIgnoreCase("NULL"))
{
value = "!=";
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Is Not?ؼ???ֻ?ܺ??null");
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Is Not?ؼ???ֻ?ܺ??null");
}
i = i + 1; //????not??ֹӰ??????????
}
else if(tokens[i + 1].getString().equalsIgnoreCase("NULL"))
{
value = "==";
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Is?ؼ???ֻ?ܺ??null");
}
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, Is?ؼ????÷?????");
}
}
else if(value.equalsIgnoreCase("NULL"))
{
value = "null";
}
else if(value.equalsIgnoreCase("DISTINCT"))
{
this.distinctGatherField = "";
value = "";
}
else if(value.equalsIgnoreCase("ASC"))
{
value = "";
}
else if(value.equalsIgnoreCase("DESC"))
{
value = "desc";
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanExp, ??֧?ֵĹؼ????÷?:" + value);
}
}
else if(token.getType() == Tokenizer.STRING)
{
value = value.trim();
value = value.substring(1, value.length()-1);
value = "\"" + value + "\"";
}
expList.add(new NormalNode(value));
}
}
int size = expList.size();
if (size == 0)
{
expList.add(new NormalNode(""));
}
return new ExpressionNode(expList);
}
private void scanBy(Token []tokens, int start, int next)
{
while (start < next)
{
start++;
if (start == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanBy, ??ʼλ?ó???????λ??");
}
int end = Tokenizer.scanComma(tokens, start, next);
if (end < 0)
{
end = next;
}
int atPos = Tokenizer.scanKeyWord("AT", tokens, start, end);
if (atPos < 0)
{
ExpressionNode expNode = scanExp(tokens, start, end);
if(expNode.getNodeList() == null || expNode.getNodeList().size() == 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanBy, ???????Ϊ??ֵ");
}
Node node = null;
if(expNode.getNodeList().size() == 1)
{
if(expNode.getNodeList().get(0) instanceof NormalNode)
{
String value = ((NormalNode)expNode.getNodeList().get(0)).getValue();
if(value != null && !value.trim().isEmpty() && Pattern.compile("^[\\d]+$").matcher(value).matches())
{
node = expNode.getNodeList().get(0);
}
}
}
if(node == null && expNode.hasField(false))
{
node = expNode;
}
if(node == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanBy, ??????????Ͳ???");
}
this.groupList.add(node);
}
else //not support 'AT'
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanBy, ??֧??At???");
}
start = end;
}
if(this.groupList == null || this.groupList.size() == 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanBy, û?????????κη?????");
}
}
private void scanOrders(Token []tokens, int start, int next)
{
start++;
if (start == next || !tokens[start].isKeyWord("BY"))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanOrders, Order?Ӿ??ʽ????");
}
while (start < next)
{
start++;
if (start == next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanOrders, ??ʼλ?ó???????λ??");
}
int end = Tokenizer.scanComma(tokens, start, next);
if (end < 0)
{
end = next;
}
ExpressionNode orderNode = scanExp(tokens, start, end);
boolean desc = false;
Node tail = orderNode.getNodeList().get(orderNode.getNodeList().size() - 1);
if(tail instanceof NormalNode && ((NormalNode)tail).getValue().equals("desc"))
{
desc = true;
orderNode.getNodeList().remove(tail);
}
Node node = null;
if(orderNode.getNodeList().size() == 2 && orderNode.getNodeList().get(1) instanceof NormalNode
&& ((NormalNode)orderNode.getNodeList().get(1)).getValue().isEmpty() || orderNode.getNodeList().size() == 1)
{
if(orderNode.getNodeList().get(0) instanceof NormalNode)
{
String value = ((NormalNode)orderNode.getNodeList().get(0)).getValue();
if(value != null && !value.trim().isEmpty() && Pattern.compile("^[\\d]+$").matcher(value).matches())
{
node = orderNode.getNodeList().get(0);
}
}
}
if(node == null && orderNode.hasField(true))
{
node = orderNode;
}
if(node == null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanOrders, ??????????Ͳ???");
}
if(desc)
{
ArrayList newNodeList = new ArrayList();
newNodeList.add(new NormalNode("-"));
newNodeList.add(new ParenNode(orderNode));
node = new ExpressionNode(newNodeList);
desc = false;
}
this.sortList.add(node);
start = end;
}
if (this.sortList == null || this.sortList.size() == 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":scanOrders, ?????ֶβ???Ϊ??ֵ");
}
}
public static List fnames = Arrays.asList(new String[]{"_file","_ext","_date","_size"});
private void execute()
{
if(this.tableNode != null)
{
if(this.columnList != null && this.columnList.size() != 0)
{
for(ExpressionNode expNode : this.columnList)
{
expNode.optimize();
}
}
if(this.groupList != null && this.groupList.size() != 0)
{
List tempList = new ArrayList();
for(int g=0, sz=this.groupList.size(); g this.columnList.size())
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????ȡ???кŲ???");
}
}
catch(NumberFormatException ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????????Ͳ???", ex);
}
grpNode = this.columnList.get(colNo - 1);
}
grpNode.optimize();
tempList.add(grpNode);
}
this.groupList = tempList;
}
if(this.whereNode != null)
{
this.whereNode.optimize();
}
if(this.havingNode != null)
{
this.havingNode.optimize();
}
if(this.sortList != null && this.sortList.size() != 0)
{
for(int s=0, sz=this.sortList.size(); s=0) {
qfnames += "," + fds[a];
}
}
if (qfnames.length()>0) {
//this.tableNode.setFileAttrQuery(true);
//fds = qfnames.substring(1).split(",");
}
Map stdMap = new LinkedHashMap();
DataStruct gds = this.tableNode.dataStruct();
if(gds != null && gds.getFieldCount() > 0)
{
if(fds.length == 0)
{
fds = new String[1];
fds[0] = gds.getFieldName(0);
bak = new String[1];
//System.out.println("5----"+fds[0].toLowerCase());
bak[0] = "'" + fds[0].toLowerCase() + "'";
fxs = new Expression[1];
fxs[0] = new Expression(String.format("#%d", 1));
}
else
{
String[] fns = gds.getFieldNames();
Map n2cMap = new LinkedHashMap();
Next:
for(int a = 0; a < fds.length; a++)
{
//System.out.println("6----"+bak[a]);
bak[a] = "'" + fds[a] + "'";
// 20220715 xingjl add
fxs[a] = new Expression(String.format("#%d", a+1));
for(int b = 0; b < fns.length; b++)
{
// 20220715 xingjl remove
//fxs[a] = new Expression(String.format("#%d", b+1));
if(fds[a].equalsIgnoreCase(fns[b]))
{
if(whereExp != null && this.tableNode.getType() == TableNode.TYPE_GTB)
{
n2cMap.put(bak[a], fns[b]);
}
stdMap.put(fds[a], fns[b]);
fds[a] = fns[b];
continue Next;
}
else if(this.tableNode.getAlias() != null && !this.tableNode.getAlias().isEmpty())
{
if(fds[a].toLowerCase().startsWith(this.tableNode.getAlias().toLowerCase() + ".") && SimpleJoin.getRealFieldName(fds[a]).equalsIgnoreCase(fns[b]))
{
stdMap.put(fds[a], fns[b]);
fds[a] = fns[b];
continue Next;
}
else if(fns[b].toLowerCase().startsWith(this.tableNode.getAlias().toLowerCase() + ".") && SimpleJoin.getRealFieldName(fns[b]).equalsIgnoreCase(fds[a]))
{
stdMap.put(fds[a], fns[b]);
fds[a] = fns[b];
continue Next;
}
}
}
MessageManager mm = ParseMessage.get();
throw new RQException("execute:" + fds[a] + mm.getMessage("field.notExist") + " in " + Arrays.asList(fns));
}
whereExp = ExpressionTranslator.translateExp(whereExp, n2cMap);
}
}
//xingjl remove 20220215
// Set fdsSet = new HashSet(Arrays.asList(fds));
// fds = new String[fdsSet.size()];
// fdsSet.toArray(fds);
this.tableNode.setAccessColumn(fds);
boolean hasMasterFieldfromExists = false;
if(whereExp != null && !this.subQueryOfExistsEntryList.isEmpty())
{
for(int m = 0; m < this.subQueryOfExistsEntryList.size(); m++)
{
String subQueryOfExistsIdent = this.subQueryOfExistsEntryList.get(m).getKey();
if(whereExp.contains(subQueryOfExistsIdent))
{
hasMasterFieldfromExists = true;
break;
}
}
}
boolean hasMasterFieldfromIn = false;
if(whereExp != null && !this.subQueryOfInEntryList.isEmpty())
{
for(int m = 0; m < this.subQueryOfInEntryList.size(); m++)
{
String subQueryOfInIdent = this.subQueryOfInEntryList.get(m).getKey();
if(whereExp.contains(subQueryOfInIdent))
{
hasMasterFieldfromIn = true;
break;
}
}
}
boolean hasMasterFieldfromWhere = false;
if(whereExp != null && !this.subQueryOfWhereEntryList.isEmpty())
{
for(int m = 0; m < this.subQueryOfWhereEntryList.size(); m++)
{
String subQueryOfWhereIdent = this.subQueryOfWhereEntryList.get(m).getKey();
if(whereExp.contains(subQueryOfWhereIdent))
{
hasMasterFieldfromWhere = true;
break;
}
}
}
Map trMap = new LinkedHashMap();
for(int i = 0; i < fds.length; i++)
{
trMap.put(fds[i], fxs[i].toString());
if(fds[i].startsWith("\"") && fds[i].endsWith("\"") && fds[i].substring(1, fds[i].length() - 1).indexOf("\"") == -1)
{
trMap.put(SimpleJoin.getRealFieldName(fds[i]), fxs[i].toString());
}
trMap.put("'"+fds[i]+"'", fxs[i].toString());
}
if(whereExp != null && !whereExp.equals("false") && this.tableNode.getType() == TableNode.TYPE_GTB
&& !hasMasterFieldfromExists && !hasMasterFieldfromIn && !hasMasterFieldfromWhere && this.topFilter == null)
{
whereExp = ExpressionTranslator.translateExp(whereExp, stdMap);
whereExp = ExpressionTranslator.translateExp(whereExp, trMap);
this.tableNode.setWhere(whereExp);
whereExp = null;
}
if(whereExp != null && whereExp.equals("false"))
{
this.icur = null;
}
else
{
this.icur = this.tableNode.getCursor();
}
this.ds = new DataStruct(fds);
ICursor cur = fillSubQueryField(this.ics, this.icur, this.subQueryOfExistsEntryList, this.parameterList, this.tableNode.getAlias(), SubQueryCursor.Exist_Type, this.ds);
if(cur != null && cur instanceof SubQueryCursor && !cur.equals(this.icur))
{
this.ds = ((SubQueryCursor)cur).getTableDataStruct();
}
else if(cur != null)
{
this.ds = cur.getDataStruct();
}
this.icur = cur;
cur = fillSubQueryField(this.ics, this.icur, this.subQueryOfInEntryList, this.parameterList, this.tableNode.getAlias(), SubQueryCursor.In_Type, this.ds);
if(cur != null && cur instanceof SubQueryCursor && !cur.equals(this.icur))
{
this.ds = ((SubQueryCursor)cur).getTableDataStruct();
}
else if(cur != null)
{
this.ds = cur.getDataStruct();
}
this.icur = cur;
cur = fillSubQueryField(this.ics, this.icur, this.subQueryOfWhereEntryList, this.parameterList, this.tableNode.getAlias(), SubQueryCursor.Where_Type, this.ds);
if(cur != null && cur instanceof SubQueryCursor && !cur.equals(this.icur))
{
this.ds = ((SubQueryCursor)cur).getTableDataStruct();
}
else if(cur != null)
{
this.ds = cur.getDataStruct();
}
this.icur = cur;
if(this.topFilter != null)
{
this.topFilter = ExpressionTranslator.translateExp(this.topFilter, stdMap);
this.topFilter = ExpressionTranslator.translateExp(this.topFilter, trMap);
Expression[] topExps = new Expression[]{new Expression(this.topFilter)};
String[] topNames = new String[]{"_1"};
if(this.icur != null)
{
Table tab = this.icur.groups(null, null, topExps, topNames, null, ctx);
if(tab == null || tab.length() != 1 || !(tab.get(1) instanceof BaseRecord)
|| ((BaseRecord)tab.get(1)).getFieldCount() != 1 || !(((BaseRecord)tab.get(1)).getFieldValue(0) instanceof Sequence))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, top?Ż?????쳣");
}
Table res = null;
Sequence seq = (Sequence)((BaseRecord)tab.get(1)).getFieldValue(0);
for(int i = 1; i <= seq.length(); i++)
{
Object obj = seq.get(i);
if(!(obj instanceof BaseRecord))
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, top?Ż?????쳣");
}
BaseRecord rec = (BaseRecord)obj;
if(res == null)
{
res = new Table(rec.dataStruct());
}
res.add(rec);
}
this.icur = new MemoryCursor(res);
}
}
if(whereExp != null && !whereExp.equals("false"))
{
whereExp = ExpressionTranslator.translateExp(whereExp, stdMap);
whereExp = ExpressionTranslator.translateExp(whereExp, trMap);
Expression flt = new Expression(whereExp);
if(this.icur != null)
{
this.icur.addOperation(new Select(flt, null), ctx);
}
whereExp = null;
}
boolean gatherSign = false;
boolean fieldNotGroupSign = false;
ArrayList nameList = new ArrayList();
ArrayList functionList = new ArrayList();
ArrayList gatherList = new ArrayList();
ArrayList expressList = new ArrayList();
ArrayList paramList = new ArrayList();
ArrayList classifyList = new ArrayList();
ArrayList numberList = new ArrayList();
if(this.groupList != null && this.groupList.size() != 0)
{
for(int g = 0, len = this.groupList.size(); g n2cMap = new LinkedHashMap();
for(int c = 0, len = classifyList.size(); c < len; c++)
{
String grpExp = classifyList.get(c);
n2cMap.put(grpExp, String.format("#%d", c+1));
}
for(int g = 0, len = gatherList.size(); g < len; g++)
{
String funExp = gatherList.get(g);
n2cMap.put(funExp, String.format("#%d", sizeGroup+g+1));
}
havExp = ExpressionTranslator.translateExp(havExp, n2cMap);
Expression flt = new Expression(havExp);
if(this.icur != null)
{
this.icur.addOperation(new Select(flt, null), ctx);
}
}
int sizeExpress = expressList.size();
Expression[] exps = new Expression[sizeExpress];
String[] names = new String[sizeExpress];
this.aliasList.toArray(names);
for(int i = 0; i < sizeExpress; i++)
{
String exp = expressList.get(i);
Map n2cMap = new LinkedHashMap();
for(int j=0, length=classifyList.size(); j= 0 || this.limitNumber >= 0)
{
if(this.topNumber >= 0 && this.limitNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Limit?ؼ??ֲ???ͬʱʹ??");
}
else if(this.topNumber >= 0 && this.offsetNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Offset?ؼ??ֲ???ͬʱʹ??");
}
limit = this.topNumber >= 0 ? this.topNumber : this.limitNumber;
offset = this.offsetNumber > 0 ? this.offsetNumber : 0;
limit = limit + offset;
if(limit <= ICursor.FETCHCOUNT)
{
this.topNumber = -1;
this.limitNumber = -1;
this.offsetNumber = -1;
}
else
{
limit = -1;
offset = -1;
}
}
Expression[] ordExps = new Expression[this.sortList.size()];
for(int s = 0, size = ordExps.length; s < size; s++)
{
String ordExp = this.sortList.get(s).toExpression();
if(this.sortList.get(s) instanceof NormalNode)
{
try
{
int colNo = Integer.parseInt(ordExp);
if(colNo <= 0 || colNo > this.columnList.size())
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????ȡ???кŲ???");
}
ordExp = "#" + colNo;
}
catch(NumberFormatException ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????????Ͳ???", ex);
}
}
else
{
Map n2cMap = new LinkedHashMap();
for(int e = 0, len = expressList.size(); e < len; e++)
{
n2cMap.put(expressList.get(e), "#" + (e + 1));
}
for(int a = 0, len = this.aliasList.size(); a < len; a++)
{
String aliExp = "'" + this.aliasList.get(a) + "'";
n2cMap.put(aliExp, "#" + (a + 1));
}
ordExp = ExpressionTranslator.translateExp(ordExp, n2cMap);
}
ordExps[s] = new Expression(ordExp);
}
if(limit >= 0)
{
if(ordExps.length > 1)
{
StringBuffer sb = new StringBuffer();
sb.append("[");
for(int ox = 0; ox < ordExps.length; ox++)
{
if(ox > 0)
{
sb.append(",");
}
sb.append(ordExps[ox].toString());
}
sb.append("]");
if(this.icur != null)
{
Sequence seq = (Sequence)CursorUtil.top(this.icur, limit, new Expression(sb.toString()), new Expression("~"), ctx);
this.icur = new MemoryCursor(seq);
}
}
else
{
if(this.icur != null)
{
Sequence seq = (Sequence)CursorUtil.top(this.icur, limit, ordExps[0], new Expression("~"), ctx);
this.icur = new MemoryCursor(seq);
}
}
if(offset > 0)
{
if(this.icur != null)
{
this.icur.skip(offset);
}
}
}
else
{
if(this.icur != null)
{
if(this.icur instanceof MemoryCursor || this.isMemory)
{
this.icur = new MemoryCursor(this.icur.fetch().sort(ordExps, null, null, this.ctx));
}
else
{
int capacityEx = EnvUtil.getCapacity(ordExps.length);
this.icur = CursorUtil.sortx(this.icur, ordExps, this.ctx, capacityEx, null);
}
}
}
}
}
else
{
if(this.havingNode != null)
{
this.havingNode.setFromHaving();
String havingExp = this.havingNode.toExpression();
havingExp = ExpressionTranslator.translateExp(havingExp, stdMap);
havingExp = ExpressionTranslator.translateExp(havingExp, trMap);
Expression flt = new Expression(havingExp);
if(this.icur != null)
{
this.icur.addOperation(new Select(flt, null), ctx);
}
}
cur = fillSubQueryField(this.ics, this.icur, this.subQueryOfSelectEntryList, this.parameterList, this.tableNode.getAlias(), SubQueryCursor.Select_Type, this.ds);
if(cur != null && cur instanceof SubQueryCursor && !cur.equals(this.icur))
{
this.ds = ((SubQueryCursor)cur).getTableDataStruct();
}
else if(cur != null)
{
this.ds = cur.getDataStruct();
}
this.icur = cur;
if(this.ds != null)
{
for(int i = trMap.size(); i < this.ds.getFieldCount(); i++)
{
trMap.put("'" + this.ds.getFieldName(i) + "'", this.ds.getFieldName(i));
}
}
if(this.hasDistinct)
{
int sizeExpress = expressList.size();
Expression[] exps = new Expression[sizeExpress];
String[] names = new String[sizeExpress];
this.aliasList.toArray(names);
for(int i = 0; i < sizeExpress; i++)
{
String exp = expressList.get(i);
exp = ExpressionTranslator.translateExp(exp, stdMap);
exp = ExpressionTranslator.translateExp(exp, trMap);
exps[i] = new Expression(exp);
}
if(this.icur != null)
{
this.icur.addOperation(new New(exps, names, null), ctx);
}
Expression[] grps = new Expression[sizeExpress];
for(int k = 0; k < sizeExpress; k++)
{
grps[k] = new Expression(String.format("#%d", k + 1));
}
if(this.icur != null)
{
Table tab = this.icur.groups(grps, names, null, null, null, ctx);
this.icur = new MemoryCursor(tab);
/*
if(this.icur instanceof MemoryCursor || this.isMemory)
{
Table tab = CursorUtil.groups(this.icur, grps, names, cnts, nms, null, ctx);
this.icur = new MemoryCursor(tab);
}
else
{
int capacity = EnvUtil.getCapacity(grps.length + cnts.length);
this.icur = CursorUtil.hashGroupx(this.icur, grps, names, cnts, nms, null, ctx, capacity);
}
*/
}
if(this.sortList != null && this.sortList.size() != 0)
{
int limit = -1, offset = -1;
if(this.topNumber >= 0 || this.limitNumber >= 0)
{
if(this.topNumber >= 0 && this.limitNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Limit?ؼ??ֲ???ͬʱʹ??");
}
else if(this.topNumber >= 0 && this.offsetNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Offset?ؼ??ֲ???ͬʱʹ??");
}
limit = this.topNumber >= 0 ? this.topNumber : this.limitNumber;
offset = this.offsetNumber > 0 ? this.offsetNumber : 0;
limit = limit + offset;
if(limit <= ICursor.FETCHCOUNT)
{
this.topNumber = -1;
this.limitNumber = -1;
this.offsetNumber = -1;
}
else
{
limit = -1;
offset = -1;
}
}
Expression[] ordExps = new Expression[this.sortList.size()];
for(int s = 0, size = ordExps.length; s < size; s++)
{
String ordExp = this.sortList.get(s).toExpression();
if(this.sortList.get(s) instanceof NormalNode)
{
try
{
int colNo = Integer.parseInt(ordExp);
if(colNo <= 0 || colNo > this.columnList.size())
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????ȡ???кŲ???");
}
ordExp = "#" + colNo;
}
catch(NumberFormatException ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????????Ͳ???", ex);
}
}
else
{
Map n2cMap = new LinkedHashMap();
for(int e = 0, len = expressList.size(); e < len; e++)
{
String exp = expressList.get(e);
exp = ExpressionTranslator.translateExp(exp, stdMap);
n2cMap.put(exp, "#" + (e + 1));
}
for(int a = 0, len = this.aliasList.size(); a < len; a++)
{
String aliExp = "'"+this.aliasList.get(a)+"'";
n2cMap.put(aliExp, "#" + (a + 1));
}
ordExp = ExpressionTranslator.translateExp(ordExp, stdMap);
ordExp = ExpressionTranslator.translateExp(ordExp, n2cMap);
}
ordExps[s] = new Expression(ordExp);
}
if(limit >= 0)
{
if(ordExps.length > 1)
{
StringBuffer sb = new StringBuffer();
sb.append("[");
for(int ox = 0; ox < ordExps.length; ox++)
{
if(ox > 0)
{
sb.append(",");
}
sb.append(ordExps[ox].toString());
}
sb.append("]");
if(this.icur != null)
{
Sequence seq = (Sequence)CursorUtil.top(this.icur, limit, new Expression(sb.toString()), new Expression("~"), ctx);
this.icur = new MemoryCursor(seq);
}
}
else
{
if(this.icur != null)
{
Sequence seq = (Sequence)CursorUtil.top(this.icur, limit, ordExps[0], new Expression("~"), ctx);
this.icur = new MemoryCursor(seq);
}
}
if(offset > 0)
{
if(this.icur != null)
{
this.icur.skip(offset);
}
}
}
else
{
if(this.icur != null)
{
if(this.icur instanceof MemoryCursor || this.isMemory)
{
this.icur = new MemoryCursor(this.icur.fetch().sort(ordExps, null, null, this.ctx));
}
else
{
int capacityEx = EnvUtil.getCapacity(ordExps.length);
this.icur = CursorUtil.sortx(this.icur, ordExps, this.ctx, capacityEx, null);
}
}
}
}
}
else
{
if(this.sortList != null && this.sortList.size() != 0)
{
int limit = -1, offset = -1;
if(this.topNumber >= 0 || this.limitNumber >= 0)
{
if(this.topNumber >= 0 && this.limitNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Limit?ؼ??ֲ???ͬʱʹ??");
}
else if(this.topNumber >= 0 && this.offsetNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Offset?ؼ??ֲ???ͬʱʹ??");
}
limit = this.topNumber >= 0 ? this.topNumber : this.limitNumber;
offset = this.offsetNumber > 0 ? this.offsetNumber : 0;
limit = limit + offset;
if(limit <= ICursor.FETCHCOUNT)
{
this.topNumber = -1;
this.limitNumber = -1;
this.offsetNumber = -1;
}
else
{
limit = -1;
offset = -1;
}
}
Expression[] ordExps = new Expression[this.sortList.size()];
for(int s = 0, size = ordExps.length; s < size; s++)
{
String ordExp = this.sortList.get(s).toExpression();
if(this.sortList.get(s) instanceof NormalNode)
{
try
{
int colNo = Integer.parseInt(ordExp);
if(colNo <= 0 || colNo > this.columnList.size())
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????ȡ???кŲ???");
}
ordExp = "#" + colNo;
}
catch(NumberFormatException ex)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, ??????????Ͳ???", ex);
}
}
else
{
Map n2cMap = new LinkedHashMap();
for(int a = 0, len = this.aliasList.size(); a < len; a++)
{
String aliExp = "'" + this.aliasList.get(a) + "'";
String exp = expressList.get(a);
exp = ExpressionTranslator.translateExp(exp, stdMap);
String colExp = "(" + exp + ")";
n2cMap.put(aliExp, colExp);
}
ordExp = ExpressionTranslator.translateExp(ordExp, stdMap);
ordExp = ExpressionTranslator.translateExp(ordExp, n2cMap);
ordExp = ExpressionTranslator.translateExp(ordExp, trMap);
}
ordExps[s] = new Expression(ordExp);
}
if(limit >= 0)
{
if(ordExps.length > 1)
{
StringBuffer sb = new StringBuffer();
sb.append("[");
for(int ox = 0; ox < ordExps.length; ox++)
{
if(ox > 0)
{
sb.append(",");
}
sb.append(ordExps[ox].toString());
}
sb.append("]");
if(this.icur != null)
{
Sequence seq = (Sequence)CursorUtil.top(this.icur, limit, new Expression(sb.toString()), new Expression("~"), ctx);
this.icur = new MemoryCursor(seq);
}
}
else
{
if(this.icur != null)
{
Sequence seq = (Sequence)CursorUtil.top(this.icur, limit, ordExps[0], new Expression("~"), ctx);
this.icur = new MemoryCursor(seq);
}
}
if(offset > 0)
{
if(this.icur != null)
{
this.icur.skip(offset);
}
}
}
else
{
if(this.icur != null)
{
if(this.icur instanceof MemoryCursor || this.isMemory)
{
this.icur = new MemoryCursor(this.icur.fetch().sort(ordExps, null, null, this.ctx));
}
else
{
int capacityEx = EnvUtil.getCapacity(ordExps.length);
this.icur = CursorUtil.sortx(this.icur, ordExps, this.ctx, capacityEx, null);
}
}
}
}
int sizeExpress = expressList.size();
Expression[] exps = new Expression[sizeExpress];
String[] names = new String[sizeExpress];
this.aliasList.toArray(names);
for(int i = 0; i < sizeExpress; i++)
{
String exp = expressList.get(i);
exp = ExpressionTranslator.translateExp(exp, stdMap);
exp = ExpressionTranslator.translateExp(exp, trMap);
exps[i] = new Expression(exp);
}
if(this.icur != null)
{
this.icur.addOperation(new New(exps, names, null), ctx);
}
}
}
if(this.topNumber >= 0 && this.limitNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Limit?ؼ??ֲ???ͬʱʹ??");
}
else if(this.topNumber >= 0 && this.offsetNumber >= 0)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":execute, Top?ؼ?????Offset?ؼ??ֲ???ͬʱʹ??");
}
else if(this.topNumber >= 0)
{
if(this.icur != null)
{
this.icur = new SubCursor(this.icur, this.topNumber);
}
}
else if(this.limitNumber >= 0)
{
if(this.offsetNumber > 0)
{
if(this.icur != null)
{
this.icur.skip(this.offsetNumber);
}
}
if(this.icur != null)
{
this.icur = new SubCursor(this.icur, this.limitNumber);
}
}
else if(this.offsetNumber > 0)
{
if(this.icur != null)
{
this.icur.skip(this.offsetNumber);
}
}
Expression[] colExps = new Expression[this.finalList.size()];
for(int i=0, len=colExps.length; i paramList = new ArrayList();
while(true)
{
StringBuffer sb = new StringBuffer();
int comma = Tokenizer.scanComma(tokens, start, next);
if(comma < 0)
{
for(int i = start; i < next; i++)
{
sb.append(tokens[i].getOriginString());
sb.append(tokens[i].getSpaces());
}
if(sb.length() > 0)
{
paramList.add(sb.toString().trim());
}
break;
}
else
{
for(int i = start; i < comma; i++)
{
sb.append(tokens[i].getOriginString());
sb.append(tokens[i].getSpaces());
}
if(sb.length() > 0)
{
paramList.add(sb.toString());
}
else
{
throw new RQException("????????????Ϊ??");
}
start = comma + 1;
if(start >= next)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":getParams, ??????ʽ????");
}
}
}
String[] params = new String[paramList.size()];
paramList.toArray(params);
return params;
}
private Token[] optimizeWhere(Token[] whereTokens, List paramList)
{
PerfectWhere pw = new PerfectWhere(whereTokens, paramList);
String topFilter = pw.getTopFromTokens(null, null, this.tableNode.getName(), this.tableNode.getAlias());
if(this.topFilter == null)
{
this.topFilter = topFilter;
}
else if(topFilter != null)
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("syntax.error") + ":optimizeWhere, WHERE?Ӿ䱻?ظ?????");
}
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, ??֧?ֵ?????????");
}
}
public String getProcValue(Object param)
{
if(param == null)
{
return "null";
}
else if(param instanceof String)
{
return String.format("\"%s\"", param.toString());
}
else if(param instanceof Boolean)
{
return param.toString();
}
else if(param instanceof Number)
{
return param.toString();
}
else if(param instanceof java.sql.Date)
{
return String.format("date(\"%s\",\"yyyy-MM-dd\")", new SimpleDateFormat("yyyy-MM-dd").format((java.sql.Date)param));
}
else if(param instanceof java.sql.Time)
{
return String.format("time(\"%s\",\"HH:mm:ss.SSS\")", new SimpleDateFormat("HH:mm:ss.SSS").format((java.sql.Time)param));
}
else if(param instanceof java.sql.Timestamp)
{
return String.format("datetime(\"%s\",\"yyyy-MM-dd HH:mm:ss.SSS\")", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format((java.sql.Timestamp)param));
}
else if(param instanceof Date)
{
return String.format("datetime(\"%s\",\"yyyy-MM-dd HH:mm:ss.SSS\")", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format((Date)param));
}
else
{
MessageManager mm = ParseMessage.get();
throw new RQException(mm.getMessage("function.paramError") + ":getProcValue, ??֧?ֵ?????????");
}
}
private ICursor fillSubQueryField(ICellSet ics, ICursor icur, List> subQueryEntryList, List paramList, String tableName, 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();
Set tableNames = new HashSet();
tableNames.add(tableName);
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(int m = 0, sz = outerFieldSet.size(); m < sz; m++)
{
String outerField = outerFieldSet.iterator().next();
for(int k = 0, len = fieldNames.length; k < len; k++)
{
String fieldName = fieldNames[k];
String bakOuterField = outerField;
outerField = SimpleJoin.getRealFieldName(outerField);
if(fieldName.equalsIgnoreCase(outerField))
{
fn2cnMap.put(bakOuterField, "#" + (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].trim().toLowerCase(), fn2cnMap);
outerExpsList.add(new Expression(numberCode));
}
else if(innerFieldSet.contains(fltExps[0].trim().toLowerCase())) //?ڲ??ֶ?
{
String numberCode = ExpressionTranslator.translateExp(fltExps[0].trim().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].trim().toLowerCase(), fn2cnMap);
outerExpsList.add(new Expression(numberCode));
}
else if(innerFieldSet.contains(fltExps[1].trim().toLowerCase())) //?ڲ??ֶ?
{
String numberCode = ExpressionTranslator.translateExp(fltExps[1].trim().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();
List subQueryList = new ArrayList();
for(int n = 0, len = subQueryTokens.length; n < len; n++)
{
String theFieldName = null;
if(n < len - 2
&& subQueryTokens[n].getString().equalsIgnoreCase(tableName)
&& subQueryTokens[n + 1].getType() == Tokenizer.DOT)
{
for(String fieldName : fieldNames)
{
if(subQueryTokens[n + 2].getString().equalsIgnoreCase(fieldName))
{
theFieldName = fieldName;
break;
}
}
}
if(theFieldName != null)
{
subQueryListList.add(subQueryList);
subQueryList = new ArrayList();
fieldNameList.add(theFieldName);
n += 2;
}
else
{
subQueryList.add(subQueryTokens[n]);
}
}
if(!subQueryList.isEmpty())
{
subQueryListList.add(subQueryList);
}
subQueryListListList.add(subQueryListList);
fieldNameListList.add(fieldNameList);
String aliasName = subQueryEntry.getKey();
colNameList.add(aliasName);
}
}
if(!colNameList.isEmpty())
{
icur = new SubQueryCursor(icur, type, ics, paramList, colNameList, subQueryListListList, fieldNameListList, this.ctx, ds);
}
return icur;
}
void setMemory(boolean isMemory)
{
this.isMemory = isMemory;
}
void setParallel(int parallelNumber)
{
this.parallelNumber = parallelNumber;
}
void setTopFilter(String topFilter)
{
this.topFilter = topFilter;
}
}