OmniSciDB  72c90bc290
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HeavyDBRelJsonReader.java
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to you under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package org.apache.calcite.rel.externalize;
18 
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;
23 
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;
44 
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;
53 import java.util.Map;
54 import java.util.Objects;
55 
61 public class HeavyDBRelJsonReader {
62  private static final TypeReference<LinkedHashMap<String, Object>> TYPE_REF =
63  new TypeReference<LinkedHashMap<String, Object>>() {};
64 
65  private final RelOptCluster cluster;
66  private final RelOptSchema relOptSchema;
67  private final HeavyDBRelJson relJson = new HeavyDBRelJson(null);
68  private final Map<String, RelNode> relMap = new LinkedHashMap<>();
69  private RelNode lastRel;
70 
72  RelOptCluster cluster, RelOptSchema relOptSchema, Schema schema) {
73  this.cluster = cluster;
74  this.relOptSchema = relOptSchema;
75  Util.discard(schema);
76  }
77 
78  public RelNode read(String s) throws IOException {
79  lastRel = null;
80  final ObjectMapper mapper = new ObjectMapper();
81  Map<String, Object> o =
82  mapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
83  .readValue(s, TYPE_REF);
84  @SuppressWarnings("unchecked")
85  final List<Map<String, Object>> rels = (List) o.get("rels");
86  readRels(rels);
87  return lastRel;
88  }
89 
90  private void readRels(List<Map<String, Object>> jsonRels) {
91  for (Map<String, Object> jsonRel : jsonRels) {
92  readRel(jsonRel);
93  }
94  }
95 
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);
102  }
103  RelInput input = new RelInput() {
104  public RelOptCluster getCluster() {
105  return cluster;
106  }
107 
108  public RelTraitSet getTraitSet() {
109  return cluster.traitSetOf(Convention.NONE);
110  }
111 
112  public RelOptTable getTable(String table) {
113  final List<String> list = getStringList(table);
114  return relOptSchema.getTableForMember(list);
115  }
116 
117  public RelNode getInput() {
118  final List<RelNode> inputs = getInputs();
119  assert inputs.size() == 1;
120  return inputs.get(0);
121  }
122 
123  public List<RelNode> getInputs() {
124  final List<String> jsonInputs = getStringList("inputs");
125  if (jsonInputs == null) {
126  return ImmutableList.of(lastRel);
127  }
128  final List<RelNode> inputs = new ArrayList<>();
129  for (String jsonInput : jsonInputs) {
130  inputs.add(lookupInput(jsonInput));
131  }
132  return inputs;
133  }
134 
135  public RexNode getExpression(String tag) {
136  return relJson.toRex(this, jsonRel.get(tag));
137  }
138 
139  public ImmutableBitSet getBitSet(String tag) {
140  return ImmutableBitSet.of(getIntegerList(tag));
141  }
142 
143  public List<ImmutableBitSet> getBitSetList(String tag) {
144  List<List<Integer>> list = getIntegerListList(tag);
145  if (list == null) {
146  return null;
147  }
148  final ImmutableList.Builder<ImmutableBitSet> builder = ImmutableList.builder();
149  for (List<Integer> integers : list) {
150  builder.add(ImmutableBitSet.of(integers));
151  }
152  return builder.build();
153  }
154 
155  public List<String> getStringList(String tag) {
156  // noinspection unchecked
157  return (List<String>) jsonRel.get(tag);
158  }
159 
160  public List<Integer> getIntegerList(String tag) {
161  // noinspection unchecked
162  return (List<Integer>) jsonRel.get(tag);
163  }
164 
165  public List<List<Integer>> getIntegerListList(String tag) {
166  // noinspection unchecked
167  return (List<List<Integer>>) jsonRel.get(tag);
168  }
169 
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));
176  }
177  return inputs;
178  }
179 
180  public Object get(String tag) {
181  return jsonRel.get(tag);
182  }
183 
184  public String getString(String tag) {
185  return (String) jsonRel.get(tag);
186  }
187 
188  public float getFloat(String tag) {
189  return ((Number) jsonRel.get(tag)).floatValue();
190  }
191 
192  public boolean getBoolean(String tag, boolean default_) {
193  final Boolean b = (Boolean) jsonRel.get(tag);
194  return b != null ? b : default_;
195  }
196 
197  public <E extends Enum<E>> E getEnum(String tag, Class<E> enumClass) {
198  return Util.enumVal(enumClass, getString(tag).toUpperCase(Locale.ROOT));
199  }
200 
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));
207  }
208  return nodes;
209  }
210 
211  public RelDataType getRowType(String tag) {
212  final Object o = jsonRel.get(tag);
213  return relJson.toType(cluster.getTypeFactory(), o);
214  }
215 
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>>() {
222  @Override
223  public Map.Entry<String, RelDataType> get(int index) {
224  return Pair.of(names.get(index), expressionList.get(index).getType());
225  }
226 
227  @Override
228  public int size() {
229  return names.size();
230  }
231  });
232  }
233 
234  public RelCollation getCollation() {
235  // noinspection unchecked
236  return relJson.toCollation((List) get("collation"));
237  }
238 
239  public RelDistribution getDistribution() {
240  return relJson.toDistribution(get("distribution"));
241  }
242 
243  public ImmutableList<ImmutableList<RexLiteral>> getTuples(String tag) {
244  // noinspection unchecked
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));
250  }
251  return builder.build();
252  }
253 
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));
258  }
259  return builder.build();
260  }
261  };
262  try {
263  RelNode rel;
264 
265  if (!type.equalsIgnoreCase("EnumerableTableScan")) {
266  rel = (RelNode) constructor.newInstance(input);
267  } else {
268  Objects.requireNonNull(cluster);
269  Objects.requireNonNull(relOptSchema);
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")));
276  }
277  relMap.put(id, rel);
278  lastRel = rel;
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;
285  }
286  throw new RuntimeException(e2);
287  }
288  }
289 
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,
301  distinct,
302  false,
303  false,
304  operands,
305  filterOperand == null ? -1 : filterOperand,
306  RelCollations.EMPTY,
307  type,
308  name);
309  }
310 
311  private RelNode lookupInput(String jsonInput) {
312  RelNode node = relMap.get(jsonInput);
313  if (node == null) {
314  throw new RuntimeException(
315  "unknown id " + jsonInput + " for relational expression");
316  }
317  return node;
318  }
319 }
320 
321 // End RelJsonReader.java
static final TypeReference< LinkedHashMap< String, Object > > TYPE_REF
RexNode toRex(RelInput relInput, Object o)
HeavyDBRelJsonReader(RelOptCluster cluster, RelOptSchema relOptSchema, Schema schema)
void readRel(final Map< String, Object > jsonRel)
AggregateCall toAggCall(RelInput relInput, Map< String, Object > jsonAggCall)
void readRels(List< Map< String, Object >> jsonRels)
string name
Definition: setup.in.py:72