in c/driver/postgresql/copy/writer.h [568:757]
static inline ArrowErrorCode MakeCopyFieldWriter(
struct ArrowSchema* schema, struct ArrowArrayView* array_view,
const PostgresTypeResolver& type_resolver,
std::unique_ptr<PostgresCopyFieldWriter>* out, ArrowError* error) {
struct ArrowSchemaView schema_view;
NANOARROW_RETURN_NOT_OK(ArrowSchemaViewInit(&schema_view, schema, error));
switch (schema_view.type) {
case NANOARROW_TYPE_BOOL:
using T = PostgresCopyBooleanFieldWriter;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
case NANOARROW_TYPE_INT8:
case NANOARROW_TYPE_INT16:
case NANOARROW_TYPE_UINT8: {
using T = PostgresCopyNetworkEndianFieldWriter<int16_t>;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_INT32:
case NANOARROW_TYPE_UINT16: {
using T = PostgresCopyNetworkEndianFieldWriter<int32_t>;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_UINT32:
case NANOARROW_TYPE_INT64:
case NANOARROW_TYPE_UINT64: {
using T = PostgresCopyNetworkEndianFieldWriter<int64_t>;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_DATE32: {
constexpr int32_t kPostgresDateEpoch = 10957;
using T = PostgresCopyNetworkEndianFieldWriter<int32_t, kPostgresDateEpoch>;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_TIME64: {
switch (schema_view.time_unit) {
case NANOARROW_TIME_UNIT_MICRO:
using T = PostgresCopyNetworkEndianFieldWriter<int64_t>;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
default:
return ADBC_STATUS_NOT_IMPLEMENTED;
}
}
case NANOARROW_TYPE_HALF_FLOAT:
case NANOARROW_TYPE_FLOAT: {
using T = PostgresCopyFloatFieldWriter;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_DOUBLE: {
using T = PostgresCopyDoubleFieldWriter;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_DECIMAL128: {
using T = PostgresCopyNumericFieldWriter<NANOARROW_TYPE_DECIMAL128>;
const auto precision = schema_view.decimal_precision;
const auto scale = schema_view.decimal_scale;
*out = T::Create<T>(array_view, precision, scale);
return NANOARROW_OK;
}
case NANOARROW_TYPE_DECIMAL256: {
using T = PostgresCopyNumericFieldWriter<NANOARROW_TYPE_DECIMAL256>;
const auto precision = schema_view.decimal_precision;
const auto scale = schema_view.decimal_scale;
*out = T::Create<T>(array_view, precision, scale);
return NANOARROW_OK;
}
case NANOARROW_TYPE_BINARY:
case NANOARROW_TYPE_LARGE_BINARY:
case NANOARROW_TYPE_FIXED_SIZE_BINARY:
case NANOARROW_TYPE_BINARY_VIEW:
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_LARGE_STRING:
case NANOARROW_TYPE_STRING_VIEW: {
using T = PostgresCopyBinaryFieldWriter;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_TIMESTAMP: {
switch (schema_view.time_unit) {
case NANOARROW_TIME_UNIT_NANO: {
using T = PostgresCopyTimestampFieldWriter<NANOARROW_TIME_UNIT_NANO>;
*out = T::Create<T>(array_view);
break;
}
case NANOARROW_TIME_UNIT_MILLI: {
using T = PostgresCopyTimestampFieldWriter<NANOARROW_TIME_UNIT_MILLI>;
*out = T::Create<T>(array_view);
break;
}
case NANOARROW_TIME_UNIT_MICRO: {
using T = PostgresCopyTimestampFieldWriter<NANOARROW_TIME_UNIT_MICRO>;
*out = T::Create<T>(array_view);
break;
}
case NANOARROW_TIME_UNIT_SECOND: {
using T = PostgresCopyTimestampFieldWriter<NANOARROW_TIME_UNIT_SECOND>;
*out = T::Create<T>(array_view);
break;
}
}
return NANOARROW_OK;
}
case NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO: {
using T = PostgresCopyIntervalFieldWriter;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
case NANOARROW_TYPE_DURATION: {
switch (schema_view.time_unit) {
case NANOARROW_TIME_UNIT_SECOND: {
using T = PostgresCopyDurationFieldWriter<NANOARROW_TIME_UNIT_SECOND>;
*out = T::Create<T>(array_view);
break;
}
case NANOARROW_TIME_UNIT_MILLI: {
using T = PostgresCopyDurationFieldWriter<NANOARROW_TIME_UNIT_MILLI>;
*out = T::Create<T>(array_view);
break;
}
case NANOARROW_TIME_UNIT_MICRO: {
using T = PostgresCopyDurationFieldWriter<NANOARROW_TIME_UNIT_MICRO>;
*out = T::Create<T>(array_view);
break;
}
case NANOARROW_TIME_UNIT_NANO: {
using T = PostgresCopyDurationFieldWriter<NANOARROW_TIME_UNIT_NANO>;
*out = T::Create<T>(array_view);
break;
}
}
return NANOARROW_OK;
}
case NANOARROW_TYPE_DICTIONARY: {
struct ArrowSchemaView value_view;
NANOARROW_RETURN_NOT_OK(
ArrowSchemaViewInit(&value_view, schema->dictionary, error));
switch (value_view.type) {
case NANOARROW_TYPE_BINARY:
case NANOARROW_TYPE_STRING:
case NANOARROW_TYPE_LARGE_BINARY:
case NANOARROW_TYPE_LARGE_STRING: {
using T = PostgresCopyBinaryDictFieldWriter;
*out = T::Create<T>(array_view);
return NANOARROW_OK;
}
default:
break;
}
break;
}
case NANOARROW_TYPE_LIST:
case NANOARROW_TYPE_LARGE_LIST:
case NANOARROW_TYPE_FIXED_SIZE_LIST: {
// For now our implementation only supports primitive children types
// See PostgresCopyListFieldWriter::Write for limtiations
struct ArrowSchemaView child_schema_view;
NANOARROW_RETURN_NOT_OK(
ArrowSchemaViewInit(&child_schema_view, schema->children[0], error));
PostgresType child_type;
NANOARROW_RETURN_NOT_OK(PostgresType::FromSchema(type_resolver, schema->children[0],
&child_type, error));
std::unique_ptr<PostgresCopyFieldWriter> child_writer;
NANOARROW_RETURN_NOT_OK(MakeCopyFieldWriter(schema->children[0],
array_view->children[0], type_resolver,
&child_writer, error));
if (schema_view.type == NANOARROW_TYPE_FIXED_SIZE_LIST) {
using T = PostgresCopyListFieldWriter<true>;
*out = T::Create<T>(array_view, child_type.oid(), std::move(child_writer));
} else {
using T = PostgresCopyListFieldWriter<false>;
*out = T::Create<T>(array_view, child_type.oid(), std::move(child_writer));
}
return NANOARROW_OK;
}
default:
break;
}
ArrowErrorSet(error, "COPY Writer not implemented for type %d", schema_view.type);
return EINVAL;
}