On Mar 5, 2009, at 5:01 PM, Jim Starkey wrote:

my 2¢:
1) retain the current lexer if you care for charset support (drizzle can probably skip this) 2) retain the current lexer if you care for all the edge cases it handles (hard to fully recreate with a tool, trust me) 3) build a grammar for the MySQL/drizzle language, start small, without joins and subselects feeding of the token stream from the existing lexer (this is one function and one token struct, should be relatively easy to adapt to other lexers) 4) let the generated (or handwritten if you have too much time) parser build an AST(!) _not_ a parse tree (reason: parse trees change as you change the parser, ASTs are not supposed to change simply because you split a recognition step. an AST needs design, obviously) 5) _only_ build an AST, do no binding or anything else (except you need it to successfully parse, like names of functions added by plugins or something like that - note: you probably do not need the function's prototypes, treat that part as a name binding problem) 6) traverse the AST, do name binding (if there are more things you need to do to verify the semantics of the sentence, either do multiple passes or if you know beforehand that this will be too slow, try to do it in one pass) 7) optimize the tree (probably a peephole optimizer, like constant folding etc) 8) restructure the rest of the code that it can deal with the tree you've built (this should probably not be the last step chronologically, because i'm sure there will be problems where you cannot easily change code to the nice new reality you've created with the AST ;))


A couple of thoughts and quibbles.

First, drizzle should be all Unicode/UTF-8. Translations between local character sets and UTF-8 are client, not server, issues.

yeah, that's why i noted that drizzle might want to skip this step. other's are not this fortunate :( although i fully agree that some unicode encoding ought to be enough support in a server.
luckily this is a lexer issue, the parser couldn't care less :)

Second, AST (abstract syntax tree -- I had to look it up myself) is differs from a "parse" tree in that a parse tree represents syntactic irrelevancies like parenthesis. In all fairly, I think that parse trees are primarily generated by undergraduates before they change their majors to marketing.

sorry, i should've spelled AST out at least once.
parse trees have merit outside undergrad classes, though ;) syntax- aware editors are one prime example for the need of every little semantically useless information about the input. servers naturally need only know what the meaning of the sentence was and can build the abstract view of things.

Third, I applaud your definition of parser. To make it short and simple: *Parsers parse*. Having a parse do *anything* else is *always* a mistake (I've written dozens of parsers and made lots of mistakes).

oh yeah, it's really easy to mess it up badly, i agree. however, depending on the language you need to parse, you can't produce a "pure" parser (see the C++ parser mess…). i'm not yet certain where the mysql dialect falls into in this respect. most likely you need information about the added UDFs, because otherwise using one in a query would be a syntax error, because you couldn't descend into the function call rule. the same thing probably applies to user defined types, if they ever materialize. otoh, maybe we can fake UDF recognition by blindly accepting anything that remotely looks like a function call and then resolve it in a later stage. i will certainly find out, though. moving it into the parser is nice because you can error out much earlier and skip a postprocessing step that needs to find all the potential function calls in the tree. this is not a major design decision, because it's rather localized.

Fourth, trying to augment a syntax tree during semantic analysis will prove short sighted. Stuff like view processing, virtual field substitution, validation expression incorporation, and filterset integration all happen during semantic analysis. Trying to stick with the original tree only leads to grief (see Rdb/ELN for a good example).

i honestly think there are a few operations that can be done with rewriting/augmenting the existing tree. others are more natural and maintainable if done on separate trees (i.e. one pass takes an input tree and builds a second tree from it). most of the trees for sql should not be large anyway, unlike those used in compilers. i'm not experienced enough to comment on the specific examples you mention, so i won't :)

Fifth, are some easy tricks for taking constant expressions and type conversions out of inner loops. Call me when you get there.

i'll track you down ;)

And last, an execution structure is a sublime alternative to the horrible MySQL execution spaghetti. It makes so much for sense to simplify and accelerate the code by making decisions at compile/ optimize time rather than looking at dozens of flags and switches at runtime to figure out what's supposed to happen. And, might I add, it's also maintainable.


+1

cheers,
-k
--
Kay Roepke
Software Engineer, MySQL Enterprise Tools

Sun Microsystems GmbH    Sonnenallee 1, DE-85551 Kirchheim-Heimstetten
Geschaeftsfuehrer: Thomas Schroeder, Wolfang Engels, Dr. Roland Boemer
Vorsitz d. Aufs.rat.: Martin Haering                    HRB MUC 161028


_______________________________________________
Mailing list: https://launchpad.net/~drizzle-discuss
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~drizzle-discuss
More help   : https://help.launchpad.net/ListHelp

Reply via email to