Skip to content

pdo_firebird: Formatting time zone types #15230

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

Closed
wants to merge 5 commits into from
Closed

pdo_firebird: Formatting time zone types #15230

wants to merge 5 commits into from

Conversation

sim1984
Copy link
Contributor

@sim1984 sim1984 commented Aug 4, 2024

The previous solution for implementing support for Firebird 4.0+ data types was simple, but had a significant drawback. The TIME WITH TIME ZONE and TIMESTAMP WITH TIME ZONE data types were returned as a string, but did not have a fixed format. This patch adds support for formats for types with time zones.

I did not add new attributes with formats, but used the existing ones. That is, the TIME WITH TIME ZONE data types use the output format defined in ATTR_TIME_FORMAT, after which the time zone name is added. The TIMESTAMP WITH TIME ZONE data type uses the ATTR_TIMESTAMP_FORMAT format, after which the time zone name is added.

This solution requires adding new functions from the Firebird object-oriented API. There are no ready-made files for the C language, but they can be created using the CLOOP tool. Thus, these are automatically generated files. I did not add the entire API, since it is quite large, I limited myself to a minimal set of functions for decoding types with time zones.

The Firebird OO API is a set of interfaces. The entry point is the fb_get_master_interface(void) function, which returns a pointer to the Master interface from which all other interfaces can be obtained. There are no classes or abstract classes in C, but the Firebird developers have provided for this. In fact, all interfaces are replaced by structures with a homemade virtual function table, which can be seen in the code. Since a function pointer takes up as much as void*, I replaced the functions that we do not need with a stub.

The amount of code to change is quite large, and I am waiting for help in organizing this patch correctly.

Thank you.

@sim1984 sim1984 requested a review from SakiTakamachi as a code owner August 4, 2024 16:40
@sim1984 sim1984 changed the title Formatting time zone types. Formatting time zone types in pdo_firebird Aug 4, 2024
@sim1984 sim1984 changed the title Formatting time zone types in pdo_firebird pdo_firebird: Formatting time zone types Aug 4, 2024
@sim1984
Copy link
Contributor Author

sim1984 commented Aug 4, 2024

A few more comments. The fb_get_master_interface function in fbclient 3.0+. The functions for formatting types with time zones in fblcient 4.0+. Perhaps some checks should be added inside the code, since many people may still have fbclient 2.5.

@cmb69
Copy link
Member

cmb69 commented Aug 4, 2024

I'm not sure if it's a good idea to include parts of the Firebird API in php-src. At least that appears to warrant some discussion on the internals mailing list.

@SakiTakamachi
Copy link
Member

@sim1984
Do you know if this functionality is provided by FB as an API? If it's unclear, I'm thinking of asking this upstream.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 5, 2024

I can easily check if the Util interface has the required function, since all interfaces have versions. That is, it will not be difficult to install client 3.0 or 4.0. It is not very clear to me how to check for the presence of fb_get_master_interface(void). This function is available starting with fbclient 3.0. But I do not see an easy way to ask the client version. The functions either return numbers 6.3, or a text representation. It is rather reckless to rely on parsing what is returned as text. In general, I will think about this issue.

As for the pieces of Firebird API built into pdo_firebird, it actually does not exist. As I have already described, this is generated text

cloop FirebirdInterface.idl c-header fb_api.h FB_OOAPI_H fb_
cloop FirebirdInterface.idl c-impl fb_api_impl.c fb_api.h fb_

Since these files are quite large, I extracted only the required functionality from them and implemented it into the code.

@cmb69
Copy link
Member

cmb69 commented Aug 7, 2024

@sim1984, do (some) Linux distros actually ship binaries which contain the new Firebird APIs? If so, in which language? C++?

Or asking another way, are there any build instructions for Windows, so we could do these library builds?

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 8, 2024

@sim1984, do (some) Linux distros actually ship binaries which contain the new Firebird APIs? If so, in which language? C++?

I didn't quite get the question. fbclient already contains the Firebird OO API. And it itself is written in C++. Naturally, all exported functions are enclosed in extern "C" {}. In fact, exactly one function is added for the new API (the entry point to the OO API)

extern "C" IMaster* ISC_EXPORT fb_get_master_interface();

It essentially returns a pointer to a structure with function pointers. Something like a virtual method table. These function pointers can return other structures with their own function pointers. In C++, all this is wrapped in classes.

And yes, there are programs (quite a few) on Linux and Windows that successfully use the new API. Let me remind you that it appeared in Firebird 3.0 (2015), now Firebird 5.0 has been released.

Or asking another way, are there any build instructions for Windows, so we could do these library builds?

Are you asking about how to generate API interfaces for different languages?

@cmb69
Copy link
Member

cmb69 commented Aug 9, 2024

fbclient already contains the Firebird OO API. And it itself is written in C++.

Why don't we use C++ to access that API? This shouldn't be a big issue; e.g. ext/intl already uses C++ to use ICU (at least partially). If we want to ensure that users without C++ compiler (are there any nowadays?) can still build ext/pdo_firebird, we could make the C++ code optional (and not support the new datatypes for C builds).

In my opinion, this is much better than relying on an untested automatically generated C API, and bundling this in php-src. And even if for now there are just a couple of functions, these may become more and more in the future.

Or asking another way, are there any build instructions for Windows, so we could do these library builds?

Are you asking about how to generate API interfaces for different languages?

So far we downloaded the Firebird kits (e.g. from https://www.firebirdsql.org/en/firebird-3-0), and repackaged these for our Windows builds (there are headers in include/, and the libraries in libs/). But looking at a Firebird 4.0 kit, it seems there are no libraries for the new C++ API in libs/). So to roll our Windows builds, we would need some instructions how to build the C++ libs, and I now found some at https://www.firebirdsql.org/en/building-the-code/, although that likely builds the Firebird server as well, while we only need the client libraries.

Anyhow, I'll have a closer look at this PR as soon as possible, to understand what is going on. :)

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 10, 2024

I didn't know if it was possible to use C++. But if it is allowed, I can rework this patch. It will be even more convenient for me.

@cmb69
Copy link
Member

cmb69 commented Aug 10, 2024

Let's see if we get feedback on the internals mailing list; I do hope that waiting until after feature freeze (2024-08-13) will not block the general idea of formatting the time zone types.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 10, 2024

Ok, let's wait to see what others think. I have compiled pdo_firebird using C++. All OO API dependent functions are collected in a separate file pdo_firebird_utils.cpp

I am not very good at writing config.m4, so I did a lot based on the intl example, but it's not a fact that everything is correct there. Nevertheless, I successfully managed to build for Ubuntu 22.04 (WSL) and pass the pdo_firebird tests.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 10, 2024

I also have a backup option. Convert to ISC_TIME_TZ_EX and ISC_TIMESTAMP_TZ_EX. These types contain both UTC time and offset in minutes. That is, even without using the OO API, it is possible to display time in this format 2017-05-09 23:55:57 +0360

Time zone identifiers are in include/firebird/TimeZones.h, but the table of names will have to be written separately.

| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Ard Biesheuvel <abies@php.net> |
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
| Author: Ard Biesheuvel <abies@php.net> |
| Author: Denis Simonov |

And add your email address, if it can be public.

Same for the header file below.

@cmb69
Copy link
Member

cmb69 commented Aug 12, 2024

I have compiled pdo_firebird using C++.

In my opinion this is cleaner than the old C version. And now I finally understand what the API is about, and it's good to see that nothing would need to be done regarding the Windows fbclient packages.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 12, 2024

I'll update the code a bit later. Thanks for the review.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 12, 2024

Everything seems to be fine now. All builds are successful.

The only note: the minimum required version is now fbclient 3.0. With fbclient version 2.5 there will be an error: "The procedure entry point fb_get_master_interface was not found in the DLL."

@cmb69
Copy link
Member

cmb69 commented Aug 12, 2024

The only note: the minimum required version is now fbclient 3.0. With fbclient version 2.5 there will be an error: "The procedure entry point fb_get_master_interface was not found in the DLL."

Hmm, If we still want to support that old fbclient, we could probably exclude the not yet guared code in pdo_firebird_utils.cpp/h with #if FB_API_VERSION >= 30. I have no idea whether fbclient 2.5 is still used by anybody; maybe it's still the default for some conservative distros like CentOS.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 12, 2024

The FB_API_VERSION macro is defined in the ibase header file.h and does not determine in any way the version of the fbclient binary library installed on the system. In any case, the fb_get_master_interface call is only required when working with time zone types. Therefore, this is not a big problem. There is a workaround for older versions of fbclient.

@cmb69
Copy link
Member

cmb69 commented Aug 12, 2024

Since nobody objected to require C++ to build PDO_Firebird (at least after clarification), I'm going to apply this PR, particularly to get early feedback about the C++ requirement. We can still fine-tune some details, and if there are strong objections (especially by @SakiTakamachi, who's the code owner of this extension), we can even revert the commit, and look out for an alternative implementation.

Thanks for your work, @sim1984!

@cmb69 cmb69 closed this in 225034d Aug 12, 2024
petk added a commit to petk/php-src that referenced this pull request Aug 13, 2024
Follow-up of phpGH-15230:

- Redundant variables removed
- Redundant duplicate middle newlines removed
- PHP_CXX_COMPILE_STDCXX macro arguments quoted
- When extension is built as shared the PHP_ADD_SOURCES works
  differently, and PHP_ADD_SOURCES_X needs to be used so this can be
  used:

    ./configure --with-pdo-firebird=shared
@petk
Copy link
Member

petk commented Aug 13, 2024

When building extension as shared the PHP_ADD_SOURCES_X macro needs to be used:

./configure --with-pdo-firebird=shared

Should be fixed in #15371

petk added a commit that referenced this pull request Aug 13, 2024
Follow-up of GH-15230:

- Redundant variables removed
- Redundant duplicate middle newlines removed
- PHP_CXX_COMPILE_STDCXX macro arguments quoted
- When extension is built as shared the PHP_ADD_SOURCES works
  differently, and PHP_ADD_SOURCES_X needs to be used so this can be
  used:

    ./configure --with-pdo-firebird=shared
*/

#include "pdo_firebird_utils.h"
#include <firebird/Interface.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

@sim1984 @cmb69 It seems that firebird/Interface.h isn't included in firebird 2.5: is it correct? If so, what about adding a note to the UPGRADING file, declaring the new firebird supported versions (from 3.0 to 5? Is it correct?)

Copy link
Member

Choose a reason for hiding this comment

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

Uh, yes, this needs to be mentioned in these docs files also. So, the 3.0 is the minimum required now?

And then also version needs to be checked in config.m4.

Copy link
Member

Choose a reason for hiding this comment

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

Oh right, I completely forgot about that. However, see #15230 (comment). The question is: is fbclient 2.5 still relevant (i.e. used by any distros we support)?

Copy link
Contributor

Choose a reason for hiding this comment

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

is fbclient 2.5 still relevant (i.e. used by any distros we support)?

I don't think that on Alpine Linux there's a ready to use firebird client (at least, I couldn't find it).
So, the only solution is to manually compile it: when doing so, users can choose the firebird version they are going to install.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Minimum requirements: fbclient version 3.0 or higher. Firebird server itself can be version 2.5, usually if it is on another machine.

Copy link
Member

Choose a reason for hiding this comment

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

See PR #15498.

@sim1984
Copy link
Contributor Author

sim1984 commented Aug 19, 2024

If fbclient 3.0+ is required, some legacy checks can be removed from the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants