solnic changed the topic of #rom-rb to: Ruby Object Mapper | Mailing List: https://groups.google.com/forum/?fromgroups#!forum/rom-rb | Logs: http://irclog.whitequark.org/rom-rb
postmodern has quit [Quit: Leaving]
snusnu has joined #rom-rb
snusnu1 has joined #rom-rb
snusnu has quit [Ping timeout: 245 seconds]
snusnu has joined #rom-rb
snusnu1 has quit [Ping timeout: 240 seconds]
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
cored has joined #rom-rb
cored has quit [Changing host]
cored has joined #rom-rb
cored has quit [Ping timeout: 240 seconds]
ahawkins has joined #rom-rb
mbj has joined #rom-rb
<mbj> snusnu: hola
<mbj> snusnu: Sorry for beeing so uncommunicative the last weeks. Very busy.
<mbj> snusnu: I'll be here in two hours in "OSS mode".
<mbj> Doing some mutant work, and I'm happy to chat about all the stuff where my reaction is pending.
<ahawkins> mbj: hey man!
<mbj> ahawkins: hola
<mbj> ahawkins: prepping for some OSS activity.
<ahawkins> mbj: ping me when we can discuss mutant :)
<mbj> ahawkins: I have a nice branch for mutant fixing lots of stuff, see https://github.com/mbj/mutant/pull/186
<mbj> ahawkins: This one centralizes the test selection stuff in a test framework agnostic way.
<mbj> ahawkins: All minitest users have to do is: Returning a list of Mutant::Test instances that has some metadata.
<mbj> ahawkins: Also we can IMO now signalling the "test execution had exception bubbling through the framework" case.
<ahawkins> mbj: colol
<mbj> ahawkins: So its a architectural cleanup.
<ahawkins> mbj: ya I figured as much
<snusnu> yo mbj
<snusnu> mbj: wdyt about adding wrap/group to morpher?
<mbj> snusnu: would make sense.
<mbj> snusnu: Morpher could support RA ops like that one.
<mbj> snusnu: I actually think lots of stuff in axiom could get implemented on top of morpher more easy.
<snusnu> mbj: my motivation is that i cannot really compose relations that have been wrapped/grouped because axiom cannot push down ops like restrictions etc that happen *after* the wrap/group
<mbj> snusnu: Currently an Axiom::Relation is both AST and evaluator.
<snusnu> wrap/group is a bitch wrt sql ..
<mbj> snusnu: splitting the AST from the evaluator makes such domains more easy IMO.
<mbj> snusnu: Also when some poeple on twitter loudly disagree ;)
<snusnu> mbj: do you understand my motivation tho?
<mbj> snusnu: Partially. I need to learn about wrap/unwrap in axiom. I never used that feature so far.
<snusnu> mbj: the thing is this, since sql does not support wrap/group, axiom currently doesn't apply any rewriting rules that would push the wrap/group op up the RA tree .. even if it would, it would not be able to always do it
<snusnu> mbj: the effect of this is that if you apply, say, a restriction to an already wrapped/grouped relation, the op will happen in memory
<snusnu> in practice, this makes it rather unfeasible to use wrap/group in relations that are registered in some schema object
<snusnu> because you cannot further compose them, at least not without loosing performance
<mbj> snusnu: Depends on the optimizer.
<mbj> snusnu: The axiom optimizer is quite nice. And support for doing wrap/unwrap at the minimum efford place in the AST might be possible.
<snusnu> not really, the closure property of RA implies that you can apply, say, a restriction on a TVA (tuple valued attribute) .. making it impossible to push the wrap *after* the restriction
<snusnu> bernard explained the theory over there
<snusnu> so, we have to find some practical middleground that works with SQL without being completely inefficient
<mbj> snusnu: Depends a bit, there are cases where a symetrical composition can happend resulting in the wrap unwrap is still placed nicely.
<mbj> snusnu: But I agree this would be a rare case.
<snusnu> so, i had the thought that morpher might be able to do wrap/group, so that i don't need to add those ops to my relational schema
<mbj> snusnu: Yeah
<snusnu> therefore not risking a performance penalty
<mbj> snusnu: morpher is operating on some kind of a schema-free input. So a wrap/unwrap needs a more complex node than in the axiom case. In axiom you only need to specify the info on *top* of the header.
<snusnu> i expect that it would need to be somewhat scoped inside a hash transform?
<mbj> snusnu: If morpher would know the "type" of the returned data at a given point of the transform tree world would be easier.
<mbj> snusnu: I'd not try to implement it in terms of hash transform.
<mbj> snusnu: hash-transform is a workaround for me not finishing the more primitive nodes hash-transform can be represented with.
<snusnu> i wouldn't either, i was just thinking that semantically, a wrap/group node only makes sense *inside* a hash_transform node
<mbj> snusnu: So if I'm not able to make it happen in a primitive node, I just choose the complex node for now and optimize later.
<snusnu> fair enough
<mbj> snusnu: So you could do the same: Implement it in a custom hash-transform and spot duplication / simplification in future.
<snusnu> there's only one thought that i'm still not decided on just yet … *if* i let morpher handle the wrap/group ops, then i need to define my "mappers" in order to be able to work with wrapped/grouped objects … if i don't let morpher do it, i could *infer* my mappers
<snusnu> hmm
<mbj> snusnu: you can reflect on any morpher node.
<snusnu> i think the best solution would be to try to implement as much optimizations involving wrap/group as possible
<mbj> snusnu: Its not a black-box
<snusnu> that's not the point
<snusnu> if in my relation schema, nothing gets wrapped/grouped, i cannot produce properly wrapped/grouped mappers by reflecting on the relation headers
<mbj> snusnu: ahh
<snusnu> therefore i need to define my mappers explicitly, because at some point, obviously, wrap/group needs to be declared
<mbj> snusnu: you could just add a special case header.
<snusnu> a special case header
<snusnu> ?
<mbj> snusnu: A header with additional metadata, but not doing wrap/group on RA level.
<mbj> A your-app-secific subclass of an axiom header with some metadata you can sue to build wrap/group on morpher level.
<snusnu> there's no way to capture what gets wrapped and what not tho
<snusnu> i mean, there could be, but i dunno
<mbj> I need to do some axiom wrap/unwraps befoe I can say something definitive.
<snusnu> anyways, there might be other reasons why i cannot completely infer the mappers for all the cases anyway
<snusnu> at least not if i want nicely readable attribute names
<snusnu> my database schema is "natural join optimized"
<snusnu> i have fields like accounts.account_id, account_email
<snusnu> i have a naming convention where i always prepend the singularized table name to the attribute name
<snusnu> but here's the thing, obviously, FK attributes MUST NOT have the singularized table name prepended .. they must be left as is, to match primary keys in referenced tables
<snusnu> so, in order to be able to infer that, my schema needs to know about FK constraints first
<snusnu> otherwise, i'd have to specify manual "renamings" in my (morpher dsl) mappers
<mbj> snusnu: Thats not a bad idea.
<mbj> snusnu: The natural join is IMO also a nice idea. But I'd love that it would just be sugar for an explicit join.
<mbj> snusnu: my-best-join = natural_join_semantics + explicit left-right-column-association
<mbj> For internal representation.
<snusnu> i guess inner joins et al can be produced on the sql generator level
<snusnu> out of naturally joined relations
<mbj> I actually do not think natural joins should be used for primary join representation in an algebra.
<mbj> inner joins are just SQL speach
<snusnu> i'm not entirely certain right now, but i somehow think that once you introduce a different kind of join, like solnic wants to in the rom-rb axiom fork, then things start to get screwed up, because of renaming
<snusnu> this stuff has no place in the RA level
<mbj> unrename(join(rename(left), rename(right))) == join(left, right, conditions)
<mbj> where conditions = intersection(rename_for_left, rename_for_right)
<mbj> so I'm fine with both.
<snusnu> the thing is this, once you support Relation#join(other, join_predicates = {}) .. you're essentially saying that either you target SQL specifically, or you do additional renaming yourself in order to transform it into a natural join, which then obviously would need another sql processing to be turned into an inner join
<mbj> Actually I think natural join is best than. But we should have a frontend that produced the more primitive join tree out of the sugared one.
<mbj> snusnu: See how symbolike_key is implemented in morpher. Thats how I'd like to do implement joins in axion.
<snusnu> yeah, the sql processor should be able to rewrite natural joins into sql inner joins and whatnot
<mbj> Internally you use the rename(join(rename(left), rename(right)) construct. Where you could use a join(left, right, conditions) from the AST IR that gets preprocessed into the first one.
<mbj> I need to get active and add that stuff. Its many times more easy than what I had to do for unparser / mutant ;)
<mbj> *morpher
<snusnu> keep in mind tho, that if you support Relation#join(other, predicates = {}) and you translate that into a automatically renamed natural join, there still needs to be some sql processor that turns that natural join into an inner one
<snusnu> or maybe you don't, i dunno
<snusnu> sure you have to
<mbj> snusnu: yeah, i know.
<mbj> snusnu: But requting a renamed natural join in sql to an inner join is *easy*.
<mbj> snusnu: Or emitting an inner join AST from axiom joined AST is also easy.
<mbj> *axiom natural joined.
<snusnu> good to know
<snusnu> i'm not so sure about the automatic renaming tho, that's essentially what we've dubbed the jersey thing back in dm-mapper days
<mbj> snusnu: Its very easy with the AST representation.
<mbj> snusnu: I'd hide renaming from mappers.
<mbj> snusnu: I'd hide renaming from SQL in a way that axiom-ast => sql-ast directly emitts inner joins.
<mbj> Or that an optimizer produces it.
<mbj> snusnu: Should we pair on that? I have a very sharp vision how to do it.
<snusnu> i'm afraid i don't really have time, and also my location isn't best suited for pairing :)
<snusnu> you'd be a lot faster without me
<mbj> snusnu: heh, I'll try. Gonna start an OSS cycle in around 60min.
<snusnu> awesome :)
mbj has quit [Quit: leaving]
ahawkins has quit [Ping timeout: 276 seconds]
snusnu has quit [Quit: Leaving.]
ahawkins_ has joined #rom-rb
lgierth has joined #rom-rb
snusnu has joined #rom-rb
snusnu has quit [Quit: Leaving.]
jordanyee has joined #rom-rb
snusnu has joined #rom-rb
ahawkins_ has quit [Quit: leaving]
jordanyee has quit [Quit: MacBook went to sleep.]
jordanyee has joined #rom-rb
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
lgierth has quit [Ping timeout: 252 seconds]
lgierth has joined #rom-rb
solnic has joined #rom-rb
<solnic> snusnu: ping
snusnu has quit [Quit: Leaving.]
solnic has quit [Quit: Linkinus - http://linkinus.com]
snusnu has joined #rom-rb
lgierth has quit [Quit: Ex-Chat]
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
solnic has joined #rom-rb
<solnic> snusnu: I'm not adding any new joins to axiom. it's still the same stuff, the only diff is that it stores join key predicates so it can be used in sql processing
<solnic> snusnu: also, locally I already have some code that turns axiom's joins into inner sql joins
<solnic> I'll push it later this week
<snusnu> solnic: how does it handle the actual renaming necessary for the natural join tho?
<snusnu> solnic: i mean, how would it be able to perform the natural join in memory, if things haven't been renamed properly
<solnic> snusnu: l.join(r, :id => :user_id) is just a shortcut for l.rename(:id => :user_id).join(r) BUT it stores key predicates
<snusnu> solnic: ok, so you still have to rename other clashing names manually
<snusnu> that's fair enough i guess
<solnic> yes
<solnic> sorry gotta run, ttyl
solnic has quit [Quit: Leaving...]
<snusnu> ok
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
snusnu has quit [Ping timeout: 240 seconds]
lgierth has joined #rom-rb