public SqlRexConvertlet get(SqlCall call) { SqlRexConvertlet convertlet; final SqlOperator op = call.getOperator(); // Is there a convertlet for this operator // (e.g. SqlStdOperatorTable.plusOperator)? convertlet = (SqlRexConvertlet) map.get(op); if (convertlet != null) { return convertlet; } // Is there a convertlet for this class of operator // (e.g. SqlBinaryOperator)? Class<? extends Object> clazz = op.getClass(); while (clazz != null) { convertlet = (SqlRexConvertlet) map.get(clazz); if (convertlet != null) { return convertlet; } clazz = clazz.getSuperclass(); } // Is there a convertlet for this class of expression // (e.g. SqlCall)? clazz = call.getClass(); while (clazz != null) { convertlet = (SqlRexConvertlet) map.get(clazz); if (convertlet != null) { return convertlet; } clazz = clazz.getSuperclass(); } return null; }
/** * Registers method if it: a. is public, and b. is named "convertXxx", and c. has a return type of * "RexNode" or a subtype d. has a 2 parameters with types ConvertletContext and SqlNode (or a * subtype) respectively. */ private void registerNodeTypeMethod(final Method method) { if (!Modifier.isPublic(method.getModifiers())) { return; } if (!method.getName().startsWith("convert")) { return; } if (!RexNode.class.isAssignableFrom(method.getReturnType())) { return; } final Class[] parameterTypes = method.getParameterTypes(); if (parameterTypes.length != 2) { return; } if (parameterTypes[0] != SqlRexContext.class) { return; } final Class parameterType = parameterTypes[1]; if (!SqlNode.class.isAssignableFrom(parameterType)) { return; } map.put( parameterType, new SqlRexConvertlet() { public RexNode convertCall(SqlRexContext cx, SqlCall call) { try { return (RexNode) method.invoke(ReflectiveConvertletTable.this, cx, call); } catch (IllegalAccessException e) { throw Util.newInternal(e, "while converting " + call); } catch (InvocationTargetException e) { throw Util.newInternal(e, "while converting " + call); } } }); }
protected RexNode register(RexNode expr) { final String key = expr.toString(); final RexNode previous = mapDigestToExpr.put(key, expr); if (!allowDups && (previous != null)) { throw new SubExprExistsException(expr); } return expr; }
/** Converts a {@link Map} of integers to a {@link TargetMapping}. */ public static TargetMapping target(Map<Integer, Integer> map, int sourceCount, int targetCount) { final PartialFunctionImpl mapping = new PartialFunctionImpl(sourceCount, targetCount, MappingType.FUNCTION); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { mapping.set(entry.getKey(), entry.getValue()); } return mapping; }
/** * Registers that one operator is an alias for another. * * @param alias Operator which is alias * @param target Operator to translate calls to */ protected void addAlias(final SqlOperator alias, final SqlOperator target) { map.put( alias, new SqlRexConvertlet() { public RexNode convertCall(SqlRexContext cx, SqlCall call) { Util.permAssert(call.getOperator() == alias, "call to wrong operator"); final SqlCall newCall = target.createCall(SqlParserPos.ZERO, call.getOperandList()); return cx.convertExpression(newCall); } }); }
private List<Object> explainInputs(List<RelNode> inputs) { final List<Object> list = jsonBuilder.list(); for (RelNode input : inputs) { String id = relIdMap.get(input); if (id == null) { input.explain(this); id = previousId; } list.add(id); } return list; }
@SuppressWarnings("unchecked") private static <K, V> HashMap<K, V> copy(Map<K, V> map) { HashMap<K, V> copy = new HashMap<K, V>(); for (Iterator<Map.Entry<K, V>> i = map.entrySet().iterator(); i.hasNext(); ) { Map.Entry<K, V> e = i.next(); if (e.getValue() instanceof Set) { copy.put(e.getKey(), (V) copy((Set) e.getValue())); } else { copy.put(e.getKey(), e.getValue()); } } return copy; }
protected void explain_(RelNode rel, List<Pair<String, Object>> values) { final Map<String, Object> map = jsonBuilder.map(); map.put("id", null); // ensure that id is the first attribute map.put("relOp", relJson.classToTypeName(rel.getClass())); for (Pair<String, Object> value : values) { if (value.right instanceof RelNode) { continue; } put(map, value.left, value.right); } // omit 'inputs: ["3"]' if "3" is the preceding rel final List<Object> list = explainInputs(rel.getInputs()); if (list.size() != 1 || !list.get(0).equals(previousId)) { map.put("inputs", list); } final String id = Integer.toString(relIdMap.size()); relIdMap.put(rel, id); map.put("id", id); relList.add(map); previousId = id; }
protected RexNode lookup(RexNode expr) { return mapDigestToExpr.get(expr.toString()); }
private void put(Map<String, Object> map, String name, Object value) { map.put(name, relJson.toJson(value)); }
/** Returns a JSON string describing the relational expressions that were just explained. */ public String asString() { final Map<String, Object> map = jsonBuilder.map(); map.put("rels", relList); return jsonBuilder.toJsonString(map); }
/** * Registers a convertlet for a given operator instance * * @param op Operator instance, say {@link org.eigenbase.sql.fun.SqlStdOperatorTable#MINUS} * @param convertlet Convertlet */ protected void registerOp(SqlOperator op, SqlRexConvertlet convertlet) { map.put(op, convertlet); }