17 package org.apache.calcite.rel.externalize;
19 import com.fasterxml.jackson.core.type.TypeReference;
20 import com.fasterxml.jackson.databind.DeserializationFeature;
21 import com.fasterxml.jackson.databind.ObjectMapper;
22 import com.google.common.collect.ImmutableList;
24 import org.apache.calcite.adapter.enumerable.EnumerableTableScan;
25 import org.apache.calcite.plan.Convention;
26 import org.apache.calcite.plan.RelOptCluster;
27 import org.apache.calcite.plan.RelOptSchema;
28 import org.apache.calcite.plan.RelOptTable;
29 import org.apache.calcite.plan.RelTraitSet;
30 import org.apache.calcite.rel.RelCollation;
31 import org.apache.calcite.rel.RelCollations;
32 import org.apache.calcite.rel.RelDistribution;
33 import org.apache.calcite.rel.RelInput;
34 import org.apache.calcite.rel.RelNode;
35 import org.apache.calcite.rel.core.AggregateCall;
36 import org.apache.calcite.rel.type.RelDataType;
37 import org.apache.calcite.rex.RexLiteral;
38 import org.apache.calcite.rex.RexNode;
39 import org.apache.calcite.schema.Schema;
40 import org.apache.calcite.sql.SqlAggFunction;
41 import org.apache.calcite.util.ImmutableBitSet;
42 import org.apache.calcite.util.Pair;
43 import org.apache.calcite.util.Util;
45 import java.io.IOException;
46 import java.lang.reflect.Constructor;
47 import java.lang.reflect.InvocationTargetException;
48 import java.util.AbstractList;
49 import java.util.ArrayList;
50 import java.util.LinkedHashMap;
51 import java.util.List;
52 import java.util.Locale;
54 import java.util.Objects;
62 private static final TypeReference<LinkedHashMap<String, Object>>
TYPE_REF =
63 new TypeReference<LinkedHashMap<String, Object>>() {};
68 private final Map<String, RelNode>
relMap =
new LinkedHashMap<>();
78 public RelNode
read(String s)
throws IOException {
80 final ObjectMapper mapper =
new ObjectMapper();
81 Map<String, Object> o =
82 mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,
true)
84 @SuppressWarnings(
"unchecked")
85 final List<Map<String, Object>> rels = (List) o.get(
"rels");
90 private void readRels(List<Map<String, Object>> jsonRels) {
91 for (Map<String, Object> jsonRel : jsonRels) {
96 private void readRel(
final Map<String, Object> jsonRel) {
97 String
id = (String) jsonRel.get(
"id");
98 String
type = (String) jsonRel.get(
"relOp");
99 Constructor constructor = null;
100 if (!type.equalsIgnoreCase(
"EnumerableTableScan")) {
101 constructor = relJson.getConstructor(
type);
103 RelInput input =
new RelInput() {
104 public RelOptCluster getCluster() {
108 public RelTraitSet getTraitSet() {
109 return cluster.traitSetOf(Convention.NONE);
112 public RelOptTable getTable(String table) {
113 final List<String> list = getStringList(table);
114 return relOptSchema.getTableForMember(list);
117 public RelNode getInput() {
118 final List<RelNode> inputs = getInputs();
119 assert inputs.size() == 1;
120 return inputs.get(0);
123 public List<RelNode> getInputs() {
124 final List<String> jsonInputs = getStringList(
"inputs");
125 if (jsonInputs == null) {
126 return ImmutableList.of(
lastRel);
128 final List<RelNode> inputs =
new ArrayList<>();
129 for (String jsonInput : jsonInputs) {
135 public RexNode getExpression(String tag) {
136 return relJson.toRex(
this, jsonRel.get(tag));
139 public ImmutableBitSet getBitSet(String tag) {
140 return ImmutableBitSet.of(getIntegerList(tag));
143 public List<ImmutableBitSet> getBitSetList(String tag) {
144 List<List<Integer>> list = getIntegerListList(tag);
148 final ImmutableList.Builder<ImmutableBitSet> builder = ImmutableList.builder();
149 for (List<Integer> integers : list) {
150 builder.add(ImmutableBitSet.of(integers));
152 return builder.build();
155 public List<String> getStringList(String tag) {
157 return (List<String>) jsonRel.get(tag);
160 public List<Integer> getIntegerList(String tag) {
162 return (List<Integer>) jsonRel.get(tag);
165 public List<List<Integer>> getIntegerListList(String tag) {
167 return (List<List<Integer>>) jsonRel.get(tag);
170 public List<AggregateCall> getAggregateCalls(String tag) {
171 @SuppressWarnings(
"unchecked")
172 final List<Map<String, Object>> jsonAggs = (List) jsonRel.get(tag);
173 final List<AggregateCall> inputs =
new ArrayList<>();
174 for (Map<String, Object> jsonAggCall : jsonAggs) {
175 inputs.add(
toAggCall(
this, jsonAggCall));
180 public Object
get(String tag) {
181 return jsonRel.get(tag);
184 public String getString(String tag) {
185 return (String) jsonRel.get(tag);
188 public float getFloat(String tag) {
189 return ((Number) jsonRel.get(tag)).floatValue();
192 public boolean getBoolean(String tag,
boolean default_) {
193 final Boolean b = (Boolean) jsonRel.get(tag);
194 return b != null ? b : default_;
197 public <E extends Enum<E>> E getEnum(String tag, Class<E> enumClass) {
198 return Util.enumVal(enumClass, getString(tag).toUpperCase(Locale.ROOT));
201 public List<RexNode> getExpressionList(String tag) {
202 @SuppressWarnings(
"unchecked")
203 final List<Object> jsonNodes = (List) jsonRel.get(tag);
204 final List<RexNode> nodes =
new ArrayList<>();
205 for (Object jsonNode : jsonNodes) {
206 nodes.add(relJson.toRex(
this, jsonNode));
211 public RelDataType getRowType(String tag) {
212 final Object o = jsonRel.get(tag);
213 return relJson.toType(cluster.getTypeFactory(), o);
216 public RelDataType getRowType(String expressionsTag, String fieldsTag) {
217 final List<RexNode> expressionList = getExpressionList(expressionsTag);
218 @SuppressWarnings(
"unchecked")
219 final List<String> names = (List<String>)
get(fieldsTag);
220 return cluster.getTypeFactory().createStructType(
221 new AbstractList<Map.Entry<String, RelDataType>>() {
223 public Map.Entry<String, RelDataType>
get(
int index) {
224 return Pair.of(names.get(index), expressionList.get(index).getType());
234 public RelCollation getCollation() {
236 return relJson.toCollation((List)
get(
"collation"));
239 public RelDistribution getDistribution() {
240 return relJson.toDistribution(
get(
"distribution"));
243 public ImmutableList<ImmutableList<RexLiteral>> getTuples(String tag) {
245 final List<List> jsonTuples = (List)
get(tag);
246 final ImmutableList.Builder<ImmutableList<RexLiteral>> builder =
247 ImmutableList.builder();
248 for (List jsonTuple : jsonTuples) {
249 builder.add(getTuple(jsonTuple));
251 return builder.build();
254 public ImmutableList<RexLiteral> getTuple(List jsonTuple) {
255 final ImmutableList.Builder<RexLiteral> builder = ImmutableList.builder();
256 for (Object jsonValue : jsonTuple) {
257 builder.add((RexLiteral)
relJson.
toRex(
this, jsonValue));
259 return builder.build();
265 if (!type.equalsIgnoreCase(
"EnumerableTableScan")) {
266 rel = (RelNode) constructor.newInstance(input);
268 Objects.requireNonNull(
cluster);
270 Objects.requireNonNull(jsonRel);
271 Objects.requireNonNull(jsonRel.get(
"table"));
272 Objects.requireNonNull(
273 relOptSchema.getTableForMember((List<String>) jsonRel.get(
"table")));
274 rel = EnumerableTableScan.create(
cluster,
275 relOptSchema.getTableForMember((List<String>) jsonRel.get(
"table")));
279 }
catch (InstantiationException | IllegalAccessException e) {
280 throw new RuntimeException(e);
281 }
catch (InvocationTargetException e) {
282 final Throwable e2 = e.getCause();
283 if (e2 instanceof RuntimeException) {
284 throw(RuntimeException) e2;
286 throw new RuntimeException(e2);
290 private AggregateCall
toAggCall(RelInput relInput, Map<String, Object> jsonAggCall) {
291 final SqlAggFunction aggregation =
292 relJson.toAggregation(relInput, (String) jsonAggCall.get(
"agg"));
293 final Boolean distinct = (Boolean) jsonAggCall.get(
"distinct");
294 @SuppressWarnings(
"unchecked")
295 final List<Integer> operands = (List<Integer>) jsonAggCall.get(
"operands");
296 final Integer filterOperand = (
Integer) jsonAggCall.get(
"filter");
297 final RelDataType
type =
298 relJson.toType(cluster.getTypeFactory(), jsonAggCall.get(
"type"));
299 final String
name = (String) jsonAggCall.get(
"name");
300 return AggregateCall.create(aggregation,
305 filterOperand == null ? -1 : filterOperand,
312 RelNode node = relMap.get(jsonInput);
314 throw new RuntimeException(
315 "unknown id " + jsonInput +
" for relational expression");
static final TypeReference< LinkedHashMap< String, Object > > TYPE_REF
final HeavyDBRelJson relJson
RexNode toRex(RelInput relInput, Object o)
final Map< String, RelNode > relMap
HeavyDBRelJsonReader(RelOptCluster cluster, RelOptSchema relOptSchema, Schema schema)
void readRel(final Map< String, Object > jsonRel)
AggregateCall toAggCall(RelInput relInput, Map< String, Object > jsonAggCall)
RelNode lookupInput(String jsonInput)
void readRels(List< Map< String, Object >> jsonRels)
final RelOptCluster cluster
final RelOptSchema relOptSchema