private void ProcessTargetEntries(QueryTreeDataInternal result, JToken query) { var setOperations = query.SelectToken("QUERY.setOperations"); if (setOperations.Type == JTokenType.String) // it is empty { var targetEntries = query.SelectToken("QUERY.targetList"); foreach (var child in targetEntries.Children()) { var targetEntry = child.SelectToken("TARGETENTRY"); var expr = targetEntry.SelectToken("expr"); var toAdd = ResolveExpression(result, expr); result.TargetEntries.Add(toAdd); } } else { var rtes = setOperations.SelectTokens("..rtindex").Values <int>(); foreach (var rteNumer in rtes) { var rte = result.Rtes[rteNumer - 1]; var targetEntries = query.SelectToken("QUERY.targetList"); foreach (var child in targetEntries.Children()) { var targetEntry = child.SelectToken("TARGETENTRY"); var expr = targetEntry.SelectToken("expr"); var toAdd = ResolveExpression(result, expr, rteNumer); result.TargetEntries.Add(toAdd); } } } }
private void ProcessCtes(QueryTreeDataInternal result, JToken query) { foreach (var cteChild in query.SelectToken("QUERY.cteList").Children()) { var cteName = cteChild.SelectToken("COMMONTABLEEXPR.ctename").Value <string>(); result.Ctes.Add(cteName, ProcessQuery(result, cteChild.SelectToken("COMMONTABLEEXPR.ctequery"))); } }
private QueryTreeDataInternal FindCte(QueryTreeDataInternal data, string cteName) { if (data.Ctes.ContainsKey(cteName)) { return(data.Ctes[cteName]); } return(FindCte(data.Parent, cteName)); }
private void ProcessHavingClause(QueryTreeDataInternal result, JToken query) { var having = query.SelectToken("QUERY.havingQual"); if (having != null && having.Type != JTokenType.String) { result.HavingQuals.Add(ResolveExpression(result, having)); } }
private void ProcessRtes(QueryTreeDataInternal result, JToken query) { var rTable = query.SelectToken("QUERY.rtable"); foreach (var child in rTable.Children()) { var rte = child.SelectToken("RTE"); Rte rteToAdd = new Rte(); rteToAdd.RteKind = EnumParsingSupport.ConvertFromNumericOrDefault <RteKind>(rte.SelectToken("rtekind").Value <int>()); switch (rteToAdd.RteKind) { case RteKind.Relation: { rteToAdd.RelId = rte.SelectToken("relid").Value <uint>(); rteToAdd.RelKind = EnumParsingSupport.ConvertUsingAttributeOrDefault <RelKind, EnumMemberAttribute, string>(rte.SelectToken("relkind").Value <string>(), x => x.Value); } break; case RteKind.Subquery: { rteToAdd.SubQuery = ProcessQuery(result, rte.SelectToken("subquery")); } break; case RteKind.Join: { rteToAdd.JoinType = EnumParsingSupport.ConvertFromNumericOrDefault <JoinType>(rte.SelectToken("jointype").Value <int>()); foreach (var expr in rte.SelectToken("joinaliasvars").Children()) { rteToAdd.JoinVars.Add(ResolveExpression(result, expr)); } } break; case RteKind.Function: break; case RteKind.TableFunc: break; case RteKind.Values: break; case RteKind.CTE: { rteToAdd.CteName = rte.SelectToken("ctename").Value <string>(); } break; case RteKind.NamedTupleStore: break; } result.Rtes.Add(rteToAdd); } }
private void ProcessGroupClause(QueryTreeDataInternal result, JToken query) { var groupClause = query.SelectToken("QUERY.groupClause"); if (groupClause != null && groupClause.Type != JTokenType.String) { foreach (var child in groupClause.Children()) { result.GroupByEntries.Add(ResolveExpression(result, child)); } } }
public QueryPlanNode Provide(JObject jObject) { QueryTreeDataInternal queryTree = new QueryTreeDataInternal(); ProcessRtes(queryTree, jObject); QueryPlanNode result = null; var plan = jObject.SelectToken("..planTree"); if (plan != null) { result = LoadPlanNode(null, plan, queryTree); } return(result ?? new QueryPlanNode()); }
private QueryTreeDataInternal ProcessQuery(QueryTreeDataInternal parent, JToken query) { QueryTreeDataInternal result = new QueryTreeDataInternal(); result.Parent = parent; result.CommandType = ParseCommandType(query); ProcessCtes(result, query); ProcessRtes(result, query); ProcessTargetEntries(result, query); ProcessJoinTree(result, query); ProcessHavingClause(result, query); ProcessGroupClause(result, query); ProcessSortClause(result, query); return(result); }
private void FillFromCte(QueryTreeDataInternal query, QueryTreeDataInternal cte, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > whereQuals, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > joinQuals, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > havingQuals, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > groupBys, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > orderBys) { if (!whereQuals.ContainsKey(query)) { whereQuals.Add(query, new List <ExpressionResult>()); } if (!joinQuals.ContainsKey(query)) { joinQuals.Add(query, new List <ExpressionResult>()); } if (!havingQuals.ContainsKey(query)) { havingQuals.Add(query, new List <ExpressionResult>()); } if (!groupBys.ContainsKey(query)) { groupBys.Add(query, new List <ExpressionResult>()); } if (!orderBys.ContainsKey(query)) { orderBys.Add(query, new List <ExpressionResult>()); } foreach (var q in cte.WhereQuals) { whereQuals[query].Add(ResolveExpression(q)); } foreach (var q in cte.JoinQuals) { joinQuals[query].Add(ResolveExpression(q)); } foreach (var q in cte.HavingQuals) { havingQuals[query].Add(ResolveExpression(q)); } foreach (var q in cte.GroupByEntries) { groupBys[query].Add(ResolveExpression(q)); } foreach (var q in cte.OrderByEntries) { orderBys[query].Add(ResolveExpression(q)); } }
private void ProcessRtes(QueryTreeDataInternal result, JToken query) { var rTable = query.SelectToken("..rtable"); foreach (var child in rTable.Children()) { var rte = child.SelectToken("RTE"); Rte rteToAdd = new Rte(); rteToAdd.RteKind = EnumParsingSupport.ConvertFromNumericOrDefault <RteKind>(rte.SelectToken("rtekind").Value <int>()); switch (rteToAdd.RteKind) { case RteKind.Relation: { rteToAdd.RelId = rte.SelectToken("relid").Value <uint>(); rteToAdd.RelKind = EnumParsingSupport.ConvertUsingAttributeOrDefault <RelKind, EnumMemberAttribute, string>(rte.SelectToken("relkind").Value <string>(), x => x.Value); } break; } result.Rtes.Add(rteToAdd); } }
private void ProcessJoinTree(QueryTreeDataInternal result, JToken query) { var fromExpr = query.SelectToken("QUERY.jointree.FROMEXPR"); if (fromExpr != null && fromExpr.Type != JTokenType.String) // is not empty { var quals = fromExpr.SelectToken("quals"); if (quals.Type != JTokenType.String) { result.WhereQuals.Add(ResolveExpression(result, quals)); } var fromList = fromExpr.SelectToken("fromlist"); if (fromList.Type != JTokenType.String) { foreach (var joinQuals in fromList.SelectTokens("..quals")) { result.JoinQuals.Add(ResolveExpression(result, joinQuals)); } } } }
private QueryPlanNode LoadPlanNode(QueryPlanNode parent, JToken jObject, QueryTreeDataInternal queryTree) { if (jObject.ToString() != "<>") { var planNode = jObject.First.First; var operationName = ((JProperty)jObject.First).Name.ToUpper(); QueryPlanNode node = new QueryPlanNode(); node.StartupCost = planNode.SelectToken("startup_cost").Value <decimal>(); node.TotalCost = planNode.SelectToken("total_cost").Value <decimal>(); if (operationName.Contains("INDEX") && planNode.SelectToken("indexid") != null) { node.ScanOperation = new AnyIndexScanOperation() { IndexId = planNode.SelectToken("indexid").Value <uint>() }; } else if (operationName == "SEQSCAN" && planNode.SelectToken("scanrelid") != null) { var index = planNode.SelectToken("scanrelid").Value <int>(); var rte = queryTree.Rtes[index - 1]; if (rte.RelKind == RelKind.Relation) { node.ScanOperation = new RelationSequenceScanOperation() { RelationId = rte.RelId.Value }; } } var left = planNode.SelectToken("lefttree"); LoadPlanNode(node, left, queryTree); var right = planNode.SelectToken("righttree"); LoadPlanNode(node, right, queryTree); if (parent != null) { parent.Plans.Add(node); } return(node); } return(null); }
public UnknownExpression(QueryTreeDataInternal source) : base(source) { }
public ExpressionResult(QueryTreeDataInternal source) { Source = source; }
public ConstExpression(QueryTreeDataInternal source) : base(source) { }
public AttributeExpressionResult(QueryTreeDataInternal source) : base(source) { }
public OperatorExpressionResult(QueryTreeDataInternal source) : base(source) { Arguments = new List <ExpressionResult>(); }
private EvalExpression ResolveExpression(QueryTreeDataInternal data, JToken expression, int?forcedRteNumber = null) { var exprType = expression.First.Value <JProperty>().Name; var expressionData = expression?.First?.First; switch (exprType) { case "CONST": { var typeId = expressionData.SelectToken("consttype").Value <uint>(); return(new ConstExpression(data) { TypeID = typeId, DbType = PostgresDbTypeCovertUtility.Convert(EnumParsingSupport.ConvertUsingAttributeOrDefault <PostgresDbType, PostgresDbTypeIdentificationAttribute, long>(typeId, x => x.OID)) }); } case "VAR": { var rteNumber = forcedRteNumber.HasValue ? forcedRteNumber.Value : expressionData.SelectToken("varnoold").Value <int>(); var attributeNumber = expressionData.SelectToken("varoattno").Value <int>(); var levelUpIndex = expressionData.SelectToken("varlevelsup").Value <int>(); var typeId = expressionData.SelectToken("vartype").Value <uint>(); var dataToUse = data; if (levelUpIndex > 0) { for (int i = 0; i < levelUpIndex; i++) { dataToUse = dataToUse.Parent; } } return(new VariableExpression(dataToUse, rteNumber, attributeNumber) { TypeID = typeId, DbType = PostgresDbTypeCovertUtility.Convert(EnumParsingSupport.ConvertUsingAttributeOrDefault <PostgresDbType, PostgresDbTypeIdentificationAttribute, long>(typeId, x => x.OID)) }); } case "RELABELTYPE": { var typeId = expressionData.SelectToken("resulttype").Value <uint>(); expressionData = expressionData.SelectToken("arg"); if (expressionData?.First?.Value <JProperty>().Name == "VAR") { expressionData = expressionData.First.First; var rteNumber = forcedRteNumber.HasValue ? forcedRteNumber.Value : expressionData.SelectToken("varnoold").Value <int>(); var attributeNumber = expressionData.SelectToken("varoattno").Value <int>(); var levelUpIndex = expressionData.SelectToken("varlevelsup").Value <int>(); var dataToUse = data; if (levelUpIndex > 0) { for (int i = 0; i < levelUpIndex; i++) { dataToUse = dataToUse.Parent; } } return(new VariableExpression(dataToUse, rteNumber, attributeNumber) { TypeID = typeId, DbType = PostgresDbTypeCovertUtility.Convert(EnumParsingSupport.ConvertUsingAttributeOrDefault <PostgresDbType, PostgresDbTypeIdentificationAttribute, long>(typeId, x => x.OID)) }); } break; } case "FUNCEXPR": { var typeId = expressionData.SelectToken("funcresulttype").Value <uint>(); var result = new FunctionExpression(data) { ResultTypeID = typeId, ResultDbType = PostgresDbTypeCovertUtility.Convert(EnumParsingSupport.ConvertUsingAttributeOrDefault <PostgresDbType, PostgresDbTypeIdentificationAttribute, long>(typeId, x => x.OID)) }; foreach (var argExpr in expressionData.SelectToken("args").Children()) { result.Arguments.Add(ResolveExpression(data, argExpr, forcedRteNumber)); } return(result); } case "SUBLINK": { return(new SublinkExpression(data) { SubQuery = ProcessQuery(data, expressionData.SelectToken("subselect")) }); } case "BOOLEXPR": { var result = new BooleanExpression(data); result.Operator = expressionData.SelectToken("boolop").Value <string>(); foreach (var argExpr in expressionData.SelectToken("args").Children()) { result.Arguments.Add(ResolveExpression(data, argExpr, forcedRteNumber)); } return(result); } case "OPEXPR": { var typeId = expressionData.SelectToken("opresulttype").Value <uint>(); var result = new OperatorExpression(data) { ResultTypeID = typeId, ResultDbType = PostgresDbTypeCovertUtility.Convert(EnumParsingSupport.ConvertUsingAttributeOrDefault <PostgresDbType, PostgresDbTypeIdentificationAttribute, long>(typeId, x => x.OID)) }; result.OperatorID = expressionData.SelectToken("opno").Value <uint>(); foreach (var argExpr in expressionData.SelectToken("args").Children()) { result.Arguments.Add(ResolveExpression(data, argExpr, forcedRteNumber)); } return(result); } case "AGGREF": { var result = new AggregateExpression(data); foreach (var argExpr in expressionData.SelectToken("args").Children()) { result.Arguments.Add(ResolveExpression(data, argExpr, forcedRteNumber)); } return(result); } case "TARGETENTRY": { var expr = expressionData.SelectToken("expr"); return(ResolveExpression(data, expr, forcedRteNumber)); } case "SCALARARRAYOPEXPR": { var result = new OperatorExpression(data); result.OperatorID = expressionData.SelectToken("opno").Value <uint>(); foreach (var argExpr in expressionData.SelectToken("args").Children()) { result.Arguments.Add(ResolveExpression(data, argExpr, forcedRteNumber)); } return(result); } case "NULLTEST": { var result = new NullTestExpression(data); result.TestType = EnumParsingSupport.ConvertFromNumericOrDefault <NullTestType>(expressionData.SelectToken("nulltesttype").Value <int>()); result.Argument = ResolveExpression(data, expressionData.SelectToken("arg"), forcedRteNumber); return(result); } case "SORTGROUPCLAUSE": { var tleSortGroupRef = expressionData.SelectToken("tleSortGroupRef").Value <int>(); if (tleSortGroupRef > 0) { var query = expression.Parent.Parent.Parent; foreach (var t in query.SelectToken("targetList").Children()) { if (tleSortGroupRef == t.First.First.SelectToken("ressortgroupref").Value <int>()) { var expr = t.First.First.SelectToken("expr"); return(ResolveExpression(data, expr)); } } } break; } } return(new UnknownExpression(data)); }
public NullTestExpressionResult(QueryTreeDataInternal source) : base(source) { TestType = NullTestType.Unknown; }
public AggregateExpressionResult(QueryTreeDataInternal source) : base(source) { Arguments = new List <ExpressionResult>(); }
public VariableExpression(QueryTreeDataInternal source, int rteNumber, int position) : base(source) { RteNumber = rteNumber; Position = position; }
public SublinkExpression(QueryTreeDataInternal source) : base(source) { }
private void FillAllRtesGroups(QueryTreeDataInternal node, Dictionary <QueryTreeDataInternal, List <Rte> > rtes, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > targetResults, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > whereQuals, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > joinQuals, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > havingQuals, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > groupBys, Dictionary <QueryTreeDataInternal, List <ExpressionResult> > orderBys) { if (node == null) { return; } foreach (var rte in node.Rtes) { var query = node; if (rte.SubQuery != null) { FillAllRtesGroups(rte.SubQuery, rtes, targetResults, whereQuals, joinQuals, havingQuals, groupBys, orderBys); } if (!targetResults.ContainsKey(query)) { targetResults.Add(query, new List <ExpressionResult>()); foreach (var e in query.TargetEntries) { var targetResult = ResolveExpression(e); targetResults[query].Add(targetResult); if (targetResult is SublinkExpressionResult) { var sublink = (SublinkExpressionResult)targetResult; FillAllRtesGroups(sublink.SubQuery, rtes, targetResults, whereQuals, joinQuals, havingQuals, groupBys, orderBys); } } } if (!whereQuals.ContainsKey(query)) { whereQuals.Add(query, new List <ExpressionResult>()); foreach (var q in query.WhereQuals) { var exprResult = ResolveExpression(q); whereQuals[query].Add(exprResult); if (exprResult is SublinkExpressionResult) { var sublink = (SublinkExpressionResult)exprResult; FillAllRtesGroups(sublink.SubQuery, rtes, targetResults, whereQuals, joinQuals, havingQuals, groupBys, orderBys); } } } if (!joinQuals.ContainsKey(query)) { joinQuals.Add(query, new List <ExpressionResult>()); foreach (var q in query.JoinQuals) { var exprResult = ResolveExpression(q); joinQuals[query].Add(exprResult); if (exprResult is SublinkExpressionResult) { var sublink = (SublinkExpressionResult)exprResult; FillAllRtesGroups(sublink.SubQuery, rtes, targetResults, whereQuals, joinQuals, havingQuals, groupBys, orderBys); } } } if (!havingQuals.ContainsKey(query)) { havingQuals.Add(query, new List <ExpressionResult>()); foreach (var q in query.HavingQuals) { var exprResult = ResolveExpression(q); havingQuals[query].Add(exprResult); if (exprResult is SublinkExpressionResult) { var sublink = (SublinkExpressionResult)exprResult; FillAllRtesGroups(sublink.SubQuery, rtes, targetResults, whereQuals, joinQuals, havingQuals, groupBys, orderBys); } } } if (!groupBys.ContainsKey(query)) { groupBys.Add(query, new List <ExpressionResult>()); foreach (var q in query.GroupByEntries) { groupBys[query].Add(ResolveExpression(q)); } } if (!orderBys.ContainsKey(query)) { orderBys.Add(query, new List <ExpressionResult>()); foreach (var q in query.OrderByEntries) { orderBys[query].Add(ResolveExpression(q)); } } if (rte.CteName != null) { FillFromCte(query, FindCte(query, rte.CteName), whereQuals, joinQuals, havingQuals, groupBys, orderBys); } if (!rtes.ContainsKey(query)) { rtes.Add(query, new List <Rte>()); } rtes[query].Add(rte); } }
public BooleanExpression(QueryTreeDataInternal source) : base(source) { Arguments = new List <EvalExpression>(); }
public EvalExpression(QueryTreeDataInternal source) { Source = source; }