// 单表复杂查询条件 // SCHOOL=1 AND (ID=4 OR ID=3) // 应该展开为 // (SCHOOL=1 AND ID=4) OR (SCHOOL=1 AND ID=3) @Test public void test_单表查询_复杂条件展开() { TableNode table = new TableNode("TABLE1"); table.query("SCHOOL=1 AND (ID=4 OR ID=3)"); extraCmd.put(ConnectionProperties.CHOOSE_INDEX_MERGE, true); IQueryTree qc = (IQueryTree) optimizer.optimizeAndAssignment(table, null, extraCmd); extraCmd.put(ConnectionProperties.CHOOSE_INDEX_MERGE, false); Assert.assertTrue(qc instanceof IMerge); Assert.assertTrue(((IMerge) qc).isUnion()); // 是union查询 Assert.assertTrue(((IMerge) qc).getSubNodes().get(0) instanceof IQuery); Assert.assertTrue(((IMerge) qc).getSubNodes().get(1) instanceof IQuery); IQuery query1 = (IQuery) ((IMerge) qc).getSubNodes().get(0); Assert.assertEquals("TABLE1.ID = 4", query1.getKeyFilter().toString()); Assert.assertEquals("TABLE1.SCHOOL = 1", query1.getValueFilter().toString()); IQuery query2 = (IQuery) ((IMerge) qc).getSubNodes().get(1); Assert.assertEquals("TABLE1.ID = 3", query2.getKeyFilter().toString()); Assert.assertEquals("TABLE1.SCHOOL = 1", query2.getValueFilter().toString()); }
@Test public void test_单表查询_无条件() { TableNode table = new TableNode("TABLE1"); QueryTreeNode qn = table; IQueryTree qc = (IQueryTree) optimizer.optimizeAndAssignment(qn, null, extraCmd); Assert.assertTrue(qc instanceof IMerge); Assert.assertEquals(QUERY_CONCURRENCY.SEQUENTIAL, ((IMerge) qc).getQueryConcurrency()); // 串行 IDataNodeExecutor dne = ((IMerge) qc).getSubNodes().get(0); Assert.assertTrue(dne instanceof IQuery); IQuery query = (IQuery) dne; Assert.assertEquals(null, query.getKeyFilter()); Assert.assertEquals(null, query.getValueFilter()); }
// 单表主键查询 // ID为主键,同时在ID上存在索引 // 因为!=不能使用主键索引 // valueFilter为ID!=1 @Test public void test_单表查询_主键条件_不等于只能是valueFilter() { TableNode table = new TableNode("TABLE1"); table.query("ID != 1"); IQueryTree qc = (IQueryTree) optimizer.optimizeAndAssignment(table, null, extraCmd); Assert.assertTrue(qc instanceof IMerge); Assert.assertEquals( QUERY_CONCURRENCY.GROUP_CONCURRENT, ((IMerge) qc).getQueryConcurrency()); // 并行 IDataNodeExecutor dne = ((IMerge) qc).getSubNodes().get(0); Assert.assertTrue(dne instanceof IQuery); IQuery query = (IQuery) dne; Assert.assertEquals(null, query.getKeyFilter()); Assert.assertEquals("TABLE1.ID != 1", query.getValueFilter().toString()); }
// 单表非主键索引查询 // NAME上存在索引 // 会生成一个Join节点 // 左边通过NAME索引找到满足条件的PK,keyFilter应该为NAME=1 // 与pk->data Join // Join类型为IndexNestLoop @Test public void test_单表查询_value条件() { TableNode table = new TableNode("TABLE1"); table.query("NAME = 1"); IQueryTree qc = (IQueryTree) optimizer.optimizeAndAssignment(table, null, extraCmd); Assert.assertTrue(qc instanceof IMerge); Assert.assertEquals( QUERY_CONCURRENCY.GROUP_CONCURRENT, ((IMerge) qc).getQueryConcurrency()); // 并行 IDataNodeExecutor dne = ((IMerge) qc).getSubNodes().get(0); Assert.assertTrue(dne instanceof IJoin); IJoin join = (IJoin) dne; IQuery left = (IQuery) join.getLeftNode(); Assert.assertEquals("TABLE1._NAME.NAME = 1", left.getKeyFilter().toString()); }
// 单表or查询 // 查询条件由or连接, // 由于NAME和ID上存在索引,所以会生成两个子查询 // or的两边分别作为子查询的keyFilter // 由于NAME=2323的子查询为非主键索引查询 // 所以此处会生成一个join节点 // 最后一个merge节点用于合并子查询的结果 @Test public void test_单表查询_OR条件_1() { TableNode table = new TableNode("TABLE1"); table.query("NAME = 2323 OR ID=1"); extraCmd.put(ConnectionProperties.CHOOSE_INDEX_MERGE, true); IQueryTree qc = (IQueryTree) optimizer.optimizeAndAssignment(table, null, extraCmd); extraCmd.put(ConnectionProperties.CHOOSE_INDEX_MERGE, false); Assert.assertTrue(qc instanceof IMerge); Assert.assertTrue(((IMerge) qc).isUnion()); // 是union查询 Assert.assertTrue(((IMerge) qc).getSubNodes().get(0) instanceof IQuery); IQuery query = (IQuery) ((IMerge) qc).getSubNodes().get(0); Assert.assertEquals("TABLE1.ID = 1", query.getKeyFilter().toString()); Assert.assertTrue(((IMerge) qc).getSubNodes().get(1) instanceof IMerge); Assert.assertTrue( ((IMerge) ((IMerge) qc).getSubNodes().get(1)).getSubNodes().get(0) instanceof IJoin); IJoin join = (IJoin) ((IMerge) ((IMerge) qc).getSubNodes().get(1)).getSubNodes().get(0); Assert.assertEquals( "TABLE1._NAME.NAME = 2323", ((IQuery) join.getLeftNode()).getKeyFilter().toString()); }