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));
                }
            }
        }
示例#7
0
        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));
     }
 }
示例#10
0
        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));
                    }
                }
            }
        }
示例#12
0
 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;
 }