private bool TryOptimizeIN(SelectASTNode selectASTNode, ReadLogicalElement input, TableDefinition tableDefinition, out CartesianProductElement result) { if (selectASTNode.Condition is RelOpASTNode relOpASTNode && relOpASTNode.RelationOperator == Compiler.Common.RelOp.In) { SelectASTNode innerSelectASTNode = null; IdentifierASTNode outerIdentifierASTNode = null; if (relOpASTNode.Right is SelectASTNode) { innerSelectASTNode = (SelectASTNode)relOpASTNode.Right; if (relOpASTNode.Left is IdentifierASTNode) { outerIdentifierASTNode = (IdentifierASTNode)relOpASTNode.Left; } } if (relOpASTNode.Right is IdentifierASTNode) { outerIdentifierASTNode = (IdentifierASTNode)relOpASTNode.Right; if (relOpASTNode.Left is SelectASTNode) { innerSelectASTNode = (SelectASTNode)relOpASTNode.Left; } } if (innerSelectASTNode != null && outerIdentifierASTNode != null) { result = new CartesianProductElement(input, GetElementForTreeNode(innerSelectASTNode) as ReadLogicalElement, GetColumnFromIdentifierNode(tableDefinition, outerIdentifierASTNode), SelectColumnsToColumns(_relationManager.GetTable(innerSelectASTNode.From.Identifier.Identifier), innerSelectASTNode.SelectColumns).First().AttributeDefinition); return(true); } } result = null; return(false); }
private LogicalElement GetElementForTreeNode(SyntaxTreeNode node) { if (node is SelectASTNode selectASTNode) { Table table = _relationManager.GetTable(selectASTNode.From.Identifier.Identifier); ReadLogicalElement result = new RelationElement(table.TableDefinition); Condition condition = null; if (selectASTNode.Condition != null) { condition = BooleanExpressionToCondition(table.TableDefinition, selectASTNode.Condition); //// todo: IN (1,2,3) //// todo: IN (select id from products) AND x = 1 //if (TryOptimizeIN(selectASTNode, result, table.TableDefinition, out CartesianProductElement productElement)) //{ // result = productElement; //} //else //{ //} } if (selectASTNode.Join != null) { Join join = JoinNodeToJoin(table.TableDefinition, selectASTNode.Join); ReadLogicalElement joinRelation = new RelationElement(join.RightTable); if (condition != null) { (Condition leftPushedDownCondition, Condition leftover1) = TryPushdown((RelationElement)result, condition); (Condition rightPushedDownCondition, Condition leftover2) = TryPushdown((RelationElement)joinRelation, leftover1); leftPushedDownCondition = leftPushedDownCondition.Simplify(); rightPushedDownCondition = rightPushedDownCondition.Simplify(); condition = leftover2?.Simplify(); if (leftPushedDownCondition != null) { result = new SelectionElement(result, leftPushedDownCondition); } if (rightPushedDownCondition != null) { joinRelation = new SelectionElement(joinRelation, rightPushedDownCondition); } } else { result = new RelationElement(table.TableDefinition); joinRelation = new RelationElement(join.RightTable); } result = new CartesianProductElement(result, joinRelation, join.LeftColumn, join.RightColumn); } else { result = new RelationElement(table.TableDefinition); } if (condition != null) { result = new SelectionElement(result, condition); } result = new ProjectionElement(result, SelectColumnsToColumns(table, selectASTNode.SelectColumns)); return(result); } else if (node is InsertASTNode insertASTNode) { Table table = _relationManager.GetTable(insertASTNode.Into.Identifier); Set set = new Set(table.TableDefinition); set.Add(insertASTNode.Arguments.Select(x => GetValueFromFactor(x)).ToArray()); return(new InsertElement(table.TableDefinition, new MemorySetElement(table.TableDefinition, set))); } return(null); }