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

UDF by descriptor parameters sometimes get ttype_dynamic for character set [CORE5315] #5591

Open
firebird-automations opened this issue Jul 22, 2016 · 2 comments

Comments

@firebird-automations
Copy link
Collaborator

Submitted by: Geoff Worboys (gworboys)

Using "by descriptor" parameters a UDF can read the character set of a string input parameter by extracting the lower byte of paramdsc.dsc_sub_type. For example a UDF created to reflect the type and character set of its input parameter will work as expected in the following:

CREATE PROCEDURE TestReflectType (
"Param1" VARCHAR(80) CHARACTER SET WIN1252
) RETURNS (
"Result" VARCHAR(255)
) AS
BEGIN
"Result" = ReflectType("Param1");
SUSPEND;
END

The "Result" comes back reporting the character set was WIN1252 (id=53). However doing the following select from a client:

SELECT ReflectType('abcdef') FROM RDB$DATABASE

reports the character set as 127 - which is the ttype_dynamic value used internally to indicate the attachment character set. This value is not useful to a UDF (it doesn't know the attachment character set), and the ttype_dynamic should probably not escape the engine. The UDF parameter handling needs to be updated to replace ttype_dynamic with the attachment character set.

Note that the following EXECUTE BLOCK exhibits the same behaviour as the SELECT statement:

EXECUTE BLOCK (
"Param1" VARCHAR(80) CHARACTER SET WIN1252 = ?
) RETURNS (
"Result" VARCHAR(255)
) AS
BEGIN
"Result" = ReflectType("Param1");
SUSPEND;
END

But this may be a separate problem - regardless of the UDF parameter handling, "Param1" should have a character set as declared. If I can confirm it is a separate issue I'll raise another ticket and leave a reference to it here.

Edit: The EXECUTE BLOCK situation is a separate issue, see CORE5316

@firebird-automations
Copy link
Collaborator Author

Modified by: Geoff Worboys (gworboys)

description: Using "by descriptor" parameters a UDF can read the character set of a string input parameter by extracting the lower byte of paramdsc.dsc_sub_type. For example a UDF created to reflect the type and character set of its input parameter will work as expected in the following:

CREATE PROCEDURE TestReflectType (
"Param1" VARCHAR(80) CHARACTER SET WIN1252
) RETURNS (
"Result" VARCHAR(255)
) AS
BEGIN
"Result" = ReflectType("Param1");
SUSPEND;
END

The "Result" comes back reporting the character set was WIN1252 (id=53). However doing the following select from a client:

SELECT ReflectType('abcdef') FROM RDB$DATABASE

reports the character set as 127 - which is the ttype_dynamic value used internally to indicate the attachment character set. This value is not useful to a UDF (it doesn't know the attachment character set), and the ttype_dynamic should probably not escape the engine. The UDF parameter handling needs to be updated to replace ttype_dynamic with the attachment character set.

Note that the following EXECUTE BLOCK exhibits the same behaviour as the SELECT statement:

EXECUTE BLOCK (
"Param1" VARCHAR(80) CHARACTER SET WIN1252 = ?
) RETURNS (
"Result" VARCHAR(255)
) AS
BEGIN
"Result" = ReflectType("Param1");
SUSPEND;
END

But this may be a separate problem - regardless of the UDF parameter handling, "Param1" should have a character set as declared. If I can confirm it is a separate issue I'll raise another ticket and leave a reference to it here.

=>

Using "by descriptor" parameters a UDF can read the character set of a string input parameter by extracting the lower byte of paramdsc.dsc_sub_type. For example a UDF created to reflect the type and character set of its input parameter will work as expected in the following:

CREATE PROCEDURE TestReflectType (
"Param1" VARCHAR(80) CHARACTER SET WIN1252
) RETURNS (
"Result" VARCHAR(255)
) AS
BEGIN
"Result" = ReflectType("Param1");
SUSPEND;
END

The "Result" comes back reporting the character set was WIN1252 (id=53). However doing the following select from a client:

SELECT ReflectType('abcdef') FROM RDB$DATABASE

reports the character set as 127 - which is the ttype_dynamic value used internally to indicate the attachment character set. This value is not useful to a UDF (it doesn't know the attachment character set), and the ttype_dynamic should probably not escape the engine. The UDF parameter handling needs to be updated to replace ttype_dynamic with the attachment character set.

Note that the following EXECUTE BLOCK exhibits the same behaviour as the SELECT statement:

EXECUTE BLOCK (
"Param1" VARCHAR(80) CHARACTER SET WIN1252 = ?
) RETURNS (
"Result" VARCHAR(255)
) AS
BEGIN
"Result" = ReflectType("Param1");
SUSPEND;
END

But this may be a separate problem - regardless of the UDF parameter handling, "Param1" should have a character set as declared. If I can confirm it is a separate issue I'll raise another ticket and leave a reference to it here.

Edit: The EXECUTE BLOCK situation is a separate issue, see CORE5316

@firebird-automations
Copy link
Collaborator Author

Commented by: Geoff Worboys (gworboys)

Just confirming that this problem appears to be fixed in Firebird v3 (released version).

This:
SELECT ReflectType('abcdef') FROM RDB$DATABASE

gives the UDF input type as having the client connection character set (rather than 127) - and that makes sense.

Note that this:
SELECT ReflectType(:ParamName) FROM RDB$DATABASE

returns UDF input type as having the database default character set regardless of the connection character set. Definitely better than FB v2.

If you want to close this as "Won't Fix" that's okay with me. Now I know the problem exists I can work around it until I migrate to FB v3.

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

No branches or pull requests

1 participant