private void GenerateRange(IEnumerable <RangeHPartitioningAttributeDefinition> attributePartitions, List <RangeHPartitionAttributeDefinition> partitionParts,
                            RelationData relation, ref VirtualHPartitioningDefinition result)
 {
     if (attributePartitions.Count() > 0)
     {
         var first = attributePartitions.First();
         foreach (var p in first.Partitions)
         {
             var pp = new List <RangeHPartitionAttributeDefinition>(partitionParts);
             pp.Add(p);
             GenerateRange(attributePartitions.Skip(1), pp, relation, ref result);
         }
     }
     else
     {
         var toPart = partitionParts.Take(partitionParts.Count - 1).Select(x => toSqlValueStringConverter.ConvertStringRepresentation(x.DbType, x.FromValueInclusive)).ToList();
         toPart.Add(partitionParts.Select(x => toSqlValueStringConverter.ConvertStringRepresentation(x.DbType, x.ToValueExclusive)).Last());
         result.PartitionStatements.Add(String.Format("PARTITION OF {0}.{1} FOR VALUES FROM ({2}) TO ({3})",
                                                      relation.SchemaName, relation.Name,
                                                      String.Join(",", partitionParts.Select(x => toSqlValueStringConverter.ConvertStringRepresentation(x.DbType, x.FromValueInclusive))),
                                                      String.Join(",", toPart)
                                                      )
                                        );
     }
 }
        public IVirtualHPartitioning Create(VirtualHPartitioningDefinition definition)
        {
            string partitioningQuery = "SELECT hypopg_partition_table(@RelationName, @PartitioningStatement)";
            string relationFullName  = definition.SchemaName + "." + definition.RelationName;
            var    param             = new
            {
                RelationName          = relationFullName,
                PartitioningStatement = definition.PartitioningStatement
            };

            Execute(partitioningQuery, param);
            int counter = 1;

            foreach (var partitionStatement in definition.PartitionStatements)
            {
                string query         = "SELECT * FROM hypopg_add_partition(@Name, @PartitionStatement)";
                string partitionName = $"hypo_partition_{relationFullName}_{counter})";
                var    param2        = new
                {
                    Name = partitionName,
                    PartitionStatement = partitionStatement
                };
                Execute(query, param2);
                counter++;
            }
            return(null);
        }
        public VirtualHPartitioningDefinition Generate(HPartitioningDefinition hPartitioningDefinition)
        {
            var result = new VirtualHPartitioningDefinition();

            result.PartitionStatements = new HashSet <string>();
            var relation = hPartitioningDefinition.Relation;

            if (hPartitioningDefinition.PartitioningAttributes.First() is RangeHPartitioningAttributeDefinition)
            {
                var partitioningAttributes = hPartitioningDefinition.PartitioningAttributes.Cast <RangeHPartitioningAttributeDefinition>();
                result.PartitioningStatement = String.Format("PARTITION BY RANGE ({0})", String.Join(",", partitioningAttributes.Select(x => x.Attribute.Name)));
                GenerateRange(partitioningAttributes, new List <RangeHPartitionAttributeDefinition>(), relation, ref result);
            }
            else if (hPartitioningDefinition.PartitioningAttributes.First() is HashHPartitioningAttributeDefinition)
            {
                var partitioningAttributes = hPartitioningDefinition.PartitioningAttributes.Cast <HashHPartitioningAttributeDefinition>();
                result.PartitioningStatement = String.Format("PARTITION BY HASH ({0})", String.Join(",", partitioningAttributes.Select(x => x.Attribute.Name)));
                int partitionCounts = partitioningAttributes.Sum(x => x.Modulus);
                for (int i = 0; i < partitionCounts; i++)
                {
                    result.PartitionStatements.Add(String.Format("PARTITION OF {0}.{1} FOR VALUES WITH (MODULUS {2}, REMAINDER {3})",
                                                                 relation.SchemaName, relation.Name, partitionCounts, i
                                                                 )
                                                   );
                }
            }
            result.SchemaName   = hPartitioningDefinition.Relation.SchemaName;
            result.RelationName = hPartitioningDefinition.Relation.Name;
            return(result);
        }