7
7
using namespace duckdb ;
8
8
using namespace cpp11 ;
9
9
10
+ static
10
11
data_ptr_t GetColDataPtr (const RType &rtype, SEXP coldata) {
11
12
switch (rtype.id ()) {
12
13
case RType::LOGICAL:
@@ -51,6 +52,7 @@ data_ptr_t GetColDataPtr(const RType &rtype, SEXP coldata) {
51
52
return (data_ptr_t )DATAPTR_RO (coldata);
52
53
case RTypeId::LIST:
53
54
return (data_ptr_t )DATAPTR_RO (coldata);
55
+ case RTypeId::MATRIX:
54
56
case RTypeId::STRUCT:
55
57
// Will bind child columns dynamically. Could also optimize by descending early and recording.
56
58
return (data_ptr_t )coldata;
@@ -83,6 +85,7 @@ static void AppendColumnSegment(SRC *source_data, idx_t sexp_offset, Vector &res
83
85
}
84
86
}
85
87
88
+ static
86
89
void AppendListColumnSegment (const RType &rtype, SEXP *source_data, idx_t sexp_offset, Vector &result, idx_t count) {
87
90
source_data += sexp_offset;
88
91
auto &result_mask = FlatVector::Validity (result);
@@ -104,9 +107,84 @@ void AppendListColumnSegment(const RType &rtype, SEXP *source_data, idx_t sexp_o
104
107
}
105
108
}
106
109
110
+ template <class SRC , class DST , class RTYPE >
111
+ static inline
112
+ void AppendMatrixSegmentAtomic (SRC *src_ptr, int nrows, int ncols, idx_t sexp_offset,
113
+ Vector &child_vector, idx_t count) {
114
+ auto child_data = FlatVector::GetData<DST>(child_vector);
115
+ auto &child_mask = FlatVector::Validity (child_vector);
116
+ idx_t vector_idx = 0 ;
117
+ for (idx_t i = 0 ; i < count; i++) {
118
+ auto matrix_elt_idx = sexp_offset + i;
119
+ for (idx_t k = 0 ; k < ncols; k++) {
120
+ auto val = src_ptr[matrix_elt_idx];
121
+ if (RTYPE::IsNull (val)) {
122
+ child_mask.SetInvalid (vector_idx++);
123
+ } else {
124
+ child_data[vector_idx++] = RTYPE::Convert (val);
125
+ }
126
+ matrix_elt_idx += nrows;
127
+ }
128
+ }
129
+ }
130
+
131
+ static
132
+ void AppendMatrixColumnSegment (const RType &rtype, bool experimental, SEXP source_data, idx_t sexp_offset, Vector &result, idx_t count) {
133
+ auto element_rtype = rtype.GetMatrixElementType ();
134
+ auto nrows = Rf_nrows (source_data);
135
+ auto ncols = Rf_ncols (source_data);
136
+ auto &child_vector = ArrayVector::GetEntry (result);
137
+
138
+ switch (element_rtype.id ()) {
139
+ case RType::LOGICAL: // LGLSXP
140
+ AppendMatrixSegmentAtomic<int , bool , RBooleanType>(LOGICAL_POINTER (source_data),
141
+ nrows, ncols, sexp_offset, child_vector, count);
142
+ break ;
143
+
144
+ case RType::INTEGER: // INTSXP
145
+ AppendMatrixSegmentAtomic<int , int , RIntegerType>(INTEGER_POINTER (source_data),
146
+ nrows, ncols, sexp_offset, child_vector, count);
147
+ break ;
148
+
149
+ case RType::INTEGER64: // REALSXP
150
+ AppendMatrixSegmentAtomic<int64_t , int64_t , RInteger64Type>((int64_t *)NUMERIC_POINTER (source_data),
151
+ nrows, ncols, sexp_offset, child_vector, count);
152
+ break ;
153
+
154
+ case RType::NUMERIC: // REALSXP
155
+ AppendMatrixSegmentAtomic<double , double , RDoubleType>(NUMERIC_POINTER (source_data),
156
+ nrows, ncols, sexp_offset, child_vector, count);
157
+ break ;
158
+
159
+ case RType::COMPLEX: // CPLXSXP
160
+ cpp11::stop (" Matrix with complex numbers are not supported." );
161
+ break ;
162
+
163
+ case RTypeId::BYTE: // RAWSXP
164
+ cpp11::stop (" Matrix of type raw is not supported." );
165
+ break ;
166
+
167
+ case RType::STRING: // STRSXP
168
+ if (experimental) {
169
+ D_ASSERT (result.GetType ().id () == LogicalTypeId::POINTER);
170
+ AppendMatrixSegmentAtomic<SEXP, uintptr_t , DedupPointerEnumType>((SEXP *)DATAPTR_RO (source_data),
171
+ nrows, ncols, sexp_offset, child_vector, count);
172
+ } else {
173
+ AppendMatrixSegmentAtomic<SEXP, string_t , RStringSexpType>((SEXP *)DATAPTR_RO (source_data),
174
+ nrows, ncols, sexp_offset, child_vector, count);
175
+ }
176
+ break ;
177
+
178
+ default :
179
+ cpp11::stop (" AppendMatrixColumnSegment: Unsupported matrix type for scan" );
180
+ }
181
+ }
182
+
183
+ static
107
184
void AppendAnyColumnSegment (const RType &rtype, bool experimental, data_ptr_t coldata_ptr, idx_t sexp_offset, Vector &v,
108
185
idx_t this_count);
109
186
187
+ static
110
188
void AppendStructColumnSegment (const RType &rtype, bool experimental, SEXP source_data, idx_t sexp_offset,
111
189
Vector &result, idx_t count) {
112
190
// No NULL values for STRUCTs.
@@ -120,6 +198,7 @@ void AppendStructColumnSegment(const RType &rtype, bool experimental, SEXP sourc
120
198
}
121
199
}
122
200
201
+ static
123
202
void AppendAnyColumnSegment (const RType &rtype, bool experimental, data_ptr_t coldata_ptr, idx_t sexp_offset, Vector &v,
124
203
idx_t this_count) {
125
204
switch (rtype.id ()) {
@@ -253,6 +332,11 @@ void AppendAnyColumnSegment(const RType &rtype, bool experimental, data_ptr_t co
253
332
AppendListColumnSegment (rtype, data_ptr, sexp_offset, v, this_count);
254
333
break ;
255
334
}
335
+ case RTypeId::MATRIX: {
336
+ auto data_ptr = (SEXP)coldata_ptr;
337
+ AppendMatrixColumnSegment (rtype, experimental, data_ptr, sexp_offset, v, this_count);
338
+ break ;
339
+ }
256
340
case RTypeId::STRUCT: {
257
341
auto data_ptr = (SEXP)coldata_ptr;
258
342
AppendStructColumnSegment (rtype, experimental, data_ptr, sexp_offset, v, this_count);
0 commit comments