开始测试:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.apache.calcite.jdbc.CalciteConnection;
import org.apache.calcite.schema.SchemaPlus;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.ice.adapter.JsonSchema;
public class CalciteTest2 {
public static void main(String[] args) throws Exception {
long begin = System.currentTimeMillis();
new CalciteTest2().run();
long duration = System.currentTimeMillis() - begin;
System.out.println("total:" + duration);
}
public void run() throws ClassNotFoundException, SQLException {
Class.forName("org.apache.calcite.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:calcite:");
CalciteConnection optiqConnection = (CalciteConnection) connection.unwrap(CalciteConnection.class);
SchemaPlus rootSchema = optiqConnection.getRootSchema();
String json = "[{\"CUST_ID\":{\"a\":1},\"PROD_ID\":23.56,\"USER_ID\":300,\"USER_NAME\":\"user1\"},"
+ "{\"USER_ID\":310,\"CUST_ID\":{\"a\":2},\"PROD_ID\":210.45,\"USER_NAME\":\"user2\"},"
+ "{\"USER_ID\":320,\"CUST_ID\":{\"a\":3},\"PROD_ID\":210.46,\"USER_NAME\":\"user3\"},"
+ "{\"USER_ID\":330,\"CUST_ID\":{\"a\":4},\"PROD_ID\":210.47,\"USER_NAME\":\"user4\"},"
+ "{\"USER_ID\":340,\"CUST_ID\":{\"a\":5},\"PROD_ID\":210.48,\"USER_NAME\":\"user5\"},"
+ "{\"USER_ID\":350,\"CUST_ID\":{\"a\":6},\"PROD_ID\":210.49,\"USER_NAME\":\"user6\"},"
+ "{\"USER_ID\":360,\"CUST_ID\":{\"a\":7},\"PROD_ID\":210.40,\"USER_NAME\":\"user7\"}]";
Statement statement = connection.createStatement();
ResultSet resultSet = null;
long begin = System.currentTimeMillis();
for (int i = 0; i < 1; i++) {
rootSchema.add("abc", new JsonSchema("test", json));
resultSet = statement.executeQuery(
"select * from \"abc" + "\".\"test\" order by USER_ID desc limit 2 offset 2 ");
}
System.out.println("query:" + (System.currentTimeMillis() - begin));
while (resultSet.next()) {
JSONObject jo = new JSONObject();
int n = resultSet.getMetaData().getColumnCount();
for (int i = 1; i <= n; i++) {
jo.put(resultSet.getMetaData().getColumnName(i), resultSet.getObject(i));
}
System.out.println(jo.toJSONString());
}
resultSet.close();
statement.close();
connection.close();
}
}
// End JdbcExample.java
Adapter 类封装
package com.yonyou.ice.adapter;
import org.apache.calcite.DataContext;
import org.apache.calcite.linq4j.AbstractEnumerable;
import org.apache.calcite.linq4j.Enumerable;
import org.apache.calcite.linq4j.Enumerator;
import org.apache.calcite.linq4j.Linq4j;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.Types;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.schema.ScannableTable;
import org.apache.calcite.schema.SchemaPlus;
import org.apache.calcite.schema.Schemas;
import org.apache.calcite.schema.Statistic;
import org.apache.calcite.schema.Statistics;
import org.apache.calcite.schema.Table;
import org.apache.calcite.schema.impl.AbstractSchema;
import org.apache.calcite.schema.impl.AbstractTable;
import org.apache.calcite.util.BuiltInMethod;
import org.apache.calcite.util.Pair;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Implementation of {@link org.apache.calcite.schema.Schema} that exposes the
* public fields and methods in a json.
*/
public class JsonSchema extends AbstractSchema {
private String target;
private String topic;
Map<String, Table> table = null;
/**
* Creates a JsonSchema.
*
* @param target
* Object whose fields will be sub-objects of the schema
*/
public JsonSchema(String topic, String target) {
super();
this.topic = topic;
if (!target.startsWith("[")) {
this.target = '[' + target + ']';
} else {
this.target = target;
}
final ImmutableMap.Builder<String, Table> builder = ImmutableMap.builder();
final Table table = fieldRelation();
if (table != null) {
builder.put(topic, table);
this.table = builder.build();
}
}
@Override
public String toString() {
return "JsonSchema(topic=" + topic + ":target=" + target + ")";
}
/**
* Returns the wrapped object.
*
* <p>
* May not appear to be used, but is used in generated code via
* {@link org.apache.calcite.util.BuiltInMethod#REFLECTIVE_SCHEMA_GET_TARGET}
* .
*/
public String getTarget() {
return target;
}
@Override
protected Map<String, Table> getTableMap() {
return table;
}
/**
* Returns an expression for the object wrapped by this schema (not the
* schema itself).
*/
Expression getTargetExpression(SchemaPlus parentSchema, String name) {
return Types.castIfNecessary(target.getClass(),
Expressions.call(Schemas.unwrap(getExpression(parentSchema, name), JsonSchema.class),
BuiltInMethod.REFLECTIVE_SCHEMA_GET_TARGET.method));
}
private <T> Table fieldRelation() {
JSONArray jsonarr = JSON.parseArray(target);
// final Enumerator<Object> enumerator = Linq4j.enumerator(list);
return new JsonTable(jsonarr);
}
private static class JsonTable extends AbstractTable implements ScannableTable {
private final JSONArray jsonarr;
// private final Enumerable<Object> enumerable;
public JsonTable(JSONArray obj) {
this.jsonarr = obj;
}
public RelDataType getRowType(RelDataTypeFactory typeFactory) {
final List<RelDataType> types = new ArrayList<RelDataType>();
final List<String> names = new ArrayList<String>();
JSONObject jsonobj = jsonarr.getJSONObject(0);
for (String string : jsonobj.keySet()) {
final RelDataType type;
type = typeFactory.createJavaType(jsonobj.get(string).getClass());
names.add(string);
types.add(type);
}
if (names.isEmpty()) {
names.add("line");
types.add(typeFactory.createJavaType(String.class));
}
return typeFactory.createStructType(Pair.zip(names, types));
}
public Statistic getStatistic() {
return Statistics.UNKNOWN;
}
public Enumerable<Object[]> scan(DataContext root) {
return new AbstractEnumerable<Object[]>() {
public Enumerator<Object[]> enumerator() {
return new JsonEnumerator(jsonarr);
}
};
}
}
public static class JsonEnumerator implements Enumerator<Object[]> {
private Enumerator<Object[]> enumerator;
public JsonEnumerator(JSONArray jsonarr) {
List<Object[]> objs = new ArrayList<Object[]>();
for (Object obj : jsonarr) {
objs.add(((JSONObject) obj).values().toArray());
}
enumerator = Linq4j.enumerator(objs);
}
public Object[] current() {
return (Object[]) enumerator.current();
}
public boolean moveNext() {
return enumerator.moveNext();
}
public void reset() {
enumerator.reset();
}
public void close() {
enumerator.close();
}
}
}