-
Notifications
You must be signed in to change notification settings - Fork 173
feat(c/driver/postgresql): Timestamp write support #861
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
8aa5d49
e630986
289606c
78b817d
776119d
80b21e5
bcd344b
bfbf242
c8f7a6b
60ef31d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -216,6 +216,10 @@ struct BindStream { | |
| type_id = PostgresTypeId::kBytea; | ||
| param_lengths[i] = 0; | ||
| break; | ||
| case ArrowType::NANOARROW_TYPE_TIMESTAMP: | ||
| type_id = PostgresTypeId::kTimestamp; | ||
| param_lengths[i] = 8; | ||
| break; | ||
| default: | ||
| SetError(error, "%s%" PRIu64 "%s%s%s%s", "[libpq] Field #", | ||
| static_cast<uint64_t>(i + 1), " ('", bind_schema->children[i]->name, | ||
|
|
@@ -337,6 +341,31 @@ struct BindStream { | |
| param_values[col] = const_cast<char*>(view.data.as_char); | ||
| break; | ||
| } | ||
| case ArrowType::NANOARROW_TYPE_TIMESTAMP: { | ||
| int64_t val = array_view->children[col]->buffer_views[1].data.as_int64[row]; | ||
| auto unit = bind_schema_fields[col].time_unit; | ||
|
|
||
| // TODO: maybe upstream to nanoarrow as ArrowTimeUnitGetMultiplier | ||
| switch (unit) { | ||
| case NANOARROW_TIME_UNIT_SECOND: | ||
| val *= 1000000; | ||
| break; | ||
| case NANOARROW_TIME_UNIT_MILLI: | ||
| val *= 1000; | ||
| break; | ||
| case NANOARROW_TIME_UNIT_MICRO: | ||
| break; | ||
| case NANOARROW_TIME_UNIT_NANO: | ||
| val /= 1000; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should handle truncation/overflow here |
||
| break; | ||
| } | ||
|
|
||
| // 2000-01-01 00:00:00.000000 in microseconds | ||
| constexpr int64_t kPostgresTimestampEpoch = 946684800000000; | ||
| const uint64_t value = ToNetworkInt64(val - kPostgresTimestampEpoch); | ||
| std::memcpy(param_values[col], &value, sizeof(int64_t)); | ||
| break; | ||
| } | ||
| default: | ||
| SetError(error, "%s%" PRId64 "%s%s%s%s", "[libpq] Field #", col + 1, " ('", | ||
| bind_schema->children[col]->name, | ||
|
|
@@ -605,6 +634,9 @@ AdbcStatusCode PostgresStatement::CreateBulkTable( | |
| case ArrowType::NANOARROW_TYPE_BINARY: | ||
| create += " BYTEA"; | ||
| break; | ||
| case ArrowType::NANOARROW_TYPE_TIMESTAMP: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably differentiate between WITH/WITHOUT TIMEZONE? note that in WITH TIMEZONE, Arrow always stores the underlying value in UTC so there's no need for us to do any time zone math (thankfully!)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. I mistakenly assumed with TIMEZONE was a different type. For this PR planning to just raise if a timezone is detected, as I'm not yet sure how to transmit that information via the binary protocol
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we need to check for timezone here, too? |
||
| create += " TIMESTAMP"; | ||
| break; | ||
| default: | ||
| SetError(error, "%s%" PRIu64 "%s%s%s%s", "[libpq] Field #", | ||
| static_cast<uint64_t>(i + 1), " ('", source_schema.children[i]->name, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -141,7 +141,16 @@ int MakeSchema(struct ArrowSchema* schema, const std::vector<SchemaField>& field | |
| CHECK_ERRNO(ArrowSchemaSetTypeStruct(schema, fields.size())); | ||
| size_t i = 0; | ||
| for (const SchemaField& field : fields) { | ||
| CHECK_ERRNO(ArrowSchemaSetType(schema->children[i], field.type)); | ||
| switch (field.type) { | ||
| case NANOARROW_TYPE_TIMESTAMP: | ||
| // TODO: don't hardcode unit here | ||
| CHECK_ERRNO(ArrowSchemaSetTypeDateTime(schema->children[i], field.type, | ||
| NANOARROW_TIME_UNIT_MICRO, | ||
|
||
| /*timezone=*/nullptr)); | ||
| break; | ||
| default: | ||
| CHECK_ERRNO(ArrowSchemaSetType(schema->children[i], field.type)); | ||
| } | ||
| CHECK_ERRNO(ArrowSchemaSetName(schema->children[i], field.name.c_str())); | ||
| if (!field.nullable) { | ||
| schema->children[i]->flags &= ~ARROW_FLAG_NULLABLE; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.