use of org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory in project ignite-3 by apache.
the class SortedIndexSpoolPlannerTest method testPartialIndexForCondition.
/**
* Check case when exists index (collation) isn't applied not for whole join condition but may be used by part of
* condition.
*/
@Test
public void testPartialIndexForCondition() throws Exception {
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
publicSchema.addTable("T0", new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("JID0", f.createJavaType(Integer.class)).add("JID1", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "T0", "hash");
}
});
publicSchema.addTable("T1", new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("JID0", f.createJavaType(Integer.class)).add("JID1", f.createJavaType(Integer.class)).add("VAL", f.createJavaType(String.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "T1", "hash");
}
}.addIndex(RelCollations.of(ImmutableIntList.of(1, 0)), "t1_jid0_idx"));
String sql = "select * " + "from t0 " + "join t1 on t0.jid0 = t1.jid0 and t0.jid1 = t1.jid1";
IgniteRel phys = physicalPlan(sql, publicSchema, "MergeJoinConverter", "NestedLoopJoinConverter", "FilterSpoolMergeToHashIndexSpoolRule");
System.out.println("+++ \n" + RelOptUtil.toString(phys));
IgniteSortedIndexSpool idxSpool = findFirstNode(phys, byClass(IgniteSortedIndexSpool.class));
List<RexNode> lowerBound = idxSpool.indexCondition().lowerBound();
assertNotNull(lowerBound);
assertEquals(4, lowerBound.size());
assertTrue(((RexLiteral) lowerBound.get(0)).isNull());
assertTrue(((RexLiteral) lowerBound.get(2)).isNull());
assertTrue(((RexLiteral) lowerBound.get(3)).isNull());
assertTrue(lowerBound.get(1) instanceof RexFieldAccess);
List<RexNode> upperBound = idxSpool.indexCondition().upperBound();
assertNotNull(upperBound);
assertEquals(4, upperBound.size());
assertTrue(((RexLiteral) upperBound.get(0)).isNull());
assertTrue(((RexLiteral) lowerBound.get(2)).isNull());
assertTrue(((RexLiteral) lowerBound.get(3)).isNull());
assertTrue(upperBound.get(1) instanceof RexFieldAccess);
}
use of org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory in project ignite-3 by apache.
the class UnionPlannerTest method prepareSchema.
/**
* Create schema for tests.
*
* @return Ignite schema.
*/
private IgniteSchema prepareSchema() {
IgniteTypeFactory f = new IgniteTypeFactory(IgniteTypeSystem.INSTANCE);
TestTable tbl1 = new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("NAME", f.createJavaType(String.class)).add("SALARY", f.createJavaType(Double.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "Table1", "hash");
}
};
TestTable tbl2 = new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("NAME", f.createJavaType(String.class)).add("SALARY", f.createJavaType(Double.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "Table2", "hash");
}
};
TestTable tbl3 = new TestTable(new RelDataTypeFactory.Builder(f).add("ID", f.createJavaType(Integer.class)).add("NAME", f.createJavaType(String.class)).add("SALARY", f.createJavaType(Double.class)).build()) {
@Override
public IgniteDistribution distribution() {
return IgniteDistributions.affinity(0, "Table3", "hash");
}
};
IgniteSchema publicSchema = new IgniteSchema("PUBLIC");
publicSchema.addTable("TABLE1", tbl1);
publicSchema.addTable("TABLE2", tbl2);
publicSchema.addTable("TABLE3", tbl3);
return publicSchema;
}
use of org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory in project ignite-3 by apache.
the class LogicalRelImplementor method visit.
/**
* {@inheritDoc}
*/
@Override
public Node<RowT> visit(IgniteTableScan rel) {
RexNode condition = rel.condition();
List<RexNode> projects = rel.projects();
ImmutableBitSet requiredColumns = rel.requiredColumns();
InternalIgniteTable tbl = rel.getTable().unwrap(InternalIgniteTable.class);
assert tbl != null;
IgniteTypeFactory typeFactory = ctx.getTypeFactory();
RelDataType rowType = tbl.getRowType(typeFactory, requiredColumns);
Predicate<RowT> filters = condition == null ? null : expressionFactory.predicate(condition, rowType);
Function<RowT, RowT> prj = projects == null ? null : expressionFactory.project(projects, rowType);
ColocationGroup group = ctx.group(rel.sourceId());
if (!group.nodeIds().contains(ctx.localNodeId())) {
return new ScanNode<>(ctx, rowType, Collections.emptyList());
}
return new TableScanNode<>(ctx, rowType, tbl, group.partitions(ctx.localNodeId()), filters, prj, requiredColumns);
}
use of org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory in project ignite-3 by apache.
the class LogicalRelImplementor method visit.
/**
* {@inheritDoc}
*/
@Override
public Node<RowT> visit(IgniteIndexScan rel) {
// TODO: fix this
// RexNode condition = rel.condition();
// List<RexNode> projects = rel.projects();
InternalIgniteTable tbl = rel.getTable().unwrap(InternalIgniteTable.class);
IgniteTypeFactory typeFactory = ctx.getTypeFactory();
ImmutableBitSet requiredColumns = rel.requiredColumns();
// List<RexNode> lowerCond = rel.lowerBound();
// List<RexNode> upperCond = rel.upperBound();
RelDataType rowType = tbl.getRowType(typeFactory, requiredColumns);
// Predicate<Row> filters = condition == null ? null : expressionFactory.predicate(condition, rowType);
// Supplier<Row> lower = lowerCond == null ? null : expressionFactory.rowSource(lowerCond);
// Supplier<Row> upper = upperCond == null ? null : expressionFactory.rowSource(upperCond);
// Function<Row, Row> prj = projects == null ? null : expressionFactory.project(projects, rowType);
//
// IgniteIndex idx = tbl.getIndex(rel.indexName());
//
// ColocationGroup group = ctx.group(rel.sourceId());
Iterable<RowT> rowsIter = (Iterable<RowT>) List.of(new Object[] { 0, 0 }, // idx.scan(ctx, group, filters, lower, upper, prj, requiredColumns);
new Object[] { 1, 1 });
return new ScanNode<>(ctx, rowType, rowsIter);
}
use of org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory in project ignite-3 by apache.
the class RelJson method toRex.
RexNode toRex(RelInput relInput, Object o) {
RelOptCluster cluster = relInput.getCluster();
RexBuilder rexBuilder = cluster.getRexBuilder();
if (o == null) {
return null;
} else if (o instanceof Map) {
Map map = (Map) o;
Map<String, Object> opMap = (Map) map.get("op");
IgniteTypeFactory typeFactory = Commons.typeFactory(cluster);
if (opMap != null) {
if (map.containsKey("class")) {
opMap.put("class", map.get("class"));
}
List operands = (List) map.get("operands");
List<RexNode> rexOperands = toRexList(relInput, operands);
Object jsonType = map.get("type");
Map window = (Map) map.get("window");
if (window != null) {
final SqlAggFunction operator = (SqlAggFunction) toOp(opMap);
final RelDataType type = toType(typeFactory, jsonType);
final List<RexNode> partitionKeys = window.containsKey("partition") ? toRexList(relInput, (List) window.get("partition")) : new ArrayList<>();
List<RexFieldCollation> orderKeys = new ArrayList<>();
if (window.containsKey("order")) {
orderKeys = toRexFieldCollationList(relInput, (List) window.get("order"));
}
RexWindowBound lowerBound;
RexWindowBound upperBound;
boolean physical;
if (window.get("rows-lower") != null) {
lowerBound = toRexWindowBound(relInput, (Map) window.get("rows-lower"));
upperBound = toRexWindowBound(relInput, (Map) window.get("rows-upper"));
physical = true;
} else if (window.get("range-lower") != null) {
lowerBound = toRexWindowBound(relInput, (Map) window.get("range-lower"));
upperBound = toRexWindowBound(relInput, (Map) window.get("range-upper"));
physical = false;
} else {
// No ROWS or RANGE clause
lowerBound = null;
upperBound = null;
physical = false;
}
boolean distinct = (Boolean) map.get("distinct");
return rexBuilder.makeOver(type, operator, rexOperands, partitionKeys, ImmutableList.copyOf(orderKeys), lowerBound, upperBound, physical, true, false, distinct, false);
} else {
SqlOperator operator = toOp(opMap);
RelDataType type;
if (jsonType != null) {
type = toType(typeFactory, jsonType);
} else {
type = rexBuilder.deriveReturnType(operator, rexOperands);
}
return rexBuilder.makeCall(type, operator, rexOperands);
}
}
Integer input = (Integer) map.get("input");
if (input != null) {
// Check if it is a local ref.
if (map.containsKey("type")) {
RelDataType type = toType(typeFactory, map.get("type"));
return map.get("dynamic") == Boolean.TRUE ? rexBuilder.makeDynamicParam(type, input) : rexBuilder.makeLocalRef(type, input);
}
List<RelNode> inputNodes = relInput.getInputs();
int i = input;
for (RelNode inputNode : inputNodes) {
RelDataType rowType = inputNode.getRowType();
if (i < rowType.getFieldCount()) {
RelDataTypeField field = rowType.getFieldList().get(i);
return rexBuilder.makeInputRef(field.getType(), input);
}
i -= rowType.getFieldCount();
}
throw new RuntimeException("input field " + input + " is out of range");
}
String field = (String) map.get("field");
if (field != null) {
Object jsonExpr = map.get("expr");
RexNode expr = toRex(relInput, jsonExpr);
return rexBuilder.makeFieldAccess(expr, field, true);
}
String correl = (String) map.get("correl");
if (correl != null) {
RelDataType type = toType(typeFactory, map.get("type"));
return rexBuilder.makeCorrel(type, new CorrelationId(correl));
}
if (map.containsKey("literal")) {
Object literal = map.get("literal");
RelDataType type = toType(typeFactory, map.get("type"));
if (literal == null) {
return rexBuilder.makeNullLiteral(type);
}
if (type.getSqlTypeName() == SqlTypeName.SYMBOL) {
literal = toEnum(literal);
}
return rexBuilder.makeLiteral(literal, type, false);
}
throw new UnsupportedOperationException("cannot convert to rex " + o);
} else if (o instanceof Boolean) {
return rexBuilder.makeLiteral((Boolean) o);
} else if (o instanceof String) {
return rexBuilder.makeLiteral((String) o);
} else if (o instanceof Number) {
Number number = (Number) o;
if (number instanceof Double || number instanceof Float) {
return rexBuilder.makeApproxLiteral(BigDecimal.valueOf(number.doubleValue()));
} else {
return rexBuilder.makeExactLiteral(BigDecimal.valueOf(number.longValue()));
}
} else {
throw new UnsupportedOperationException("cannot convert to rex " + o);
}
}
Aggregations