samcv ZofBot, state your purpose 00:16
ZofBot samcv, r = FIRST { rand }; has $
samcv k
TimToady I believe I found the bug in Grammar::Debugger 00:18
actually, the bug is in Grammar::Tracer 00:28
samcv i'm not sure how to fix this problem in DateTime::Math
Ambiguous call to 'infix:<->'; these signatures all match:
:(DateTime:D \a, DateTime:D \b)
:(DateTime:D $a, DateTime:D $b)
Zoffix m: dd DateTime.now - DateTime.now 00:29
camelia Duration.new(<-4417/2205500>)
samcv doesn't make sense to me
.WHAT shows they're both datetime objects
Zoffix samcv: by removing that op. It's now implemented in core so one of those multies is the core one and the other is the one the module provides
samcv oh. yes
very true
i'm make a pr then
TimToady the closure that Grammar::Tracer provides has -> $c, |args, but then uses $meth($obj, |args), and $obj is the type object rather than the instantiated object 00:30
samcv PR sent now 00:33
Zoffix samcv++
samcv TimToady, can you check this github.com/perl6/specs/pull/120 and see how you feel about this for META and licenses to the spec? 00:36
right now it's kind of anarchy of what people put there from what i have seen checking all META files in the ecosystem
this would greatly simplify it and make the license in a standardized format that is well defined and used by a great number of license tracking systems 00:37
TimToady seems reasonable to me, if people actually want their code to be used 00:38
samcv it is ok if i merge that? 00:39
i've also put PR template for the ecosystem to encourage people to add licenses to their projects. because github.com/perl6/ecosystem/blob/ma...EMPLATE.md like... almost none of them (including me) have them 00:40
doesn't *require* a license but should nudge people in the right direction, because it's something often overlooked, by myself and others when publishing modules 00:44
TimToady the legal interface is just about as important as the technical one 00:46
speaking as someone who wrote his own license...
Zoffix pfft.. show off! Next you'll tell us you wrote your own programming language! 00:48
TimToady .tell jnthn Grammar::Tracer calls $meth($obj, |args) where it should call $meth($c, |args)
yoleaux TimToady: I'll pass your message to jnthn.
samcv also TimToady we have a 'support' key, and only define email, buggtracker 00:54
what about the module's homepage? 00:55
should that be defined as 'homepage'?
the rakudo credits has github.com/rakudo/rakudo/blob/nom/CREDITS#L8 web-address 00:58
so that's a possibility too and more specific
and this is meta metacpan.org/pod/CPAN::Meta::Spec#resources 01:07
TimToady foresees that the next wave of malware will involve forking projects to a different auth and giving them a spam homepage :) 01:13
samcv oh my
also nicely the spdx defines what to write if there is no license as well as if the creator of the META file doesn't know the license
NONE for no license and NOASSERTION if whoever adds the field doesn't know or makes no assertion as to the license 01:14
i think it would be cool if we had travis ci check to make sure there is at least some license field, even if it says NONE or NOASSERTION it's better than just blank 01:15
and obviously if nobody has the ability to change the meta file then not like you have to listen to travis, and it wouldn't affect commits, just PR 01:16
Geth roast: 0c6b07b278 | TimToady++ | 2 files
fix for correct BUILD semantics of grammar

This test uses a module that lists a bunch of internal methods. This is suboptimal, but for now just add the methods that are called when a proper new/BUILDALL are done. (The old code only worked because class Grammar bypassed all that and went straight to nqp, which in turn made it impossible to support user grammars with their own attributes.) ... (5 more lines)
01:33
samcv TimToady, design.perl6.org/S22.html#emulates hehehe 01:40
dunno if this is implemented yet or not. but it says thet it will load one module as if it were another if it does not have the original module
dunno you could probably cause mischief with that 01:41
TimToady you can cause mischief with just about anything :)
samcv :-)
gonna make a Bag of all the keys in every single META file in the ecosystem to get a distribution of usage 01:46
Geth rakudo/nom: db42d62f81 | TimToady++ | src/core/Grammar.pm
user grammars should work more like real classes

We now actually call .new (as we ought) to fire off all the BUILDALL stuff for Capture, Match, and whatever attributes the user adds to their grammar.
  (Capture and Match already had switched to using BUILD for the release, but
the parse methods didn't honor that yet.)
01:55
samcv bag(emulates(10), test-depends(301), version(813), name(813), api(4), description(813), excludes(9), resources(145), build-depends(195), supersedes(9), production(10), support(211), source-uri, licence(4), author(285), source-url(779), superseded-by(9), resource(13), tags(149), license(108), auth(155), perl(739), provides(803), meta6(54), history, repo-type(31), authors(411), owner(9), authority(8), depends(771), source-type(69)) 02:07
TimToady, only 4 in eco have licenses... 02:08
and two of them are my modules
that i just changed today
idk maybe that's wrong
that should be right though. i mean it picked up every other thing 02:09
that's still depressing
err oh some are mispelled?
nice...
ugexe if its worth anything zef has a white/black list for licenses in its config that you can use on those 4 distributions 02:11
samcv also we have author and authors dunno if author is valid? 02:12
ugexe, what do you mean by that? 02:13
just made a PR to zef to add a license field to its META file 02:16
ugexe "License" : { "whitelist" : "*", "blacklist" : [] } # you can change this in the config to filter dists-to-be-installed by license
samcv ah
ah i see
that's cool though
can you blacklist modules with no license? 02:17
Zoffix 10 dists have emulates?
Zoffix wonders which those are
samcv Zoffix, gist.github.com/51e8a1fd862ad512a7...1006c176e2 this is the code to find that 02:18
can probably modify it to print out more useful info
Zoffix `excludes`? what's that
samcv design.perl6.org/S22.html#excludes
also i want to know who misspelled license... 4 modules worth
and who used author instead of authors 02:19
which semes to be many people
Zoffix FWIW, we have an ecosystem JSON file; other than normalizing source URL, it's basically the original META files: ecosystem-api.p6c.org/projects.json
samcv oh. how often updated 02:20
Zoffix every 15 minutes or so. That's our ecosystem file zef/panda use
samcv nice
Zoffix Complimentary errors file: ecosystem-api.p6c.org/errors.json
s/lim/lem/;
ugexe github.com/rakudo/rakudo/blob/nom/...ion.pm#L40 # author has history 02:21
samcv oh no i broke mine
ugexe method auth { $!auth // $!author // $!authority } # just think about *this*
Zoffix I fixed the first two errors 02:22
Geth rakudo/nom: 894ba82de8 | (Zoffix Znet)++ | src/core/IO/Spec/Win32.pm
[io grant] Make IO::Spec::Win32.split about 82% faster
02:23
Zoffix drops to bed
Hm... A critique of TPF grant program on blogs.perl.org right after I posted a TPF grant report... 02:39
samcv heh 02:40
seems people are using `auth` as a key, but that's not in the spec 02:42
well it says what auth is. but it's not in the META section 02:43
it just defines it as a term but doesn't say it's a metadata key at all
ugexe take anything in there with a grain of salt. but auth happened because dynamically creating the auth from multiple fields did not work well 03:21
method auth { $!auth // $!author // $!authority } # this is still supported for backcompat, but will probably go aware just be $!auth 03:27
TimToady well, auth is just supposed to be the part of the identity that names who dunnit, such that if someone else dunnit, it's a different one 03:40
samcv yeah i know what it is. but the spec needs to be updated to say that's a META6.json key 03:49
ugexe i mean that same spec also documents @?INC 03:59
anything you think is missing or wrong probably is 04:00
Geth roast: 0b199e1a4d | (David Warring)++ | S12-introspection/attributes.t
add test for RT #131174

incorrect attribute container shape
05:04
synopsebot6 Link: rt.perl.org/rt3/Public/Bug/Display...?id=131174
samcv ugh so many META6 git repos 05:58
META6, and META6bin and META6::Test
gotta make changes in at least two of them
Geth nqp: c594acaf4c | usev6++ | src/vm/jvm/runtime/org/perl6/nqp/runtime/Ops.java
[JVM] Avoid StringIndexOutOfBoundsException

  ... when using nqp::ord with empty string or invalid offset
06:05
roast: 896191b66b | usev6++ | S32-io/lock.t
[JVM] Fudge another two file locking tests
06:20
[Tux] This is Rakudo version 2017.04.2-6-g894ba82de built on MoarVM version 2017.04 06:58
csv-ip5xs 3.049
test 12.700
test-t 5.102 - 5.476
csv-parser 13.658
lizmat Files=1191, Tests=56770, 198 wallclock secs (11.83 usr 4.59 sys + 1162.78 cusr 109.40 csys = 1288.60 CPU) 08:02
yoleaux 19 Apr 2017 22:43Z <Zoffix> lizmat: some material for Weekly, if there's space: There's an OSX REPL history bug that made it into release (and thus R*). Displays a message about failed mkdir '/' and doesn't save history. Most users can probably just ignore the message and move on with their lives, but if they really need saved history they can make a shell alias for REPL That Saves:
19 Apr 2017 22:43Z <Zoffix> lizmat: gist.github.com/zoffixznet/6a0d212...fa9efcc263
samcv .tell yoleaux thx for your tireless message relaying
yoleaux samcv: Thanks for the message.
lizmat :-) 08:03
nine dogbert17: BIOS update did the trick. Temperature is now being reported correctly and when I turn off the spinning rust I use for multimedia data, the system is now almost inaudible. Not even heavy spec testing raises the noise level :)
dogbert17_ nine: very cool, sound as if you're quite satisfied :) 09:32
jnthn should prod the folks meant to be building/delivering his new machine today.. 09:35
yoleaux 00:48Z <TimToady> jnthn: Grammar::Tracer calls $meth($obj, |args) where it should call $meth($c, |args)
nine dogbert17_: oh definitely :) 09:44
jnthn Argh, what... 10:06
perl6-m -e "say 'README.md'.IO.e" 10:07
True
perl6-m -e "say 'README.md'.IO.resolve.e"
False
Zoffix ...
jnthn (Yes, there is a README.md)
On Windows fwiw
No problem on Linux 10:08
say 'README.md'.IO.resolve
evalable6 "/home/bisectable/git/whateverable/README.md".IO
jnthn Is correct
oh wait 10:09
It's not
perl6-m -e "say 'README.md'.IO.resolve"
"\C:\consulting\rakudo\README.md".IO
Spot the extra \
Let me grab rakudo HEAD
Zoffix jnthn: what perl6 version?
jnthn Though I was pretty close anyway
This is Rakudo version 2017.04.2-4-gb4fa6d6 built on MoarVM version 2017.04
implementing Perl 6.c.
Zoffix guesses the 63x faster Win32 spec method was also some x wronger :( 10:11
Good thing I merged it post-release
jnthn Confirmed at HEAD
Now back to the last release 10:12
And will check there
I'd bumped to get the perf improvements which actually knocked 50ms-100ms off startup time
perl6-m --version 10:14
This is Rakudo version 2017.04.2 built on MoarVM version 2017.04
implementing Perl 6.c.
perl6-m -e "say 'README.md'.IO.resolve"
"\C:\consulting\rakudo\README.md".IO
:(
Zoffix craaaap 10:15
nine rakudo startup takes 85ms here. Knocking off 50-100ms of that would be fantastic ;)
Zoffix heh
jnthn nine: This isn't Rakudo startup, it's my app's startup, fwiw, which loads a ton of modules, and in doing so spent about 50% of its time in Windows path mangling 10:16
Thus starting up about twice as slow on my Windows host compared to in my Linux VM :)
nine oh, ok :) 10:18
jnthn Urgh, this bug is...uh...a problem
Guess I can work around it with say 'README.md'.IO.absolute.IO.e for now 10:19
Zoffix bisect: say ".".IO.WHAT.new('C:/README.md', :SPEC(IO::Spec::Win32.new)).resolve 10:21
bisectable6 Zoffix, On both starting points (old=2015.12 new=894ba82) the exit code is 0 and the output is identical as well
Zoffix, Output on both points: Ā«"\C:\README.md".IOĀ»
Zoffix reaaaally
jnthn o.O 10:22
Zoffix C:\>perl6 -e "dd $*PERL.compiler.version; dd 'vcredist.bmp'.IO.resolve" 10:23
v2016.11
"\\C:\\vcredist.bmp".IO(:SPEC(IO::Spec::Win32))
Well, I'm glad it's not a regression I broke :}
But how in the world has this stayed undetected for so long :/
nine Very few Windows users? 10:24
jnthn Or few users of .resolve? 10:26
Then take the intersection 10:28
nine set(jnthn) 10:30
jnthn Apparently ;) 10:31
Zoffix jnthn: so how many percent of startup time 50-100ms is? 10:34
Ah, there's a comment in IO::Path.resolve that says '# XXXX: Not portable yet; assumes POSIX semantics'. I guess that's how not-portability manifests itself 10:36
jnthn Zoffix: It stood a bit over 600ms; now it's reliably under 600ms 10:41
As opposed to 200ms-300ms on Linux
Oh, to be fair, that's also including time to generate the usage message
from MAIN
Which has quite a few candidates
Ulti on macOS `time perl6 -e 'sub MAIN {}' ` is 0.178s real for me 10:43
yoleaux 19 Apr 2017 18:51Z <Zoffix> Ulti: there are some unmerged PRs that've been marinating for months. Do you mind merging them? github.com/MattOates/Text--Homoglyph/pulls
Ulti whoa
doh should have properly reviewed those 10:47
why are people messing around with the file name
Zoffix: I'll fix it up, some of my other modules also need the .* perl version really 10:49
Zoffix Ulti: "Is there a preference for .json rather than .info I wasnt aware of?" Not a preference. META.info is not a thing. It's an old, pre-Christmas meta name 10:50
Ulti whoa there are loads of PR I've ignored 10:51
Zoffix: okedoke I'll make sure to change that
thanks
Zoffix .ask mst would you know whether it's possible to debug Travis's IRC bot connection timeouts to Freenode? We've not seen their bot for a while and they responded to me: twitter.com/travisci/status/855034311103455232 12:26
yoleaux Zoffix: I'll pass your message to mst.
Zoffix The username it joins with is `travis-ci` 12:27
m: use nqp; dd nqp::getlexdyn(q|$*PERL|) 12:50
camelia Mu
Zoffix What sort of name does getlexdyn take? 12:51
reading its use in sauce, suggests the above should work, so what gives? 12:52
m: use nqp; my $*PERL = 42; dd nqp::getlexdyn(q|$*PERL|)
camelia Mu
Zoffix m: use nqp; my $*PERL = 42; { dd nqp::getlexdyn(q|$*PERL|) }
camelia Int $*PERL = 42
Zoffix Ahhh. OK, got it
jnthn It doesn't do any failover stuff 12:58
Geth rakudo/nom: 1d6a0023e8 | (Zoffix Znet)++ | src/core/Rakudo/Internals.pm
Micro-optimize reg/init dynamic

The nqp concat is about 60% faster, but I don't think these methods
  are called all that many times.
13:20
Zoffix ZOFFLOP: t/spec/S10-packages/precompilation.t 14:10
AlexDaniel ā€œI'd bumped to get the perf improvements which actually knocked 50ms-100ms off startup timeā€ 50ms-100ms startup time improvement? WAT? 14:12
ah
read the next messageā€¦ okay
jnthn Context is everything :P 14:13
AlexDaniel would've been better if context came before that message :) 14:14
Geth rakudo/nom: 277b6e5b74 | (Zoffix Znet)++ | src/core/IO/Spec/Unix.pm
[io grant] Make IO::Spec::Unix.rel2abs 2.9x faster

Used by IO::Path.absolute and .absolute is used all over the place, so this should give some sort of gravity boost.
  - Don't call .catdir, do the thing ourself and bypass the slurpy
  - Don't call .canonpath twice; once should be sufficient
  - Don't add '/' to end of path like .catdir does, as .canonpath
   strips it anyway (similar patch to .catdir coming up soon)
AlexDaniel hmmm I should really make statisfiable6 measure startup time 14:16
mhm okay, issue #131ā€¦ github.com/perl6/whateverable/issues/131 14:18
Zoffix "similar patch to .catdir coming up soon"; it isn't, as in catdir it handles a special case, but it don't matter for rel2abs 14:23
roast++ :) 14:24
m: dd IO::Spec::Unix.catdir: '' 14:26
camelia "/"
Zoffix Weird special case IMO
ZOFVM: Files=1241, Tests=133747, 110 wallclock secs (21.56 usr 3.07 sys + 2293.52 cusr 123.34 csys = 2441.49 CPU) 14:32
m: use MONKEY; augment class Rat { has $!foo; method x { $!foo } }; Rat.new.x 14:37
camelia P6opaque: no such attribute '$!foo' in type Rat when trying to get a value
in method x at <tmp> line 1
in block <unit> at <tmp> line 1
Zoffix Can't augment-in new attributes, eh?
jnthn No 14:39
Maybe some day we'll manage it but...it's rather problematic to support 14:41
Or at least, it is if you're using memory layout for attributes where you just store them in an object body 14:42
Which is what P6opaque does
nine How are mixins handled? 14:43
jnthn nine: By a change of type table on the individual object being mixed in to, migrating the attributes to another piece of memory that P6opaque has a slot for (which is waste on most objects), making every attribute lookup we do cost an extra branch because of checking this pointer, forcing a deopt of the whole stack and hoping it's sufficient but it ain't because threads but we usually get away with it, and probably leaking memory if you mix i 14:49
Zoffix "Invalid BUILD_LEAST_DERIVED plan"... welll, that's new :o
m: gist.github.com/zoffixznet/280bdb9...d50c265da2
camelia Invalid BUILD_LEAST_DERIVED plan
in block <unit> at <tmp> line 26
14:50
jnthn nine: There are ways to do better on most of the problematic things there. 14:51
Zoffix m: $ = 42 but role { has int $!x }
camelia ( no output )
Zoffix m: $ = 42 but role { has int $!x = 42 }
camelia Invalid BUILD_LEAST_DERIVED plan
in block <unit> at <tmp> line 1
jnthn Though I suspect many of them involve making mixed-in-to things perform a bit worse as the cost for making everything that isn't cheaper 14:52
Zoffix Rakudobugged: rt.perl.org/Ticket/Display.html?id=131181 14:53
jnthn Zoffix: That's an...interesting...one :) 14:54
Zoffix :) 14:55
nine jnthn: I'm glad we have still opportunities for huge improvements like that :)
jnthn We do but...
If multis are anything to go by, people nearly never say "oh gosh, thanks for spending hours/days/weeks/months figuring out how to make X fast", just "omg Y is so slow compared to X" :P 14:56
Zoffix heh
jnthn So if we make most things faster but not mixins, then they comparatively end up seeming glacial, even if they didn't get any worse. ;) 14:57
So far we didn't actually define the cross-thread visibility of mixins though :) 14:59
Or, well, many other things
Which we'll need to at some point
But these things are pretty hard; I think it took until Java 5 for them to get a good one. :) 15:00
timotimo hm. the build least derived interpreter can only handle instructions 0 through 7 and also 13 15:03
Zoffix ZOFFLOP: t/spec/S11-modules/nested.t 15:13
Geth rakudo/nom: 74680d44f4 | (Zoffix Znet)++ | src/core/IO/Path.pm
[io grant] Make IO::Path.is-absolute about 80% faster

Benched with IO::Spec::Unix spec
15:14
Zoffix s/Benched with <(.+/pre-set attr/ 15:17
AlexDaniel bloatable6: releases 15:18
bloatable6 AlexDaniel, gist.github.com/555bfbc3b0a41c3d68...fbe0e9e77c
AlexDaniel we are growing \o/ :S 15:19
Zoffix ?
That URL is busted
AlexDaniel Zoffix: F5, github problems
Zoffix ah
Geth rakudo/nom: ff23416b1e | (Zoffix Znet)++ | src/core/IO/Path.pm
[io grant] Make IO::Path.is-relative about 2.1x faster

Benched for repeated calls or paths made with
  !new-from-absolute-paths.
15:22
Zoffix ZOFFLOP: t/spec/S11-modules/nested.t 15:44
Geth rakudo/nom: 7364afdcf7 | (Zoffix Znet)++ | src/core/IO/Spec/Unix.pm
Improve readability of code

  && and || codegen to nqp::if/nqp::unless, so we can use those to
make this code more readable.
15:52
Zoffix Hm, consistently getting 114s stresstests now; was 111s in the morning. Wonder if that's just Google giving less "power" to my VM or my optimizations actually suck :| 15:53
So... what's global deopt and interning? 15:57
ok 112s now. I guess the former hypothesis is truer 16:01
Geth rakudo/nom: d272667638 | (Zoffix Znet)++ | src/core/IO/Spec/Unix.pm
[io grant] Make IO::Spec::Unix.join about 40% faster

Used in a bunch of places in IO::Path like
  .add/.child/.parent/.sibling and .new from parts.
Get more speed by copying relevant bits of .catpath impl into .join and avoiding the method call.
16:03
ugexe just confirming (from backlog) that .resolve never worked right on windows 17:20
Zoffix will fix it by next release 17:29
Can someone give me perms to make new repos in github.com/perl6-community-modules/ ? 17:45
Gonna start FastIO module...
timotimo it says you are already in this organization 17:58
Zoffix timotimo: but I can't make new repos. 17:59
I see I'm listed as "Member". Can I be "Owner"? If, can you create FastIO repo and give me commit bit to it
timotimo that mig htahve don et
...
that might have done it 18:00
Zoffix Yey
timotimo++ thanks
timotimo though i considered perl6-community-modules to just be for when modules got abandoned 18:04
Zoffix I thought it was modules made by perl6 community 18:06
kinda long to type tho 18:07
.oO( perl6-mods )
timotimo stack some mods on yo perl6 18:08
Zoffix Interesting. Coverage shows IO::Path.perl is hit, but I can see it has a definite bug; it won't roundtrip 18:15
m: ".".IO.perl.eval
camelia No such method 'eval' for invocant of type 'Str'
in block <unit> at <tmp> line 1
Zoffix m: ".".IO.perl.EVAL
camelia ( no output )
Zoffix reallly
Ah, it passes args as named, so it doesn't crash outright, but the args *are* ignored 18:16
m: dd ".".IO.perl
camelia "\".\".IO(:SPEC(IO::Spec::Unix),:CWD(\"/home/camelia\"))"
Zoffix m: dd ".".IO.WHAT.new(".", :SPEC(IO::Spec::Win32)).perl
camelia "\".\".IO(:SPEC(IO::Spec::Win32),:CWD(\"/home/camelia\"))"
Zoffix m: dd ".".IO.WHAT.new(".", :SPEC(IO::Spec::Win32)).perl.EVAL.perl
camelia "\".\".IO(:SPEC(IO::Spec::Unix),:CWD(\"/home/camelia\"))"
Zoffix hehe
Zoffix spots an error in github.com/rakudo/rakudo/commit/7364afdcf7 18:19
I mean in github.com/rakudo/rakudo/commit/ff23416b1e
timotimo if and not_i swapped? 18:21
oh, no that's probably fine
oooh
$!SPEC vs $.SPEC
er
$*SPEC
Zoffix Yup
timotimo in one of those
well, it's past the release, which is good :) 18:22
Geth rakudo/nom: ce37b31a3d | (Zoffix Znet)++ | src/core/IO/Path.pm
Fix typo

Change in earlier commit accidentally swapped $!SPEC to $*SPEC
18:25
Zoffix Looking through IO::Path, I'm a bit dubious will get any sort of miraculous perf gains by abandoning $*SPEC 18:33
s/will/we'll/;
[Coke] m: s/will/we'll/; 18:34
camelia Use of uninitialized value of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
in block <unit> at <tmp> line 1
Zoffix At least on Linux, there's not much of a loss of perf due to $*SPEC. Possibly just a couple of method calls saved in a few select IO::Path methods + 1 DYNAMIC call 18:35
I think I'm gonna do something more fun: instead of hacking away all the $!SPEC stuff and maintaining same API, make an new IO::Path from scratch, starting with *nix-only support. 18:40
And if that ends up only marginally faster, give up.
I mean in FastIO module, not in core. 18:41
The one pain-point I see is for every new IO::Path we make, we stringify $*CWD 18:43
timotimo will be interesting to see 19:17
MasterDuke_ timotimo: i had the allocation stuff wrong before, but it looks like it's good now 19:40
timotimo oh!
i didn't notice :( 19:41
MasterDuke_ well, in the branch i'm working on
but now you can recreate the two views in the current allocations tab
timotimo fantabulastic
MasterDuke_ total allocations by type, and which routines they were allocated in 19:42
timotimo it's dinner time here right now! 19:43
MasterDuke_ what was the other info you were interested in? which routines called a particular other routine?
timotimo exactly
i.e. "who the hell is calling bind_one_param all the damn time" 19:44
MasterDuke_ i'll see if i can figure that out
nine That would be sooo helpful 20:00
MasterDuke_ i do enjoy sql, and haven't gotten to do any at $work in a while 20:02