Hi.
I've really enjoyed Brent's Lava parser, and used them (with some
modifications) to parse SQL for DB2 for an internal project. I'd like to
share some of this work - at least the stuff that should be (fairly) easy to
merge into Lava. There is more - but I don't really know how you'd
translate Insert/Update/Delete statements from SQL into Magma.
I've stripped out most of the stuff that there just isn't any support for at
this time (not to mention it was mostly DB2 specific - maybe the standard,
but I'm not sure). I've made some changes to the AST, although I can't
claim that all of them will work with Magma (since I haven't tried any at
all). The changes are:
Common Table Expressions:
In the Statement section of the parser, I've added a section that deal with
WITH clauses. This should have the effect of creating 'temporary' tables in
the main select (roughly analogous to subQueries), and I think this should
just work. Here's an example of a query using this:
with t1 as (select * from me), t2 as (select him from you)
SELECT col1, wm.col2
from wamu wm
WHERE col1 = 'me' AND wm.col2 != col1
There are several other things you can do with CTE's (such as recursive
queries and putting change statements in them), but I doubt these will work
as is - and really aren't to common. I think they make for nicer organized
queries, though.
In the columnReference and tableReference I have added a schema attribute
and accessors to deal with schemas, like:
schema.table.column
schema.table
I think these might map to Namespaces if those ever make it into Squeak in a
consistent manner. Otherwise, they could probably just be ignored in Magma,
I guess.
In tableReferenceList, I've added a joinTableReference clause. This allows
for things like:
from table1 join table2 on table1.col = table2.col
This is the 'new' standard for joins (SQL-92) that several database vendors
have been pushing. The code to use it in Magma probably isn't fully thought
out - it currently uses a JoinedTableReference class to represent this.
Currently this reduces the JoinedTableReference to a LaTableReference, and
puts the joinConditions (on clause) in the joinCondition part of the
LaSelection. To make it fully useful with minimal work, I think you could
move the joinConditions to the whereCondition, and it should just work.
In tableAlias, I've added a clause where you can just use the an alias
without the "as". This is valid (at least in DB2).
In predicate, I've added an existsPredicate. This causes the subquery to
run, and if something is found, then that rows (from the outer query) is
returned, else it isn't. Also, a not exists is present, so:
[not] exists (select 1 from table where name = 'me')
This is represented in the AST, but I have no idea or suggestions at this
time as to how this should work with Magma.
Finally, in literal, I've added a "null" string, which should probably
equate to nil internally. Or at least I think I did - it looks like it is
already in version .36, so maybe that was already there. Oh well.
Oh, and I also added a lot of #qualifier messages to several of the AST
classes - that was so I could analyze the parsed results for my purposes,
and I just left them in.
Here's my Parser definition (based off of your Monticello version 31) and a
change set containing the AST changes.
Thanks,
Chris Cunningham