   {
     return GDF_SUCCESS;
   }
+
+  // TODO Check if the num_rows is > MAX_ROWS (MAX_INT)
 
   // check that the columns data are not null, have matching types,
   // and the same number of rows

    // a partitioning operator on the hash value. Also computes the number of
    // rows in each partition
    compute_row_partition_numbers<hash_function>
    <<<grid_size, HASH_KERNEL_BLOCK_SIZE, num_partitions * sizeof(size_type)>>>(table_to_hash, 
                                                                                num_rows,
                                                                                num_partitions,
                                                                                partitioner_type(num_partitions),
                                                                                row_partition_numbers,
                                                                                partition_sizes);
  }


  CUDA_CHECK_LAST();

  // Compute exclusive scan of the partition sizes in-place to determine 
  // the starting point for each partition in the output
  size_type * scanned_partition_sizes{partition_sizes};
  thrust::exclusive_scan(thrust::cuda::par,
                         partition_sizes, 
                         partition_sizes + num_partitions, 
                         scanned_partition_sizes);
  CUDA_CHECK_LAST();


  CUDA_CHECK_LAST();

  CUDA_TRY(cudaFree(row_partition_numbers));
  CUDA_TRY(cudaFree(block_partition_sizes));

  cudaStreamSynchronize(s1);
  cudaStreamDestroy(s1);
  CUDA_TRY(cudaFree(partition_sizes));

  return GDF_SUCCESS;
