dkubb / axiom Goto Github PK
View Code? Open in Web Editor NEWSimplifies querying of structured data using relational algebra
Home Page: https://github.com/dkubb/axiom
License: MIT License
Simplifies querying of structured data using relational algebra
Home Page: https://github.com/dkubb/axiom
License: MIT License
Hello,
During 'grape' gem integration (rack API framework) and Mongoid I encountered an issue with ActiveSupport and Axiom.
Final stacktrace occurs while calling Class that is including Mongoid::Document.
ArgumentError: comparison of Class with Class failed
from org/jruby/RubyComparable.java:168:in `<'
from /Users/ernest.bursa/.rvm/gems/jruby-1.7.6@ayeappz/gems/activesupport-4.0.1/lib/active_support/core_ext/class/subclasses.rb:19:in `descendants'
from org/jruby/RubyObjectSpace.java:173:in `each_object'
...
I have examined that there is problem with class Axiom::Types::Infinity. That class can not be compared to other classes (done by ActiveSupport in subclasses.rb)
Excerpt from subclasses.rb:
def descendants # :nodoc:
...
rescue StandardError # JRuby
def descendants # :nodoc:
descendants = []
ObjectSpace.each_object(Class) do |k|
descendants.unshift k if k < self # fails here
end
descendants.uniq!
descendants
end
end
Are we able to make Axiom::Types::Infinity comparable?
Looks like a ton of tests are failing with this error.
I am upgrading from Veritas to Axiom and noticed that my custom tuple enumerator is breaking now because of automatic object graph freezing that is now happening. Example that illustrates the problem:
require 'adamantium'
# both must be true to avoid exception
DONT_AUTO_FREEZE=false
OVERRIDE_FREEZE_OBJECT=false
if DONT_AUTO_FREEZE
module Adamantium
module ClassMethods
def new(*)
#freezer.freeze(super)
super
end
end
end
end
require 'axiom'
if OVERRIDE_FREEZE_OBJECT
Axiom::Relation.class_eval do
private
def freeze_object(object); object; end
end
end
class CustomEnumerator < Enumerator
def initialize(tuple_source)
@array_will_freeze = []
super() do |y|
@array_will_freeze << "sadf"
tuple_source.each do |t|
p t
y << t
end
end
end
end
tuple_enumerator = CustomEnumerator.new([[1, "one"],[2,"two"],[3,"three"],[4,"four"],[5,"five"]])
relation = Axiom::Relation.new([ [ :id, Integer ], [ :value, String ] ], tuple_enumerator)
p relation.restrict { |r| r.id.gt(2).and(r.id.lt(4)) }.to_a
p relation.restrict { |r| r.id.gt(1).and(r.id.lt(3)) }.to_a
p relation.restrict { |r| r.id.gt(3).and(r.id.lt(5)) }.to_a
if both changes enabled by DONT_AUTO_FREEZE
and OVERRIDE_FREEZE_OBJECT
are not enabled, the following exception occurs:
axiom_test.rb:30:in `block in initialize': can't modify frozen Array (RuntimeError)
from /home/aaron/.rvm/gems/ruby-1.9.3-p429@flatfiles/gems/axiom-0.1.0/lib/axiom/relation.rb:109:in `each'
from /home/aaron/.rvm/gems/ruby-1.9.3-p429@flatfiles/gems/axiom-0.1.0/lib/axiom/relation.rb:109:in `each'
from /home/aaron/.rvm/gems/ruby-1.9.3-p429@flatfiles/gems/axiom-0.1.0/lib/axiom/relation.rb:109:in `each'
from /home/aaron/.rvm/gems/ruby-1.9.3-p429@flatfiles/gems/axiom-0.1.0/lib/axiom/algebra/restriction.rb:51:in `each'
from axiom_test.rb:42:in `to_a'
from axiom_test.rb:42:in `<main>'
This is obviously a contrived example. See (sort of) real use case here:
https://github.com/ahamid/flatfiles/blob/master/lib/flatfiles/record_file_enumerator.rb
https://github.com/ahamid/flatfiles/blob/master/lib/flatfiles/veritas/tuple_provider.rb#L71
Is there really an assumption that the tuple enumerator represents a static, frozen content? I am a bit confused by how Adamantium is configured but Axiom::Relation
appears to be inheriting Adamantium functionality via its inclusion of Equalizer
:
https://github.com/dkubb/axiom/blob/master/lib/axiom/relation.rb#L8
(it appears that the module inclusion hook is called both for Equalizer and Relation)
Following some conversations of the dm2 team about the rspecs new expetation syntax. Are you interested to convert available specs to the new syntax? I can help with that.
Given two relations of different types, testing them for equality should always return false.
Veritas::TABLE_DEE == Veritas::Relation.new([ [:ID, Integer] ], [ [20] ])
# => true
This is a bug. The only relations that should ever be considered equal are those that have the same headers and the same set of tuples (order irrelevant).
The issue comes from the fact Veritas is coercing and projecting the other side of the comparison to match itself, before doing the comparison, which breaks the intention.
Veritas::Relation.new([ [:ID, Integer] ], [ [20] ]).header
# => [<Attribute::Integer name: ID>]
Veritas::TABLE_DEE.send(:coerce, Veritas::Relation.new([ [:ID, Integer] ], [ [20] ])).header
# => []
Problem One (possibly the only issue here is unnecessary validation?).
Joining relations with no common attributes doesn't work due to an assertion in Veritas:
# say, users
r = Veritas::Relation.new(
[ ["UNO", Integer], ["USERNAME", String] ],
[
[42, "Bob"]
]
)
# say, pets
s = Veritas::Relation.new(
[ ["PNO", Integer], ["PNAME", String] ],
[
[1, "Mongo"]
]
)
r.join(s) #=> Veritas::InvalidHeaderError: the headers must have common attributes
From page 88 of Database in Depth:
r JOIN s
is a relation with (a) a heading that is the (set-theoretic) union of the headings of r and s and (b) a body consisting of the set of all tuples t such that t is the (set-theoretic) union of a tuple appearing in r and a tuple appearing in s.
(snip)
Third (also important), cartesian product is a special case of join, too: if n = 0, meaning there are no Y's and thus r and s have no common attributes at all, r JOIN s degenerates to r TIMES s .... snip ... Why? Because (a) the set of attributes common to r and s in this case is the empty set of attributes; (b) every possible tuple has the same value for the empty set of attributes; thus every tuple in r joins to every tuple in s, and so we get the cartesian product as stated.
Problem two (possibly solved simply by fixing the first issue):
TABLE_DEE joined with any relation, r should always yield the relation r.
Veritas::Relation.new([], [ [] ]).join(r) # same error is previously, but should simply return r
From page 89 (pre-amble about a prefix notation for Tutorial D's JOIN):
For example, the join of parts and suppliers could alternatively be expressed as follows:
JOIN { P, S }
(snip)
The join of a single relation, JOIN { r }, is just r itself; this case is perhaps not of much practical importance. Perhaps surprisingly, however, the join of no relations at all, JOIN {}, is very important indeed!—and the result is TABLE_DEE.
(snip)
- In like manner, 1 is the identity with respect to "
*
"; that is, for all numbers x, the expressions x * 1 and 1 * x are both identically equal to x. As a consequence, the product of no numbers is 1.- In the relational algebra, TABLE_DEE is the identity with respect to JOIN; that is, the join of any relation r with TABLE_DEE is simply r. As a consequence, the join of no relations is TABLE_DEE.
Let me know if I've got the wrong end of the stick or if this is indeed a bug :) I'm off to bed!
In order to push ROM 0.1.0 we need a new version of axiom. Please push it before end of the week if possible.
Can Axiom::Relation automaticaly convert input data by attribute map?
For example
header = [[:id, Integer], [:name, String]]
relation1 = Axiom::Relation.new(header, [[ 1, 'Some string' ]])
# {#<Axiom::Tuple data={#<Axiom::Attribute::Integer name=:id type=Axiom::Types::Integer required?=true>=>1, #<Axiom::Attribute::String name=:name type=Axiom::Types::String required?=true>=>"Some string"}
relation2 = Axiom::Relation.new(header, [[ '2', :kukuruku ]])
# # {#<Axiom::Tuple data={#<Axiom::Attribute::Integer name=:id type=Axiom::Types::Integer required?=true>=>"2", #<Axiom::Attribute::String name=:name type=Axiom::Types::String required?=true>=>:kukuruku}
As we can see in the second case in relation contains incorrect data types
I was trying to extend a TVA on some relation and I've had no luck. I guess it's because axiom can't yet infer the proper tuple/relation type for the extended attribute? I'm willing to help and would appreciate any pointers, thx!
Update #restrict
so that the following are equivalent:
# using a block
relation.restrict { |r| r.first_name.eq('John').and(r.last_name.eq('Doe') }
# using a Hash
relation.restrict(:first_name => 'John', :last_name => 'Doe')
I do not plan on extending this much further since I prefer for the block syntax to be used when more complex conditions are used. However, since matching all the attributes and values is such a common case, I felt it is important for there to be a simple way to express this.
This is too aggressive, axiom should not freeze globally available class objects. This can break people's code and currently it breaks all specs in rom-session because rspec tries to monkey-patch BasicObject
which happens to be frozen.
I’ve recently started to question the current implementation of Axiom::Relation#one
. It currently must be called on a sorted relation, but i actually see no reason for this restriction. Why would i have to do something like relation.restrict(some_key: value).sort.one
?
It’s purpose is to extract one tuple from a relation, and bail out if there is more than one tuple present. I don’t see any necessity for sorting here.
The only reason, it seems, is that when the relation gets compiled to sql, sorting it can prevent from loading shitloads of records by passing a LIMIT
, which itself is only available on sorted relations. I’m not at all sure tho, if this safety net justifies having to sort everytime i want one tuple. After all, probably the most common usecase is when i know that i get only one result, because i restricted on a key field.
I’m having a hard time imagining (frequent) real life queries, where i want to retrieve one tuple, that is not identified by a (candidate) key. If this means that #one
is potentially expensively loading shitloads of records, then so be it. I’m finding the current behavior too defensive.
Please correct me if I'm missing something. Any thoughts are highly appreciated. Thx!
relation = Veritas::Relation.new(
[ [ :id, String ], [ :name, String ], [ :color, String ], [ :weight, Float ], [ :city, String ] ],
[
[ 'P1', 'Nut', 'Red', 12.0, 'London' ],
[ 'P2', 'Bolt', 'Green', 17.0, 'Paris' ],
[ 'P3', 'Screw', 'Blue', 17.0, 'Oslo' ],
[ 'P4', 'Screw', 'Red', 14.0, 'London' ],
[ 'P5', 'Cam', 'Blue', 12.0, 'Paris' ],
[ 'P6', 'Cog', 'Red', 19.0, nil ],
]
)
ordered = relation.summarize( relation.project([:city]) ){ |r| r.add(:sum, r.weight.sum) }.sort_by do |r|
[r.city.asc, r.sum.asc]
end.to_a
This leads to an exception:
NoMethodError: undefined method `nonzero?' for nil:NilClass
from veritas-0.0.7/lib/veritas/relation/operation/order/direction_set.rb:95:in `block in cmp_tuples'
from veritas-0.0.7/lib/veritas/relation/header.rb:124:in `block in each'
from veritas-0.0.7/lib/veritas/relation/header.rb:124:in `each'
from veritas-0.0.7/lib/veritas/relation/header.rb:124:in `each'
from veritas-0.0.7/lib/veritas/relation/operation/order/direction_set.rb:94:in `reduce'
from veritas-0.0.7/lib/veritas/relation/operation/order/direction_set.rb:94:in `cmp_tuples'
from veritas-0.0.7/lib/veritas/relation/operation/order/direction_set.rb:73:in `block in sort_tuples'
from veritas-0.0.7/lib/veritas/relation/operation/order/direction_set.rb:73:in `sort'
from veritas-0.0.7/lib/veritas/relation/operation/order/direction_set.rb:73:in `sort_tuples'
from veritas-0.0.7/lib/veritas/relation/operation/order.rb:92:in `each'
I think nil values should always be sorted as "greater" than any non-nil value. What do you think ?
How do you create relation with Boolean values ?
relation = Axiom::Relation.new(
[ [ :id, String ], [ :name, String ], [ :color, String ], [ :weight, Float ], [ :city, String ], [:bool, TrueClass] ],
[
[ 'P1', 'Nut', 'Red', 12.0, 'London', true ],
[ 'P2', 'Bolt', 'Green', 17.0, 'Paris', true ],
[ 'P3', 'Screw', 'Blue', 17.0, 'Oslo', false ],
[ 'P4', 'Screw', 'Red', 14.0, 'London', false ],
[ 'P5', 'Cam', 'Blue', 12.0, 'Paris', false ],
[ 'P6', 'Cog', 'Red', 19.0, 'London', true ],
]
)
leads to an exception:
NoMethodError: undefined method `new' for TrueClass:Class
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/attribute.rb:41:in `coerce'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation/header.rb:77:in `coerce_attribute'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation/header.rb:46:in `block in coerce'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation/header.rb:48:in `map'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation/header.rb:48:in `coerce'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation.rb:73:in `initialize'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation/materialized.rb:29:in `initialize'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/adamantium-0.0.7/lib/adamantium/class_methods.rb:17:in `new'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/adamantium-0.0.7/lib/adamantium/class_methods.rb:17:in `new'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation.rb:58:in `new'
from RUBY_PATH/lib/ruby/gems/1.9.1/gems/axiom-0.1.0/lib/axiom/relation.rb:56:in `new'
Same problem with having Symbols in a tuple.
Opening this ticket in response to http://twitter.com/#!/dkubb/status/218702893480550401
What the title says.
I experienced this yesterday after a fresh checkout of veritas:
1.9.3-p125-perf ~/development/veritas (master) $ bundle exec rake yard --trace
** Invoke yard (first_time)
** Execute yard
[error]: Missing 'redcarpet' gem for Markdown formatting. Install it with `gem install redcarpet`
[warn]: Syntax error in `license`:(1,18): syntax error, unexpected tinteger, expecting $end
[warn]: ParserSyntaxError: syntax error in `LICENSE`:(1,18): syntax error, unexpected tINTEGER, expecting $end
[warn]: Stack trace:
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/parser/ruby/ruby_parser.rb:533:in `on_parse_error'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/parser/ruby/ruby_parser.rb:50:in `parse'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/parser/ruby/ruby_parser.rb:50:in `parse'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/parser/ruby/ruby_parser.rb:15:in `parse'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/parser/source_parser.rb:440:in `parse'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/parser/source_parser.rb:44:in `block in parse'
... lots of warnings omitted
in file `lib/veritas/relation/operation/insertion.rb' near line 18
[warn]: in YARD::Handlers::Ruby::MixinHandler: Undocumentable mixin: YARD::Parser::UndocumentableError for class Veritas::Relation::Operation::Order::Direction
[warn]: in file 'lib/veritas/relation/operation/order/direction.rb':11:
11: include Equalizer.new(:attribute)
[warn]: in YARD::Handlers::Ruby::MixinHandler: Undocumentable mixin: YARD::Parser::UndocumentableError for class Veritas::Relation::Operation::Order::DirectionSet
[warn]: in file 'lib/veritas/relation/operation/order/direction_set.rb':10:
10: include Equalizer.new(:to_ary)
rake aborted!
singleton can't be dumped
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/serializers/yardoc_serializer.rb:88:in `dump'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/serializers/yardoc_serializer.rb:88:in `dump'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/serializers/yardoc_serializer.rb:67:in `serialize'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/registry_store.rb:173:in `save'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/registry.rb:159:in `save'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/cli/yardoc.rb:256:in `run'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/yard-0.8.2.1/lib/yard/rake/yardoc_task.rb:69:in `block in define'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:205:in `call'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:205:in `block in execute'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:200:in `each'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:200:in `execute'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:158:in `block in invoke_with_call_chain'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/monitor.rb:211:in `mon_synchronize'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:151:in `invoke_with_call_chain'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/task.rb:144:in `invoke'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:116:in `invoke_task'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:94:in `block (2 levels) in top_level'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:94:in `each'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:94:in `block in top_level'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:133:in `standard_exception_handling'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:88:in `top_level'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:66:in `block in run'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:133:in `standard_exception_handling'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/1.9.1/rake/application.rb:63:in `run'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/lib/ruby/gems/1.9.1/gems/rake-0.9.2.2/bin/rake:32:in `<top (required)>'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/bin/rake:19:in `load'
/Users/jan/.rbenv/versions/1.9.3-p125-perf/bin/rake:19:in `<main>'
Tasks: TOP => yard
Ruby version:
1.9.3-p125-perf ~/development/veritas (master) $ ruby --version
ruby 1.9.3p125 (2012-02-16 revision 34643) [x86_64-darwin11.3.0]
Thats 1.9.3-p125 with the Falcon patches
Gems:
1.9.3-p125-perf ~/development/veritas (master) $ bundle
Using rake (0.9.2.2)
Using ZenTest (4.8.1)
Using RubyInline (3.11.2)
Using sexp_processor (3.0.10)
Using ParseTree (3.0.8)
Using backports (2.6.1)
Using env (0.3.0)
Using ffi (1.0.11)
Using ffi-hunspell (0.2.5)
Using ruby_parser (2.0.6)
Using flay (1.4.3)
Using flog (2.5.3)
Using git (1.2.5)
Using rb-fchange (0.0.5)
Using rb-fsevent (0.9.1)
Using rb-inotify (0.8.8)
Using listen (0.4.7)
Using thor (0.15.3)
Using guard (1.1.1)
Using bundler (1.1.3)
Using guard-bundler (0.1.3)
Using guard-rspec (0.7.3)
Using json (1.7.3)
Using rdoc (3.12)
Using jeweler (1.8.4)
Using rbench (0.2.3)
Using ruby2ruby (1.2.2)
Using reek (1.2.8) from git://github.com/dkubb/reek.git (at master)
Using roodi (2.1.0)
Using rspec (1.3.2)
Using yard (0.8.2.1)
Using yard-spellcheck (0.1.5)
Using yardstick (0.5.0)
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Rubygems Version is 1.8.11
Hey Dan just a heads up that I tried examples from the readme and got this:
ruby-1.9.2-p290 :003 > relation = Veritas::Relation.new([ [ :id, Integer ] ], [ [ 1 ] ])
=> #<Veritas::Relation::Materialized:0x007fc6a0b0c818 @header=[<Attribute::Integer name: id>], @tuples=[[1]], @directions=#<Veritas::Relation::Operation::Order::DirectionSet:0x007fc6a2945d70 @directions=[], @__memory={}>, @__memory={}>
ruby-1.9.2-p290 :004 > new_relation = relation.project([ :a, :b, :c ])
NoMethodError: undefined method `to_sym' for nil:NilClass
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/attribute.rb:115:in `initialize'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/support/immutable.rb:213:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/support/immutable.rb:213:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/support/abstract_class.rb:37:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/attribute.rb:63:in `coerce'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation/header.rb:42:in `block in coerce_attributes'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation/header.rb:42:in `map'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation/header.rb:42:in `coerce_attributes'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation/header.rb:29:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation/header.rb:286:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation/header.rb:145:in `project'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/algebra/projection.rb:22:in `initialize'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/support/immutable.rb:213:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/support/immutable.rb:213:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/relation.rb:59:in `new'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/algebra/projection.rb:133:in `project_relation'
from /Users/solnic/.rvm/gems/ruby-1.9.2-p290@veritas/bundler/gems/veritas-945ff60005b9/lib/veritas/algebra/projection.rb:90:in `project'
from (irb):4
veritas master and activesupport 3.2.8
require "active_support/core_ext/date_time/conversions"
require "veritas"
/home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/bundler/gems/veritas-7e587d210e36/lib/veritas/attribute/date_time.rb:10:in `<class:DateTime>': bad value for range (ArgumentError)
from /home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/bundler/gems/veritas-7e587d210e36/lib/veritas/attribute/date_time.rb:7:in `<class:Attribute>'
from /home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/bundler/gems/veritas-7e587d210e36/lib/veritas/attribute/date_time.rb:4:in `<module:Veritas>'
from /home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/bundler/gems/veritas-7e587d210e36/lib/veritas/attribute/date_time.rb:3:in `<top (required)>'
from /home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/gems/backports-2.6.5/lib/backports/tools.rb:314:in `require'
from /home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/gems/backports-2.6.5/lib/backports/tools.rb:314:in `require_with_backports'
from /home/lars/.rvm/gems/ruby-1.9.3-p327@datamapper/bundler/gems/veritas-7e587d210e36/lib/veritas.rb:108:in `<top (required)>'
from test.rb:4:in `require'
Not sure if bug or a feature but:
irb(main):001:0> r1 = Axiom::Relation::Base.new(:foo, [[:name, String]])
irb(main):002:0> r2 = Axiom::Relation::Base.new(nil, [[:name, String]])
irb(main):003:0> r1 == r2
=> true
EDIT: ok according to this I'm pretty sure it's a bug
I was under the impression that the issue title describes the expected behavior. However, when i do some_base_relation_gateway.sort.drop(1).take(1)
, neither ORDER BY
nor OFFSET/LIMIT
clauses get pushed down to the underlying (postgres) adapter. The result being that the operations are ("silently") handled in memory, while performing (potentially) slow queries.
I'm trying to implement pagination, and for UX (pagination links) I need to know the total count of tuples inside the paginated relation. The current API for Relation#summarize
, and adding a :count
column specifically, forces me to know an existing attribute name present in the relation. Ideally, that wouldn't be necessary tho, because it leaves the burden of knowing relation internals to the callsite (in order to paginate, I need to know one (arbitrary?) NOT NULL
attribute).
I'm currently pondering, whether I should simply accept having to know one attribute name (thus including it as a param in the API for pagination) or whether I should do something "clever" to get at one arbitrary name. Something like the following (which imo really is ugly):
def count
relation.summarize { |r|
r.add(:count, r.send(relation.header.keys.to_a[0].to_a[0].name).count)
}.sort.one[:count]
end
Both options seem less than ideal to me. It seems like what i really want, is COUNT (*)
, but nowhere in axiom-sql-generator
specs can I find examples of axiom actually being able to produce that.
Any pointers would be very much appreciated! Thx in advance!
Error when attempting to use Axiom:
/Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom/support/equalizer.rb:18:in `initialize': undefined local variable or method `include_comparison_methods' for #<Axiom::Equalizer:0x007fa94bd5d698> (NameError)
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom/support/operation/binary.rb:6:in `new'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom/support/operation/binary.rb:6:in `<module:Binary>'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom/support/operation/binary.rb:5:in `<module:Operation>'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom/support/operation/binary.rb:4:in `<module:Axiom>'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom/support/operation/binary.rb:3:in `<top (required)>'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom.rb:90:in `require'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/axiom-0.1.1/lib/axiom.rb:90:in `<top (required)>'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/rom-relation-0.1.2/lib/rom-relation.rb:10:in `require'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/rom-relation-0.1.2/lib/rom-relation.rb:10:in `<top (required)>'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/rom-0.1.2/lib/rom.rb:4:in `require'
from /Users/acook/.rvm/gems/ruby-2.1.1@rom/gems/rom-0.1.2/lib/rom.rb:4:in `<top (required)>'
from ./run_me.rb:6:in `require'
from ./run_me.rb:6:in `<main>'
Sample project to reproduce bug: https://gist.github.com/acook/dbaa454f21681b4d27cd
I just created a new rails project like so:
rails new veritas-test
I then added veritas to the Gemfile, like so:
gem 'veritas'
I tried to boot that app with rails c
and got the following error:
veritas-test$ rails c
/Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/veritas-0.0.7/lib/veritas/attribute.rb:36:in `inherited': private method `inherited' called for Object:Class (NoMethodError)
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/veritas-0.0.7/lib/veritas/attribute/object.rb:7:in `<class:Attribute>'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/veritas-0.0.7/lib/veritas/attribute/object.rb:4:in `<module:Veritas>'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/veritas-0.0.7/lib/veritas/attribute/object.rb:3:in `<top (required)>'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/veritas-0.0.7/lib/veritas.rb:95:in `require'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/veritas-0.0.7/lib/veritas.rb:95:in `<top (required)>'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler/runtime.rb:68:in `require'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler/runtime.rb:68:in `block (2 levels) in require'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler/runtime.rb:66:in `each'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler/runtime.rb:66:in `block in require'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler/runtime.rb:55:in `each'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler/runtime.rb:55:in `require'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/bundler-1.0.22/lib/bundler.rb:122:in `require'
from /Users/jeff/workspace/practitionerhq/veritas-test/config/application.rb:7:in `<top (required)>'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.3/lib/rails/commands.rb:39:in `require'
from /Users/jeff/.rvm/gems/ruby-1.9.2-p290/gems/railties-3.2.3/lib/rails/commands.rb:39:in `<top (required)>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'
Any idea what's going on here? Obviously it's calling inherited on Object, which appears to be private. If I just load irb, then require rubygems and veritas, it does not blow up like this.
If I can figure this out, and it turns out to be Rails, I'll submit the issue / patch there, but before diving in I wanted to know if this was a known issue or if there was a known workaround.
Thanks!
Hello together,
I'm checking out this file https://github.com/dkubb/axiom/blob/master/lib/axiom.rb right now. The first thing I see, is that all external dependencies and all files in lib are required. Is there a good reason to avoid using autoload in this file? I think it would be good for lib users if the gem has defer logic like this in it especially for start up times.
Thanks :)
Best regards,
zirni
Is this supposed to work and if yes then how a tuple should look like?
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.