Search in sources :

Example 16 with IgniteTypeFactory

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);
}
Also used : IgniteSortedIndexSpool(org.apache.ignite.internal.sql.engine.rel.IgniteSortedIndexSpool) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) IgniteRel(org.apache.ignite.internal.sql.engine.rel.IgniteRel) IgniteDistribution(org.apache.ignite.internal.sql.engine.trait.IgniteDistribution) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema) RexFieldAccess(org.apache.calcite.rex.RexFieldAccess) RexNode(org.apache.calcite.rex.RexNode) Test(org.junit.jupiter.api.Test)

Example 17 with IgniteTypeFactory

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;
}
Also used : IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) RelDataTypeFactory(org.apache.calcite.rel.type.RelDataTypeFactory) IgniteSchema(org.apache.ignite.internal.sql.engine.schema.IgniteSchema)

Example 18 with IgniteTypeFactory

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);
}
Also used : ColocationGroup(org.apache.ignite.internal.sql.engine.metadata.ColocationGroup) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) InternalIgniteTable(org.apache.ignite.internal.sql.engine.schema.InternalIgniteTable) TableScanNode(org.apache.ignite.internal.sql.engine.exec.rel.TableScanNode) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType) ScanNode(org.apache.ignite.internal.sql.engine.exec.rel.ScanNode) TableScanNode(org.apache.ignite.internal.sql.engine.exec.rel.TableScanNode) RexNode(org.apache.calcite.rex.RexNode)

Example 19 with IgniteTypeFactory

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);
}
Also used : InternalIgniteTable(org.apache.ignite.internal.sql.engine.schema.InternalIgniteTable) ImmutableBitSet(org.apache.calcite.util.ImmutableBitSet) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) RelDataType(org.apache.calcite.rel.type.RelDataType) ScanNode(org.apache.ignite.internal.sql.engine.exec.rel.ScanNode) TableScanNode(org.apache.ignite.internal.sql.engine.exec.rel.TableScanNode)

Example 20 with IgniteTypeFactory

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);
    }
}
Also used : RelOptCluster(org.apache.calcite.plan.RelOptCluster) SqlOperator(org.apache.calcite.sql.SqlOperator) IgniteTypeFactory(org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlAggFunction(org.apache.calcite.sql.SqlAggFunction) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) RexWindowBound(org.apache.calcite.rex.RexWindowBound) RexBuilder(org.apache.calcite.rex.RexBuilder) ImmutableIntList(org.apache.calcite.util.ImmutableIntList) List(java.util.List) ArrayUtils.asList(org.apache.ignite.internal.util.ArrayUtils.asList) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) CorrelationId(org.apache.calcite.rel.core.CorrelationId) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

IgniteTypeFactory (org.apache.ignite.internal.sql.engine.type.IgniteTypeFactory)80 Test (org.junit.jupiter.api.Test)48 RelDataType (org.apache.calcite.rel.type.RelDataType)47 IgniteSchema (org.apache.ignite.internal.sql.engine.schema.IgniteSchema)27 ImmutableBitSet (org.apache.calcite.util.ImmutableBitSet)22 RelDataTypeFactory (org.apache.calcite.rel.type.RelDataTypeFactory)21 AggregateCall (org.apache.calcite.rel.core.AggregateCall)19 IgniteRel (org.apache.ignite.internal.sql.engine.rel.IgniteRel)19 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)17 RexNode (org.apache.calcite.rex.RexNode)12 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)11 ArrayList (java.util.ArrayList)10 SchemaPlus (org.apache.calcite.schema.SchemaPlus)8 IgniteDistribution (org.apache.ignite.internal.sql.engine.trait.IgniteDistribution)8 PlanningContext (org.apache.ignite.internal.sql.engine.prepare.PlanningContext)7 List (java.util.List)6 MappingQueryContext (org.apache.ignite.internal.sql.engine.prepare.MappingQueryContext)6 MultiStepPlan (org.apache.ignite.internal.sql.engine.prepare.MultiStepPlan)6 MultiStepQueryPlan (org.apache.ignite.internal.sql.engine.prepare.MultiStepQueryPlan)6 QueryTemplate (org.apache.ignite.internal.sql.engine.prepare.QueryTemplate)6