query.java
来自「数据仓库展示程序」· Java 代码 · 共 1,168 行 · 第 1/3 页
JAVA
1,168 行
}
public Exp validate(Exp exp, boolean scalar) {
Exp resolved = (Exp) resolvedNodes.get(exp);
if (resolved != null) {
// Expression has already been resolved.
return scalar ? convertToScalar(resolved) : resolved;
}
stack.push(exp);
try {
// Put in a placeholder while we're resolving to prevent
// recursion.
resolvedNodes.put(exp, placeHolder);
resolved = exp.accept(this);
if (scalar) {
resolved = convertToScalar(resolved);
}
resolvedNodes.put(exp, resolved);
return resolved;
} finally {
stack.pop();
}
}
private Exp convertToScalar(Exp exp) {
return funTable.createValueFunCall(exp, this);
}
public Parameter validate(Parameter parameter) {
Parameter resolved = (Parameter) resolvedNodes.get(parameter);
if (resolved != null) {
return parameter; // already resolved
}
stack.push(parameter);
try {
resolvedNodes.put(parameter, placeHolder);
resolved = (Parameter) parameter.accept(this);
resolvedNodes.put(parameter, resolved);
return resolved;
} finally {
stack.pop();
}
}
public void validate(MemberProperty memberProperty) {
if (resolvedNodes.put(memberProperty, placeHolder) != null) {
return; // already resolved
}
stack.push(memberProperty);
try {
memberProperty.resolve(this);
} finally {
stack.pop();
}
}
public void validate(QueryAxis axis) {
if (resolvedNodes.put(axis, placeHolder) != null) {
return; // already resolved
}
stack.push(axis);
try {
axis.resolve(this);
} finally {
stack.pop();
}
}
public void validate(Formula formula) {
if (resolvedNodes.put(formula, placeHolder) != null) {
return; // already resolved
}
stack.push(formula);
try {
formula.accept(this);
} finally {
stack.pop();
}
}
public boolean canConvert(Exp fromExp, int to, int[] conversionCount) {
return FunUtil.canConvert(fromExp, to, conversionCount);
}
public Exp convert(Exp fromExp, int to) {
return FunUtil.convert(fromExp, to, this);
}
public boolean requiresExpression() {
return requiresExpression(stack.size() - 1);
}
private boolean requiresExpression(int n) {
if (n < 1) {
return false;
}
final Object parent = stack.get(n - 1);
if (parent instanceof Formula) {
return ((Formula) parent).isMember();
} else if (parent instanceof FunCall) {
final FunCall funCall = (FunCall) parent;
if (funCall.isCallToTuple()) {
return requiresExpression(n - 1);
} else {
int k = whichArg(funCall, stack.get(n));
if (k < 0) {
// Arguments of call have mutated since call was placed
// on stack. Presumably the call has already been
// resolved correctly, so the answer we give here is
// irrelevant.
return false;
}
return funTable.requiresExpression(funCall, k, this);
}
} else {
return false;
}
}
public FunTable getFunTable() {
return funTable;
}
public Parameter createOrLookupParam(FunCall funCall) {
Util.assertTrue(funCall.getArg(0) instanceof Literal,
"The name of parameter must be a quoted string");
String name = (String) ((Literal) funCall.getArg(0)).getValue();
Parameter param = lookupParam(name);
ParameterFunDef funDef = (ParameterFunDef) funCall.getFunDef();
if (funDef.getName().equals("Parameter")) {
if (param != null) {
if (param.getDefineCount() > 0) {
throw Util.newInternal("Parameter '" + name +
"' is defined more than once");
} else {
param.incrementDefineCount();
return param;
}
}
final Exp arg1 = funCall.getArg(1);
final Type type;
final int category = funCall.getCategory();
switch (category) {
case Category.Member:
Dimension dimension = (Dimension) arg1;
type = new MemberType(dimension.getHierarchy(), null, null);
break;
case Category.String:
type = new StringType();
break;
case Category.Numeric:
type = new NumericType();
break;
case Category.Integer:
type = new DecimalType(Integer.MAX_VALUE, 0);
break;
default:
throw Category.instance.badValue(category);
}
param = new Parameter(
funDef.parameterName, category,
funDef.exp, funDef.parameterDescription, type);
// Append it to the array of known parameters.
Parameter[] old = parameters;
final int count = old.length;
parameters = new Parameter[count + 1];
System.arraycopy(old, 0, parameters, 0, count);
parameters[count] = param;
return param;
} else {
if (param != null) {
return param;
}
// We're looking at a ParamRef("p"), and its defining
// Parameter("p") hasn't been seen yet. Just this once, walk
// over the entire query finding parameter definitions.
if (!haveCollectedParameters) {
haveCollectedParameters = true;
collectParameters();
param = lookupParam(name);
if (param != null) {
return param;
}
}
throw Util.newInternal("Parameter '" + name +
"' is referenced but never defined");
}
}
private void collectParameters() {
final Walker walker = new Walker(Query.this);
while (walker.hasMoreElements()) {
final Object o = walker.nextElement();
if (o instanceof Parameter) {
// Parameter has already been resolved.
;
} else if (o instanceof FunCall) {
final FunCall call = (FunCall) o;
if (call.getFunName().equalsIgnoreCase("Parameter")) {
// Parameter definition which has not been resolved
// yet. Resolve it and add it to the list of parameters.
// Because we're resolving out out of the proper order,
// the resolver doesn't hold the correct ancestral
// context, but it should be OK.
final Parameter param = (Parameter) validate(call, false);
param.resetDefineCount();
}
}
}
}
/*
private void replace(QueryPart oldChild, QueryPart newChild) {
QueryPart parent = (QueryPart) stack.get(stack.size() - 2);
int childIndex = whichArg(parent, oldChild);
Util.assertTrue(childIndex >= 0);
parent.replaceChild(childIndex, newChild);
}
*/
private int whichArg(final Object node, final Object arg) {
if (node instanceof Walkable) {
final Object[] children = ((Walkable) node).getChildren();
for (int i = 0; i < children.length; i++) {
if (children[i] == arg) {
return i;
}
}
}
return -1;
}
}
/**
* Source of metadata within the scope of a query.
*
* <p>Note especially that {@link #getCalculatedMember(String[])}
* returns the calculated members defined in this query.
*/
private class QuerySchemaReader extends DelegatingSchemaReader {
public QuerySchemaReader(SchemaReader cubeSchemaReader) {
super(cubeSchemaReader);
}
public Member getMemberByUniqueName(
String[] uniqueNameParts,
boolean failIfNotFound) {
final String uniqueName = Util.implode(uniqueNameParts);
Member member = lookupMemberFromCache(uniqueName);
if (member == null) {
// Not a calculated member in the query, so go to the cube.
member = schemaReader.getMemberByUniqueName(uniqueNameParts,
failIfNotFound);
}
if (getRole().canAccess(member)) {
return member;
} else {
return null;
}
}
public Member getCalculatedMember(String[] nameParts) {
final String uniqueName = Util.implode(nameParts);
return lookupMemberFromCache(uniqueName);
}
public List getCalculatedMembers(Hierarchy hierarchy) {
List definedMembers = getDefinedMembers();
List result = new ArrayList();
for (int i = 0; i < definedMembers.size(); i++) {
Member member = (Member) definedMembers.get(i);
if (member.getHierarchy().equals(hierarchy)) {
result.add(member);
}
}
return result;
}
public List getCalculatedMembers(Level level) {
List hierachyMembers = getCalculatedMembers(level.getHierarchy());
List result = new ArrayList();
for (int i = 0; i < hierachyMembers.size(); i++) {
Member member = (Member) hierachyMembers.get(i);
if (member.getLevel().equals(level)) {
result.add(member);
}
}
return result;
}
public List getCalculatedMembers() {
return getDefinedMembers();
}
public OlapElement getElementChild(OlapElement parent, String s) {
// first look in cube
OlapElement mdxElement = schemaReader.getElementChild(parent, s);
if (mdxElement != null) {
return mdxElement;
}
// then look in defined members (removed sf#1084651)
// then in defined sets
for (int i = 0; i < formulas.length; i++) {
Formula formula = formulas[i];
if (formula.isMember()) {
continue; // have already done these
}
if (Util.equals(formula.getNames()[0], s)) {
return formula.getNamedSet();
}
}
return mdxElement;
}
public OlapElement lookupCompound(
OlapElement parent,
String[] names,
boolean failIfNotFound,
int category) {
// First look to ourselves.
switch (category) {
case Category.Unknown:
case Category.Member:
if (parent == cube) {
final Member calculatedMember = getCalculatedMember(names);
if (calculatedMember != null) {
return calculatedMember;
}
}
}
switch (category) {
case Category.Unknown:
case Category.Set:
if (parent == cube) {
final NamedSet namedSet = getNamedSet(names);
if (namedSet != null) {
return namedSet;
}
}
}
// Then delegate to the next reader.
OlapElement olapElement = super.lookupCompound(
parent, names, failIfNotFound, category);
if (olapElement instanceof Member) {
Member member = (Member) olapElement;
final Formula formula = (Formula)
member.getPropertyValue(Property.FORMULA.name);
if (formula != null) {
// This is a calculated member defined against the cube.
// Create a free-standing formula using the same
// expression, then use the member defined in that formula.
final Formula formulaClone = (Formula) formula.clone();
formulaClone.createElement(Query.this);
formulaClone.accept(createValidator());
olapElement = formulaClone.getMdxMember();
}
}
return olapElement;
}
public NamedSet getNamedSet(String[] nameParts) {
if (nameParts.length != 1) {
return null;
}
return lookupNamedSet(nameParts[0]);
}
}
/**
* PrintWriter used for unparsing queries. Remembers which parameters have
* been printed. The first time, they print themselves as "Parameter";
* subsequent times as "ParamRef".
*/
static class QueryPrintWriter extends PrintWriter {
final HashSet parameters = new HashSet();
QueryPrintWriter(Writer writer) {
super(writer);
}
}
}
// End Query.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?