From: Date: September 6 2007 4:13pm Subject: Re: Re: [PATCH] (super)user-loadable mysqld parsers List-Archive: http://lists.mysql.com/internals/35004 Message-Id: <20070906141302.GD32583@w3.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="vA66WO2vHvL/CRSR" --vA66WO2vHvL/CRSR Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable * Arnold Daniels [2007-09-05 20:44-0400] > Hi Eric, > > First of all let me say that at least one person is enthusiastic (me). I = do=20 > have a few question remarks: > > You mentioned about the possibility to add an XQuery parser. But then how= =20 > would you map the data in the storage engines, which is relational data, = to=20 > XQuery? Or are you thinking about a special XML engine? Personally I like= =20 > the way DB2 solves this. You do an pass a value to the XQuery > SELECT XMLCAST(XMLQUERY(for $i in $t/product/description/category return= =20 > $i' PASSING BY REF T.DESCRIPTION AS "t" RETURNING SEQUENCE) AS=20 > VARCHAR(128)) FROM xmlproduct AS t The XQuery portion of your query was for $i in $t/product/description/category return $i which leads me to guess a schema where the XPaths represent joins through tables ala: SELECT XMLrepresentationOf(something.primaryKey) FROM something JOIN Products ON something.product=3DProducts.primaryKey JOIN Descriptions ON Product.description=3DDescriptions.primaryKey JOIN Categories ON Description.Category=3DCategories.primaryKey Lots of folks have done XQuery/relational mappings, and I have the impression they have this sort of mapping. This problem can be viewed as: 1 How would you represent your relational data in XQuery? 2 How would you query that representation? Given that approach, you need knowledge of the schema rather than a lot SQL-like code mapping the XML names and type to SQL terms. That, however, is if you wish to do everything in XQuery. If you want the outer language to be SQL, then yes, something like the DB2 name/type mapping is needed. > This functionality cannot be mimicked by a function, like ExtractValue(),= =20 > because a function can't make the query return more rows than selected.= =20 > Lets say that table had 7 rows with 3 products in the XML per row, the=20 > query should return 21 record. Agreed. Violating these restriction semantics would mean you weren't acutally using XQuery, just something that looked like it. Aside { When we started work on SPARQL, we had to prove to ourselves that we shouldn't use an existing W3C spec, namely XQuery. Some approaches were suggested and the ones that violated the predicate-as-restriction rule were dismissed. The remaining ones mostly focused around a canonical representation in XML. We didnt't find those close enough to our data model (and consequently they were too verbose) for our liking. That said, I'm always keen to enable interoperability between query systems. } > Here you see however that the XQuery parser isn't choosen to be `the`=20 > parser because this would be quite useless. Instead the XMLQuery if the= =20 > directive. Useless to folks who want to use SQL as their main language, but that's not how the XQuery (or SPARQL) folks see the world. If you offer someone a standard language, it's most useful to them if they don't have to do any transformations into another language. Otherwise, the "standard" query is different on MySQL and on Oracle, or DB2 ... > I don't know much about SPARQL, but from what I've read the query does ma= p=20 > well to relational data. However simply choosing the parser based on the= =20 > syntax seems rather confusing. For instance the '?' is also used to inser= t=20 > data from a prepared statement. Now when you forget to type a comma, the= =20 > query is suddenly interpreted as SPASQL. Making a change to the=20 > client/server protocol doesn't seem like the best solution to me as well,= =20 > because that well have a huge impact across the software development worl= d,=20 > and not in a good way. A simple solution seems to be to just specify it i= n=20 > the query: > > SPASQL SELECT ?s WHERE { ?s "hibbyhop"; That's what I originally implemented, but Brian Miezejewski's proposal was to differentiate parsers based on the protocol. I was fearful of the work it involved, but looking now, the patch actually isn't so large. > Both cases require that the parser actually integrates with the current= =20 > (SQL) parser, this is probably a bit harder to implement. Also, this seem= s=20 > like a perfect candidate for the INSTALL PLUGIN syntax. I can imagine a few ways to do this: =3D=3D Parser Integration (extend sql_yacc.yy and sql_lex.cc): Integrating with the SQL parser has a pretty high implementation and deployment cost. There are currently 285 shift/reduce conflicts in the grammar and adding a language like XQuery, which has 5 special cases in the lexer, would make quiet a soup. I'm doing some work with mechanical grammar recombination in the yacker, but that's kinda researchy. Another drawback is the likelyhood of collisions on popular idioms like set foo=3D"bar". =3D=3D Parser Encapsulation (add parser state to dispatch other language): The lexer could have a special state where it expected another language span and had some lexer rules controlling when that span would end. For example: posn | start | end |example start|!(SELECT|SET|SHOW|...)|rest of query|XQuery for $i ... any |CALLOUT(%language, ...|balanced ')' |... IN CALLOUT('XQuery', for $= i ... These require query-time transformation of an otherwise standard language; nice if you see the world through SQL eyes, less so if you see the world through XQuery or SPARQL eyes and want platform-independent queries. Also, this requires that all the THD manipulation done so far when parsing be compatible with whatever the next parser will do to it. A relational API that composed query plan would be a pretty cool way to handle this sort of integration, but that seems a good ways out. (I'd have a lot of fun working on that, though.) =3D=3D Callout function (encapsulate query as a string): This looks like the ... IN CALLOUT('XQuery', for $i ... above, except you need quotes around, and quote escaping of, the foreign query. This is compatible with the User Defined Function interface. It is simple to implement, but hard to use; same challenges as above. =3D=3D Prefix matching (look for string before calling SQL parser): This is how I implemented the first SPARQL parser: if (!strncmp(inBuf, "SPARQL:", 7)) { lex->ptr =3D (uchar*)inBuf+7; sparqlFrob frob(thd, (char**)&lex->ptr); parse_res =3D frob.parse(); } else { parse_res =3D MYSQLparse((void *)thd); } It worked well enough, but required a priori knowledge of all the possible extension languages and the requirement that they not conflict with any possible first token in the MySQL SQL grammar. As described above, this was not a verbatim SPARQL query. Ulimately, I like the protocol-switched approach as it gives the user explicit control and means that SPARQL queries on MySQL will be like SPARQL queries in Jena or any other implementation. =3D=3D=20 > Best regards, > Arnold > > > Eric Prud'hommeaux wrote: >> Attached is a dynParser patch to add alternate parsers into mysqld >> (and a parser that uses this interface). I developed this for the >> SPASQL project [SPA], but expect folks might want to use it to add >> parsers for other variants of SQL as well as totally different >> languages like XQuery and SPARQL. >> [SPA] http://esw.w3.org/topic/SPASQL >> >> The extension works by adding three new request types to the >> client/server protocol: PARSER1, PARSER2, PARSER3. The API function >> mysql_send_query takes a fourth parameter in order to send this to the >> server. On the server side, sql_parse.cc responds to requests for >> PARSER{1,2,3} by invoking dynamic_parsers[N].initialize->parse(). >> See [SRC] and [DYN] (below) for compilation and execution instructions. >> [SRC] http://www.w3.org/2005/05/22-SPARQL-MySQL/#srcbuild >> [DYN] http://www.w3.org/2005/05/22-SPARQL-MySQL/#dynParser >> >> >> A couple notes about protocol compatibility: a stock 5.x client does >> everything we need except invoke PARSERn requests. This is 'cause I >> left COM_QUERY where it was, and stuck the user-selected parsers at >> the end of the enum. >> /* add-on parsers */ >> COM_PARSER0, /* !!! change to COM_QUERY on next protocol change */ >> COM_PARSER1, COM_PARSER2, COM_PARSER3,=20 >> The cost is a slight discontinuity in the code for COM_QUERY vs. the >> other parsers. On the other hand, I haven't made MYSQLparse conform to >> the user parser API so it requires special code anyways. (I never >> figured out how to set defaults in set_var so I couldn't gracefully >> make MYSQLparse the default parser, plus it's dangerous to have the >> core parser be a shared library, and finally, if you did change >> parser0 from MYSQLparse to some other parser, you could find yourself >> with no tested way to talk to mysqld.) >> >> COM_PARSER0 is only used as a base for counting parser offsetsd; it is >> never passed so we could save an enum by assigning it to the previous >> value: >> >> /* add-on parsers */ >> COM_PARSER0 =3D COM_STMT_FETCH, COM_PARSER1, COM_PARSER2, COM_PARSER= 3,=20 >> but it may make sense to move COM_QUERY there instead. >> >> Brian and I discussed implementing a stacked parser approach: >> mysql> add_parser("libsparql", ParserPos_FRONT); >> mysql> SELECT ?s WHERE { ?s "hibbyhop"; >> The cost of this is that you can't force any particular parser to >> handle a particular request (unless you remove_parser and add_parser >> to get the one you like up front for that query). It would, however, >> provide a neat extensibility mechanism where 3rd party providers could >> supply parsers for add-on functionality. I prototyped this a bit in a >> Dynamic_parser and believe that a Dynamic_parser could provide a >> parser that stacked other Dynamic_parsers and even target queries at a >> particular parser if one chose. However, I have not really implemented >> this. >> >> Any feedback will be enthusiastically welcomed. I'm motivated to type >> madly on this on the off-chance I can get it into the 5.2 release as >> I have several pharmaceuticals interested in the SPASQL project and >> am anxious to get them working with the MySQL implementation. >> ----------------------------------------------------------------------= -- >> >> diff -au sql/set_var.cc.orig sql/set_var.cc >> --- sql/set_var.cc.orig 2007-09-03 19:17:28.000000000 -0400 >> +++ sql/set_var.cc 2007-09-04 17:48:12.000000000 -0400 >> @@ -69,6 +69,10 @@ >> extern ulong ndb_report_thresh_binlog_mem_usage; >> #endif >> +/* dynamically-loaded parsers */ >> +#include "dyn_parser.h" >> +#include >> + >> extern CHARSET_INFO *character_set_filesystem; >> @@ -88,6 +92,8 @@ >> delay_key_write_type_names, NULL >> }; >> +struct dynamic_parser_info dynamic_parsers[3]; >> + >> static int sys_check_ftb_syntax(THD *thd, set_var *var); >> static bool sys_update_ftb_syntax(THD *thd, set_var * var); >> static void sys_default_ftb_syntax(THD *thd, enum_var_type type); >> @@ -117,6 +123,11 @@ >> static void fix_max_relay_log_size(THD *thd, enum_var_type type); >> static void fix_max_connections(THD *thd, enum_var_type type); >> static int check_max_delayed_threads(THD *thd, set_var *var); >> +static int sys_check_parser(THD *thd, set_var *var); >> +static bool sys_update_parserN(THD *thd, set_var * var, uchar parser); >> +static bool sys_update_parser0(THD *thd, set_var * var); >> +static bool sys_update_parser1(THD *thd, set_var * var); >> +static bool sys_update_parser2(THD *thd, set_var * var); >> static void fix_thd_mem_root(THD *thd, enum_var_type type); >> static void fix_trans_mem_root(THD *thd, enum_var_type type); >> static void fix_server_id(THD *thd, enum_var_type type); >> @@ -348,6 +359,21 @@ >> =20 >> &SV::optimizer_prune_level); >> static sys_var_thd_ulong sys_optimizer_search_depth(&vars,=20 >> "optimizer_search_depth", >> =20 >> &SV::optimizer_search_depth); >> +static sys_var_str sys_dynamic_parser0(&vars,=20 >> "dynamic_parser1", >> + sys_check_parser, >> + sys_update_parser0, >> + 0, >> + dynamic_parsers[0].name); >> +static sys_var_str sys_dynamic_parser1(&vars,=20 >> "dynamic_parser2", >> + sys_check_parser, >> + sys_update_parser1, >> + 0, >> + dynamic_parsers[1].name); >> +static sys_var_str sys_dynamic_parser2(&vars,=20 >> "dynamic_parser3", >> + sys_check_parser, >> + sys_update_parser2, >> + 0, >> + dynamic_parsers[2].name); >> const char *optimizer_use_mrr_names[] =3D {"auto", "force", "disable",= =20 >> NullS}; >> TYPELIB optimizer_use_mrr_typelib=3D { >> @@ -828,6 +854,44 @@ >> sizeof(ft_boolean_syntax)-1); >> } >> +static int sys_check_parser(THD *thd, set_var *var) >> +{ >> + if (thd->security_ctx->master_access & SUPER_ACL) { >> + void* lib =3D dlopen(var->value->str_value.ptr(), RTLD_NOW); >> + if (lib) { >> + dlclose(lib); >> + return 0; >> + } >> + else >> + { >> + char* errstr =3D dlerror(); >> + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), errstr); // !!! need n= ew=20 >> error >> + return 1; >> + } >> + } >> + else >> + { >> + my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); >> + return 1; >> + } >> +} >> + >> +static bool sys_update_parserN(THD *thd, set_var * var, uchar parser) >> +{ >> + strmake(dynamic_parsers[parser].name, var->value->str_value.c_ptr(), >> + sizeof(dynamic_parsers[parser].name)-1); >> + if (dynamic_parsers[parser].handle) >> + dlclose(dynamic_parsers[parser].handle); >> + dynamic_parsers[parser].handle =3D dlopen(dynamic_parsers[parser].nam= e,=20 >> RTLD_NOW); >> + dynamic_parsers[parser].initialize =3D=20 >> (t_initialize*)dlsym(dynamic_parsers[parser].handle,=20 >> "_Z10initializeP3THDPPc"); >> + return 0; >> +} >> +static bool sys_update_parser0(THD *thd, set_var * var) >> +{ return sys_update_parserN(thd, var, 0); } >> +static bool sys_update_parser1(THD *thd, set_var * var) >> +{ return sys_update_parserN(thd, var, 1); } >> +static bool sys_update_parser2(THD *thd, set_var * var) >> +{ return sys_update_parserN(thd, var, 2); } >> /* >> If one sets the LOW_PRIORIY UPDATES flag, we also must change the >> diff -au client/mysqltest.c.orig client/mysqltest.c >> --- client/mysqltest.c.orig 2007-09-03 19:07:45.000000000 -0400 >> +++ client/mysqltest.c 2007-09-03 14:51:56.000000000 -0400 >> @@ -500,7 +500,7 @@ >> struct st_connection *cn=3D (struct st_connection*)arg; >> mysql_thread_init(); >> - VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len)); >> + VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len,= =20 >> 0)); >> mysql_thread_end(); >> pthread_mutex_lock(&cn->mutex); >> @@ -517,7 +517,7 @@ >> pthread_t tid; >> if (flags & QUERY_REAP_FLAG) >> - return mysql_send_query(&cn->mysql, q, q_len); >> + return mysql_send_query(&cn->mysql, q, q_len, 0); >> if (pthread_mutex_init(&cn->mutex, NULL) || >> pthread_cond_init(&cn->cond, NULL)) >> @@ -534,7 +534,7 @@ >> #else /*EMBEDDED_LIBRARY*/ >> -#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q= ,=20 >> q_len) >> +#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q,= =20 >> q_len, 0) >> #endif /*EMBEDDED_LIBRARY*/ >> diff -au client/mysql.cc.orig client/mysql.cc >> --- client/mysql.cc.orig 2007-09-03 19:07:45.000000000 -0400 >> +++ client/mysql.cc 2007-09-03 14:52:29.000000000 -0400 >> @@ -1828,7 +1828,17 @@ >> for (uint retry=3D0;; retry++) >> { >> int error; >> - if (!mysql_real_query(&mysql,buf,length)) >> + uchar parser =3D 0; >> + if (!strncmp(buf, "parser", 6) && buf[6] !=3D 0 && buf[7] =3D=3D ':= ') { >> + parser =3D buf[6]-'0'; >> + if (parser > 0 || parser < PARSERS) { >> + buf +=3D 8; >> + length -=3D 8; >> + } else { >> + // !!! error: invalid parser >> + } >> + } >> + if (!mysql_parser_query(&mysql,buf,length,parser)) >> return 0; >> error=3D put_error(&mysql); >> if (mysql_errno(&mysql) !=3D CR_SERVER_GONE_ERROR || retry > 1 || >> diff -au sql/sql_parse.cc.orig sql/sql_parse.cc >> --- sql/sql_parse.cc.orig 2007-08-26 04:36:04.000000000 -0400 >> +++ sql/sql_parse.cc 2007-09-05 09:54:19.000000000 -0400 >> @@ -28,6 +28,10 @@ >> #include "events.h" >> #include "sql_trigger.h" >> +/* dynamically-loaded parsers */ >> +#include "dyn_parser.h" >> +#include >> + >> /** >> @defgroup Runtime_Environment Runtime Environment >> @{ >> @@ -80,6 +84,10 @@ >> { C_STRING_WITH_LEN("Set option") }, >> { C_STRING_WITH_LEN("Fetch") }, >> { C_STRING_WITH_LEN("Daemon") }, >> + { C_STRING_WITH_LEN("Parser 0") }, >> + { C_STRING_WITH_LEN("Parser 1") }, >> + { C_STRING_WITH_LEN("Parser 2") }, >> + { C_STRING_WITH_LEN("Parser 3") }, >> { C_STRING_WITH_LEN("Error") } // Last command number >> }; >> @@ -431,7 +439,7 @@ >> */ >> thd->query_id=3Dnext_query_id(); >> thd->set_time(); >> - mysql_parse(thd, thd->query, length, & found_semicolon); >> + mysql_parse(thd, thd->query, length, & found_semicolon, 0); >> close_thread_tables(thd); // Free tables >> if (thd->is_fatal_error) >> @@ -842,6 +850,9 @@ >> break; >> } >> case COM_QUERY: >> + case COM_PARSER1: >> + case COM_PARSER2: >> + case COM_PARSER3: >> { >> if (alloc_query(thd, packet, packet_length)) >> break; // fatal error is set >> @@ -856,7 +867,8 @@ >> if (!(specialflag & SPECIAL_NO_PRIOR)) >> my_pthread_setprio(pthread_self(),QUERY_PRIOR); >> - mysql_parse(thd, thd->query, thd->query_length, & found_semicolon); >> + int parser =3D command =3D=3D COM_QUERY ? 0 : command - COM_PARSER0; >> + mysql_parse(thd, thd->query, thd->query_length, & found_semicolon,= =20 >> parser); >> while (!thd->killed && found_semicolon && !thd->net.report_error) >> { >> @@ -885,7 +897,7 @@ >> thd->set_time(); /* Reset the query start time. */ >> /* TODO: set thd->lex->sql_command to SQLCOM_END here */ >> VOID(pthread_mutex_unlock(&LOCK_thread_count)); >> - mysql_parse(thd, next_packet, length, & found_semicolon); >> + mysql_parse(thd, next_packet, length, & found_semicolon, parser); >> } >> if (!(specialflag & SPECIAL_NO_PRIOR)) >> @@ -5302,7 +5314,7 @@ >> */ >> void mysql_parse(THD *thd, const char *inBuf, uint length, >> - const char ** found_semicolon) >> + const char ** found_semicolon, uchar parser) >> { >> DBUG_ENTER("mysql_parse"); >> @@ -5336,7 +5348,24 @@ >> Lex_input_stream lip(thd, inBuf, length); >> - bool err=3D parse_sql(thd, &lip, NULL); >> + bool err; >> + if (parser =3D=3D 0) { >> + err=3D parse_sql(thd, &lip, NULL); >> + } else { >> + struct dynamic_parser_info* p =3D &dynamic_parsers[parser-1]; >> + if (p->initialize) { >> + char* space =3D (char*)malloc(strlen(lip.get_ptr())+1); >> + strcpy(space, lip.get_ptr()); >> + >> + Dynamic_parser* parser =3D p->initialize(thd, &space); >> + err=3D parser->parse(); >> + delete parser; >> + } else { >> + my_error(ER_WRONG_DB_NAME ,MYF(0), "parser not loaded");//!!!need error >> + err=3D 1; >> + } >> + } >> + >> *found_semicolon=3D lip.found_semicolon; >> if (!err) >> @@ -7160,6 +7189,14 @@ >> return err_status; >> } >> + >> +/* fill Dynamic_parser's vtable with dummy functions */ >> +int Dynamic_parser::parse() { >> +} >> + >> +Dynamic_parser::~Dynamic_parser() { >> +} >> + >> /** >> @} (end of group Runtime_Environment) >> */ >> diff -au sql-common/client.c.orig sql-common/client.c >> --- sql-common/client.c.orig 2007-09-03 19:07:45.000000000 -0400 >> +++ sql-common/client.c 2007-09-05 07:54:48.000000000 -0400 >> @@ -2757,7 +2757,8 @@ >> */ >> int STDCALL >> -mysql_send_query(MYSQL* mysql, const char* query, ulong length) >> +mysql_send_query(MYSQL* mysql, const char* query, + ulong length,=20 >> unsigned char parser) >> { >> DBUG_ENTER("mysql_send_query"); >> DBUG_PRINT("enter",("rpl_parse: %d rpl_pivot: %d", >> @@ -2777,7 +2778,8 @@ >> mysql->last_used_con =3D mysql; >> #endif >> - DBUG_RETURN(simple_command(mysql, COM_QUERY, (uchar*) query, length,= =20 >> 1)); >> + enum enum_server_command command =3D parser ? COM_PARSER0 + parser := =20 >> COM_QUERY; >> + DBUG_RETURN(simple_command(mysql, command, (uchar*) query, length, 1)= ); >> } >> @@ -2788,7 +2790,20 @@ >> DBUG_PRINT("enter",("handle: 0x%lx", (long) mysql)); >> DBUG_PRINT("query",("Query =3D '%-.4096s'",query)); >> - if (mysql_send_query(mysql,query,length)) >> + if (mysql_send_query(mysql,query,length,0)) >> + DBUG_RETURN(1); >> + DBUG_RETURN((int) (*mysql->methods->read_query_result)(mysql)); >> +} >> + >> + >> +int STDCALL >> +mysql_parser_query(MYSQL *mysql, const char *query, ulong length, uchar= =20 >> parser) >> +{ >> + DBUG_ENTER("mysql_real_query"); >> + DBUG_PRINT("enter",("handle: 0x%lx", (long) mysql)); >> + DBUG_PRINT("query",("Query =3D '%-.4096s'",query)); >> + >> + if (mysql_send_query(mysql,query,length,parser)) >> DBUG_RETURN(1); >> DBUG_RETURN((int) (*mysql->methods->read_query_result)(mysql)); >> } >> diff -au sql/slave.cc.orig sql/slave.cc >> diff -au sql/log_event.cc.orig sql/log_event.cc >> --- sql/log_event.cc.orig 2007-09-03 19:07:45.000000000 -0400 >> +++ sql/log_event.cc 2007-09-03 14:53:12.000000000 -0400 >> @@ -2083,7 +2083,7 @@ >> /* Execute the query (note that we bypass=20 >> dispatch_command()) */ >> const char* found_semicolon=3D NULL; >> - mysql_parse(thd, thd->query, thd->query_length, &found_semicolon); >> + mysql_parse(thd, thd->query, thd->query_length, &found_semicolon,= =20 >> 0); >> log_slow_statement(thd); >> } >> else >> diff -au sql/mysql_priv.h.orig sql/mysql_priv.h >> --- sql/mysql_priv.h.orig 2007-08-26 18:38:30.000000000 -0400 >> +++ sql/mysql_priv.h 2007-09-03 14:53:51.000000000 -0400 >> @@ -970,7 +970,7 @@ >> bool force_switch); >> void mysql_parse(THD *thd, const char *inBuf, uint length, >> - const char ** semicolon); >> + const char ** semicolon, uchar parser); >> bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length); >> bool is_update_query(enum enum_sql_command command); >> diff -au include/mysql_com.h.orig include/mysql_com.h >> --- include/mysql_com.h.orig 2007-08-25 15:13:27.000000000 -0400 >> +++ include/mysql_com.h 2007-09-03 14:54:03.000000000 -0400 >> @@ -60,6 +60,7 @@ >> servers won't be able to handle them as 'unsupported'. >> */ >> +#define PARSERS 3 // c.f. COM_PARSER1, COM_PARSER2, COM_PARSER3 below >> enum enum_server_command >> { >> COM_SLEEP, COM_QUIT, COM_INIT_DB, COM_QUERY, COM_FIELD_LIST, >> @@ -69,6 +70,11 @@ >> COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE, >> COM_STMT_PREPARE, COM_STMT_EXECUTE, COM_STMT_SEND_LONG_DATA,=20 >> COM_STMT_CLOSE, >> COM_STMT_RESET, COM_SET_OPTION, COM_STMT_FETCH, COM_DAEMON, >> + >> + /* add-on parsers */ >> + COM_PARSER0, /* !!! change to COM_QUERY on next protocol change */ >> + COM_PARSER1, COM_PARSER2, COM_PARSER3, + >> /* don't forget to update const char *command_name[] in sql_parse.cc = */ >> /* Must be last */ >> diff -au include/mysql.h.orig include/mysql.h >> --- include/mysql.h.orig 2007-09-03 19:07:45.000000000 -0400 >> +++ include/mysql.h 2007-09-03 14:54:03.000000000 -0400 >> @@ -446,9 +446,13 @@ >> int STDCALL mysql_select_db(MYSQL *mysql, const char *db); >> int STDCALL mysql_query(MYSQL *mysql, const char *q); >> int STDCALL mysql_send_query(MYSQL *mysql, const char *q, >> - unsigned long length); >> + unsigned long length, + unsigned char parser); >> int STDCALL mysql_real_query(MYSQL *mysql, const char *q, >> - unsigned long length); >> + unsigned long length); >> +int STDCALL mysql_parser_query(MYSQL *mysql, const char *q, >> + unsigned long length, >> + unsigned char parser); >> MYSQL_RES * STDCALL mysql_store_result(MYSQL *mysql); >> MYSQL_RES * STDCALL mysql_use_result(MYSQL *mysql); >> diff -au include/dyn_parser.h.orig include/dyn_parser.h >> --- include/dyn_parser.h.orig 2007-09-03 19:10:02.000000000 -0400 >> +++ include/dyn_parser.h 2007-09-03 19:09:52.000000000 -0400 >> @@ -0,0 +1,33 @@ >> +#ifndef _dyn_parser_h >> +#define _dyn_parser_h >> +/*-- use only from C++ >> + #ifdef __cplusplus >> + extern "C" { >> + #endif >> +*/ >> + >> +class Dynamic_parser { >> + >> +public: >> + Dynamic_parser(THD *thd, char** ptr) { >> + this->thd=3D thd; >> + } >> + virtual ~Dynamic_parser(); >> + virtual int parse(); >> + >> + THD *thd; >> +}; >> +extern "C" { >> + typedef Dynamic_parser* t_initialize(THD *, char **); >> +} >> + >> +struct dynamic_parser_info { >> + char name[FN_REFLEN]; >> + void* handle; >> + t_initialize* initialize; >> + // Dynamic_parser* (*initialize)(THD *, char **); >> +}; >> +extern struct dynamic_parser_info dynamic_parsers[]; >> + >> +#endif /* _dyn_parser_h */ >> + >> diff -au sql/backup/meta_backup.cc.orig sql/backup/meta_backup.cc >> --- sql/backup/meta_backup.cc.orig 2007-09-03 21:55:06.000000000 -0400 >> +++ sql/backup/meta_backup.cc 2007-09-03 21:55:43.000000000 -0400 >> @@ -361,7 +361,7 @@ >> pthread_mutex_unlock(&::LOCK_thread_count); >> const char *ptr; >> - ::mysql_parse(thd,thd->query,thd->query_length,&ptr); >> + ::mysql_parse(thd,thd->query,thd->query_length,&ptr,0); >> thd->net.vio=3D save_vio; >> diff -au sql/ha_ndbcluster_binlog.cc.orig sql/ha_ndbcluster_binlog.cc >> --- sql/ha_ndbcluster_binlog.cc.orig 2007-09-03 21:56:23.000000000 -0400 >> +++ sql/ha_ndbcluster_binlog.cc 2007-09-03 21:56:28.000000000 -0400 >> @@ -277,7 +277,7 @@ >> thd->options&=3D ~OPTION_BIN_LOG; >> DBUG_PRINT("query", ("%s", thd->query)); >> - mysql_parse(thd, thd->query, thd->query_length, &found_semicolon); >> + mysql_parse(thd, thd->query, thd->query_length, &found_semicolon, 0); >> if (no_print_error && thd->query_error) >> { >> ----------------------------------------------------------------------= -- >> >> %{ >> #define YY_sparqlParser_STYPE yy_sparqlParser_stype >> /* $Id: sparqlParser.yy,v 1.9 2007/09/05 18:40:30 eric Exp $ >> >> TODO: >> research pre-existing var.jt in conjunction with trump >> >> OUTLINE: >> >> Some SPARQL graph pattern opperations correspond to SQL subselects. Thes= e=20 >> create >> a new BindingContext, which keeps track of looks for table alias re-use >> opportunities. These occur in a given binding context where more than one >> subject/predicate pair is in the same table. For instance, both (?s,=20 >> T1.p1) and >> (?s, T1.p2) both map to the alias T1_0. (Ohterwise, you get needless joi= ns=20 >> like >> FROM T1 AS T1_0 JOIN T1 AS T1_1 ON T1_0.id=3DT1_1.id >> WHERE T1_0.p1=3Do1 AND T1_1.p1=3Do2 >> >> sparqlFrob::object(subject, predicate, object) >> >> */ >> %} >> %name sparqlParser >> %define LSP_NEEDED >> %define ERROR_BODY =3D0 >> %define LEX_BODY =3D0 >> %header{ >> #include >> #include >> using namespace std; >> #undef yyFlexLexer >> #define yyFlexLexer sparqlFlexLexer >> >> #ifndef FLEXFIX >> #define FLEXFIX YY_sparqlParser_STYPE *val >> #define FLEXFIX2 val >> #endif >> >> #define MYSQL_YACC >> #define YYINITDEPTH 100 >> #define YYMAXDEPTH 3200 /* Because of 64K stack */ >> #include "mysql_priv.h" >> #include "slave.h" >> #include "lex_symbol.h" >> #include "item_create.h" >> #include "sp_head.h" >> #include "sp_pcontext.h" >> #include "sp_rcontext.h" >> #include "sp.h" >> #include >> #include >> >> #include "sparqlFrob.h" >> #define YY_sparqlParser_PARSE_PARAM sparqlFrob *yySparqlFrob >> >> #define PLS_REPORT "Please report this bug, along with the query that=20 >> triggered it." >> >> static char * Iso8601formatStr =3D "%Y-%m-%dT%H:%i:%sZ"; >> //DATE_TIME_FORMAT Iso8601_format =3D {Iso8601formatStr,=20 >> strlen(Iso8601formatStr)}; >> >> extern String Global_string; // call test->print(&Global_string); p=20 >> Global_string.c_ptr(); call Global_string.free() >> >> /* DEBUGGING/DEVELOPMENT >> * aggregates a string representing the parsed input. >> */ >> class Buf { >> protected: >> char* data; >> int len; >> public: >> Buf() { >> len =3D 0; >> data =3D 0; >> } >> Buf(char *str); >> Buf(int count, ...); >> ~Buf() { >> if (data) delete[] data; >> } >> char *str() {return data;} >> }; >> >> >> /* forward class declarations */ >> class BindingContext; >> >> >> /* static function declarations */ >> static const char* scan_string(THD *thd, LEX_STRING *lex_string, = =20 >> const char *start, const char *end, const char look_for); >> >> >> /* Item_POS: overload the mysql Item object for all the SPARQL parts >> * of speach (URIs, bNodes, variables, and various forms of literal). >> * >> * Item overloads: bind_field >> */ >> class Item_POS >> { >> protected: >> Item *item; >> public: >> Item_POS (Item* item_arg) {item =3D item_arg;} >> virtual ~Item_POS () {} >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) = =3D=20 >> 0; >> virtual bool is_URI () {return false;} >> virtual bool is_variable () {return false;} >> virtual bool is_blank_node () {return false;} >> virtual bool is_string () {return false;} >> Item* get_item () {return item;} // OK 'cause ALL Item_POS's are Items. >> virtual void print(String *str)=3D 0; >> }; >> >> >> class Item_URI : public Item_field, public Item_POS >> { >> protected: >> LEX_STRING table; >> LEX_STRING field; >> LEX_STRING value; >> >> public: >> Item_URI(Name_resolution_context *context_arg, LEX_STRING uri, THD=20 >> *thd); >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); >> virtual bool is_URI () {return true;} >> LEX_STRING get_table () {return table;} >> LEX_STRING get_field () {return field;} >> LEX_STRING get_value () {return value;} >> void print(String *str); >> }; >> extern Item_URI *XSD_integer; >> extern Item_URI *XSD_float; >> extern Item_URI *XSD_decimal; >> >> >> /* Item_variable: represent SPARQL variable. >> * >> * includes the status of a variable's use in the current JOIN. A variab= le=20 >> in >> * a nested JOIN is different from a variable in an outer context (the >> * UnionGraphContext::close handles the correlation=20 >> (U0.foo=3DoldTable.oldField). >> * >> * Item_variable has the same virtual functions as an Item, but is never >> * added to the SQL compile tree (for instance, in the form of a table >> * constraint or a select item). >> */ >> class Item_variable : public Item_field, public Item_POS >> { >> private: >> Name_resolution_context *nr_context; >> GraphContext *gc; >> bool bound; >> bool primary_key; >> TABLE_LIST *jt; >> Item_variable *outer; >> sparqlFrob *frob; >> const char *real_table_name; >> int ref_count; >> const char* get_primary_key () {return=20 >> frob->get_primary_key(real_table_name);} >> Item* make_Item_field(Name_resolution_context *context_arg, >> const char *db_arg, const char *table_name_arg, >> const char *field_name_arg, const char* real_table_name); >> >> public: >> Item_variable(Name_resolution_context *context_arg, const char=20 >> *variable_name, Item_variable *outer_arg, sparqlFrob *frob_arg, int=20 >> ref_count_arg); >> >> /* Item_field Virtual Overloads: >> * Item_variable behaves as as an Item_result_field when the variable >> * identifies a primary key and as an Item_field the rest of the time. >> * These methods produce a URI when the constructed from the primary >> * key field name and value. >> */ >> void make_field(Send_field *tmp_field); >> virtual bool fix_fields(THD *, Item **); >> virtual bool send(Protocol *protocol, String *buffer); >> >> /* Item_POS Virtual Overloads: >> * >> */ >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); >> virtual bool is_variable () {return true;} >> >> /* SparqlFrob interface */ >> bool same_variable (const char* variable_name) { >> return !strcmp(orig_field_name, variable_name); >> } >> bool outer_has_no_refs () {return outer ? outer->ref_count =3D=3D 0 : = true;} >> static Item_variable* match_var_in_list (List=20 >> *p_item_variables, const char *var); >> >> /* BindingContext interface */ >> void add_ref_count (int ref_count_arg) {ref_count+=3D ref_count_arg;} >> Item* get_null_item(); >> >> /* debugging */ >> void print(String *str); >> }; >> >> >> /* Item_blank_node: represent SPARQL bNode. >> */ >> class Item_blank_node : public Item_variable >> { >> public: >> Item_blank_node (Name_resolution_context *context_arg, const char= =20 >> *node_name, sparqlFrob *frob_arg) : Item_variable(context_arg,=20 >> node_name, NULL, frob_arg, 0) {} >> virtual bool is_blank_node () {return true;} >> void print(String *str); >> }; >> >> >> /* Item_literal_string: represent SPARQL xsd:string typed literal. >> */ >> class Item_literal_string : public Item_string, public Item_POS >> { >> private: >> Item_POS *lang_or_datatype; >> public: >> Item_literal_string (LEX_STRING string, Item_POS=20 >> *lang_or_datatype, CHARSET_INFO *charset) : Item_string(string.str,= =20 >> string.length, charset), Item_POS(this) { >> this->lang_or_datatype =3D lang_or_datatype; >> } >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); >> virtual bool is_string () {return true;} >> Item_POS* get_language_or_datatype () { >> return lang_or_datatype; >> } >> Item_URI* get_datatype () { >> return lang_or_datatype && lang_or_datatype->is_URI() ? =20 >> (Item_URI*)lang_or_datatype : NULL; >> } >> Item_literal_string* get_language () { >> return lang_or_datatype && lang_or_datatype->is_string() ? =20 >> (Item_literal_string*)lang_or_datatype : NULL; >> } >> void print(String *str); >> }; >> >> >> /* Item_literal_int: represent SPARQL xsd:integer typed literal. >> */ >> class Item_literal_int : public Item_int, public Item_POS >> { >> public: >> Item_literal_int (LEX_STRING string, Item_POS *lang_or_datatype,= =20 >> CHARSET_INFO *charset) : Item_int(string.str), Item_POS(this) {} >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); >> virtual bool is_string () {return false;} >> Item_URI* get_datatype () {return XSD_integer;} >> Item_literal_string* get_language () {return NULL;} >> void print(String *str); >> }; >> >> >> /* Item_literal_decimal: represent SPARQL xsd:decimal typed literal. >> */ >> class Item_literal_decimal : public Item_decimal, public Item_POS >> { >> public: >> Item_literal_decimal (LEX_STRING string, Item_POS *lang_or_datatype,= =20 >> CHARSET_INFO *charset) : Item_decimal(string.str, string.length,=20 >> charset), Item_POS(this) {} >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); >> virtual bool is_string () {return false;} >> Item_URI* get_datatype () {return XSD_decimal;} >> Item_literal_string* get_language () {return NULL;} >> void print(String *str); >> }; >> >> >> /* Item_literal_float: represent SPARQL xsd:float typed literal. >> */ >> class Item_literal_float : public Item_float, public Item_POS >> { >> public: >> Item_literal_float (LEX_STRING string, Item_POS *lang_or_datatype,=20 >> CHARSET_INFO *charset) : Item_float(string.str, string.length),=20 >> Item_POS(this) {} >> virtual void bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); >> virtual bool is_string () {return false;} >> Item_URI* get_datatype () {return XSD_float;} >> Item_literal_string* get_language() {return NULL;} >> void print(String *str); >> }; >> >> >> /* Item_primary_key_field: reference to an Item_field that is a primary= =20 >> key. >> * Used to create foreign key/primary key constraints on joins. >> */ >> class Item_primary_key_field : public Item_field >> { >> protected: >> sparqlFrob *frob; >> const char* real_table_name; >> public: >> Item_primary_key_field(Name_resolution_context *context_arg, >> const char *db_arg, const char *table_name_arg, sparqlFrob=20 >> *frob_arg, const char* real_table_name_arg); >> virtual bool fix_fields(THD *, Item **); >> }; >> >> >> #if 0 >> /* Item_func_call: not implemented >> */ >> class Item_func_call : public Item_POS >> { >> protected: >> Item_POS* name; >> List* args; >> public: >> Item_func_call (Name_resolution_context *context_arg, Item_POS*=20 >> name, List* args) : >> Item_POS(context_arg, "") { >> this->name =3D name; >> this->args =3D args; >> } >> ~Item_func_call() {} >> void bind_field (const char *table_name, const char *alias, const= =20 >> char *field_name_arg, bool trump, T HD *thd, TABLE_LIST *jt) {} >> bool fix_fields(THD *, Item **); >> }; >> #endif >> >> >> /* Alias_info: aliases for a table, indexed by subject. >> * If it's not in subjects, you need a new alias. >> */ >> class Alias_info { >> friend class GraphContext; >> private: >> LEX_STRING table; >> List subjects; >> public: >> Alias_info(LEX_STRING table) { >> this->table =3D table; >> } >> bool same_table(LEX_STRING table) { >> return !strcmp(this->table.str, table.str); >> } >> }; >> >> >> /* BindingContext: SQL table aliases and constraints for a given >> * SPARQL group graph pattern. >> */ >> class BindingContext { >> protected: >> List item_variables; >> // All known table aliases for in the context. >> List aliases; >> Name_resolution_context *name_res_context; >> BindingContext *parent; >> LEX *lex; >> List *constraints; >> >> public: >> BindingContext(GraphContext *gc_param, BindingContext *parent_param= ,=20 >> LEX *lex_param) { >> parent=3D parent_param; >> lex=3D lex_param; >> //name_res_context=3D lex->current_context(); >> } >> Item_variable* ensure_bound_item_variable(const char *name, =20 >> sparqlFrob *sparql_frob, int ref_count); >> void select_star(THD *thd); >> List* get_item_variables () { return &item_variables; } >> Alias_info* get_table_alias(THD *thd, Item_POS *s, Item_URI *p, Item_P= OS=20 >> *o); >> Item* get_bound_variable_constraints(Item *conjunction_constraints, = =20 >> GraphContext *gc); >> void start_constraints(); >> void end_and_check_constraints() { >> assert(constraints =3D=3D lex->select_lex.expr_list.pop()); >> } >> Item* make_item_constraints() { >> return constraints->elements ? new Item_cond_and(*constraints) : NUL= L; >> } >> }; >> >> >> /* GraphContext: corresponds to a SPARQL graph context. >> */ >> class GraphContext { >> protected: >> GraphContext *parent; >> THD *thd; >> Buf *buf; // temporary >> >> public: >> sparqlFrob *sparql_frob; // !!! should be protected >> GraphContext (GraphContext *parent_param, sparqlFrob *sparql_frob_para= m)=20 >> { >> sparql_frob=3D sparql_frob_param; >> parent=3D parent_param; >> thd=3D sparql_frob->thd; >> buf=3D NULL; >> } >> virtual ~GraphContext () {} >> virtual void close () { >> cout << "SPARQL: close {" << endl << buf->str() << "}" << endl; >> } >> virtual void no_right_union () { >> cout << "SPARQL: non-UNION {" << endl << buf->str() << "}" << endl; >> } >> void set_Buf (Buf *buf_param) { buf=3D buf_param; } >> Buf* get_Buf () { return buf; } >> virtual bool is_optional () { return false; } >> virtual BindingContext* get_binding_context () { >> return parent->get_binding_context(); >> } >> const char* get_alias_string(Alias_info *ai, Item_POS *s, THD *thd); >> }; >> >> >> /* BindingGraphContext: the graph contexts that require a new=20 >> BindingContext. >> * Raison d'etre: factored common code from Union and Graph contexts. >> */ >> class BindingGraphContext : public GraphContext { >> friend class Union2GraphContext; // why doesn't BindingGraphContext wo= rk=20 >> here? >> protected: >> BindingContext *bindings; >> SELECT_LEX *current_select; >> BindingGraphContext(GraphContext *parent_param, sparqlFrob=20 >> *sparql_frob_param); >> public: >> void select_var(Item_variable *var, bool exists); >> virtual BindingContext* get_binding_context() { return bindings; } >> }; >> >> >> /* RootGraphContext: the graph context just inside the WHERE. >> */ >> class RootGraphContext : public BindingGraphContext { >> public: >> RootGraphContext(GraphContext *parent, sparqlFrob *sparql_frob); >> virtual void close () { >> bindings->end_and_check_constraints(); >> } >> }; >> >> >> /* OptionalGraphContext: OPTIONAL { }. >> * ^^^ >> */ >> class OptionalGraphContext : public GraphContext { >> public: >> OptionalGraphContext (GraphContext *parent, sparqlFrob *sparql_frob) := =20 >> GraphContext(parent, sparql_frob) { >> /* if (!(on_context=3D make_join_on_context(thd, $1, $3))) >> assert(0); >> thd->lex->push_context(on_context); >> */ >> } >> virtual void close () { >> /* thd->lex->pop_context(); >> */ >> } >> virtual bool is_optional () { return true; } >> }; >> >> >> /* Union1GraphContext: { } UNION { }. >> * ^^^ >> */ >> class Union1GraphContext : public BindingGraphContext { >> public: >> Union1GraphContext(GraphContext *parent, sparqlFrob *sparql_frob); >> virtual void no_right_union () { >> /* Just a spurious {} so copy the context up to the parent. >> @@@ TODO >> */ >> my_printf_error(1, "SPARQL: implementation limitation: not ready to= =20 >> deal with non-UNION %s. "PLS_REPORT, MYF(0), buf->str()); >> } >> virtual void close(); >> Item* map_variables_to_outer_context () { // !!! does nothing >> return NULL; >> } >> }; >> >> >> /* Union1GraphContext: { } UNION { }. >> * ^^^ >> */ >> class Union2GraphContext : public BindingGraphContext { >> private: >> BindingGraphContext *left; // left side of the UNION >> >> public: >> Union2GraphContext(GraphContext *parent, sparqlFrob *sparql_frob); >> virtual void close(); >> }; >> >> >> /* GraphGraphContext: GRAPH { }. >> * ^^^ >> */ >> class GraphGraphContext : public BindingGraphContext { >> public: >> GraphGraphContext (GraphContext *parent, sparqlFrob *sparql_frob) : = =20 >> BindingGraphContext(parent, sparql_frob) {} >> }; >> >> >> %} >> >> %union { >> int num; >> LEX_STRING lex_str; >> Item *item; >> List *item_list; >> List *BindingGraphContext_list; >> Item_POS *item_pos; >> GraphContext *graph_context; >> BindingGraphContext *binding_graph_context; >> Buf *buf; >> } >> >> %token IT_BASE >> %token IT_PREFIX >> %token IT_SELECT >> %token IT_DISTINCT >> %token GT_TIMES >> %token IT_CONSTRUCT >> %token IT_DESCRIBE >> %token IT_ASK >> %token IT_FROM >> %token IT_NAMED >> %token IT_WHERE >> %token IT_ORDER >> %token IT_BY >> %token IT_ASC >> %token IT_DESC >> %token IT_LIMIT >> %token IT_OFFSET >> %token GT_LCURLEY >> %token GT_RCURLEY >> %token GT_DOT >> %token IT_OPTIONAL >> %token IT_GRAPH >> %token IT_UNION >> %token IT_FILTER >> %token GT_COMMA >> %token GT_LPAREN >> %token GT_RPAREN >> %token GT_SEMI >> %token IT_a >> %token GT_LBRACKET >> %token GT_RBRACKET >> %token GT_MINUS >> %token GT_PLUS >> %token GT_OR >> %token GT_AND >> %token GT_EQUAL >> %token GT_NEQUAL >> %token GT_LT >> %token GT_GT >> %token GT_LE >> %token GT_GE >> %token GT_DIVIDE >> %token GT_NOT >> %token IT_STR >> %token IT_LANG >> %token IT_LANGMATCHES >> %token IT_DATATYPE >> %token IT_BOUND >> %token IT_isIRI >> %token IT_isURI >> %token IT_isBLANK >> %token IT_isLITERAL >> %token IT_REGEX >> %token GT_DTYPE >> %token IT_true >> %token IT_false >> %token Q_IRI_REF >> %token QNAME_NS >> %token QNAME >> %token BLANK_NODE_LABEL >> %token VAR1 >> %token VAR2 >> %token LANGTAG >> %token INTEGER >> %token DECIMAL >> %token DOUBLE >> %token STRING_LITERAL1 >> %token STRING_LITERAL2 >> %token STRING_LITERAL_LONG1 >> %token STRING_LITERAL_LONG2 >> %token NIL >> %token ANON >> %type Query >> %type =20 >> _O_QSelectQuery_E__Or__QConstructQuery_E__Or__QDescribeQuery_E__Or__QAsk= Query_E__C >> %type Prolog >> %type _QBaseDecl_E_Opt >> %type _QPrefixDecl_E_Star >> %type BaseDecl >> %type PrefixDecl >> %type SelectQuery >> %type _QDISTINCT_E_Opt >> %type _QVar_E_Plus >> %type _O_QVar_E_Plus_Or__QTIMES_E__C >> %type _QDatasetClause_E_Star >> %type ConstructQuery >> %type DescribeQuery >> %type _QVarOrIRIref_E_Plus >> %type _O_QVarOrIRIref_E_Plus_Or__QTIMES_E__C >> %type _QWhereClause_E_Opt >> %type AskQuery >> %type DatasetClause >> %type _O_QDefaultGraphClause_E__Or__QNamedGraphClause_E__C >> %type DefaultGraphClause >> %type NamedGraphClause >> %type SourceSelector >> %type WhereClause >> %type _QWHERE_E_Opt >> %type SolutionModifier >> %type _QOrderClause_E_Opt >> %type _QLimitClause_E_Opt >> %type _QOffsetClause_E_Opt >> %type OrderClause >> %type _QOrderCondition_E_Plus >> %type OrderCondition >> %type _O_QASC_E__Or__QDESC_E__C >> %type _O_QASC_E__Or__QDESC_E____QBrackettedExpression_E__C >> %type =20 >> _O_QFunctionCall_E__Or__QVar_E__Or__QBrackettedExpression_E__C >> %type LimitClause >> %type OffsetClause >> %type GroupGraphPattern >> %type GraphPattern >> %type _QDOT_E_Opt >> %type =20 >> _O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C >> %type =20 >> _Q_O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C_E_Opt >> %type FilteredBasicGraphPattern >> %type _QBlockOfTriples_E_Opt >> %type =20 >> _O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C >> %type =20 >> _Q_O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C_E_Opt >> %type BlockOfTriples >> %type _QTriplesSameSubject_E_Opt >> %type _O_QDOT_E____QTriplesSameSubject_E_Opt_C >> %type _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star >> %type GraphPatternNotTriples >> %type OptionalGraphPattern >> %type GraphGraphPattern >> %type GroupOrUnionGraphPattern >> %type _O_QUNION_E____QGroupGraphPattern_E__C >> %type =20 >> _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star >> %type Constraint >> %type =20 >> _O_QBrackettedExpression_E__Or__QBuiltInCall_E__Or__QFunctionCall_E__C >> %type FunctionCall >> %type ArgList >> %type _O_QCOMMA_E____QExpression_E__C >> %type _Q_O_QCOMMA_E____QExpression_E__C_E_Star >> %type =20 >> _O_QNIL_E__Or__QLPAREN_E____QExpression_E____QCOMMA_E____QExpression_E_S= tar___QRPAREN_E__C >> %type ConstructTemplate >> %type ConstructTriples >> %type _O_QDOT_E____QConstructTriples_E__C >> %type _Q_O_QDOT_E____QConstructTriples_E__C_E_Opt >> %type =20 >> _O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C >> %type =20 >> _Q_O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C_E_Opt >> %type TriplesSameSubject >> %type PropertyList >> %type _QPropertyListNotEmpty_E_Opt >> %type PropertyListNotEmpty >> %type _O_QSEMI_E____QPropertyList_E__C >> %type _Q_O_QSEMI_E____QPropertyList_E__C_E_Opt >> %type ObjectList >> %type _O_QCOMMA_E____QObjectList_E__C >> %type _Q_O_QCOMMA_E____QObjectList_E__C_E_Opt >> %type Verb >> %type TriplesNode >> %type BlankNodePropertyList >> %type Collection >> %type _QGraphNode_E_Plus >> %type GraphNode >> %type VarOrTerm >> %type VarOrIRIref >> %type VarOrBlankNodeOrIRIref >> %type Var >> %type GraphTerm >> %type _O_QMINUS_E__Or__QPLUS_E__C >> %type _Q_O_QMINUS_E__Or__QPLUS_E__C_E_Opt >> %type Expression >> %type ConditionalOrExpression >> %type _O_QOR_E____QConditionalAndExpression_E__C >> %type _Q_O_QOR_E____QConditionalAndExpression_E__C_E_Star >> %type ConditionalAndExpression >> %type _O_QAND_E____QValueLogical_E__C >> %type _Q_O_QAND_E____QValueLogical_E__C_E_Star >> %type ValueLogical >> %type RelationalExpression >> %type =20 >> _O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression= _E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__O= r__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C >> %type =20 >> _Q_O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpressi= on_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E_= _Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C_E_= Opt >> %type NumericExpression >> %type AdditiveExpression >> %type =20 >> _O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicati= veExpression_E__C >> %type =20 >> _Q_O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplica= tiveExpression_E__C_E_Star >> %type MultiplicativeExpression >> %type =20 >> _O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__C >> %type =20 >> _Q_O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E= __C_E_Star >> %type UnaryExpression >> %type PrimaryExpression >> %type BrackettedExpression >> %type BuiltInCall >> %type RegexExpression >> %type _Q_O_QCOMMA_E____QExpression_E__C_E_Opt >> %type IRIrefOrFunction >> %type _QArgList_E_Opt >> %type RDFLiteral >> %type _O_QDTYPE_E____QIRIref_E__C >> %type _O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C >> %type _Q_O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C_E_Opt >> %type NumericLiteral >> %type BooleanLiteral >> %type String >> %type IRIref >> %type QName >> %type BlankNode >> %% >> >> Query: >> { >> LEX *lex=3D yySparqlFrob->thd->lex; >> SELECT_LEX *sel=3D lex->current_select; >> lex->current_select->parsing_place =3D NO_MATTER; >> sel->offset_limit=3D NULL; >> sel->select_limit=3D NULL; >> // create root context right away so SELECTs have a context >> yySparqlFrob->push_context( >> new RootGraphContext(yySparqlFrob->head_context(), yySparqlFrob)); >> } >> Prolog=20 >> _O_QSelectQuery_E__Or__QConstructQuery_E__Or__QDescribeQuery_E__Or__QAsk= Query_E__C >> { >> Buf *b =3D new Buf(2, $2, $3); >> cout << "Query end -- " << b->str() << endl; >> delete b; >> }; >> >> _O_QSelectQuery_E__Or__QConstructQuery_E__Or__QDescribeQuery_E__Or__QAsk= Query_E__C: >> SelectQuery {$$ =3D $1} >> | ConstructQuery {$$ =3D $1; YYABORT;} >> | DescribeQuery {$$ =3D $1; YYABORT;} >> | AskQuery {$$ =3D $1; YYABORT;}; >> >> Prolog: >> _QBaseDecl_E_Opt _QPrefixDecl_E_Star {$$ =3D new Buf(2, $1, $2)}; >> >> _QBaseDecl_E_Opt: >> {$$ =3D new Buf()} >> | BaseDecl {$$ =3D $1}; >> >> _QPrefixDecl_E_Star: >> {$$ =3D new Buf()} >> | _QPrefixDecl_E_Star PrefixDecl {$$ =3D new Buf(2, $1, $2)}; >> >> BaseDecl: >> IT_BASE Q_IRI_REF {$$ =3D new Buf(2, new Buf("BASE"), new Buf($2.str= ))}; >> >> PrefixDecl: >> IT_PREFIX QNAME_NS Q_IRI_REF {$$ =3D new Buf(3, $1, new Buf($2.str),= new=20 >> Buf($3.str))}; >> >> SelectQuery: >> IT_SELECT >> { >> LEX *lex=3D yySparqlFrob->lex; >> SELECT_LEX *sel=3D lex->current_select; >> >> sel->parsing_place =3D SELECT_LIST; >> lex->sql_command=3D SQLCOM_SELECT; // SQLCOM_EMPTY_QUERY; >> } >> _QDISTINCT_E_Opt _O_QVar_E_Plus_Or__QTIMES_E__C >> { >> //SELECT_LEX *sel=3D yySparqlFrob->lex->current_select; >> >> // commented out 'cause the didn't seem to be needed - EGP 20060326 >> // lex->create_view_select_start =3D $1->get_item()->name; >> //sel->parsing_place =3D NO_MATTER; >> //sel->set_braces(0); >> } >> _QDatasetClause_E_Star WhereClause SolutionModifier >> { >> LEX *lex=3D yySparqlFrob->lex; >> SELECT_LEX *sel=3D lex->current_select; >> >> // Now that we have all the variables, fix up the SELECTs. >> yySparqlFrob->select_variables(); >> >> sel->parsing_place =3D NO_MATTER; >> $$ =3D new Buf(6, new Buf("SELECT"), $3, $4, $6, $7, $8); >> } >> ; >> >> _QDISTINCT_E_Opt: >> {$$ =3D new Buf()} >> | IT_DISTINCT >> { >> yySparqlFrob->set_distinct(true); >> $$ =3D $1; >> }; >> >> _QVar_E_Plus: >> Var >> { >> THD *thd=3D yySparqlFrob->thd; >> LEX *lex=3D thd->lex; >> SELECT_LEX *sel=3D lex->current_select; >> //sel->use_index_ptr=3Dsel->ignore_index_ptr=3D0; >> sel->table_join_options=3D 0; >> if (add_item_to_list(thd, $1->get_item())) { >> YYABORT; >> } >> >> $$ =3D new Buf($1->get_item()->name); >> } >> | _QVar_E_Plus Var >> { >> THD *thd=3D yySparqlFrob->thd; >> if (add_item_to_list(thd, $2->get_item())) { >> YYABORT; >> } >> $$ =3D new Buf(2, $1, new Buf($2->get_item()->name)); >> }; >> >> _O_QVar_E_Plus_Or__QTIMES_E__C: >> _QVar_E_Plus {$$ =3D $1} >> | GT_TIMES >> { $$ =3D $1; } >> ; >> >> _QDatasetClause_E_Star: >> {$$ =3D new Buf()} >> | _QDatasetClause_E_Star DatasetClause {$$ =3D new Buf(2, $1, $2)}; >> >> ConstructQuery: >> IT_CONSTRUCT ConstructTemplate _QDatasetClause_E_Star WhereClause=20 >> SolutionModifier {$$ =3D new Buf(5, $1, $2, $3, $4, $5)}; >> >> DescribeQuery: >> IT_DESCRIBE _O_QVarOrIRIref_E_Plus_Or__QTIMES_E__C=20 >> _QDatasetClause_E_Star _QWhereClause_E_Opt SolutionModifier {$$ =3D new= =20 >> Buf(5, $1, $2, $3, $4, $5)}; >> >> _QVarOrIRIref_E_Plus: >> VarOrIRIref {$$ =3D new Buf($1->get_item()->name)} >> | _QVarOrIRIref_E_Plus VarOrIRIref {$$ =3D new Buf(2, $1, new=20 >> Buf($2->get_item()->name))}; >> >> _O_QVarOrIRIref_E_Plus_Or__QTIMES_E__C: >> _QVarOrIRIref_E_Plus {$$ =3D $1} >> | GT_TIMES {$$ =3D $1}; >> >> _QWhereClause_E_Opt: >> {$$ =3D new Buf()} >> | WhereClause {$$ =3D $1}; >> >> AskQuery: >> IT_ASK _QDatasetClause_E_Star WhereClause {$$ =3D new Buf(3, $1, $2,= =20 >> $3)}; >> >> DatasetClause: >> IT_FROM _O_QDefaultGraphClause_E__Or__QNamedGraphClause_E__C {$$ =3D= new=20 >> Buf(2, $1, $2)}; >> >> _O_QDefaultGraphClause_E__Or__QNamedGraphClause_E__C: >> DefaultGraphClause {$$ =3D $1} >> | NamedGraphClause {$$ =3D $1}; >> >> DefaultGraphClause: >> SourceSelector {$$ =3D $1}; >> >> NamedGraphClause: >> IT_NAMED SourceSelector {$$ =3D new Buf(2, $1, $2)}; >> >> SourceSelector: >> IRIref {$$ =3D new Buf($1->get_item()->name)}; >> >> WhereClause: >> _QWHERE_E_Opt >> { >> SELECT_LEX* sel =3D &yySparqlFrob->lex->select_lex; >> sel->parsing_place =3D IN_WHERE; >> >> /* we've been using a context (for SELECTs) but need >> to pop it so it can be pushed back on at the LCURLEY */ >> yySparqlFrob->set_next_GC(yySparqlFrob->pop_context()); >> } >> GroupGraphPattern >> { >> GraphContext *gc=3D $3; >> SELECT_LEX* sel =3D &yySparqlFrob->lex->select_lex; >> BindingContext *bc=3D gc->get_binding_context(); >> Item *constraints=3D bc->make_item_constraints(); >> yySparqlFrob->add_root_constraints(bc-> >> get_bound_variable_constraints(constraints, gc)); >> Item *where =3D yySparqlFrob->get_root_constraints(); >> if (where) { >> where->top_level_item(); >> sel->where =3D where; >> String string; >> where->print(&string); >> $$ =3D new Buf(4, $1, $3->get_Buf(), new Buf("WHERE"), new=20 >> Buf(string.c_ptr())); >> } else { >> $$ =3D new Buf(2, $1, $3->get_Buf()); >> } >> sel->parsing_place=3D NO_MATTER; >> }; >> >> _QWHERE_E_Opt: >> {$$ =3D new Buf()} >> | IT_WHERE {$$ =3D $1}; >> >> SolutionModifier: >> _QOrderClause_E_Opt _QLimitClause_E_Opt _QOffsetClause_E_Opt {$$ =3D= new=20 >> Buf(3, $1, $2, $3)}; >> >> _QOrderClause_E_Opt: >> {$$ =3D new Buf()} >> | OrderClause {$$ =3D $1}; >> >> _QLimitClause_E_Opt: >> {$$ =3D new Buf();} >> | LimitClause {$$ =3D $1}; >> >> _QOffsetClause_E_Opt: >> {$$ =3D new Buf()} >> | OffsetClause {$$ =3D $1}; >> >> OrderClause: >> IT_ORDER IT_BY _QOrderCondition_E_Plus {$$ =3D new Buf(3, $1, $2, $3= )}; >> >> _QOrderCondition_E_Plus: >> OrderCondition {$$ =3D $1} >> | _QOrderCondition_E_Plus OrderCondition {$$ =3D new Buf(2, $1, $2)}; >> >> OrderCondition: >> _O_QASC_E__Or__QDESC_E____QBrackettedExpression_E__C {$$ =3D $1} >> | _O_QFunctionCall_E__Or__QVar_E__Or__QBrackettedExpression_E__C {$$= =3D=20 >> new Buf("!!!")}; >> >> _O_QASC_E__Or__QDESC_E__C: >> IT_ASC {$$ =3D1} >> | IT_DESC {$$ =3D0}; >> >> _O_QASC_E__Or__QDESC_E____QBrackettedExpression_E__C: >> _O_QASC_E__Or__QDESC_E__C BrackettedExpression >> { >> if (add_order_to_list(yySparqlFrob->thd, $2, (bool) $1)) >> YYABORT; String string; >> $2->print(&string); >> $$ =3D new Buf(2, new Buf((char*)($1 ? "ASK" : "DESC")), new=20 >> Buf(string.c_ptr())); >> }; >> >> _O_QFunctionCall_E__Or__QVar_E__Or__QBrackettedExpression_E__C: >> FunctionCall {$$ =3D $1} >> | Var {$$ =3D $1->get_item()} >> | BrackettedExpression {$$ =3D $1}; >> >> LimitClause: >> IT_LIMIT INTEGER >> { >> SELECT_LEX *sel =3D &yySparqlFrob->lex->select_lex; >> sel->select_limit =3D new Item_uint($2.str, $2.length); >> sel->explicit_limit=3D 1; >> $$ =3D new Buf(2, $1, new Buf($2.str)); >> }; >> >> OffsetClause: >> IT_OFFSET INTEGER >> { >> SELECT_LEX *sel =3D &yySparqlFrob->lex->select_lex; >> sel->offset_limit =3D new Item_uint($2.str, $2.length); >> sel->explicit_limit=3D 1; >> $$ =3D new Buf(2, $1, new Buf($2.str)); >> }; >> >> GroupGraphPattern: >> GT_LCURLEY >> { >> GraphContext *gc =3D yySparqlFrob->was_next_GC(); >> yySparqlFrob->push_context(gc ? gc : new=20 >> Union1GraphContext(yySparqlFrob->head_context(), yySparqlFrob)); >> } >> GraphPattern GT_RCURLEY >> { >> if (yySparqlFrob->get_distinct()) >> yySparqlFrob->lex->current_select->options|=3D SELECT_DISTINCT; >> $$=3D yySparqlFrob->pop_context(); >> $$->set_Buf(new Buf(3, $1, $3, $4)); >> $$->close(); >> }; >> >> GraphPattern: >> FilteredBasicGraphPattern=20 >> _Q_O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C_E_Opt = {$$=20 >> =3D new Buf(2, $1, $2)}; >> >> _QDOT_E_Opt: >> {$$ =3D new Buf()} >> | GT_DOT {$$ =3D $1}; >> >> _O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C: >> GraphPatternNotTriples _QDOT_E_Opt GraphPattern {$$ =3D new Buf(3, $= 1,=20 >> $2, $3)}; >> >> _Q_O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C {$= $=20 >> =3D $1}; >> >> FilteredBasicGraphPattern: >> _QBlockOfTriples_E_Opt=20 >> _Q_O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C_E_Opt= {$$=20 >> =3D new Buf(2, $1, $2)}; >> >> _QBlockOfTriples_E_Opt: >> {$$ =3D new Buf()} >> | BlockOfTriples {$$ =3D $1}; >> >> _O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C: >> Constraint _QDOT_E_Opt FilteredBasicGraphPattern {$$ =3D new Buf(3, = $1,=20 >> $2, $3)}; >> >> _Q_O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C {= $$=20 >> =3D $1}; >> >> BlockOfTriples: >> TriplesSameSubject=20 >> _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star {$$ =3D new Buf(2, $1,= =20 >> $2)}; >> >> _QTriplesSameSubject_E_Opt: >> {$$ =3D new Buf()} >> | TriplesSameSubject {$$ =3D $1}; >> >> _O_QDOT_E____QTriplesSameSubject_E_Opt_C: >> GT_DOT _QTriplesSameSubject_E_Opt {$$ =3D new Buf(2, $1, $2)}; >> >> _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star: >> {$$ =3D new Buf()} >> | _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star=20 >> _O_QDOT_E____QTriplesSameSubject_E_Opt_C {$$ =3D new Buf(2, $1, $2)}; >> >> GraphPatternNotTriples: >> OptionalGraphPattern {$$ =3D $1} >> | GroupOrUnionGraphPattern {$$ =3D $1} >> | GraphGraphPattern {$$ =3D $1}; >> >> OptionalGraphPattern: >> IT_OPTIONAL >> { >> yySparqlFrob->lex->select_lex.init_nested_join(yySparqlFrob->thd); >> yySparqlFrob->set_next_GC( >> new OptionalGraphContext(yySparqlFrob->head_context(), =20 >> yySparqlFrob)); >> } >> GroupGraphPattern >> { >> GraphContext *gc=3D $3; >> SELECT_LEX* sel=3D &yySparqlFrob->lex->select_lex; >> BindingContext *bc=3D gc->get_binding_context(); >> Item *constraints=3D bc->make_item_constraints(); >> Item *constraint=3D bc->get_bound_variable_constraints(constraints, g= c); >> yySparqlFrob->add_root_constraints(constraint); >> >> String string; >> if (constraint) >> constraint->print(&string); >> >> yySparqlFrob->lex->select_lex.end_nested_join(yySparqlFrob->thd); >> >> $$ =3D new Buf(3, $1, $3->get_Buf(), new Buf(string.c_ptr())); >> }; >> >> GraphGraphPattern: >> IT_GRAPH VarOrBlankNodeOrIRIref >> { >> yySparqlFrob->set_next_GC( >> new GraphGraphContext(yySparqlFrob->head_context(), =20 >> yySparqlFrob)); >> } >> GroupGraphPattern >> { >> $$ =3D new Buf(3, $1, $2, $4->get_Buf()); >> }; >> >> GroupOrUnionGraphPattern: >> GroupGraphPattern >> { >> cout << "look for UNIONs in \"" <<=20 >> yySparqlFrob->thd->m_lip->get_ptr() << "\"?" << endl; //=20 >> yySparqlFrob->lex->ptr >> } >> _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star >> { >> $$=3D $1->get_Buf(); >> if ($3) { >> $3->push_front((BindingGraphContext*)$1); >> cout << "there were " << $3->elements << " UNION elements" << endl; >> >> yySparqlFrob->needs_select($3); >> >> // Maintain the Buf for debugging. >> cout << "0: " << (void*)$1 << ": " << $$->str() << endl; >> unsigned i=3D 1; >> List_iterator item_list_it(*$3); >> GraphContext* gc=3D item_list_it++; >> while ((gc=3D item_list_it++)) { >> cout << i++ << ": " << (void*)gc << ": " << gc->get_Buf()->str() = <<=20 >> endl; >> $$=3D new Buf(3, $$, new Buf("UNION"), gc->get_Buf()); >> } >> } else { >> $1->no_right_union(); >> } >> }; // !! check return >> >> _O_QUNION_E____QGroupGraphPattern_E__C: >> IT_UNION >> { >> yySparqlFrob->set_next_GC( >> new Union2GraphContext(yySparqlFrob->head_context(), =20 >> yySparqlFrob)); >> //cout << " found UNION start \"" << yySparqlFrob->lex->ptr << "\"= ?"=20 >> << endl; >> } >> GroupGraphPattern >> { >> $$ =3D (BindingGraphContext*)$3; >> //cout << " UNION end at \"" << yySparqlFrob->lex->ptr << "\"= ?"=20 >> << endl; >> }; >> >> _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star: >> { >> $$=3D NULL; >> } >> | _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star=20 >> _O_QUNION_E____QGroupGraphPattern_E__C >> { >> //cout << " UNION found before \"" << yySparqlFrob->lex->ptr << "\"= ?"=20 >> << endl; >> $$=3D $1 ? $1 : new List; >> $$->push_back($2); >> }; >> >> Constraint: >> IT_FILTER=20 >> _O_QBrackettedExpression_E__Or__QBuiltInCall_E__Or__QFunctionCall_E__C >> { >> LEX *lex =3D yySparqlFrob->lex; >> SELECT_LEX* sel =3D &lex->select_lex; >> sel->expr_list.head()->push_back($2); >> String string; >> $2->print(&string); >> $$ =3D new Buf(string.c_ptr()); >> }; >> >> _O_QBrackettedExpression_E__Or__QBuiltInCall_E__Or__QFunctionCall_E__C: >> BrackettedExpression {$$ =3D $1} >> | BuiltInCall {$$ =3D $1} >> | FunctionCall {$$ =3D $1}; >> >> FunctionCall: >> IRIref ArgList {$$ =3D NULL; // new=20 >> Item_func_call(yySparqlFrob->lex->current_context(), $1, $2); YYABORT /*= =20 >> !!! NI */}; >> >> ArgList: >> =20 >> _O_QNIL_E__Or__QLPAREN_E____QExpression_E____QCOMMA_E____QExpression_E_S= tar___QRPAREN_E__C {$$=20 >> =3D $1}; >> >> _O_QCOMMA_E____QExpression_E__C: >> GT_COMMA Expression {$$ =3D $2}; >> >> _Q_O_QCOMMA_E____QExpression_E__C_E_Star: >> {} >> | _Q_O_QCOMMA_E____QExpression_E__C_E_Star=20 >> _O_QCOMMA_E____QExpression_E__C >> { >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> }; >> >> _O_QNIL_E__Or__QLPAREN_E____QExpression_E____QCOMMA_E____QExpression_E_S= tar___QRPAREN_E__C: >> NIL {$$ =3D NULL} >> | GT_LPAREN { >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> } >> Expression _Q_O_QCOMMA_E____QExpression_E__C_E_Star GT_RPAREN >> { >> $$ =3D yySparqlFrob->lex->select_lex.expr_list.pop(); >> $$->push_front($3); >> }; >> >> ConstructTemplate: >> GT_LCURLEY ConstructTriples GT_RCURLEY {$$ =3D new Buf(3, $1, $2, $3= )}; >> >> ConstructTriples: >> =20 >> _Q_O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C_E_Opt = {$$=20 >> =3D $1}; >> >> _O_QDOT_E____QConstructTriples_E__C: >> GT_DOT ConstructTriples {$$ =3D new Buf(2, $1, $2)}; >> >> _Q_O_QDOT_E____QConstructTriples_E__C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QDOT_E____QConstructTriples_E__C {$$ =3D $1}; >> >> _O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C: >> TriplesSameSubject _Q_O_QDOT_E____QConstructTriples_E__C_E_Opt {$$ = =3D=20 >> new Buf(2, $1, $2)}; >> >> _Q_O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C {$= $=20 >> =3D $1}; >> >> TriplesSameSubject: >> VarOrTerm >> { >> yySparqlFrob->push_subject($1); >> } >> PropertyListNotEmpty >> { >> yySparqlFrob->pop_subject(); >> $$ =3D new Buf(2, new Buf($1->get_item()->name), $3); >> } >> | TriplesNode >> { >> yySparqlFrob->push_subject($1); >> } >> PropertyList >> { >> yySparqlFrob->pop_subject(); >> $$ =3D new Buf(2, new Buf($1->get_item()->name), $3); >> }; >> >> PropertyList: >> _QPropertyListNotEmpty_E_Opt {$$ =3D $1}; >> >> _QPropertyListNotEmpty_E_Opt: >> {$$ =3D new Buf()} >> | PropertyListNotEmpty {$$ =3D $1}; >> >> PropertyListNotEmpty: >> Verb >> { >> yySparqlFrob->push_predicate($1); >> } >> ObjectList _Q_O_QSEMI_E____QPropertyList_E__C_E_Opt >> { >> yySparqlFrob->pop_predicate(); >> $$ =3D new Buf(3, new Buf($1->get_item()->name), $3, $4); >> }; >> >> _O_QSEMI_E____QPropertyList_E__C: >> GT_SEMI PropertyList {$$ =3D new Buf(2, $1, $2)}; >> >> _Q_O_QSEMI_E____QPropertyList_E__C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QSEMI_E____QPropertyList_E__C {$$ =3D $1}; >> >> ObjectList: >> GraphNode >> { >> if (yySparqlFrob->object($1)) >> YYABORT; >> } >> _Q_O_QCOMMA_E____QObjectList_E__C_E_Opt {$$ =3D new Buf(2, new=20 >> Buf($1->get_item()->name), $3)}; >> >> _O_QCOMMA_E____QObjectList_E__C: >> GT_COMMA ObjectList {$$ =3D new Buf(2, $1, $2)}; >> >> _Q_O_QCOMMA_E____QObjectList_E__C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QCOMMA_E____QObjectList_E__C {$$ =3D $1}; >> >> Verb: >> VarOrIRIref {$$ =3D $1} >> | IT_a {$$ =3D $1}; >> >> TriplesNode: >> Collection {$$ =3D $1} >> | BlankNodePropertyList {$$ =3D $1}; >> >> BlankNodePropertyList: >> GT_LBRACKET >> { >> yySparqlFrob->push_subject(yySparqlFrob->make_blank_node()); >> } >> PropertyListNotEmpty GT_RBRACKET >> { >> //Buf* t =3D new Buf(3, $1, $3, $4); >> $$ =3D yySparqlFrob->pop_subject(); >> }; >> >> Collection: >> GT_LPAREN >> { >> yySparqlFrob->push_subject(yySparqlFrob->make_blank_node()); >> if (yySparqlFrob->type_list()) >> YYABORT >> } >> _QGraphNode_E_Plus GT_RPAREN >> { >> //Buf *t =3D new Buf(3, $1, $3, $4); >> $$ =3D yySparqlFrob->pop_subject(); >> }; >> >> _QGraphNode_E_Plus: >> GraphNode >> { >> if (yySparqlFrob->add_listElement($1)) >> YYABORT; >> }=09 >> | _QGraphNode_E_Plus GraphNode >> { >> if (yySparqlFrob->add_listElement($2)) >> YYABORT; >> $$ =3D new Buf(2, $1, new Buf($2->get_item()->name)); >> }; >> >> GraphNode: >> VarOrTerm {$$ =3D $1} >> | TriplesNode {$$ =3D $1}; >> >> VarOrTerm: >> Var {$$ =3D $1} >> | GraphTerm {$$ =3D $1}; >> >> VarOrIRIref: >> Var {$$ =3D $1} >> | IRIref {$$ =3D $1}; >> >> VarOrBlankNodeOrIRIref: >> Var {$$ =3D new Buf($1->get_item()->name)} >> | BlankNode {$$ =3D new Buf($1->get_item()->name)} >> | IRIref {$$ =3D new Buf($1->get_item()->name)}; >> >> Var: >> VAR1 >> { >> $$ =3D yySparqlFrob->ensure_variable($1.str); >> } >> | VAR2 >> { >> $$ =3D yySparqlFrob->ensure_variable($1.str); >> }; >> >> GraphTerm: >> IRIref {$$ =3D $1} >> | RDFLiteral {$$ =3D $1} >> | _Q_O_QMINUS_E__Or__QPLUS_E__C_E_Opt NumericLiteral {$$ =3D $2 /* != !!=20 >> */} >> | BooleanLiteral {$$ =3D $1} >> | BlankNode {$$ =3D $1} >> | NIL {$$ =3D $1}; >> >> _O_QMINUS_E__Or__QPLUS_E__C: >> GT_MINUS {$$ =3D $1} >> | GT_PLUS {$$ =3D $1}; >> >> _Q_O_QMINUS_E__Or__QPLUS_E__C_E_Opt: >> {$$ =3D new Buf()} >> | _O_QMINUS_E__Or__QPLUS_E__C {$$ =3D $1}; >> >> Expression: >> ConditionalOrExpression {$$ =3D $1} >> >> ConditionalOrExpression: >> ConditionalAndExpression >> { >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> } >> _Q_O_QOR_E____QConditionalAndExpression_E__C_E_Star >> { >> List *list=3D yySparqlFrob->lex->select_lex.expr_list.pop(); >> if (list->elements) >> { >> list->push_front($1); >> $$=3D new Item_cond_or(*list); >> } >> else >> $$=3D $1; >> delete list; >> }; >> >> _O_QOR_E____QConditionalAndExpression_E__C: >> GT_OR ConditionalAndExpression >> { >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> }; >> >> _Q_O_QOR_E____QConditionalAndExpression_E__C_E_Star: >> {} >> | _Q_O_QOR_E____QConditionalAndExpression_E__C_E_Star=20 >> _O_QOR_E____QConditionalAndExpression_E__C {}; >> >> ConditionalAndExpression: >> ValueLogical >> { >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> } >> _Q_O_QAND_E____QValueLogical_E__C_E_Star >> { >> List *list=3D yySparqlFrob->lex->select_lex.expr_list.pop(); >> if (list->elements) >> { >> list->push_front($1); >> $$=3D new Item_cond_and(*list); >> } >> else >> $$=3D $1; >> delete list; >> }; >> >> _O_QAND_E____QValueLogical_E__C: >> GT_AND ValueLogical >> { >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> }; >> >> _Q_O_QAND_E____QValueLogical_E__C_E_Star: >> {} >> | _Q_O_QAND_E____QValueLogical_E__C_E_Star=20 >> _O_QAND_E____QValueLogical_E__C {}; >> >> ValueLogical: >> RelationalExpression {$$ =3D $1}; >> >> RelationalExpression: >> NumericExpression >> { >> // Stick " =3D 3 " into two list elements in the expr_list. >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> } >> _Q_O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpress= ion_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E= __Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C_E= _Opt >> { >> List *list=3D yySparqlFrob->lex->select_lex.expr_list.pop(); >> if (list->elements) >> { >> chooser_compare_func_creator op =3D=20 >> (chooser_compare_func_creator)list->pop(); >> Item* value =3D list->pop(); >> // chooser_compare_func_creator eq =3D &comp_eq_creator; >> // Item* test =3D eq(0)->create($1, value); >> $$=3D op(0)->create($1, value); >> } >> else >> $$=3D $1; >> delete list; >> }; >> >> _O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression= _E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__O= r__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C: >> GT_EQUAL NumericExpression >> { >> =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)comp_eq= _creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_NEQUAL NumericExpression >> { >> =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)comp_ne= _creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_LT NumericExpression >> { >> =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)comp_lt= _creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_GT NumericExpression >> { >> =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)comp_gt= _creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_LE NumericExpression >> { >> =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)comp_le= _creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_GE NumericExpression >> { >> =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)comp_ge= _creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> }; >> >> _Q_O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpressi= on_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E_= _Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C_E_= Opt: >> {} >> |=20 >> _O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression= _E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__O= r__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C {}; >> >> NumericExpression: >> AdditiveExpression {$$ =3D $1}; >> >> AdditiveExpression: >> MultiplicativeExpression >> { >> // Stick " + 3 " into two list elements in the expr_list. >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> } >> _Q_O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplic= ativeExpression_E__C_E_Star >> { >> List *list=3D yySparqlFrob->lex->select_lex.expr_list.pop(); >> if (list->elements) >> { >> // chooser_compare_func_creator *op =3D=20 >> (chooser_compare_func_creator*)list->pop(); >> char *op =3D (char*)list->pop(); >> Item* value =3D list->pop(); >> if (op[0] =3D=3D '+') { >> $$=3D new Item_func_plus($1, value); >> } else { >> $$=3D new Item_func_minus($1, value); >> } >> // $$=3D (*op)(0)->create($1, value); >> } >> else >> $$=3D $1; >> delete list; >> }; >> >> _O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicati= veExpression_E__C: >> GT_PLUS MultiplicativeExpression >> { >> // =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_p= lus_creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)"+"); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_MINUS MultiplicativeExpression >> { >> // =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_m= inus_creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)"-"); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> }; >> >> _Q_O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplica= tiveExpression_E__C_E_Star: >> {} >> |=20 >> _Q_O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplica= tiveExpression_E__C_E_Star=20 >> _O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicati= veExpression_E__C {}; >> >> MultiplicativeExpression: >> UnaryExpression >> { >> // Stick " * 3 " into two list elements in the expr_list. >> yySparqlFrob->lex->select_lex.expr_list.push_front(new List); >> } >> _Q_O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_= E__C_E_Star >> { >> List *list=3D yySparqlFrob->lex->select_lex.expr_list.pop(); >> if (list->elements) >> { >> // chooser_compare_func_creator *op =3D=20 >> (chooser_compare_func_creator*)list->pop(); >> char *op =3D (char*)list->pop(); >> Item* value =3D list->pop(); >> if (op[0] =3D=3D '*') { >> $$=3D new Item_func_mul($1, value); >> } else { >> $$=3D new Item_func_div($1, value); >> } >> // $$=3D (*op)(0)->create($1, value); >> } >> else >> $$=3D $1; >> delete list; >> }; >> >> _O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__= C: >> GT_TIMES UnaryExpression >> { >> // =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_t= imes_creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)"*"); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> } >> | GT_DIVIDE UnaryExpression >> { >> // =20 >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_d= ivide_creator); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)"/"); >> yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); >> }; >> >> _Q_O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E= __C_E_Star: >> {} >> |=20 >> _Q_O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E= __C_E_Star=20 >> _O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__= C {}; >> >> UnaryExpression: >> GT_NOT PrimaryExpression >> { >> new Item_func_not($2); >> } >> | GT_PLUS PrimaryExpression {$$ =3D $2} >> | GT_MINUS PrimaryExpression >> { >> new Item_func_neg($2); >> } >> | PrimaryExpression {$$ =3D $1}; >> >> PrimaryExpression: >> BrackettedExpression {$$ =3D $1} >> | BuiltInCall {$$ =3D $1} >> | IRIrefOrFunction {$$ =3D $1} >> | RDFLiteral {$$ =3D $1->get_item()} >> | NumericLiteral {$$ =3D $1->get_item()} >> | BooleanLiteral {$$ =3D $1->get_item()} >> | BlankNode {$$ =3D $1->get_item()} >> | Var {$$ =3D $1->get_item()}; >> >> BrackettedExpression: >> GT_LPAREN Expression GT_RPAREN {$$ =3D $2}; >> >> BuiltInCall: >> IT_STR GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /* !!! NI = */} >> | IT_LANG GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /* !!! = NI=20 >> */} >> | IT_LANGMATCHES GT_LPAREN Expression GT_COMMA Expression=20 >> GT_RPAREN {$$ =3D $3; YYABORT /* !!! NI */} >> | IT_DATATYPE GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /* = !!!=20 >> NI */} >> | IT_BOUND GT_LPAREN Var GT_RPAREN {$$ =3D new=20 >> Item_func_isnotnull($3->get_item());} >> | IT_isIRI GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /* !!!= NI=20 >> */} >> | IT_isURI GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /* !!!= NI=20 >> */} >> | IT_isBLANK GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /* != !!=20 >> NI */} >> | IT_isLITERAL GT_LPAREN Expression GT_RPAREN {$$ =3D $3; YYABORT /*= !!!=20 >> NI */} >> | RegexExpression {$$ =3D $1}; >> >> RegexExpression: >> IT_REGEX GT_LPAREN Expression GT_COMMA Expression=20 >> _Q_O_QCOMMA_E____QExpression_E__C_E_Opt GT_RPAREN {$$ =3D $3; YYABORT /*= !!!=20 >> NI */}; >> >> _Q_O_QCOMMA_E____QExpression_E__C_E_Opt: >> {$$ =3D NULL} >> | _O_QCOMMA_E____QExpression_E__C {$$ =3D $1}; >> >> IRIrefOrFunction: >> IRIref _QArgList_E_Opt {$$ =3D NULL; // new=20 >> Item_func_call(yySparqlFrob->lex->current_context(), $1, $2); YYABORT /*= =20 >> !!! NI */}; >> >> _QArgList_E_Opt: >> {$$ =3D NULL} >> | ArgList {$$ =3D $1}; >> >> RDFLiteral: >> String _Q_O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C_E_Opt {$$ =3D= =20 >> yySparqlFrob->ensure_string($1, $2) /* !!! */}; >> >> _O_QDTYPE_E____QIRIref_E__C: >> GT_DTYPE IRIref {$$ =3D $2}; >> >> _O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C: >> LANGTAG {$$ =3D $1} >> | _O_QDTYPE_E____QIRIref_E__C {$$ =3D $1}; >> >> _Q_O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C_E_Opt: >> {$$ =3D NULL} >> | _O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C {$$ =3D $1}; >> >> NumericLiteral: >> INTEGER {$$ =3D yySparqlFrob->ensure_int($1, NULL) /* !!! */} >> | DECIMAL {$$ =3D yySparqlFrob->ensure_decimal($1, NULL) /* !!! */} >> | DOUBLE {$$ =3D yySparqlFrob->ensure_float($1, NULL) /* !!! */}; >> >> BooleanLiteral: >> IT_true {$$ =3D $1} >> | IT_false {$$ =3D $1}; >> >> String: >> STRING_LITERAL1 {$$ =3D $1} >> | STRING_LITERAL2 {$$ =3D $1} >> | STRING_LITERAL_LONG1 {$$ =3D $1} >> | STRING_LITERAL_LONG2 {$$ =3D $1}; >> >> IRIref: >> Q_IRI_REF {$$ =3D yySparqlFrob->ensure_URI($1)} >> | QName {$$ =3D $1}; >> >> QName: >> QNAME {$$ =3D yySparqlFrob->ensure_URI($1)} >> | QNAME_NS {$$ =3D yySparqlFrob->ensure_URI($1)}; >> >> BlankNode: >> BLANK_NODE_LABEL {$$ =3D yySparqlFrob->ensure_blank_node($1.str)} >> | ANON {$$ =3D yySparqlFrob->make_blank_node()}; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> %% >> >> #define YY_DECL int yyFlexLexer::yylex(YY_sparqlParser_STYPE *val, void= =20 >> *yythd) >> //int yylex(void *yylval, void *yythd); >> const LEX_STRING null_lex_str=3D{0,0}; >> >> >> int Simple_error (const char *format) { >> my_printf_error(1, format, MYF(0)); >> return 1; >> } >> >> int Item_error (const char *format, Item *item) { >> String pString; >> item->print(&pString); >> my_printf_error(1, format, MYF(0), pString.c_ptr()); >> return 1; >> } >> >> const char* scan_string (THD *thd, LEX_STRING *lex_string, const char=20 >> *start, const char *end, const char look_for) { >> const char *ptr =3D end; >> lex_string->length =3D 0; >> for (; ; ) { >> if (ptr =3D=3D start) { >> if (look_for) { >> // we didn't find it >> ptr =3D NULL; >> lex_string->length =3D 0; >> return NULL; >> } else { >> lex_string->str =3D thd->strmake(ptr, lex_string->length); >> return ptr; >> } >> } >> if (*ptr =3D=3D look_for) { >> --lex_string->length; >> lex_string->str =3D thd->strmake(ptr+1, lex_string->length); >> return ptr; >> } >> --ptr; >> ++lex_string->length; >> } >> } >> >> >> // -------------------------------------- START >> #include "FlexLexer.h" >> // -------------------------------------- END >> >> class sparqlParserPackage : public sparqlParser >> { >> private: >> yyFlexLexer theScanner; >> THD *thd; >> public: >> virtual int yylex(); >> virtual void yyerror(char *m); >> sparqlParserPackage(THD *thd, char** ptr) : theScanner(thd, ptr) { >> this->thd =3D thd; >> }; >> }; >> >> int sparqlParserPackage::sparqllex() >> { >> return theScanner.yylex(&yylval); >> } >> >> void sparqlParserPackage::yyerror(char *s) >> { >> const char *yytext=3D theScanner.YYText(); // theScanner.get_last_word= (); >> my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s, >> (yytext ? (char*) yytext : ""), >> theScanner.lineno()); >> } >> >> // Move this class definition into sparqlFrob.h and uncomment the #inclu= de >> // below. See http://www.w3.org/1999/02/26-modules/User/Yacker#encap for= =20 >> more >> // details. >> /* */ >> sparqlFrob::sparqlFrob(THD *thd, char** ptr) : Dynamic_parser(thd, ptr) >> { >> // stringstream* ss =3D new stringstream(buf, stringstream::in); >> // this->thd=3D thd; >> lex=3D thd ? thd->lex : NULL; >> distinct=3D false; >> sparqlParserPackage* aCompiler=3D new sparqlParserPackage(thd, ptr); >> parser=3D aCompiler; >> next_union_alias_index=3D 0; >> } >> sparqlFrob::~sparqlFrob() >> { >> } >> >> int sparqlFrob::parse() >> { >> sparqlParserPackage* aCompiler =3D (sparqlParserPackage*) parser; >> return aCompiler->yyparse(this); >> } >> >> const char* sparqlFrob::get_primary_key(const char *table_name) { >> TABLE_LIST *entry =3D lex->select_lex.context.table_list; >> while (entry) { >> if (!strcmp(table_name, entry->table_name)) { >> KEY *key=3D entry->table->key_info; >> >> /* Search table structure for PRIMARY KEY. >> Taken from sql_show.cc::2905 get_schema_stat_record */ >> for (unsigned i=3D 0; i < entry->table->s->keys; i++) { >> if (!strcmp(key[i].name, "PRIMARY")) { >> const char *ret =3D key[i].key_part->field->field_name; >> if (key[i].key_parts !=3D 1) >> cout << "SPARQL: table \"" << table_name << "\" primary key has " << >> key[i].key_parts << " parts -- using only 1st field, \"" << ret << >> "\"" << endl; >> return ret; >> } >> } >> >> // Couldn't find PRIMARY KEY >> const char *ret =3D entry->table->s->fieldnames.type_names[0]; >> cout << "SPARQL: could not find " << table_name << ". -- tryin= g=20 >> " << ret << endl; >> return ret; >> } >> entry=3D entry->next_global; >> } >> my_printf_error(1, "SPARQL: could not find table entry for %s.=20 >> "PLS_REPORT, MYF(0), table_name); >> return NULL; >> } >> LEX_STRING* sparqlFrob::next_union_alias () { >> char space[3]; >> space[0]=3D 'U'; >> space[1]=3D '0'+next_union_alias_index++; >> space[2]=3D 0; >> >> LEX_STRING *alias =3D new LEX_STRING; >> alias->str=3D thd->strmake(space, 3); >> alias->length =3D 2; >> return alias; >> } >> >> >> Item_variable* sparqlFrob::ensure_variable (const char *var) { >> return head_context()->get_binding_context()-> >> ensure_bound_item_variable(var, this, 1); >> } >> >> Item_URI* sparqlFrob::ensure_URI (LEX_STRING uristr) { >> Item_URI* ret; >> List_iterator item_list_it(uris); >> while ((ret =3D item_list_it++)) >> { >> if (!strcmp(ret->name, uristr.str)) { /* !!! */ >> return ret; >> } >> // if (curr_item->eq(this, 1)) >> // DBUG_RETURN(FALSE); /* Already in the set. */ >> } >> >> ret =3D new Item_URI(lex->current_context(), uristr, thd); >> uris.push_back(ret); >> return ret; >> } >> >> Item_blank_node* sparqlFrob::make_blank_node () { >> return new Item_blank_node(lex->current_context(), "", this); >> } >> >> Item_blank_node* sparqlFrob::ensure_blank_node (const char *label) { >> Item_blank_node* ret; >> List_iterator item_list_it(blank_nodes); >> while ((ret =3D item_list_it++)) >> { >> if (!strcmp(ret->name, label)) { >> return ret; >> } >> // if (curr_item->eq(this, 1)) >> // DBUG_RETURN(FALSE); /* Already in the set. */ >> } >> >> ret =3D new Item_blank_node(lex->current_context(), label, this); >> blank_nodes.push_back(ret); >> return ret; >> } >> Item_literal_string* sparqlFrob::ensure_string (LEX_STRING str, Item_POS= =20 >> *lang_or_datatype) { >> Item_literal_string* ret; >> List_iterator item_list_it(strings); >> while ((ret =3D item_list_it++)) >> if (!strncmp(ret->name, str.str, str.length) &&=20 >> ret->get_language_or_datatype() =3D=3D lang_or_datatype) // !!! check le= n or=20 >> "foo1"=3D"foo" >> return ret; >> >> Item_string* d =3D new Item_string(str.str, str.length,=20 >> thd->variables.collation_connection); >> Item_string* Iso =3D new Item_string(Iso8601formatStr,=20 >> strlen(Iso8601formatStr), &my_charset_bin); >> Item_func_str_to_date* t =3D new Item_func_str_to_date(d, Iso); //=20 >> t->str_value >> t->quick_fix_field(); >> t->fix_length_and_dec(); >> String* ptr =3D t->val_str(&Global_string); >> if (ptr) { >> LEX_STRING tmp; >> tmp.length =3D ptr->length(); >> tmp.str =3D (char*) thd->strmake((char*) ptr->ptr(), tmp.length);; >> ret =3D new Item_literal_string(tmp, lang_or_datatype, thd->charset(= )); >> } else { >> ret =3D new Item_literal_string(str, lang_or_datatype, thd->charset(= )); >> } >> strings.push_back(ret); >> return ret; >> } >> Item_literal_int* sparqlFrob::ensure_int (LEX_STRING str, Item_POS=20 >> *lang_or_datatype) { >> Item_literal_int* ret; >> List_iterator item_list_it(ints); >> while ((ret =3D item_list_it++)) >> if (!strncmp(ret->name, str.str, str.length)) // !!! check len or=20 >> "foo1"=3D"foo" >> return ret; >> ret =3D new Item_literal_int(str, lang_or_datatype, thd->charset()); >> ints.push_back(ret); >> return ret; >> } >> Item_literal_decimal* sparqlFrob::ensure_decimal (LEX_STRING str, Item_P= OS=20 >> *lang_or_datatype) { >> Item_literal_decimal* ret; >> List_iterator item_list_it(decimals); >> while ((ret =3D item_list_it++)) >> if (!strncmp(ret->name, str.str, str.length)) // !!! check len or=20 >> "foo1"=3D"foo" >> return ret; >> ret =3D new Item_literal_decimal(str, lang_or_datatype, thd->charset()= ); >> decimals.push_back(ret); >> return ret; >> } >> Item_literal_float* sparqlFrob::ensure_float (LEX_STRING str, Item_POS= =20 >> *lang_or_datatype) { >> Item_literal_float* ret; >> List_iterator item_list_it(floats); >> while ((ret =3D item_list_it++)) >> if (!strncmp(ret->name, str.str, str.length)) // !!! check len or=20 >> "foo1"=3D"foo" >> return ret; >> ret =3D new Item_literal_float(str, lang_or_datatype, thd->charset()); >> floats.push_back(ret); >> return ret; >> } >> >> void sparqlFrob::select_variables () { >> SELECT_LEX *sel=3D lex->current_select; sel->parsing_place=3D=20 >> SELECT_LIST; >> print(&Global_string); >> cout << Global_string.c_ptr(); >> Global_string.free(); >> BindingContext *bc =3D last_context()->get_binding_context(); >> >> // If nothing was selected, we know there was a "SELECT *". >> bool select_star=3D !lex->current_select->item_list.elements; >> >> /************************** >> * Handle the subselects. * >> **************************/ >> >> // Walk the list of GraphContext sets >> List_iterator > list_it(need_selects); >> List *list; >> while ((list=3D list_it++)) { >> >> // Assemble a list of selected variables. >> List selected_vars; >> >> // List of BindingGraphContexts that need newly added vars (starts= =20 >> with ()). >> List passed_gcs; >> >> // For each BindingGraphContext... >> List_iterator gc_it(*list); >> BindingGraphContext *gc; >> while ((gc=3D gc_it++)) { >> >> // Walk variables bound in this context. >> List *known_vars=3D=20 >> gc->get_binding_context()->get_item_variables(); >> List_iterator known_vars_it(*known_vars); >> Item_variable *known_var; >> while ((known_var=3D known_vars_it++)) { >> >> // If the variable has no in parents refs, skip it. >> if (!select_star && known_var->outer_has_no_refs()) >> continue; >> >> // If the variable was already selected, skip it. >> bool stupid_continue_flag=3D false; // C doesn't have a labeled continu= e. >> List_iterator selected_vars_it(selected_vars); >> Item_variable *selected_var; >> while ((selected_var=3D selected_vars_it++)) >> if (selected_var->same_variable(known_var->name)) { >> stupid_continue_flag=3D true; >> break; >> } >> if (stupid_continue_flag) >> continue; >> >> // known_var is referenced in a parent context and not yet selected in >> // this UNION. >> >> // Select in this gc... >> gc->select_var(known_var, true); >> // ...and all passed... >> List_iterator passed_gcs_it(passed_gcs); >> BindingGraphContext *passed_gc; >> while ((passed_gc=3D passed_gcs_it++)) >> passed_gc->select_var(known_var, false);// also sets binding in paren= t. >> // ...and future gcs. >> List_iterator future_gcs_it=3D gc_it; // @@@ ca=20 >> marche? >> BindingGraphContext *future_gc; >> while ((future_gc=3D future_gcs_it++)) { >> bool exists=3D=20 >> Item_variable::match_var_in_list(future_gc->get_binding_context()->get_i= tem_variables(),=20 >> known_var->name) !=3D NULL; >> future_gc->select_var(known_var, exists); >> } >> >> selected_vars.push_front(known_var); // It's selected now. >> } >> passed_gcs.push_front(gc); >> } >> } =20 >> if (select_star) >> // Select known vars and update reference counts. >> bc->select_star(thd); >> >> sel->parsing_place=3D NO_MATTER; >> } >> >> void sparqlFrob::push_subject (Item_POS *subject) { >> subjects.push_front(subject); >> } >> >> Item_POS* sparqlFrob::pop_subject () { >> return subjects.pop(); >> } >> >> void sparqlFrob::push_predicate (Item_POS *predicate) { >> predicates.push_front(predicate); >> } >> >> void sparqlFrob::pop_predicate () { >> predicates.pop(); >> } >> >> bool sparqlFrob::object (Item_POS *object) { >> Item_POS* subject =3D subjects.head(); >> if (!predicates.head()->is_URI()) >> return Item_error("predicate must be a URI, not \"%s\"",=20 >> predicates.head()->get_item()); >> Item_URI* predicate =3D (Item_URI*)predicates.head(); >> BindingContext *bc=3D head_context()->get_binding_context(); >> Alias_info *ai=3D bc->get_table_alias(thd, subject, predicate, object); >> const char *ptr =3D head_context()->get_alias_string(ai, subject, thd); >> if (!ptr) >> return true; >> >> object->bind_field(predicate->get_table().str, ptr,=20 >> predicate->get_field().str, false, thd, NULL); >> return false; >> } >> >> bool sparqlFrob::type_list () { >> return Simple_error("Lists not supported"); >> } >> >> bool sparqlFrob::add_listElement (Item_POS *item) { >> return Item_error("Lists not supported -- can't add \"%s\"",=20 >> item->get_item()); >> } >> >> void sparqlFrob::print (String *str) { >> str->append("sparqlFrob: "); >> char ptrSpace[2 + sizeof(void*)*2 + 1]; >> sprintf(ptrSpace, "%p", this); >> str->append(ptrSpace); >> str->append(distinct ? " distinct\n" : "\n"); >> str->append("uris:\n"); >> List_iterator uri_it(uris); >> Item_URI *uri; >> while ((uri=3D uri_it++)) { >> str->append(" "); >> uri->print(str); >> str->append("\n"); >> } >> str->append("subjects:\n"); >> List_iterator subjects_it(subjects); >> Item_POS *subject; >> while ((subject=3D subjects_it++)) { >> str->append(" "); >> subject->print(str); >> str->append("\n"); >> } >> str->append("root_constraints:\n"); >> List_iterator root_constraints_it(root_constraints); >> Item *root_constraint; >> while ((root_constraint=3D root_constraints_it++)) { >> str->append(" "); >> root_constraint->print(str); >> str->append("\n"); >> } >> str->append("need_selects:\n"); >> List_iterator > list_it(need_selects); >> List *list; >> while ((list=3D list_it++)) { >> str->append(" (\n"); >> List_iterator gc_it(*list); >> BindingGraphContext *gc; >> while ((gc=3D gc_it++)) { >> str->append(" "); >> sprintf(ptrSpace, "%p", gc); >> str->append(ptrSpace); >> str->append("\n"); >> } >> str->append(" )\n"); >> } >> } >> /* */ >> >> >> /* */ >> Item_URI::Item_URI(Name_resolution_context *context_arg, LEX_STRING uri,= =20 >> THD *thd) : Item_field(context_arg, NullS, NullS, uri.str),=20 >> Item_POS(this) { >> const char* ptr =3D scan_string(thd, &value, name, name + uri.length,= =20 >> '=3D'); >> if ((ptr =3D scan_string(thd, &field, name, ptr ? ptr : name + uri.len= gth,=20 >> '.'))) { >> scan_string(thd, &table, name, ptr ? ptr : name + uri.length, 0); >> } >> } >> void Item_URI::bind_field(const char *table_name, const char *alias, = =20 >> const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) { >> LEX *lex=3D thd->lex; >> SELECT_LEX *sel=3D lex->current_select; >> chooser_compare_func_creator eq =3D &comp_eq_creator; >> LEX_STRING value =3D get_value(); >> cout << "WHERE " << alias << "." << get_field().str << "=3D" << value.= str=20 >> << endl; >> Item* idI =3D new Item_field(lex->current_context(), NullS, alias,=20 >> get_field().str); >> int error; >> Item* val =3D new Item_int(value.str, (longlong) my_strtoll10(value.st= r,=20 >> NULL, &error), value.length); >> Item* test =3D eq(0)->create(idI, val); >> sel->expr_list.head()->push_back(test); >> test->top_level_item(); >> if (jt) { >> SELECT_LEX *sel=3D lex->current_select; >> sel->add_joined_table(jt); >> } >> } >> void Item_URI::print(String *str) >> { >> str->append('<'); >> str->append(name); >> str->append('>'); >> } >> /* */ >> >> >> /* */ >> Item_variable::Item_variable(Name_resolution_context *context_arg, = =20 >> const char *variable_name, Item_variable *outer_arg, sparqlFrob= =20 >> *frob_arg, int ref_count_arg) : Item_field(context_arg, NullS, NullS,= =20 >> variable_name), Item_POS(this) { >> set_name(variable_name, strlen(variable_name), system_charset_info); >> is_autogenerated_name=3D FALSE; >> nr_context=3D context_arg; >> bound=3D false; >> outer=3D outer_arg; >> frob=3D frob_arg; >> primary_key=3D false; >> gc=3D frob->head_context(); >> jt=3D NULL; >> ref_count=3D ref_count_arg; >> } >> Item* Item_variable::make_Item_field(Name_resolution_context *context_ar= g, >> const char *db_arg, >> const char *table_name_arg, >> const char *field_name_arg, const char* real_table_nam= e)=20 >> { >> return field_name_arg ? new Item_field(context_arg, db_arg, =20 >> table_name_arg, field_name_arg) : >> new Item_primary_key_field(context_arg, db_arg, =20 >> table_name_arg, frob, real_table_name); >> } >> >> /* Item_field Virtual Overloads */ >> void Item_variable::make_field(Send_field *tmp_field) //=20 >> Protocol::send_fields >> { >> if (primary_key) { >> init_make_field(tmp_field, FIELD_TYPE_STRING); >> } else { >> Item_field::make_field(tmp_field); >> } >> } >> bool Item_variable::fix_fields(THD *thd, Item **reference) >> { >> if (primary_key) >> if (!(field_name =3D get_primary_key())) >> return true; // signal an error >> return Item_field::fix_fields(thd, reference); >> } >> /* virtual overload of Item::send, which is called when serializing the= =20 >> results. >> */ >> bool Item_variable::send(Protocol *protocol, String *buffer) >> { >> if (primary_key) { >> String *res; >> if ((res=3Dval_str(buffer))) { >> // Return something in the form of "". >> size_t len =3D=20 >> 1+strlen(real_table_name)+1+strlen(field_name)+1+res->length()+1; >> // Assume res->charset() is compatible with ASCII. >> // Otherwise, we'd need to convert names et all to res->charset(). >> char space[len+1]; >> space[0] =3D '<'; >> strcpy(space+1, real_table_name); >> strcat(space, "."); >> strcat(space, field_name); >> strcat(space, "=3D"); >> strncat(space, res->ptr(), res->length()); >> space[len-1] =3D '>'; >> space[len] =3D 0; >> return protocol->store(space,len,res->charset()); >> } else >> return protocol->store_null(); >> } else { >> switch (field_type()) { >> case MYSQL_TYPE_TIMESTAMP: >> case MYSQL_TYPE_DATETIME: >> Item_string* Iso =3D new Item_string(Iso8601formatStr,=20 >> strlen(Iso8601formatStr), &my_charset_bin); >> Item * t =3D new Item_func_date_format(this, Iso, 0); // result_fi= eld >> t->quick_fix_field(); >> String* ptr =3D t->val_str(&Global_string); >> Field_datetime* f =3D new Field_datetime((bool)0, ptr->ptr(),=20 >> &my_charset_bin); >> >> // return protocol->store(f); >> } >> return protocol->store(result_field); >> } >> } >> >> /* Item_POS Virtual Overloads */ >> void Item_variable::bind_field(const char *table_name_arg, const char=20 >> *alias, const char *field_name_arg, bool trump, THD= =20 >> *thd, TABLE_LIST *jt_param) { >> LEX *lex=3D thd->lex; >> if (jt_param && (!jt || trump)) { >> // assert(!jt); >> jt =3D jt_param; >> SELECT_LEX *sel=3D lex->current_select; >> sel->add_joined_table(jt); >> } >> if (jt && bound) { >> cout << " ON " << table_name << "." << (primary_key ? "" :=20 >> field_name) << " =3D " << alias << "." << (field_name_arg ? field_name_a= rg :=20 >> "") << endl; // !!! >> Item* l =3D make_Item_field(lex->current_context(), NullS, table_nam= e,=20 >> primary_key ? NULL : field_name, real_table_name); >> Item* r =3D make_Item_field(lex->current_context(), NullS, alias,=20 >> field_name_arg, table_name_arg); >> chooser_compare_func_creator eq =3D &comp_eq_creator; >> Item* on =3D eq(0)->create(l, r); >> add_join_on(jt, on); >> } >> if (!bound || trump) { >> cout << " " << alias << "." << (field_name_arg ? field_name_arg := =20 >> "") << " AS \"" << name << "\"" << endl; >> table_name =3D (char*) alias; >> if (field_name_arg) { >> field_name =3D (char*) field_name_arg; >> primary_key =3D false; >> } else { >> primary_key =3D true; >> real_table_name =3D table_name_arg; >> } >> bound =3D true; >> // name =3D (char*) field_name; >> } >> } >> >> /* SparqlFrob interface */ >> Item_variable* Item_variable::match_var_in_list (List=20 >> *p_item_variables, const char *var) { >> List_iterator item_list_it(*p_item_variables); >> Item_variable* ret; >> while ((ret=3D item_list_it++)) >> if (ret->same_variable(var)) { >> return ret; >> } >> return NULL; >> } >> >> /* BindingContext interface */ >> Item* Item_variable::get_null_item() { >> Item *ret=3D new Item_null(); >> ret->set_name(name, strlen(name), system_charset_info); >> ret->is_autogenerated_name=3D FALSE; >> return ret; >> } >> >> /* debugging */ >> void Item_variable::print(String *str) >> { >> Item::print(str); >> str->append("{?"); >> str->append(name); >> str->append('}'); >> } >> /* */ >> >> >> /* */ >> void Item_blank_node::print(String *str) >> { >> Item::print(str); >> str->append("[_:"); >> str->append(name); >> str->append(']'); >> } >> /* */ >> >> >> /* */ >> void Item_literal_string::bind_field(const char *table_name, const char= =20 >> *alias, const char *field_name_arg, bool trump, THD=20 >> *thd, TABLE_LIST *jt) { >> cout << "WHERE " << alias << "." << field_name_arg << "=3D\"" << name = <<=20 >> "\"" << endl; >> LEX *lex=3D thd->lex; >> Item* idI =3D new Item_field(lex->current_context(), NullS, alias,=20 >> field_name_arg); >> chooser_compare_func_creator eq =3D &comp_eq_creator; >> Item* test =3D eq(0)->create(idI, get_item()); >> SELECT_LEX *sel=3D lex->current_select; >> sel->expr_list.head()->push_back(test); >> test->top_level_item(); >> if (jt) { >> sel->add_joined_table(jt); >> } >> } >> void Item_literal_string::print(String *str) >> { >> str->append('\''); >> str->append(name); >> str->append('\''); >> } >> /* */ >> >> >> /* */ >> void Item_literal_int::bind_field(const char *table_name, const char=20 >> *alias, const char *field_name_arg, bool trump, THD *thd,=20 >> TABLE_LIST *jt) { >> cout << "WHERE " << alias << "." << field_name_arg << "=3D\"" << name = <<=20 >> "\"" << endl; >> LEX *lex=3D thd->lex; >> Item* idI =3D new Item_field(lex->current_context(), NullS, alias,=20 >> field_name_arg); >> chooser_compare_func_creator eq =3D &comp_eq_creator; >> Item* test =3D eq(0)->create(idI, get_item()); >> SELECT_LEX *sel=3D lex->current_select; >> sel->expr_list.head()->push_back(test); >> test->top_level_item(); >> if (jt) { >> sel->add_joined_table(jt); >> } >> } >> void Item_literal_int::print(String *str) >> { >> str->append(name); >> } >> /* */ >> >> >> /* */ >> void Item_literal_decimal::bind_field(const char *table_name, const char= =20 >> *alias, const char *field_name_arg, bool trump, THD= =20 >> *thd, TABLE_LIST *jt) { >> cout << "WHERE " << alias << "." << field_name_arg << "=3D\"" << name = <<=20 >> "\"" << endl; >> LEX *lex=3D thd->lex; >> Item* idI =3D new Item_field(lex->current_context(), NullS, alias,=20 >> field_name_arg); >> chooser_compare_func_creator eq =3D &comp_eq_creator; >> Item* test =3D eq(0)->create(idI, get_item()); >> SELECT_LEX *sel=3D lex->current_select; >> sel->expr_list.head()->push_back(test); >> test->top_level_item(); >> if (jt) { >> sel->add_joined_table(jt); >> } >> } >> void Item_literal_decimal::print(String *str) >> { >> str->append(name); >> } >> /* */ >> >> >> /* */ >> void Item_literal_float::bind_field(const char *table_name, const char= =20 >> *alias, const char *field_name_arg, bool trump, THD *thd= ,=20 >> TABLE_LIST *jt) { >> cout << "WHERE " << alias << "." << field_name_arg << "=3D\"" << name = <<=20 >> "\"" << endl; >> LEX *lex=3D thd->lex; >> Item* idI =3D new Item_field(lex->current_context(), NullS, alias,=20 >> field_name_arg); >> chooser_compare_func_creator eq =3D &comp_eq_creator; >> Item* test =3D eq(0)->create(idI, get_item()); >> SELECT_LEX *sel=3D lex->current_select; >> sel->expr_list.head()->push_back(test); >> test->top_level_item(); >> if (jt) { >> sel->add_joined_table(jt); >> } >> } >> void Item_literal_float::print(String *str) >> { >> str->append(name); >> } >> /* */ >> >> >> /* */ >> Item_primary_key_field::Item_primary_key_field ( >> Name_resolution_context *context_arg, >> const char *db_arg, const char *table_name_arg, sparqlFrob=20 >> *frob_arg, const char* real_table_name_arg) : >> Item_field(context_arg, db_arg, table_name_arg, "") { >> frob =3D frob_arg; >> real_table_name=3D real_table_name_arg; >> } >> bool Item_primary_key_field::fix_fields(THD *thd, Item **reference) { >> field_name =3D frob->get_primary_key(real_table_name); >> return Item_field::fix_fields(thd, reference); >> } >> /* */ >> >> >> /* */ >> void BindingContext::select_star (THD *thd) { >> List_iterator list_it(item_variables); >> Item_variable *ptr; >> while ((ptr=3D list_it++)) >> add_item_to_list(thd, ptr); >> } >> Alias_info* BindingContext::get_table_alias (THD *thd, Item_POS *s,=20 >> Item_URI *p, Item_POS *o) { >> LEX_STRING table =3D p->get_table(); >> Alias_info *ai =3D NULL; >> List_iterator item_list_it(aliases); >> Alias_info *t; >> while ((t =3D item_list_it++)) { >> if (t->same_table(table)) { >> ai =3D t; >> break; >> } >> } >> if (!ai) { >> ai =3D new Alias_info(table); >> aliases.push_front(ai); >> } >> return ai; >> } >> >> /* ref_count -- 0: child context looking for the variable in a parent= =20 >> context. >> 1: normal use >> */ >> Item_variable* BindingContext::ensure_bound_item_variable (const char=20 >> *var, sparqlFrob *sparql_frob, int ref_count) { >> List_iterator item_list_it(item_variables); >> Item_variable* ret; >> while ((ret=3D item_list_it++)) >> if (ret->same_variable(var)) { >> ret->add_ref_count(ref_count); >> return ret; >> } >> >> Item_variable *outer=3D parent ? parent->ensure_bound_item_variable(va= r,=20 >> sparql_frob, 0) : NULL; >> ret=3D new Item_variable(name_res_context, var, outer, sparql_frob,=20 >> ref_count); >> item_variables.push_back(ret); >> >> return ret; >> } >> >> Item* BindingContext::get_bound_variable_constraints (Item=20 >> *conjunction_constraints, GraphContext *gc) { >> // Will need to write down our created constraints >> List nulls; >> List notNulls; >> // return NULL; >> // Walk the list of our introduced variables. >> List_iterator item_list_it(item_variables); >> Item_variable *t; >> while ((t =3D item_list_it++)) { >> if (gc->is_optional()) { >> nulls.push_front(new Item_func_isnull(t)); >> } >> notNulls.push_front(new Item_func_isnotnull(t)); >> } >> if (conjunction_constraints) >> notNulls.push_front(conjunction_constraints); >> Item *nulls_cond =3D nulls.elements ? new Item_cond_and(nulls) : NULL; >> Item *notNulls_cond =3D notNulls.elements ? new Item_cond_and(notNulls= ) :=20 >> NULL; >> if (nulls_cond && notNulls_cond) { >> List *or_cond =3D new List; >> or_cond->push_front(nulls_cond); >> or_cond->push_front(notNulls_cond); >> return new Item_cond_or(*or_cond); >> } >> // It is impossible that we have nulls and no notNulls to return=20 >> notNulls. >> return notNulls_cond; >> } >> void BindingContext::start_constraints () { >> mysql_init_select(lex); >> name_res_context=3D lex->current_context(); >> constraints=3D new List; >> lex->select_lex.expr_list.push_front(constraints); // current_select-> >> } >> /* */ >> >> >> /* */ >> const char* GraphContext::get_alias_string (Alias_info *ai, Item_POS *s,= =20 >> THD *thd) { >> List_iterator item_list_it(ai->subjects); >> Item_POS *t; >> size_t i=3D 0; >> bool found=3D false; >> while ((t=3D item_list_it++)) { >> if (t =3D=3D s) { >> found=3D true; >> break; >> } >> ++i; >> } >> char space[ai->table.length+1+1+1]; >> strncpy(space, ai->table.str, ai->table.length); >> space[ai->table.length]=3D '_'; >> space[ai->table.length+1]=3D '0'+i; >> space[ai->table.length+2]=3D 0; >> const char *ret=3D thd->strmake(space, ai->table.length+1+1+1); >> if (!found) { >> ai->subjects.push_front(s); >> Table_ident* table_i=3D new Table_ident(ai->table); >> LEX *lex=3D thd->lex; >> SELECT_LEX* sel=3D lex->current_select; // &lex->select_lex; >> LEX_STRING *alias=3D new LEX_STRING; >> alias->str=3D (char*)ret; >> alias->length=3D ai->table.length+2; >> cout << "FROM " << ai->table.str << " AS " << alias->str << endl; >> TABLE_LIST *jt=3D sel->add_table_to_list(lex->thd, table_i, alias, >> sel->get_table_join_options(), >> lex->lock_option, >> sel->pop_index_hints()); >> if (!jt) >> return NULL; >> if (is_optional()) >> jt->outer_join|=3DJOIN_TYPE_LEFT; >> if (s->is_URI()) { >> Item_URI *sURI=3D (Item_URI*)s; >> chooser_compare_func_creator eq=3D &comp_eq_creator; >> LEX_STRING value=3D sURI->get_value(); >> cout << "WHERE " << alias->str << "." << sURI->get_field().str <<= =20 >> "=3D" << value.str << endl; >> Item* idI=3D new Item_field(lex->current_context(), NullS, alias->= str,=20 >> sURI->get_field().str); >> int error; >> Item* val=3D new Item_int(value.str, (longlong)=20 >> my_strtoll10(value.str, NULL, &error), value.length); >> Item* test=3D eq(0)->create(idI, val); >> sel->expr_list.head()->push_back(test); >> test->top_level_item(); >> sel->add_joined_table(jt); >> } else if (s->is_variable()) { >> s->bind_field(ai->table.str, ret, NULL, true, thd, jt); >> } >> } >> return ret; >> } >> /* */ >> >> >> /* */ >> BindingGraphContext::BindingGraphContext (GraphContext *parent_param,=20 >> sparqlFrob *sparql_frob_param) : GraphContext (parent_param,=20 >> sparql_frob_param) { >> bindings=3D new BindingContext(this, parent ?=20 >> parent->get_binding_context() : NULL, sparql_frob->lex); >> current_select=3D NULL; >> } >> void BindingGraphContext::select_var (Item_variable *var, bool exists) { >> cout << (void*)this << " SELECTs " << (exists ? "" : "NULL AS ") <<=20 >> var->name << endl; >> current_select->add_item_to_list(thd, exists ? var->get_item() : = =20 >> var->get_null_item()); >> } >> /* */ >> >> >> /* */ >> RootGraphContext::RootGraphContext (GraphContext *parent, =20 >> sparqlFrob *sparql_frob) : BindingGraphContext(parent, sparql_frob) { >> bindings->start_constraints(); >> current_select=3D sparql_frob->lex->current_select; >> } >> /* */ >> >> >> /* */ >> Union1GraphContext::Union1GraphContext (GraphContext *parent,=20 >> sparqlFrob *sparql_frob) : BindingGraphContext(parent, sparql_fro= b)=20 >> { >> LEX *lex=3D thd->lex; >> lex->current_select->init_nested_join(thd); >> lex->current_select->end_nested_join(thd); >> lex->derived_tables|=3D DERIVED_SUBQUERY; >> mysql_new_select(lex, 1); >> current_select=3D sparql_frob->lex->current_select; >> bindings->start_constraints(); >> lex->current_select->linkage=3D DERIVED_TABLE_TYPE; >> } >> void Union1GraphContext::close () { >> thd->lex->current_select->init_nested_join(thd); >> // thd->lex->current_select->init_nested_join(thd); >> thd->lex->current_select->end_nested_join(thd); >> bindings->end_and_check_constraints(); >> } >> /* */ >> >> >> /* */ >> Union2GraphContext::Union2GraphContext (GraphContext *parent,=20 >> sparqlFrob *sparql_frob) : BindingGraphContext(parent, sparql_fro= b)=20 >> { >> left=3D (BindingGraphContext*)sparql_frob->last_context(); >> LEX *lex=3D thd->lex; >> >> lex->current_select =3D left->current_select; // next function called = with=20 >> left select >> if (mysql_new_select(lex, 0)) // sets the new lex->current_select >> assert(0); >> current_select=3D sparql_frob->lex->current_select; >> bindings->start_constraints(); >> lex->current_select->linkage=3DUNION_TYPE; >> if (sparql_frob->get_distinct()) /* UNION DISTINCT - remember position= =20 >> */ >> lex->current_select->master_unit()->union_distinct=3D >> lex->current_select; >> } >> void Union2GraphContext::close () { >> LEX *lex=3D thd->lex; >> >> lex->pop_context(); >> SELECT_LEX *sel=3D lex->current_select; >> SELECT_LEX_UNIT *unit=3D sel->master_unit(); >> lex->current_select=3D sel=3D unit->outer_select(); >> TABLE_LIST *t; >> if (!(t =3D sel-> >> add_table_to_list(thd, new Table_ident(unit), >> sparql_frob->next_union_alias(), 0, >> TL_READ,(List *)0, >> (LEX_STRING *)0))) >> assert(0); >> sel->add_joined_table(t); >> lex->pop_context(); >> >> Item *as=3D ((Union1GraphContext*)left)->map_variables_to_outer_contex= t(); >> cout << "SPARQL: close Union2 {" << endl << buf->str() << "}" << endl; >> bindings->end_and_check_constraints(); >> } >> /* */ >> >> >> Item_URI *XSD_integer=3D NULL; >> Item_URI *XSD_float=3D NULL; >> Item_URI *XSD_decimal=3D NULL; >> String Global_string; >> >> t_initialize initialize; >> Dynamic_parser* initialize(THD *thd, char **ptr) { >> return new sparqlFrob(thd, ptr); >> } >> >> >> /* */ >> Buf::Buf(char *str) { >> len =3D strlen(str); >> data =3D new char[len+1]; >> strncpy(data, str, len); >> data[len] =3D 0; >> } >> /* Build a space-separated concatonation of bufs. */ >> Buf::Buf(int count, ...) { >> va_list bufs; >> const Buf *src; >> >> // This is inefficient for a single buf as the created buf could >> // just steal the other buf's data pointer and delete it. >> >> // Walk args to find the total len. >> len =3D -1; >> va_start(bufs, count); >> for (int i =3D 0; i < count; i++) { >> src =3D va_arg(bufs, Buf*); >> len +=3D src->len+1; >> } >> va_end(bufs); >> >> data =3D new char[len+1]; >> >> // Walk args to fill the data buffer. >> len =3D -1; >> va_start(bufs, count); >> for (int i =3D 0; i < count; i++) { >> src =3D va_arg(bufs, Buf*); >> strncpy(data + len+1, src->data, src->len); >> len +=3D src->len+1; >> data[len] =3D ' '; >> delete src; >> src =3D 0; >> } >> va_end(bufs); >> data[len] =3D 0; >> } >> /* */ >> >> // $Log: sparqlParser.yy,v $ >> // Revision 1.9 2007/09/05 18:40:30 eric >> // ~ derive from Dynamic_parser >> // ~ follow meakly behind API changes in MySQL >> // >> // Revision 1.8 2007/07/10 12:34:18 eric >> // + parse ISO6801 datetimes >> // >> // Revision 1.7 2007/07/08 21:30:10 eric >> // ~ surface re-org >> // >> // Revision 1.6 2007/07/08 18:20:45 eric >> // + field_type >> // + make_field >> // ~ get primary key from "lex->select_lex" instead of recently private= =20 >> "lex" >> // ~ simplify Item_variable::send - have Item_field side call=20 >> protocol->store(result_field) instead of emulating it >> // >> // Revision 1.5 2006/12/17 15:45:34 eric >> // + Assemble result values into RDF-like literals: >> // put ""'s round strings and misc data types >> // add ^^xsd:dateTime etc. to timeish datatypes >> // send integers as bare numbers >> // >> // Left to do: handle float, double, decimal. >> // >> // Revision 1.4 2006/12/17 15:22:01 eric >> // + sparqlFrob::print(String*) >> // ~ rearranged >> // >> // Revision 1.3 2006/12/16 14:08:23 eric >> // ~ beacoup aesthetic changes >> // ~ s/Item_POS_/Item_literal_/g >> // >> // Revision 1.2 2006/12/16 02:22:40 eric >> // + primary keys return the URI identifying their tuple (as they are=20 >> written in queries) >> // >> // Revision 1.1 2006/12/15 14:45:17 eric >> // import from cvs://cvs.w3.org/WWW/2005/05/22-SPARQL-MySQL/ >> // >> // Revision 1.35 2006/05/26 18:49:51 eric >> // progress on UNIONs >> // >> // Revision 1.34 2006/05/23 09:05:24 eric >> // UNION fleshed out, needs debugging >> // >> // Revision 1.33 2006/05/11 19:15:47 eric >> // first pass at BindingContext architecture >> // >> // Revision 1.32 2006/05/01 06:39:56 eric >> // + tollerance for foreign key ambiguity >> // ~ valgrind: free[], initialize Item_variable::jt >> // >> // Revision 1.31 2006/04/29 22:06:17 eric >> // + INTEGER >> // + DECIMAL >> // + DOUBLE (well, Item_float) >> // >> // Revision 1.30 2006/04/29 21:08:26 eric >> // - pruning >> // ~ fixed strncmp (erroneous match on substring) error and marked anoth= er >> // - YYTHD macros >> // >> // Revision 1.29 2006/04/29 16:53:27 eric >> // ~ simplified get_primary_key (complicated by previous extension table= s=20 >> commit) >> // >> // Revision 1.28 2006/04/29 16:45:03 eric >> // + extension tables (tables with the same primary key as another -- bo= th=20 >> are likely to be ?s) >> // >> // Revision 1.27 2006/04/23 01:34:25 eric >> // ~ OPTIONAL using nested JOINs >> // >> // Revision 1.26 2006/04/17 09:53:57 eric >> // + postpone putting variables in a context until we have the context >> // >> // Revision 1.25 2006/04/17 01:13:22 eric >> // + OPTIONAL >> // >> // Revision 1.24 2006/04/16 23:29:00 eric >> // + start on OPTIONALS >> // >> // Revision 1.23 2006/04/16 11:23:16 eric >> // + DISTINCT >> // + ORDER BY >> // + LIMIT >> // + OFFSET >> // >> // Revision 1.22 2006/04/16 08:44:03 eric >> // + labeled blank nodes >> // >> // Revision 1.21 2006/04/15 20:27:59 eric >> // + active POS casting to make exprs work >> // >> // Revision 1.20 2006/04/15 16:18:12 eric >> // - cleaned slightly >> // >> // Revision 1.19 2006/04/15 15:32:20 eric >> // + late-binding primary keys >> // >> // Revision 1.18 2006/04/13 23:52:11 eric >> // + framed out Item_primary_key_field >> // + expr on down compiling -- need to re-derive POS_string from a=20 >> constant Item_ class >> // >> // Revision 1.17 2006/04/12 16:24:35 eric >> // + using sel->expr_list to collect outermost WHERE conjunction >> // >> // Revision 1.16 2006/04/12 14:48:03 eric >> // - reduced casting >> // >> // Revision 1.15 2006/04/11 13:20:02 eric >> // + parser errors =3D> YYABORT >> // >> // Revision 1.14 2006/04/11 11:46:45 eric >> // added CVS tags >> // >> // >> ----------------------------------------------------------------------= -- >> >> %{ #ifndef FLEXFIX >> #define FLEXFIX YY_sparqlParser_STYPE *val >> #define FLEXFIX2 val >> #endif >> #include "sparqlParser.h" >> >> #define YY_INPUT(buf,result,max_size) \ >> if ( (result =3D LexerReadStatic( (char *) buf, max_size )) < 0 ) \ >> YY_FATAL_ERROR( "input in flex scanner failed" ); >> %} >> >> IT_BASE "BASE" >> IT_PREFIX "PREFIX" >> IT_SELECT "SELECT" >> IT_DISTINCT "DISTINCT" >> GT_TIMES "*" >> IT_CONSTRUCT "CONSTRUCT" >> IT_DESCRIBE "DESCRIBE" >> IT_ASK "ASK" >> IT_FROM "FROM" >> IT_NAMED "NAMED" >> IT_WHERE "WHERE" >> IT_ORDER "ORDER" >> IT_BY "BY" >> IT_ASC "ASC" >> IT_DESC "DESC" >> IT_LIMIT "LIMIT" >> IT_OFFSET "OFFSET" >> GT_LCURLEY "{" >> GT_RCURLEY "}" >> GT_DOT "." >> IT_OPTIONAL "OPTIONAL" >> IT_GRAPH "GRAPH" >> IT_UNION "UNION" >> IT_FILTER "FILTER" >> GT_COMMA "," >> GT_LPAREN "(" >> GT_RPAREN ")" >> GT_SEMI ";" >> IT_a "a" >> GT_LBRACKET "\[" >> GT_RBRACKET "\]" >> GT_MINUS "-" >> GT_PLUS "+" >> GT_OR "||" >> GT_AND "&&" >> GT_EQUAL "=3D" >> GT_NEQUAL "!=3D" >> GT_LT "<" >> GT_GT ">" >> GT_LE "<=3D" >> GT_GE ">=3D" >> GT_DIVIDE "/" >> GT_NOT "!" >> IT_STR "STR" >> IT_LANG "LANG" >> IT_LANGMATCHES "LANGMATCHES" >> IT_DATATYPE "DATATYPE" >> IT_BOUND "BOUND" >> IT_isIRI "isIRI" >> IT_isURI "isURI" >> IT_isBLANK "isBLANK" >> IT_isLITERAL "isLITERAL" >> IT_REGEX "REGEX" >> GT_DTYPE "^^" >> IT_true "true" >> IT_false "false" >> Q_IRI_REF "<"(([!-&(-;=3D?-\]_a-z~-\x7F]|([\xC2-\xDF][\x80-\xBF])|(\xE0= ([\xA0-\xBF][\x80-\xBF]))|([\xE1-\xEC][\x80-\xBF][\x80-\xBF])|([\xE1-\xEC][= \x80-\xBF][\x80-\xBF])|(\xED([\x80-\x9F][\x80-\xBF]))|([\xEE-\xEF][\x80-\xB= F][\x80-\xBF])|(\xF0([\x90-\xBF][\x80-\xBF][\x80-\xBF]))|([\xF1-\xF3][\x80-= \xBF][\x80-\xBF][\x80-\xBF])|(\xF4([\x80-\x8E][\x80-\xBF][\x80-\xBF])|(\x8F= ([\x80-\xBE][\x80-\xBF])|(\xBF[\x80-\xBE])))]))*">" >> LANGTAG "@"([A-Za-z])+(("-"([0-9A-Za-z])+))* >> INTEGER ([0-9])+ >> DECIMAL (([0-9])+"."([0-9])*)|("."([0-9])+) >> EXPONENT [Ee]([+-])?([0-9])+ >> DOUBLE (([0-9])+"."([0-9])*({EXPONENT}))|(("."(([0-9]))+({EXPONENT}))|(= (([0-9]))+({EXPONENT}))) >> ECHAR "\\"[\"'\\bfnrt] >> HEX ([0-9])|(([A-F])|([a-f])) >> UCHAR "\\"(("u"({HEX})({HEX})({HEX})({HEX}))|("U"({HEX})({HEX})({HEX})(= {HEX})({HEX})({HEX})({HEX})({HEX}))) >> STRING_LITERAL1 "'"(((([\x00-\t\x0B-\x0C\x0E-&(-\[\]-\x7F]|([\xC2-\xDF]= [\x80-\xBF])|(\xE0([\xA0-\xBF][\x80-\xBF]))|([\xE1-\xEC][\x80-\xBF][\x80-\x= BF])|([\xE1-\xEC][\x80-\xBF][\x80-\xBF])|(\xED([\x80-\x9F][\x80-\xBF]))|([\= xEE-\xEF][\x80-\xBF][\x80-\xBF])|(\xF0([\x90-\xBF][\x80-\xBF][\x80-\xBF]))|= ([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF])|(\xF4([\x80-\x8E][\x80-\xBF]= [\x80-\xBF])|(\x8F([\x80-\xBE][\x80-\xBF])|(\xBF[\x80-\xBE])))]))|((({ECHAR= }))|(({UCHAR})))))*"'" >> STRING_LITERAL2 "\""(((([\x00-\t\x0B-\x0C\x0E-!#-\[\]-\x7F]|([\xC2-\xDF= ][\x80-\xBF])|(\xE0([\xA0-\xBF][\x80-\xBF]))|([\xE1-\xEC][\x80-\xBF][\x80-\= xBF])|([\xE1-\xEC][\x80-\xBF][\x80-\xBF])|(\xED([\x80-\x9F][\x80-\xBF]))|([= \xEE-\xEF][\x80-\xBF][\x80-\xBF])|(\xF0([\x90-\xBF][\x80-\xBF][\x80-\xBF]))= |([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF])|(\xF4([\x80-\x8E][\x80-\xBF= ][\x80-\xBF])|(\x8F([\x80-\xBE][\x80-\xBF])|(\xBF[\x80-\xBE])))]))|((({ECHA= R}))|(({UCHAR})))))*"\"" >> STRING_LITERAL_LONG1 "'''"((((("'")|("''")))?(([\x00-&(-\[\]-\x7F]|([\x= C2-\xDF][\x80-\xBF])|(\xE0([\xA0-\xBF][\x80-\xBF]))|([\xE1-\xEC][\x80-\xBF]= [\x80-\xBF])|([\xE1-\xEC][\x80-\xBF][\x80-\xBF])|(\xED([\x80-\x9F][\x80-\xB= F]))|([\xEE-\xEF][\x80-\xBF][\x80-\xBF])|(\xF0([\x90-\xBF][\x80-\xBF][\x80-= \xBF]))|([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF])|(\xF4([\x80-\x8E][\x= 80-\xBF][\x80-\xBF])|(\x8F([\x80-\xBE][\x80-\xBF])|(\xBF[\x80-\xBE])))])|((= ({ECHAR}))|(({UCHAR}))))))*"'''" >> STRING_LITERAL_LONG2 "\"\"\""((((("\"")|("\"\"")))?(([\x00-!#-\[\]-\x7F= ]|([\xC2-\xDF][\x80-\xBF])|(\xE0([\xA0-\xBF][\x80-\xBF]))|([\xE1-\xEC][\x80= -\xBF][\x80-\xBF])|([\xE1-\xEC][\x80-\xBF][\x80-\xBF])|(\xED([\x80-\x9F][\x= 80-\xBF]))|([\xEE-\xEF][\x80-\xBF][\x80-\xBF])|(\xF0([\x90-\xBF][\x80-\xBF]= [\x80-\xBF]))|([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-\xBF])|(\xF4([\x80-\x= 8E][\x80-\xBF][\x80-\xBF])|(\x8F([\x80-\xBE][\x80-\xBF])|(\xBF[\x80-\xBE]))= )])|((({ECHAR}))|(({UCHAR}))))))*"\"\"\"" >> WS (" ")|(("\t")|(("\r")|("\n"))) >> NIL "("(({WS}))*")" >> ANON "\["(({WS}))*"\]" >> NCCHAR1p ([A-Z])|(([a-z])|(((\xC3[\x80-\x96]))|(((\xC3[\x98-\xB6]))|(((= \xC3[\xB8-\xBF])|([\xC4-\xCB][\x80-\xBF]))|(((\xCD[\xB0-\xBD]))|(((\xCD\xBF= )|([\xCE-\xDF][\x80-\xBF])|(\xE0([\xA0-\xBF][\x80-\xBF]))|(\xE1([\x80-\xBF]= [\x80-\xBF])))|(((\xE2(\x80[\x8C-\x8D])))|(((\xE2(\x81[\xB0-\xBF])|([\x82-\= x85][\x80-\xBF])|(\x86[\x80-\x8F])))|(((\xE2([\xB0-\xBE][\x80-\xBF])|(\xBF[= \x80-\xAF])))|(((\xE3(\x80[\x81-\xBF])|([\x81-\xBF][\x80-\xBF]))|([\xE4-\xE= C][\x80-\xBF][\x80-\xBF])|([\xE1-\xEC][\x80-\xBF][\x80-\xBF])|(\xED([\x80-\= x9F][\x80-\xBF])))|(((\xEF([\xA4-\xB6][\x80-\xBF])|(\xB7[\x80-\x8F])))|(((\= xEF(\xB7[\xB0-\xBF])|([\xB8-\xBE][\x80-\xBF])|(\xBF[\x80-\xBD])))|(((\xF0([= \x90-\xBF][\x80-\xBF][\x80-\xBF]))|([\xF1-\xF3][\x80-\xBF][\x80-\xBF][\x80-= \xBF]))|(({UCHAR}))))))))))))))) >> NCCHAR1 (({NCCHAR1p}))|("_") >> VARNAME ((({NCCHAR1}))|([0-9]))(((({NCCHAR1}))|(([0-9])|((\xC2\xB7)|(((= \xCD[\x80-\xAF]))|((\xE2(\x80\xBF)|(\x81\x80))))))))* >> VAR2 "$"({VARNAME}) >> VAR1 "?"({VARNAME}) >> NCCHAR (({NCCHAR1}))|(("-")|(([0-9])|((\xC2\xB7)|(((\xCD[\x80-\xAF]))|(= (\xE2(\x80\xBF)|(\x81\x80))))))) >> NCNAME_PREFIX ({NCCHAR1p})(((((({NCCHAR}))|(".")))*({NCCHAR})))? >> QNAME_NS (({NCNAME_PREFIX}))?":" >> NCNAME ({NCCHAR1})(((((({NCCHAR}))|(".")))*({NCCHAR})))? >> BLANK_NODE_LABEL "_:"({NCNAME}) >> QNAME (({NCNAME_PREFIX}))?":"(({NCNAME}))? >> PASSED_TOKENS ([\t\n\r ])+ >> %% >> {PASSED_TOKENS} >> {IT_BASE} {return sparqlParser::IT_BASE;} >> {IT_PREFIX} {val->buf =3D new Buf(yytext); return sparqlParser::IT_PREF= IX;} >> {IT_SELECT} {return sparqlParser::IT_SELECT;} >> {IT_DISTINCT} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_DISTINCT;} >> {GT_TIMES} {val->buf =3D new Buf(yytext); return sparqlParser::GT_TIMES= ;} >> {IT_CONSTRUCT} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_CONSTRUCT;} >> {IT_DESCRIBE} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_DESCRIBE;} >> {IT_ASK} {val->buf =3D new Buf(yytext); return sparqlParser::IT_ASK;} >> {IT_FROM} {val->buf =3D new Buf(yytext); return sparqlParser::IT_FROM;} >> {IT_NAMED} {val->buf =3D new Buf(yytext); return sparqlParser::IT_NAMED= ;} >> {IT_WHERE} {val->buf =3D new Buf(yytext); return sparqlParser::IT_WHERE= ;} >> {IT_ORDER} {val->buf =3D new Buf(yytext); return sparqlParser::IT_ORDER= ;} >> {IT_BY} {val->buf =3D new Buf(yytext); return sparqlParser::IT_BY;} >> {IT_ASC} {val->buf =3D new Buf(yytext); return sparqlParser::IT_ASC;} >> {IT_DESC} {val->buf =3D new Buf(yytext); return sparqlParser::IT_DESC;} >> {IT_LIMIT} {val->buf =3D new Buf(yytext); return sparqlParser::IT_LIMIT= ;} >> {IT_OFFSET} {val->buf =3D new Buf(yytext); return sparqlParser::IT_OFFS= ET;} >> {GT_LCURLEY} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::GT_LCURLEY;} >> {GT_RCURLEY} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::GT_RCURLEY;} >> {GT_DOT} {val->buf =3D new Buf(yytext); return sparqlParser::GT_DOT;} >> {IT_OPTIONAL} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_OPTIONAL;} >> {IT_GRAPH} {val->buf =3D new Buf(yytext); return sparqlParser::IT_GRAPH= ;} >> {IT_UNION} {val->buf =3D new Buf(yytext); return sparqlParser::IT_UNION= ;} >> {IT_FILTER} {val->buf =3D new Buf(yytext); return sparqlParser::IT_FILT= ER;} >> {GT_COMMA} {val->buf =3D new Buf(yytext); return sparqlParser::GT_COMMA= ;} >> {GT_LPAREN} {val->buf =3D new Buf(yytext); return sparqlParser::GT_LPAR= EN;} >> {GT_RPAREN} {val->buf =3D new Buf(yytext); return sparqlParser::GT_RPAR= EN;} >> {GT_SEMI} {val->buf =3D new Buf(yytext); return sparqlParser::GT_SEMI;} >> {IT_a} {val->buf =3D new Buf(yytext); return sparqlParser::IT_a;} >> {GT_LBRACKET} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::GT_LBRACKET;} >> {GT_RBRACKET} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::GT_RBRACKET;} >> {GT_MINUS} {val->buf =3D new Buf(yytext); return sparqlParser::GT_MINUS= ;} >> {GT_PLUS} {val->buf =3D new Buf(yytext); return sparqlParser::GT_PLUS;} >> {GT_OR} {val->buf =3D new Buf(yytext); return sparqlParser::GT_OR;} >> {GT_AND} {val->buf =3D new Buf(yytext); return sparqlParser::GT_AND;} >> {GT_EQUAL} {val->buf =3D new Buf(yytext); return sparqlParser::GT_EQUAL= ;} >> {GT_NEQUAL} {val->buf =3D new Buf(yytext); return sparqlParser::GT_NEQU= AL;} >> {GT_LT} {val->buf =3D new Buf(yytext); return sparqlParser::GT_LT;} >> {GT_GT} {val->buf =3D new Buf(yytext); return sparqlParser::GT_GT;} >> {GT_LE} {val->buf =3D new Buf(yytext); return sparqlParser::GT_LE;} >> {GT_GE} {val->buf =3D new Buf(yytext); return sparqlParser::GT_GE;} >> {GT_DIVIDE} {val->buf =3D new Buf(yytext); return sparqlParser::GT_DIVI= DE;} >> {GT_NOT} {val->buf =3D new Buf(yytext); return sparqlParser::GT_NOT;} >> {IT_STR} {val->buf =3D new Buf(yytext); return sparqlParser::IT_STR;} >> {IT_LANG} {val->buf =3D new Buf(yytext); return sparqlParser::IT_LANG;} >> {IT_LANGMATCHES} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_LANGMATCHES;} >> {IT_DATATYPE} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_DATATYPE;} >> {IT_BOUND} {val->buf =3D new Buf(yytext); return sparqlParser::IT_BOUND= ;} >> {IT_isIRI} {val->buf =3D new Buf(yytext); return sparqlParser::IT_isIRI= ;} >> {IT_isURI} {val->buf =3D new Buf(yytext); return sparqlParser::IT_isURI= ;} >> {IT_isBLANK} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_isBLANK;} >> {IT_isLITERAL} {val->buf =3D new Buf(yytext); return=20 >> sparqlParser::IT_isLITERAL;} >> {IT_REGEX} {val->buf =3D new Buf(yytext); return sparqlParser::IT_REGEX= ;} >> {GT_DTYPE} {val->buf =3D new Buf(yytext); return sparqlParser::GT_DTYPE= ;} >> {IT_true} {val->buf =3D new Buf(yytext); return sparqlParser::IT_true;} >> {IT_false} {val->buf =3D new Buf(yytext); return sparqlParser::IT_false= ;} >> {Q_IRI_REF} {val->lex_str =3D get_token(1, 1); return=20 >> sparqlParser::Q_IRI_REF;} >> {QNAME_NS} {val->lex_str =3D get_token(1, 0); return=20 >> sparqlParser::QNAME_NS;} >> {QNAME} {val->lex_str =3D get_token(0, 0); return sparqlParser::QNAME;} >> {BLANK_NODE_LABEL} {val->lex_str =3D get_token(2, 0); return=20 >> sparqlParser::BLANK_NODE_LABEL;} >> {VAR1} {val->lex_str =3D get_token(1, 0); return sparqlParser::VAR1;} >> {VAR2} {val->lex_str =3D get_token(1, 0); return sparqlParser::VAR2;} >> {LANGTAG} {val->lex_str =3D get_token(0, 0); return sparqlParser::LANGT= AG;} >> {INTEGER} {val->lex_str =3D get_token(0, 0); return sparqlParser::INTEG= ER;} >> {DECIMAL} {val->lex_str =3D get_token(0, 0); return sparqlParser::DECIM= AL;} >> {DOUBLE} {val->lex_str =3D get_token(0, 0); return sparqlParser::DOUBLE= ;} >> {STRING_LITERAL1} {val->lex_str =3D get_token(1, 1); return=20 >> sparqlParser::STRING_LITERAL1;} >> {STRING_LITERAL2} {val->lex_str =3D get_token(1, 1); return=20 >> sparqlParser::STRING_LITERAL2;} >> {STRING_LITERAL_LONG1} {val->lex_str =3D get_token(1, 1); return=20 >> sparqlParser::STRING_LITERAL_LONG1;} >> {STRING_LITERAL_LONG2} {val->lex_str =3D get_token(1, 1); return=20 >> sparqlParser::STRING_LITERAL_LONG2;} >> {NIL} {val->buf =3D new Buf(yytext); return sparqlParser::NIL;} >> {ANON} {val->buf =3D new Buf(yytext); return sparqlParser::ANON;} >> <> { yyterminate();} >> %% >> int yywrap() >> { >> return(1); >> } >> >> int sparqlFlexLexer::LexerReadStatic( char* buf, int max_size ) >> { >> char** cur =3D yyptr; >> char* start =3D *cur; >> #if 0 >> for (; **cur && max_size > 0; (*cur)++, buf++) { >> *buf =3D **cur; >> max_size--; >> } >> #else >> if (**cur && max_size > 0) { >> *buf =3D **cur; >> (*cur)++, buf++; >> } >> #endif >> return *cur - start; >> } >> >> sparqlFlexLexer::sparqlFlexLexer( THD *thd, char** ptr) >> { >> this->thd =3D thd; >> yyptr =3D ptr; >> >> yyin =3D NULL; >> yyout =3D NULL; >> yy_c_buf_p =3D 0; >> yy_init =3D 1; >> yy_start =3D 0; >> yy_flex_debug =3D 0; >> yylineno =3D 1; // this will only get updated if %option yylineno >> >> yy_did_buffer_switch_on_eof =3D 0; >> >> yy_looking_for_trail_begin =3D 0; >> yy_more_flag =3D 0; >> yy_more_len =3D 0; >> yy_more_offset =3D yy_prev_more_offset =3D 0; >> >> yy_start_stack_ptr =3D yy_start_stack_depth =3D 0; >> yy_start_stack =3D 0; >> >> yy_current_buffer =3D 0; >> >> #ifdef YY_USES_REJECT >> yy_state_buf =3D new yy_state_type[YY_BUF_SIZE + 2]; >> #else >> yy_state_buf =3D 0; >> #endif >> } >> >> LEX_STRING sparqlFlexLexer::get_token(size_t skip, size_t trail) >> { >> LEX_STRING tmp; >> tmp.length =3D yyleng - skip - trail; >> tmp.str =3D (char*) thd->strmake((char*) yytext + skip, tmp.length); >> return tmp; >> } >> >> ----------------------------------------------------------------------= -- >> >> #include "dyn_parser.h" >> #include >> >> class Item_POS; >> class Item_URI; >> class Item_variable; >> class Item_blank_node; >> class Item_literal_string; >> class Item_literal_int; >> class Item_literal_decimal; >> class Item_literal_float; >> class Alias_info; >> class GraphContext; >> class BindingGraphContext; >> class RootGraphContext; >> >> class sparqlFrob : public Dynamic_parser { >> private: >> void* parser; >> List uris; >> List variables; >> List blank_nodes; >> List strings; >> List ints; >> List decimals; >> List floats; >> List subjects; >> List predicates; >> List contexts; >> List root_constraints; >> List > need_selects; >> bool distinct; >> GraphContext *last_graph_context; >> GraphContext *next_graph_context; >> uchar next_union_alias_index; >> >> public: >> sparqlFrob(THD *thd, char** ptr); >> ~sparqlFrob(); >> int parse(); >> >> Item_variable* ensure_variable (const char *var); >> Item_URI* ensure_URI (LEX_STRING uristr); >> Item_blank_node* make_blank_node (); >> Item_blank_node* ensure_blank_node (const char *label); >> Item_literal_string* ensure_string (LEX_STRING str, Item_POS=20 >> *lang_or_datatype); >> Item_literal_int* ensure_int (LEX_STRING str, Item_POS=20 >> *lang_or_datatype); >> Item_literal_decimal* ensure_decimal (LEX_STRING str, Item_POS=20 >> *lang_or_datatype); >> Item_literal_float* ensure_float (LEX_STRING str, Item_POS=20 >> *lang_or_datatype); >> void push_subject (Item_POS *subject); >> Item_POS* pop_subject (); >> void push_predicate (Item_POS *predicate); >> void pop_predicate (); >> bool object (Item_POS *object); >> bool type_list (); >> bool add_listElement (Item_POS *item); >> const char* get_primary_key(const char *table_name); >> void push_context(GraphContext *gc) {contexts.push_front(gc);} >> GraphContext* head_context() {return contexts.head();} >> GraphContext* pop_context() {return last_graph_context =3D=20 >> contexts.pop();} >> void add_root_constraints (Item *constraint) { >> if (constraint) >> root_constraints.push_front(constraint); >> } >> Item* get_root_constraints () { >> return root_constraints.elements =3D=3D 0 ? NULL : =20 >> root_constraints.elements =3D=3D 1 ? root_constraints.pop() : = new=20 >> Item_cond_and(root_constraints); >> } >> void needs_select (List *contexts) { >> need_selects.push_back(contexts); // Must iterate backwards through= =20 >> list. >> } >> void select_variables(); >> void set_distinct (bool distinct_parm) {distinct=3D distinct_parm;} >> bool get_distinct () {return distinct;} >> GraphContext *last_context () {return last_graph_context;} >> void set_next_GC (GraphContext *gc) {next_graph_context=3D gc;} >> GraphContext *was_next_GC () {GraphContext *ret=3D next_graph_context;= =20 >> next_graph_context=3D NULL; return ret;} >> LEX_STRING* next_union_alias (); >> void print(String *str); >> >> LEX *lex; >> }; >> >> t_initialize initialize; >> =20 --=20 -eric office: +1.617.258.5741 NE43-344, MIT, Cambridge, MA 02144 USA mobile: +1.617.599.3509 (eric@stripped) Feel free to forward this message to any list for any purpose other than email address distribution. --vA66WO2vHvL/CRSR Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iQEVAwUBRuAK7pZX2p1ccTnpAQKmhwf/Vfkfx6ZoRMHAoKM1EVNtc7dDW98IXUXA 6EvzB1ZkCur84VO3BEjSBDHnziG161AGRwYJ09Lx3aUUVwvwuyPskvOSVD8eyUyC D0bVqHiVTvN4nnjAeWC03ZOGjTBbHv333r+oNQ2yfeMYic1ztl6X1E8xueYQTG7F kSPsnlbht0aWNaOxoEA4LRZK9y4/EqqeKJkTIBh5XArjNE/mljzbNaFnxzRLJ6V2 0DJYCcP06TD6acNIwYc0Ywbw4z7o3z6LpawDswbz73gNOku7Yy5jPA9XjLDKaHwY OEcoz9BHC1W9iDF990SoXuDCCeFcHMtGlMNDgPme1au4K05LDtAMKw== =OjiO -----END PGP SIGNATURE----- --vA66WO2vHvL/CRSR--