Skip to content

fix: [Postgre] updateBatch() breaks char type data - #8524

Merged
kenjis merged 1 commit into
codeigniter4:developfrom
kenjis:fix-postgre-updateBatch-character
Feb 10, 2024
Merged

fix: [Postgre] updateBatch() breaks char type data#8524
kenjis merged 1 commit into
codeigniter4:developfrom
kenjis:fix-postgre-updateBatch-character

Conversation

@kenjis

@kenjiskenjis commented Feb 7, 2024

Copy link
Copy Markdown
Member

Description
Follow-up #8439
From https://forum.codeigniter.com/showthread.php?tid=89336

Checklist:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

@kenjiskenjis added bug Verified issues on the current code behavior or pull requests that will fix them database Issues or pull requests that affect the database layer labels Feb 7, 2024

@sclubricantssclubricants left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This looks good.

One other option - though I don' t know that it would be any better would be to change CHARACTER into CHARACTER VARYING in the cast method. The only reason is that it would keep the getFieldType() method more 'pure' in a sense. But I'm not sure this would be any better.

@sclubricants

sclubricants commented Feb 9, 2024

Copy link
Copy Markdown
Member

You could change to CHARACTER | CHAR TO VARCHAR in the cast() method. This should cover the other DBMS too.

https://onecompiler.com/postgresql/423ynm2e2

CREATETABLEtest_table
(
id integer,
charchar(10),
varcharvarchar(10)
);
INSERT INTO test_table (id, char, varchar) VALUES (1, 'foo', 'foo');
INSERT INTO test_table (id, char, varchar) VALUES (2, 'bar', 'bar');
INSERT INTO test_table (id, char, varchar) VALUES (3, 'baz', 'baz');
UPDATE"test_table"SET"char"= CAST(_u."char"ASVARCHAR),
"varchar"= CAST(_u."varchar"AS CHARACTER VARYING)
FROM (SELECT'Foo'"char", 1"id", 'Foo'"varchar"UNION ALLSELECT'Bar'"char", 2"id", 'Bar'"varchar"UNION ALLSELECT'Baz'"char", 3"id", 'Baz'"varchar") _u
WHERE"test_table"."id"= CAST(_u."id"ASINTEGER);
SELECT*FROM test_table;
privatefunctioncast($expression, ?string$type): string
{
if (strtoupper($type) === 'CHAR' || strtoupper($type) === 'CHARACTER') {
$type = 'VARCHAR';
}
return ($type === null) ? $expression : 'CAST(' . $expression . ' AS ' . strtoupper($type) . ')';
}

@kenjis

Copy link
Copy Markdown
MemberAuthor

@sclubricants Thank you for the review!

If character (or char) lacks a specifier, it is equivalent to character(1).
So on PostgreSQL, character(n) seems to be correct type.
And it does not seem to be pure to change CHAR to VARCHAR, too.

Anyway, the method is only for Postgre, and it will override even if the parent class has the method.
So I think there is no problem. Go with this for now.

@kenjis
kenjis merged commit 93e281a into codeigniter4:developFeb 10, 2024
@kenjis
kenjis deleted the fix-postgre-updateBatch-character branch February 10, 2024 00:16
@sclubricants

Copy link
Copy Markdown
Member

CHAR = CHARACTER
VARCHAR = CHARACTER VARYING
VARCHAR = CHAR of unspecified length

Anyways, looks good

@sclubricants

Copy link
Copy Markdown
Member
SELECT CAST('STRING'ASVARCHAR) AS TEST;

This runs on postgre but not on mysql

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugVerified issues on the current code behavior or pull requests that will fix themdatabaseIssues or pull requests that affect the database layer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@kenjis@sclubricants@michalsn