enspirit / bmg Goto Github PK
View Code? Open in Web Editor NEWBmg, Alf's successor, A Ruby Relational Algebra
License: MIT License
Bmg, Alf's successor, A Ruby Relational Algebra
License: MIT License
I came across a surprising behavior, and I wanted to verify that it is in fact a bug before attempting to fix (I'd be more than happy to submit a patch if this is agreed to be a bug). The bug is that the same query run on an InMemory::Relation
and a Sql::Relation
returns different results.
Consider the following relations:
transactions = Bmg::Relation.new([
{ id: 11, amount: 100, name: 'First Paycheck' },
{ id: 12, amount: 200, name: 'Second Paycheck' },
{ id: 13, amount: -100, name: 'Internet Bill' },
])
tags = Bmg::Relation.new([
{ id: 1, transaction_id: 11, name: 'income' },
{ id: 2, transaction_id: 12, name: 'income' },
{ id: 3, transaction_id: 13, name: 'bill' },
])
transactions
is modeling some financial transactions, and tags
is modeling the ability to tag a transaction with some semantic name, like "income." I'm looking to query all transactions for a given tag. I expressed this with the following query:
transactions.join(tags.restrict(name: 'income'), { id: :transaction_id })
.
Running this on these in-memory relations returns the right result:
[
{:id=>11, :name=>"First Paycheck", :amount=>100}
{:id=>12, :name=>"Second Paycheck", :amount=>200}
]
I get back the two transactions who are tagged as "income."
If you create the same relation in postgres and run the query on relations produced with Bmg.sequel(:transactions, ...), the query returns no results. This is because it produces the following SQL:
SELECT "t1"."id", "t1"."amount", "t1"."name"
FROM "transactions" AS "t1"
INNER JOIN "tags" AS "t2" ON ("t1"."id" = "t2"."id")
WHERE ("t2"."name" = 'income')
If you look at the join clause, the ON condition is: (t1.id = t2.id)
, but by specifying { id: :transaction_id }
in the BMG join
operator, I expected the produced ON condition to be: (t1.id = t2.transaction_id)
.
I can get the produced SQL to be what I expect by reversing the join, i.e. by doing:
tags.restrict(name: 'income').join(transactions, { transaction_id: :id })
.
But because joins in relational algebra are commutative, I would expect both of these to produce the same result. I may be misunderstanding the Hash parameter that gets passed into the join
operator though.
I created a repo that sets up and exposes the bug if someone would like to play around with it in more depth: https://github.com/amw-zero/bmg_query_bug.
Is this a bug or am I using the join
operator incorrectly?
Calling delete
and update
on a Bmg::Relation always results in the operation getting applied to the entire underlying table rather than only the rows in the relation.
For example:
Bmg.sequel(:example, DB).restrict(id: 5).delete
This will attempt to delete the entire example
table, whereas I'd expect this to only delete the row with id = 5.
Looking at the BMG code, it seems like this is intentional. So first off, is there some other way of doing this that I don't know about? And second, do we want to be able to generate SQL for delete operations on subsets of tables?
cc @blambeau
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.