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

fix: support string to number type in JSONB_POPULATE_RECORD #19937

Merged
merged 7 commits into from
Dec 27, 2024

Conversation

zwang28
Copy link
Contributor

@zwang28 zwang28 commented Dec 26, 2024

I hereby agree to the terms of the RisingWave Labs, Inc. Contributor License Agreement.

What's changed and what's your intention?

close #19918

Checklist

  • I have written necessary rustdoc comments.
  • I have added necessary unit tests and integration tests.
  • I have added test labels as necessary.
  • I have added fuzzing tests or opened an issue to track them.
  • My PR contains breaking changes.
  • My PR changes performance-critical code, so I will run (micro) benchmarks and present the results.
  • My PR contains critical fixes that are necessary to be merged into the latest release.

Documentation

  • My PR needs documentation updates.
Release note

@zwang28 zwang28 marked this pull request as ready for review December 26, 2024 06:57
@github-actions github-actions bot added the type/fix Bug fix label Dec 26, 2024
@zwang28
Copy link
Contributor Author

zwang28 commented Dec 26, 2024

Is decimal excluded here by design?

@xiangjinwu

@graphite-app graphite-app bot requested review from a team December 26, 2024 07:15
Comment on lines 327 to 329
if let Some(s) = self.0.as_str() {
F64::from_str(s).map_err(|e| format!("{e}"))
} else {
Copy link
Contributor

@xiangjinwu xiangjinwu Dec 26, 2024

Choose a reason for hiding this comment

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

Keep as_number at its current behavior and let its caller (JSONB_POPULATE_RECORD) to do more work.

Besides JSONB_POPULATE_RECORD, or actually before JSONB_POPULATE_RECORD is supported, this as_number is intended to support CAST. In PostgreSQL:

test=# select ('{"f1":4}'::jsonb -> 'f1')::int;
 int4 
------
    4
(1 row)

test=# select ('{"f1":"4"}'::jsonb -> 'f1')::int;
ERROR:  cannot cast jsonb string to type integer

That is, a JSON string shall NOT be CASTed into integer. But it can be POPULATEed into integer:

test=# select jsonb_populate_record(row(null::int), '{"f1":4}');
 jsonb_populate_record 
-----------------------
 (4)
(1 row)

test=# select jsonb_populate_record(row(null::int), '{"f1":"4"}');
 jsonb_populate_record 
-----------------------
 (4)
(1 row)

This is the PostgreSQL doc on JSONB_POPULATE_RECORD:
https://www.postgresql.org/docs/17/functions-json.html#id-1.5.8.22.8.13.2.2.9.1.2.1

To convert a JSON value to the SQL type of an output column, the following rules are applied in sequence:

  • A JSON null value is converted to an SQL null in all cases.
  • If the output column is of type json or jsonb, the JSON value is just reproduced exactly.
  • If the output column is a composite (row) type, and the JSON value is a JSON object, the fields of the object are converted to columns of the output row type by recursive application of these rules.
  • Likewise, if the output column is an array type and the JSON value is a JSON array, the elements of the JSON array are converted to elements of the output array by recursive application of these rules.
  • Otherwise, if the JSON value is a string, the contents of the string are fed to the input conversion function for the column's data type.
  • Otherwise, the ordinary text representation of the JSON value is fed to the input conversion function for the column's data type.

That is, only null/jsonb/object/array get special treatment. Other cases (bool/number) are always force_str (function defined below) first and then from_text (defined here as the input conversion function).

@xiangjinwu
Copy link
Contributor

xiangjinwu commented Dec 26, 2024

Is decimal excluded here by design?

@xiangjinwu

No. According to the PostgreSQL doc I just shared above, all data types having an input conversion function can be supported.

@zwang28 zwang28 requested a review from xiangjinwu December 26, 2024 08:11
@zwang28 zwang28 enabled auto-merge December 27, 2024 01:47
@zwang28 zwang28 added this pull request to the merge queue Dec 27, 2024
Merged via the queue into main with commit 302c3ca Dec 27, 2024
29 of 30 checks passed
@zwang28 zwang28 deleted the wangzheng/fix_jsonb branch December 27, 2024 03:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/fix Bug fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

JSONB_POPULATE_RECORD cannot convert jsonb strings to number type
3 participants