コード例 #1
0
 public override void Visit(SqlSelectItem sqlSelectItem)
 {
     sqlSelectItem.Expression.Accept(this);
     if (sqlSelectItem.Alias != null)
     {
         this.writer.Write(" AS ");
         sqlSelectItem.Alias.Accept(this);
     }
 }
コード例 #2
0
        public override int Visit(SqlSelectItem sqlSelectItem)
        {
            int hashCode = SqlSelectItemHashCode;

            hashCode = CombineHashes(hashCode, sqlSelectItem.Expression.Accept(this));
            if (sqlSelectItem.Alias != null)
            {
                hashCode = CombineHashes(hashCode, sqlSelectItem.Alias.Accept(this));
            }

            return(hashCode);
        }
            public override SqlSelectSpec Visit(SqlSelectListSpec selectSpec)
            {
                List <SqlSelectItem> selectItems = new List <SqlSelectItem>();

                foreach (SqlSelectItem selectItem in selectSpec.Items)
                {
                    selectItems.Add(SqlSelectItem.Create(
                                        selectItem.Expression.Accept(this.scalarExpressionTransformer),
                                        selectItem.Alias));
                }

                return(SqlSelectListSpec.Create(selectItems));
            }
コード例 #4
0
        public override SqlObject VisitSelect_list_spec([NotNull] sqlParser.Select_list_specContext context)
        {
            Contract.Requires(context != null);

            List <SqlSelectItem> sqlSelectItems = new List <SqlSelectItem>();

            foreach (sqlParser.Select_itemContext selectItemContext in context.select_item())
            {
                SqlSelectItem selectItem = (SqlSelectItem)this.Visit(selectItemContext);
                sqlSelectItems.Add(selectItem);
            }

            return(SqlSelectListSpec.Create(sqlSelectItems.ToImmutableArray()));
        }
コード例 #5
0
        public override SqlObject VisitSelect_item([NotNull] sqlParser.Select_itemContext context)
        {
            Contract.Requires(context != null);

            SqlScalarExpression sqlScalarExpression = (SqlScalarExpression)this.Visit(context.scalar_expression());
            SqlIdentifier       alias;

            if (context.IDENTIFIER() != null)
            {
                alias = SqlIdentifier.Create(context.IDENTIFIER().GetText());
            }
            else
            {
                alias = default;
            }

            return(SqlSelectItem.Create(sqlScalarExpression, alias));
        }
コード例 #6
0
        public override bool Visit(SqlSelectItem first, SqlObject secondAsObject)
        {
            if (!(secondAsObject is SqlSelectItem second))
            {
                return(false);
            }

            if (!Equals(first.Alias, second.Alias))
            {
                return(false);
            }

            if (!Equals(first.Expression, second.Expression))
            {
                return(false);
            }

            return(true);
        }
コード例 #7
0
        /// <summary>
        /// Repackages and passes an expression from an aggregate subquery back to the parent query.
        /// </summary>
        private SqlExpression CreateAggregateMappingExpression(SqlQuery parentQuery, SqlTable proxyTable, SqlExpression sqlExpr)
        {
            var subQuery = proxyTable.SubQuery.Queries[0];

            string alias         = parentQuery.AliasManager.CreateAlias("aggCol");
            var    groupByColumn = new SqlSelectItem
            {
                Expression = sqlExpr,
                Alias      = alias
            };

            subQuery.SelectClause.Items.Add(groupByColumn);
            subQuery.GroupByClause.Expressions.Add(groupByColumn.Expression);

            // Register an expression that can be used to access the group-by expression
            string mappedSql     = GetColumnSql(proxyTable, alias);
            var    mappedSqlExpr = new SqlExpression(mappedSql);

            SqlExpression.CopyTransforms(sqlExpr, mappedSqlExpr);
            mappedSqlExpr.DatabaseType = sqlExpr.DatabaseType;
            return(mappedSqlExpr);
        }
コード例 #8
0
 public abstract void Visit(SqlSelectItem sqlObject);
コード例 #9
0
 public override SqlObject Visit(SqlSelectItem sqlSelectItem)
 {
     return(SqlSelectItem.Create(
                sqlSelectItem.Expression.Accept(this) as SqlScalarExpression,
                sqlSelectItem.Alias?.Accept(this) as SqlIdentifier));
 }
コード例 #10
0
 public abstract TResult Visit(SqlSelectItem sqlObject);
コード例 #11
0
        public void SqlSelectListSpecTest()
        {
            CosmosObject john = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["name"] = CosmosString.Create("John"),
                ["age"]  = CosmosNumber64.Create(25)
            });

            CosmosObject johnWrapped = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["c"] = john
            });

            // { c.name, c.age }
            SqlScalarExpression cDotName = TestUtils.CreatePathExpression("c", "name");

            SqlScalarExpression cDotAge = TestUtils.CreatePathExpression("c", "age");

            SqlSelectListSpec listSpec = SqlSelectListSpec.Create(
                SqlSelectItem.Create(cDotName),
                SqlSelectItem.Create(cDotAge));

            AssertEvaluation(john, listSpec, johnWrapped);

            // { c.name AS nameAlias }
            CosmosObject johnAliased = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["nameAlias"] = CosmosString.Create("John"),
            });

            SqlSelectListSpec listSpecWithAlias = SqlSelectListSpec.Create(SqlSelectItem.Create(cDotName, SqlIdentifier.Create("nameAlias")));

            AssertEvaluation(johnAliased, listSpecWithAlias, johnWrapped);

            // { 3 + 5 }
            CosmosObject johnNonPropertyName = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["$1"] = CosmosNumber64.Create(8)
            });

            SqlLiteralScalarExpression five          = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(5));
            SqlLiteralScalarExpression three         = SqlLiteralScalarExpression.Create(SqlNumberLiteral.Create(3));
            SqlBinaryScalarExpression  fivePlusThree = SqlBinaryScalarExpression.Create(SqlBinaryScalarOperatorKind.Add, five, three);

            SqlSelectListSpec listSpecNonMember = SqlSelectListSpec.Create(SqlSelectItem.Create(fivePlusThree));

            AssertEvaluation(johnNonPropertyName, listSpecNonMember);

            // { 3 + 5 AS Five Plus Three }
            CosmosObject johnNonPropertyNameAliased = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["Five Plus Three"] = CosmosNumber64.Create(8)
            });
            SqlSelectListSpec listSpecNonMemberAliased = SqlSelectListSpec.Create(SqlSelectItem.Create(fivePlusThree, SqlIdentifier.Create("Five Plus Three")));

            AssertEvaluation(johnNonPropertyNameAliased, listSpecNonMemberAliased);

            // { c.blah[0] }
            CosmosObject numberIndex = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["blah"] = CosmosArray.Create(
                    new List <CosmosElement>()
                {
                    CosmosNumber64.Create(0),
                    CosmosNumber64.Create(1),
                    CosmosNumber64.Create(2)
                })
            });

            CosmosObject numberIndexWrapped = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["c"] = numberIndex
            });

            CosmosObject numberIndexEval = CosmosObject.Create(new Dictionary <string, CosmosElement>
            {
                ["$1"] = CosmosNumber64.Create(0)
            });

            SqlScalarExpression cDotBlah0       = TestUtils.CreatePathExpression("c", "blah", 0);
            SqlSelectListSpec   numberIndexSpec = SqlSelectListSpec.Create(SqlSelectItem.Create(cDotBlah0));

            AssertEvaluation(numberIndexEval, numberIndexSpec, numberIndexWrapped);
        }
コード例 #12
0
 public abstract TOutput Visit(SqlSelectItem sqlObject, TArg input);
コード例 #13
0
        /// <summary>
        ///     Generates SqlTable and sub query for an aggregation.
        /// </summary>
        /// <param name="structuredQuery">The structured query.</param>
        /// <param name="entity">The AggregateEntity that represents the aggregation in the 'from' tree.</param>
        /// <param name="parentTable">The table that this aggregation joins up to. Can be null if the aggregation is being performed at the top level.</param>
        /// <param name="sqlQuery">The query object.</param>
        /// <returns>
        ///     The table
        /// </returns>
        private EntityTables RegisterAggregateEntity(StructuredQuery structuredQuery, AggregateEntity entity, SqlTable parentTable, SqlQuery sqlQuery)
        {
            if (entity.GroupedEntity == null)
            {
                throw new Exception("Aggregate entity must have GroupedEntity set.");
            }
            if (entity.RelatedEntities.Count > 0)
            {
                throw new Exception("Aggregate entity should not have related entities.");                   // note: no logical reason not to, however it's likely indicative of a bug elsewhere
            }

            // Establish sub query
            // Note that sub query has its distinct reference manager for tracking tables and other elements.
            SqlQuery subquery = sqlQuery.CreateSubQuery( );

            subquery.ParentQuery = sqlQuery;
            sqlQuery.Subqueries.Add(subquery);

            // Get joining table for the entity being grouped
            EntityTables childTables =
                BuildEntityTableJoinTree(structuredQuery, entity.GroupedEntity, parentTable, subquery);                   //hmm
            SqlTable childTable = childTables.HeadTable;

            subquery.FromClause.RootTable = childTable;

            // Note: we passed in parentTable above so that the child can learn about the joining column
            // However, it will actually try to join to the table when we don't want it to, so need to manually unlink it afterwards.
            childTable.Parent = null;
            if (parentTable != null)
            {
                parentTable.Children.Remove(childTable);
            }

            // Create the proxy table
            // Note: parentTable may be null for root aggregate
            SqlTable proxyTable = sqlQuery.CreateJoinedTable("",  // not applicable
                                                             "ag", parentTable, JoinHint.Unspecified, childTable.JoinColumn, parentTable?.IdColumn);

            //if the used condition under current aggregate grouped entity or related entities, set joinhint to requried
            if (structuredQuery.Conditions.Any(c => c.Operator != ConditionType.Unspecified &&
                                               c.Operator != ConditionType.IsNull &&
                                               ConditionContainArgument(c) &&
                                               c.Expression is ResourceDataColumn &&
                                               MatchGroupedEntityNode(((ResourceDataColumn)c.Expression).NodeId, entity.GroupedEntity)
                                               ))
            {
                proxyTable.JoinHint = JoinHint.Required;
            }

            //TODO, this hacky code is resolved a special sql query issue (bug 24406), both Pete and me agree with this is not the best solution, but can fix current bug
            //TODO, we can remove this hacky code when report builder allows set the aggregated field in analyzer.
            ConvertConditionExpressionToAggregate(structuredQuery.Conditions, entity);



            proxyTable.SubQuery = new SqlUnion(subquery);
            subquery.ProxyTable = proxyTable;


            // Proxy the join column through the sub query select statement
            // (If it actually joins to something)
            if (childTable.JoinColumn != null)
            {
                string joinColumnAlias = sqlQuery.AliasManager.CreateAlias("aggCol");
                string joinColumnSql   = GetColumnSql(childTable, childTable.JoinColumn);
                var    joinColumn      = new SqlSelectItem
                {
                    Expression = new SqlExpression
                    {
                        Sql = joinColumnSql
                    },
                    Alias = joinColumnAlias
                };
                subquery.SelectClause.Items.Add(joinColumn);
                subquery.GroupByClause.Expressions.Add(joinColumn.Expression);
                proxyTable.JoinColumn = joinColumnAlias;

                var idExpr = new IdExpression
                {
                    NodeId = entity.GroupedEntity.NodeId
                };
                sqlQuery.References.RegisterMappedExpression(idExpr, joinColumn.Expression);
            }

            // Add additional grouping columns
            if (entity.GroupBy != null && entity.GroupBy.Count > 0)
            {
                proxyTable.GroupByMap = new Dictionary <ScalarExpression, SqlExpression>();
                foreach (ScalarExpression expr in entity.GroupBy)
                {
                    try
                    {
                        SqlExpression sqlExpr;
                        if (TryConvertExpression(expr, subquery, false, out sqlExpr))
                        {
                            if (!_querySettings.FullAggregateClustering)
                            {
                                // If we're not clustering everywhere, then explicitly cluster in summarize group-bys still.
                                sqlExpr = ApplyClusterOperation(sqlExpr, expr.ClusterOperation, sqlQuery);
                            }

                            proxyTable.GroupByMap[expr] = sqlExpr;
                            var mappedSqlExpr = CreateAggregateMappingExpression(sqlQuery, proxyTable, sqlExpr);
                            sqlQuery.References.RegisterMappedExpression(expr, mappedSqlExpr);

                            if (sqlExpr.OrderingSqlCallback != null && sqlExpr.OrderingSqlRequiresGrouping)
                            {
                                mappedSqlExpr.OrderingSqlCallback =
                                    exprTmp =>
                                    CreateAggregateOrderbyMappingExpression(sqlQuery, proxyTable, sqlExpr.OrderingSql).Sql;
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }

            // Return proxy table
            return(new EntityTables(proxyTable));
        }