1//===--------------------------------------------------------------------===//
2// generators.cpp
3// Description: This file contains the implementation of different generators
4//===--------------------------------------------------------------------===//
5
6#include "duckdb/common/exception.hpp"
7#include "duckdb/common/vector_operations/vector_operations.hpp"
8#include "duckdb/common/limits.hpp"
9
10namespace duckdb {
11
12template <class T>
13void TemplatedGenerateSequence(Vector &result, idx_t count, int64_t start, int64_t increment) {
14 D_ASSERT(result.GetType().IsNumeric());
15 if (start > NumericLimits<T>::Maximum() || increment > NumericLimits<T>::Maximum()) {
16 throw Exception("Sequence start or increment out of type range");
17 }
18 result.SetVectorType(VectorType::FLAT_VECTOR);
19 auto result_data = FlatVector::GetData<T>(result);
20 auto value = (T)start;
21 for (idx_t i = 0; i < count; i++) {
22 if (i > 0) {
23 value += increment;
24 }
25 result_data[i] = value;
26 }
27}
28
29void VectorOperations::GenerateSequence(Vector &result, idx_t count, int64_t start, int64_t increment) {
30 if (!result.GetType().IsNumeric()) {
31 throw InvalidTypeException(result.GetType(), "Can only generate sequences for numeric values!");
32 }
33 switch (result.GetType().InternalType()) {
34 case PhysicalType::INT8:
35 TemplatedGenerateSequence<int8_t>(result, count, start, increment);
36 break;
37 case PhysicalType::INT16:
38 TemplatedGenerateSequence<int16_t>(result, count, start, increment);
39 break;
40 case PhysicalType::INT32:
41 TemplatedGenerateSequence<int32_t>(result, count, start, increment);
42 break;
43 case PhysicalType::INT64:
44 TemplatedGenerateSequence<int64_t>(result, count, start, increment);
45 break;
46 case PhysicalType::FLOAT:
47 TemplatedGenerateSequence<float>(result, count, start, increment);
48 break;
49 case PhysicalType::DOUBLE:
50 TemplatedGenerateSequence<double>(result, count, start, increment);
51 break;
52 default:
53 throw NotImplementedException("Unimplemented type for generate sequence");
54 }
55}
56
57template <class T>
58void TemplatedGenerateSequence(Vector &result, idx_t count, const SelectionVector &sel, int64_t start,
59 int64_t increment) {
60 D_ASSERT(result.GetType().IsNumeric());
61 if (start > NumericLimits<T>::Maximum() || increment > NumericLimits<T>::Maximum()) {
62 throw Exception("Sequence start or increment out of type range");
63 }
64 result.SetVectorType(VectorType::FLAT_VECTOR);
65 auto result_data = FlatVector::GetData<T>(result);
66 auto value = (T)start;
67 for (idx_t i = 0; i < count; i++) {
68 auto idx = sel.get_index(idx: i);
69 result_data[idx] = value + increment * idx;
70 }
71}
72
73void VectorOperations::GenerateSequence(Vector &result, idx_t count, const SelectionVector &sel, int64_t start,
74 int64_t increment) {
75 if (!result.GetType().IsNumeric()) {
76 throw InvalidTypeException(result.GetType(), "Can only generate sequences for numeric values!");
77 }
78 switch (result.GetType().InternalType()) {
79 case PhysicalType::INT8:
80 TemplatedGenerateSequence<int8_t>(result, count, sel, start, increment);
81 break;
82 case PhysicalType::INT16:
83 TemplatedGenerateSequence<int16_t>(result, count, sel, start, increment);
84 break;
85 case PhysicalType::INT32:
86 TemplatedGenerateSequence<int32_t>(result, count, sel, start, increment);
87 break;
88 case PhysicalType::INT64:
89 TemplatedGenerateSequence<int64_t>(result, count, sel, start, increment);
90 break;
91 case PhysicalType::FLOAT:
92 TemplatedGenerateSequence<float>(result, count, sel, start, increment);
93 break;
94 case PhysicalType::DOUBLE:
95 TemplatedGenerateSequence<double>(result, count, sel, start, increment);
96 break;
97 default:
98 throw NotImplementedException("Unimplemented type for generate sequence");
99 }
100}
101
102} // namespace duckdb
103