Skip to content
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

Add automatic type conversion to row::get() #1127

Closed
wants to merge 5 commits into from

Conversation

zann1x
Copy link
Contributor

@zann1x zann1x commented Feb 27, 2024

As discussed in #1088, it is possible that the merge of #1116 might require users to use a different data type when calling row::get<T>(...).

This PR tries to add implicit conversions between data types in the most conservative way. I.e., conversions are only defined between integer types.
Unit tests that previously had to be changed to conform to the stricter type mapping are also reverted back to their old state.

The work here is based on #1097.

@zann1x zann1x force-pushed the automatic-conversion branch 4 times, most recently from 46976e3 to c0355f2 Compare February 29, 2024 21:40
@zann1x
Copy link
Contributor Author

zann1x commented Mar 5, 2024

I honestly don't understand why the MSVC build is failing with warning C4702: unreachable code because AFAICS these parts are actually used in the tests. Should I just disable C4702 for this file?

Copy link
Member

@vadz vadz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the functionality provided by this PR definitely looks very useful.

It's a bit of a pity to replace a type-safe type_holder template with a union, I'm not sure to understand why did it have to be done, I guess it's because template get() can't be virtual? But, in any case, if it has to be done like this, so be it.

include/soci/type-holder.h Outdated Show resolved Hide resolved
Comment on lines 350 to 351
default:
break;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we throw here too?

In any case, please remove the default label to get the warnings here too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why this should throw as the constructor is private and it is only called during preparation for statement execution.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be unreachable, right? I.e. it might be better to use std::unreachable() here but as long as we can't do this, throwing seems better than doing nothing.

@@ -37,6 +37,9 @@
//base class must have dll interface
#pragma warning(disable:4251 4275)

// As long as we don't require C++17, we must disable the warning
// "conditional expression is constant"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add the context here, i.e. where would this warning be given?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TBH I don't understand this error either. But as it didn't seem to be local to type-holder.h, I suppressed it here.
The failing build was this one: https://ci.appveyor.com/project/SOCI/soci/builds/49285927/job/fikvgmaiqq11a9np

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the line refers to the val > static_cast<U>(t_max) test? If so, I can understand why the compiler would warn about it, as it could be always false for some types, but I'm not sure how to avoid it. Using pragma push/pop around this test might be better than suppressing the warning globally, however, it's a potentially useful one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. I'll move the pragma push/pop to this section.

tests/common-tests.h Outdated Show resolved Hide resolved
include/soci/type-holder.h Outdated Show resolved Hide resolved
Comment on lines 118 to 122
{
static_assert(std::is_same<T, void>::value, "Unmatched raw type");
// dummy value to satisfy the template engine, never used
static const db_type type = (db_type)0;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we actually have to define it? I.e. could we just declare it without defining it?

static const db_type type = db_date;
};

// Base class for storing type data instances in a container of holder objects
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it actually "base"? It doesn't look like we inherit from it any longer.

@vadz
Copy link
Member

vadz commented Mar 5, 2024

I honestly don't understand why the MSVC build is failing with warning C4702: unreachable code because AFAICS these parts are actually used in the tests. Should I just disable C4702 for this file?

If possible (i.e. if it works), I'd disable it for this function with #pragma push/pop, as usual.

@vadz vadz added this to the 4.1.0 milestone Mar 5, 2024
@zann1x
Copy link
Contributor Author

zann1x commented Mar 5, 2024

It's a bit of a pity to replace a type-safe type_holder template with a union, I'm not sure to understand why did it have to be done, I guess it's because template get() can't be virtual? But, in any case, if it has to be done like this, so be it.

In an eariler attempt to fixing this issue, I've had problems getting it to work with the old class hierarchy setup that isn't explicit about its db_type. I think it was a problem of having a templated get() which I wasn't able to combine with the templated type_holder::value(). As #1097 followed that same route, I honestly didn't think about an alternative way.

@vadz
Copy link
Member

vadz commented Mar 5, 2024

I've had problems getting it to work with the old class hierarchy setup that isn't explicit about its db_type. I think it was a problem of having a templated get() which I wasn't able to combine with the templated type_holder::value()

I think it should be possible to do it by having template function in the base (non-template) class using virtual functions overridden in the derived template class, but I really don't have time to try it, so I'm just leaving it here as an idea, but will merge it as is if you decide not to follow it.

BTW, forgot to say: @Sildra if you have any comments about this, please let us know if you have any comments about this.

@zann1x
Copy link
Contributor Author

zann1x commented Mar 6, 2024

I think it should be possible to do it by having template function in the base (non-template) class using virtual functions overridden in the derived template class, but I really don't have time to try it, so I'm just leaving it here as an idea, but will merge it as is if you decide not to follow it.

I'm sorry but I really don't know/understand how to achieve that, so I would just leave it as is.

@vadz
Copy link
Member

vadz commented Mar 19, 2024

Sorry, it looks like this got conflicts due to the changes of #992, i.e. it needs to be adjusted to support movable types, such as blobs. Could you please check if this can be fixed? TIA!

@zann1x
Copy link
Contributor Author

zann1x commented Mar 22, 2024

I rebased the branch onto main and added a commit to support movable types.
The quickest solution I came up with was a separate get() method that returns a reference to the underlying value if and only if the types are matching. That was the easiest way to ensure that moving from that value is okay.

Unforunately, I don't have the time to create a more sophisticated solution at the moment. If there is more to do, it would be great if someone is willing to pick it up from here.

@vadz
Copy link
Member

vadz commented Mar 27, 2024

Thanks again! I'll merge this soon.

vadz pushed a commit that referenced this pull request Mar 27, 2024
Convert to the requested type if lossless conversion is possible to make
the behaviour more compatible with the previous SOCI versions and more
useful.

See #1127.
@vadz
Copy link
Member

vadz commented Mar 27, 2024

Squash-merged now in the commit above.

@vadz vadz closed this Mar 27, 2024
@zann1x zann1x deleted the automatic-conversion branch April 20, 2024 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants