Skip to content

Some small tweaks to Red.#404

Open
xinminglai wants to merge 8 commits into
FCO:masterfrom
xinminglai:master
Open

Some small tweaks to Red.#404
xinminglai wants to merge 8 commits into
FCO:masterfrom
xinminglai:master

Conversation

@xinminglai

Copy link
Copy Markdown
Contributor

Hi, These 3 patches add method column-values, and some small fixes for Red::Driver::Pg

Thanks!

@FCO

FCO commented Nov 2, 2019

Copy link
Copy Markdown
Owner

It seems 2 tests are failing with these changes...

Comment thread lib/Red/Driver/Pg.pm6 Outdated
}

multi method translate(Red::AST::In $_, $context?) {
if .right.value ~~ Positional {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Could you, please, put this test on the signature and remove the else?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I mean something like:

multi method translate(Red::AST::In $_ where .right.value ~~ Positional, $context?) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

But, instead of testing the right's value type, it would be better to test if it's an Red::AST::Value and if its .type is Positional.

multi method translate(Red::AST::In $_ where .right ~~ Red::AST::Value && .right.type ~~ Positional, $context?) {

Comment thread lib/Red/Driver/Pg.pm6 Outdated
my ($lstr, @lbind) := do given self.translate: .left, $context { .key, .value }

if .right.value.elems == 0 {
return "$lstr { .op } (SELECT 0 WHERE false)" => @lbind;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Why change to use in (SELECT 0 WHERE false)? why not in ()?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because In Pg, the in () will raise error, So, we should add placehoder statement to select "nothing".

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

In that way, maybe we could do an:

multi method translate(Red::AST::In $_ where .right ~~ Red::AST::Value && .right.type ~~ Positional && .right.elems, $context?) {

?

Comment thread lib/Red/Driver/Pg.pm6 Outdated
self.Red::Driver::CommonSQL::translate($_, $context, :gambi);
}

multi method translate(Red::AST::In $_, $context?) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Isn't it common? Couldn't it be on CommonSQL?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's common, But It's strange that it works in SQLite.

Comment thread lib/Red/Driver/Pg.pm6 Outdated
return "$lstr { .op } (SELECT 0 WHERE false)" => @lbind;
}

my $in-placeholder = '(' ~ (self.wildcard xx .right.value.elems).join(',') ~ ')';

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

If you fix one of my errors (https://github.com/FCO/Red/blob/master/lib/Red/Driver/CommonSQL.pm6#L521) changing "?" to self.wildcard, you could just use the self.translate: .right, $context

Comment thread lib/Red/Driver/Pg.pm6
multi method default-type-for(Red::Column $ --> Str:D) {"varchar(255)"}

multi method type-by-name("text" --> "text") {}
multi method type-by-name("json" --> "json") {}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Could you, please, add a test for json and jsonb?

for SQLite, it re-fetches the row from the model by using LastInsertedRow
class, Then the `.row{@ids}` does the right thing all the time. But in
postgres, the $data will filled by `INSERT INTO table xxx RETURNING *` after
the RETURNING, we'll $data with column names with underscores.
So, in the pg case, We convert the $data structure according to the model, make
$data look like the same as fetched with LastInsertedRow class.
Comment thread t/20-in-pg.t

model Category is table<test_category> {
has Int $.id is serial;
has Int $.parent_id is column{ :references{ Category.id }, :nullable, };

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

This test is failing here. For Red:api<2> you need to set the :model<> for is referencing or :model-name<> in this case... and receive the model type as parameter:

has Int $.parent_if is column{ :references{ .id }, :nullable };

@hermes-fco

Copy link
Copy Markdown

Code Review — Some small tweaks to Red.

Verdict: Comment (0 critical, 5 warnings, 2 suggestions)

Small but useful changes adding column-values method, fixing PG in operator with wildcard delegation, adding type-by-name for text/json/jsonb, and fixing an immutability issue in .^create. 4 files, +64/−3. 7 commits from 2019–2020.

⚠️ Note: This PR is over 5 years old and the author hasn't updated since 2020-01. FCO requested changes in 2019 that were never addressed. This review evaluates the code as-is for archival/merge consideration.


✅ Looks Good

  • lib/Red/Driver/CommonSQL.pm6:526 — Replacing hardcoded '?' with self.wildcard is a clean abstraction. Allows PG driver to use $1/$2 placeholders while SQLite keeps ?.
  • lib/MetamodelX/Red/Model.pm6:454-458 — The %data-copy fix correctly handles the case where row data uses column names vs attribute names, and avoids Raku immutability errors on row results.
  • lib/Red/Driver/Pg.pm6:118-120type-by-name additions for text, json, jsonb use idiomatic Raku value-type return annotations ((--> "text")). Minimal and correct.

⚠️ Warnings

  • t/20-in-pg.t:10-13 — Test file is PG-only and silently skips when RED_PG_TEST_DB env var is unset. This means CI won't run these tests unless the env var is configured. Consider adding a done-testing note or a skip message that's visible in CI logs.
  • t/20-in-pg.t:34-43 — ~7 lines of commented-out exploratory code left in the test file. Should be removed before merging — it adds noise and confusion.
  • No test for column-values — The new public method in MetamodelX::Red::Model has zero test coverage. A simple test verifying the returned hash structure would improve confidence.
  • No test cleanup — The test creates test_category table and records but never drops them. While consistent with other Red test files, this leaves artifacts in the test database.
  • FCO flagged test failures in 2019 — The review from Nov 2019 noted "2 tests are failing with these changes." This was never resolved by the author and should be verified before any merge.

💡 Suggestions

  • t/20-in-pg.t:10-13 — Use skip-rest inside a without $*RED-PG-TEST-DB block for cleaner Raku idiom:
    without $*RED-PG-TEST-DB {
        skip-rest "No RED_PG_TEST_DB env var set";
        exit;
    }
  • lib/MetamodelX/Red/Model.pm6:85-87 — The column-values method maps via %!attr-to-column{.name} as the hash key. Consider documenting this returns DB column names (not attribute names), since the distinction may surprise users.

📊 Stats

Metric Value
Files changed 4
Lines added +64
Lines removed −3
New tests t/20-in-pg.t (48 lines, PG-only, env-gated)
Security scan Clean — no secrets, debuggers, or merge conflicts

Reviewed by Hermes Agent

@hermes-fco

Copy link
Copy Markdown

Code Review — Some small tweaks to Red

Verdict: Comment (0 critical, 1 warning, 2 suggestions)

PR adds column-values method, fixes $data immutability in creates, improves IN placeholder via self.wildcard, and registers Pg types (text/json/jsonb). 4 files, +64/−3.


✅ Looks Good

  • column-values method — clean, concise implementation. Already landed in master's .rakumod migration.
  • self.wildcard replacement — correct fix; already landed in master at CommonSQL.rakumod:739.
  • %data-copy workaround — sensible defense against immutable Map exceptions during create+id-filter.

⚠️ Warnings

  • t/20-in-pg.t:19$GLOBAL::RED-DB should be $*RED-DB. $GLOBAL:: bypasses the dynamic variable lookup and will silently point at the wrong DB (or Nil) in any scope where $*RED-DB is locally overridden. This is a bug.
    #
    $GLOBAL::RED-DB = database "Pg", :dbname($*RED-PG-TEST-DB);
    #
    $*RED-DB = database "Pg", :dbname($*RED-PG-TEST-DB);

💡 Suggestions

  • Repo has migrated from .pm6 to .rakumod — this PR targets files that no longer exist on master (Model.pm6, CommonSQL.pm6, Pg.pm6). The column-values and self.wildcard changes have already been incorporated into the .rakumod equivalents. The remaining Pg type-by-name additions could be ported to Pg.rakumod if still needed.
  • t/20-in-pg.t:8plan 2 declared at top, but skip-rest 2 at line 9 means the plan count is technically wrong when the env var is missing (0 tests run, plan expects 2). Consider plan 2 unless $skip or moving plan after the guard.

📊 Stats

Metric Value
Files changed 4
Lines added +64
Lines removed −3
New tests 1 test file (t/20-in-pg.t)
Security scan Clean

Reviewed by Hermes Agent

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.

3 participants