%{ #define YY_sparqlParser_STYPE yy_sparqlParser_stype /* $Id: sparqlParser.y,v 1.35 2006/05/26 18:49:51 eric Exp $ TODO: research pre-existing var.jt in conjunction with trump OUTLINE: Some SPARQL graph pattern opperations correspond to SQL subselects. These 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, T1.p1) and (?s, T1.p2) both map to the alias T1_0. (Ohterwise, you get needless joins like FROM T1 AS T1_0 JOIN T1 AS T1_1 ON T1_0.id=T1_1.id WHERE T1_0.p1=o1 AND T1_1.p1=o2 sparqlFrob::object(subject, predicate, object) */ %} %name sparqlParser %define LSP_NEEDED %define ERROR_BODY =0 %define LEX_BODY =0 %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 triggered it." extern String Global_string; // call test->print(&Global_string); p Global_string.c_ptr(); call Global_string.free() class Buf { // @@@ TODO: remove or ifdef when we're not using Buf. protected: char* data; int len; public: Buf () { len = 0; data = 0; } Buf (char *str) { len = strlen(str); data = new char[len+1]; strncpy(data, str, len); data[len] = 0; } // Build a space-separated concatonation of bufs. 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 = -1; va_start(bufs, count); for (int i = 0; i < count; i++) { src = va_arg(bufs, Buf*); len += src->len+1; } va_end(bufs); data = new char[len+1]; // Walk args to fill the data buffer. len = -1; va_start(bufs, count); for (int i = 0; i < count; i++) { src = va_arg(bufs, Buf*); strncpy(data + len+1, src->data, src->len); len += src->len+1; data[len] = ' '; delete src; src = 0; } va_end(bufs); data[len] = 0; } ~Buf () { if (data) delete[] data; } char *str() {return data;} }; class BindingContext; class Item_POS { protected: Item *item; public: Item_POS (Item* item_arg) {item = item_arg;} virtual ~Item_POS () {} virtual void bind_field(const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) = 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. }; const char* scan_string (THD *thd, LEX_STRING *lex_string, const char *start, const char *end, const char look_for); 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 *thd) : Item_field(context_arg, NullS, NullS, uri.str), Item_POS(this) { const char* ptr = scan_string(thd, &value, name, name + uri.length, '='); if ((ptr = scan_string(thd, &field, name, ptr ? ptr : name + uri.length, '.'))) { scan_string(thd, &table, name, ptr ? ptr : name + uri.length, 0); } } virtual void bind_field(const char *table_name, const char *alias, 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 includes the status of a variable's use in the current JOIN. A variable in a nested JOIN is different from a variable in an outer context (the UnionGraphContext::close handles the correlation (U0.foo=oldTable.oldField). */ /* Item_variable - has the same virtual functions as an Item, but is never added to the SQL compile tree (for insta,ce, 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; public: Item_variable (Name_resolution_context *context_arg, const char *variable_name, Item_variable *outer_arg, sparqlFrob *frob_arg, int ref_count_arg) : Item_field(context_arg, NullS, NullS, variable_name), Item_POS(this) { set_name(variable_name, strlen(variable_name), system_charset_info); is_autogenerated_name= FALSE; nr_context= context_arg; bound= false; outer= outer_arg; frob= frob_arg; primary_key= false; gc= frob->head_context(); jt= NULL; ref_count= ref_count_arg; } virtual void bind_field(const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt); 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); const char* get_primary_key() {return frob->get_primary_key(real_table_name);} virtual bool is_variable () {return true;} bool same_variable (const char* variable_name) { return !strcmp(orig_field_name, variable_name); } virtual bool fix_fields(THD *, Item **); void add_ref_count (int ref_count_arg) {ref_count+= ref_count_arg;} void print(String *str); bool outer_has_no_refs () {return outer ? outer->ref_count == 0 : true;} static Item_variable* match_var_in_list (List *p_item_variables, const char *var); Item* get_null_item () { Item *ret= new Item_null(); ret->set_name(name, strlen(name), system_charset_info); ret->is_autogenerated_name= FALSE; return ret; } }; class Item_blank_node : public Item_variable { public: Item_blank_node(Name_resolution_context *context_arg, const char *node_name, sparqlFrob *frob_arg) : Item_variable(context_arg, node_name, NULL, frob_arg, 0) { } virtual bool is_blank_node () {return true;} void print(String *str); }; class Item_POS_string : public Item_string, public Item_POS { private: Item_POS *lang_or_datatype; public: Item_POS_string(LEX_STRING string, Item_POS *lang_or_datatype, CHARSET_INFO *charset) : Item_string(string.str, string.length, charset), Item_POS(this) { this->lang_or_datatype = lang_or_datatype; } virtual void bind_field(const char *table_name, const char *alias, 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() ? (Item_URI*)lang_or_datatype : NULL; } Item_POS_string* get_language () { return lang_or_datatype && lang_or_datatype->is_string() ? (Item_POS_string*)lang_or_datatype : NULL; } void print(String *str); }; class Item_POS_int : public Item_int, public Item_POS { public: Item_POS_int(LEX_STRING string, Item_POS *lang_or_datatype, CHARSET_INFO *charset) : Item_int(string.str), Item_POS(this) { } virtual void bind_field(const char *table_name, const char *alias, 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_POS_string* get_language () { return NULL; } void print(String *str); }; class Item_POS_decimal : public Item_decimal, public Item_POS { public: Item_POS_decimal(LEX_STRING string, Item_POS *lang_or_datatype, CHARSET_INFO *charset) : Item_decimal(string.str, string.length, charset), Item_POS(this) { } virtual void bind_field(const char *table_name, const char *alias, 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_POS_string* get_language () { return NULL; } void print(String *str); }; class Item_POS_float : public Item_float, public Item_POS { public: Item_POS_float(LEX_STRING string, Item_POS *lang_or_datatype, CHARSET_INFO *charset) : Item_float(string.str, string.length), Item_POS(this) { } virtual void bind_field(const char *table_name, const char *alias, 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_POS_string* get_language () { return NULL; } void print(String *str); }; 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 *frob_arg, const char* real_table_name_arg) : Item_field(context_arg, db_arg, table_name_arg, "") { frob = frob_arg; real_table_name= real_table_name_arg; } virtual bool fix_fields(THD *, Item **); }; #if 0 class Item_func_call : public Item_POS { protected: Item_POS* name; List* args; public: Item_func_call(Name_resolution_context *context_arg, Item_POS* name, List* args) : Item_POS(context_arg, "") { this->name = name; this->args = args; } ~Item_func_call () {} void bind_field(const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) {} bool fix_fields(THD *, Item **); }; #endif class Alias_info { friend class GraphContext; private: LEX_STRING table; List subjects; public: Alias_info (LEX_STRING table) { this->table = table; } bool same_table (LEX_STRING table) { return !strcmp(this->table.str, table.str); } }; class BindingContext { protected: List item_variables; List aliases; Name_resolution_context *name_res_context; BindingContext *parent; LEX *lex; List *constraints; public: BindingContext (GraphContext *gc_param, BindingContext *parent_param, LEX *lex_param) { parent= parent_param; lex= lex_param; //name_res_context= lex->current_context(); } Item_variable* ensure_bound_item_variable(const char *name, sparqlFrob *sparql_frob, int ref_count); void select_star (THD *thd) { List_iterator list_it(item_variables); Item_variable *ptr; while ((ptr= list_it++)) add_item_to_list(thd, ptr); } List* get_item_variables () { return &item_variables; } Alias_info* get_table_alias (THD *thd, Item_POS *s, Item_URI *p, Item_POS *o); Item* get_bound_variable_constraints (Item *conjunction_constraints, GraphContext *gc); void start_constraints () { mysql_init_select(lex); name_res_context= lex->current_context(); constraints= new List; lex->select_lex.expr_list.push_front(constraints); // current_select-> } void end_and_check_constraints () { assert(constraints == lex->select_lex.expr_list.pop()); // current_select-> } Item* make_item_constraints () { return constraints->elements ? new Item_cond_and(*constraints) : NULL; } }; class GraphContext { protected: GraphContext *parent; THD *thd; Buf *buf; // temporary public: sparqlFrob *sparql_frob; // !!! should be protected GraphContext (GraphContext *parent_param, sparqlFrob *sparql_frob_param) { sparql_frob= sparql_frob_param; parent= parent_param; thd= sparql_frob->thd; buf= 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= 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); }; class BindingGraphContext : public GraphContext { friend class Union2GraphContext; // why doesn't BindingGraphContext work here? protected: BindingContext *bindings; SELECT_LEX *current_select; BindingGraphContext (GraphContext *parent_param, sparqlFrob *sparql_frob_param) : GraphContext (parent_param, sparql_frob_param) { bindings= new BindingContext(this, parent ? parent->get_binding_context() : NULL, sparql_frob->lex); current_select= NULL; } public: void select_var (Item_variable *var, bool exists); virtual BindingContext* get_binding_context () { return bindings; } }; class RootGraphContext : public BindingGraphContext { public: RootGraphContext (GraphContext *parent, sparqlFrob *sparql_frob) : BindingGraphContext(parent, sparql_frob) { bindings->start_constraints(); current_select= sparql_frob->lex->current_select; } virtual void close () { bindings->end_and_check_constraints(); } }; class OptionalGraphContext : public GraphContext { public: OptionalGraphContext (GraphContext *parent, sparqlFrob *sparql_frob) : GraphContext(parent, sparql_frob) { /* if (!(on_context= 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; } }; class Union1GraphContext : public BindingGraphContext { public: Union1GraphContext (GraphContext *parent, sparqlFrob *sparql_frob) : BindingGraphContext(parent, sparql_frob) { LEX *lex= thd->lex; lex->current_select->init_nested_join(thd); lex->current_select->end_nested_join(thd); lex->derived_tables|= DERIVED_SUBQUERY; mysql_new_select(lex, 1); current_select= sparql_frob->lex->current_select; bindings->start_constraints(); lex->current_select->linkage= DERIVED_TABLE_TYPE; } 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 deal with non-UNION %s. "PLS_REPORT, MYF(0), buf->str()); } virtual void 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(); } Item* map_variables_to_outer_context () { // !!! does nothing return NULL; } }; class Union2GraphContext : public BindingGraphContext { private: BindingGraphContext *left; // left side of the UNION public: Union2GraphContext (GraphContext *parent, sparqlFrob *sparql_frob) : BindingGraphContext(parent, sparql_frob) { left= (BindingGraphContext*)sparql_frob->last_context(); LEX *lex= thd->lex; lex->current_select = left->current_select; // next function called with left select if (mysql_new_select(lex, 0)) // sets the new lex->current_select assert(0); current_select= sparql_frob->lex->current_select; bindings->start_constraints(); lex->current_select->linkage=UNION_TYPE; if (sparql_frob->get_distinct()) /* UNION DISTINCT - remember position */ lex->current_select->master_unit()->union_distinct= lex->current_select; } virtual void close () { LEX *lex= thd->lex; lex->pop_context(); SELECT_LEX *sel= lex->current_select; SELECT_LEX_UNIT *unit= sel->master_unit(); lex->current_select= sel= unit->outer_select(); TABLE_LIST *t; if (!(t = sel-> add_table_to_list(thd, new Table_ident(unit), sparql_frob->next_union_alias(), 0, TL_READ,(List *)0, (List *)0))) assert(0); sel->add_joined_table(t); lex->pop_context(); Item *as= ((Union1GraphContext*)left)->map_variables_to_outer_context(); cout << "SPARQL: close Union2 {" << endl << buf->str() << "}" << endl; bindings->end_and_check_constraints(); } }; class GraphGraphContext : public BindingGraphContext { public: GraphGraphContext (GraphContext *parent, sparqlFrob *sparql_frob) : 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 _O_QSelectQuery_E__Or__QConstructQuery_E__Or__QDescribeQuery_E__Or__QAskQuery_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 _O_QFunctionCall_E__Or__QVar_E__Or__QBrackettedExpression_E__C %type LimitClause %type OffsetClause %type GroupGraphPattern %type GraphPattern %type _QDOT_E_Opt %type _O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C %type _Q_O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C_E_Opt %type FilteredBasicGraphPattern %type _QBlockOfTriples_E_Opt %type _O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C %type _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 _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star %type Constraint %type _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 _O_QNIL_E__Or__QLPAREN_E____QExpression_E____QCOMMA_E____QExpression_E_Star___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 _O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C %type _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 _O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C %type _Q_O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression_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 _O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicativeExpression_E__C %type _Q_O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicativeExpression_E__C_E_Star %type MultiplicativeExpression %type _O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__C %type _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= yySparqlFrob->thd->lex; SELECT_LEX *sel= lex->current_select; lex->current_select->parsing_place = NO_MATTER; sel->offset_limit= NULL; sel->select_limit= NULL; // create root context right away so SELECTs have a context yySparqlFrob->push_context( new RootGraphContext(yySparqlFrob->head_context(), yySparqlFrob)); } Prolog _O_QSelectQuery_E__Or__QConstructQuery_E__Or__QDescribeQuery_E__Or__QAskQuery_E__C { Buf *b = new Buf(2, $2, $3); cout << "Query end -- " << b->str() << endl; delete b; }; _O_QSelectQuery_E__Or__QConstructQuery_E__Or__QDescribeQuery_E__Or__QAskQuery_E__C: SelectQuery {$$ = $1} | ConstructQuery {$$ = $1; YYABORT;} | DescribeQuery {$$ = $1; YYABORT;} | AskQuery {$$ = $1; YYABORT;}; Prolog: _QBaseDecl_E_Opt _QPrefixDecl_E_Star {$$ = new Buf(2, $1, $2)}; _QBaseDecl_E_Opt: {$$ = new Buf()} | BaseDecl {$$ = $1}; _QPrefixDecl_E_Star: {$$ = new Buf()} | _QPrefixDecl_E_Star PrefixDecl {$$ = new Buf(2, $1, $2)}; BaseDecl: IT_BASE Q_IRI_REF {$$ = new Buf(2, new Buf("BASE"), new Buf($2.str))}; PrefixDecl: IT_PREFIX QNAME_NS Q_IRI_REF {$$ = new Buf(3, $1, new Buf($2.str), new Buf($3.str))}; SelectQuery: IT_SELECT { LEX *lex= yySparqlFrob->lex; SELECT_LEX *sel= lex->current_select; sel->parsing_place = SELECT_LIST; lex->sql_command= SQLCOM_SELECT; // SQLCOM_EMPTY_QUERY; } _QDISTINCT_E_Opt _O_QVar_E_Plus_Or__QTIMES_E__C { //SELECT_LEX *sel= yySparqlFrob->lex->current_select; // commented out 'cause the didn't seem to be needed - EGP 20060326 // lex->create_view_select_start = $1->get_item()->name; //sel->parsing_place = NO_MATTER; //sel->set_braces(0); } _QDatasetClause_E_Star WhereClause SolutionModifier { LEX *lex= yySparqlFrob->lex; SELECT_LEX *sel= lex->current_select; // Now that we have all the variables, fix up the SELECTs. yySparqlFrob->select_variables(); sel->parsing_place = NO_MATTER; $$ = new Buf(6, new Buf("SELECT"), $3, $4, $6, $7, $8); } ; _QDISTINCT_E_Opt: {$$ = new Buf()} | IT_DISTINCT { yySparqlFrob->set_distinct(true); $$ = $1; }; _QVar_E_Plus: Var { THD *thd= yySparqlFrob->thd; LEX *lex= thd->lex; SELECT_LEX *sel= lex->current_select; sel->use_index_ptr=sel->ignore_index_ptr=0; sel->table_join_options= 0; if (add_item_to_list(thd, $1->get_item())) { YYABORT; } $$ = new Buf($1->get_item()->name); } | _QVar_E_Plus Var { THD *thd= yySparqlFrob->thd; if (add_item_to_list(thd, $2->get_item())) { YYABORT; } $$ = new Buf(2, $1, new Buf($2->get_item()->name)); }; _O_QVar_E_Plus_Or__QTIMES_E__C: _QVar_E_Plus {$$ = $1} | GT_TIMES { $$ = $1; } ; _QDatasetClause_E_Star: {$$ = new Buf()} | _QDatasetClause_E_Star DatasetClause {$$ = new Buf(2, $1, $2)}; ConstructQuery: IT_CONSTRUCT ConstructTemplate _QDatasetClause_E_Star WhereClause SolutionModifier {$$ = new Buf(5, $1, $2, $3, $4, $5)}; DescribeQuery: IT_DESCRIBE _O_QVarOrIRIref_E_Plus_Or__QTIMES_E__C _QDatasetClause_E_Star _QWhereClause_E_Opt SolutionModifier {$$ = new Buf(5, $1, $2, $3, $4, $5)}; _QVarOrIRIref_E_Plus: VarOrIRIref {$$ = new Buf($1->get_item()->name)} | _QVarOrIRIref_E_Plus VarOrIRIref {$$ = new Buf(2, $1, new Buf($2->get_item()->name))}; _O_QVarOrIRIref_E_Plus_Or__QTIMES_E__C: _QVarOrIRIref_E_Plus {$$ = $1} | GT_TIMES {$$ = $1}; _QWhereClause_E_Opt: {$$ = new Buf()} | WhereClause {$$ = $1}; AskQuery: IT_ASK _QDatasetClause_E_Star WhereClause {$$ = new Buf(3, $1, $2, $3)}; DatasetClause: IT_FROM _O_QDefaultGraphClause_E__Or__QNamedGraphClause_E__C {$$ = new Buf(2, $1, $2)}; _O_QDefaultGraphClause_E__Or__QNamedGraphClause_E__C: DefaultGraphClause {$$ = $1} | NamedGraphClause {$$ = $1}; DefaultGraphClause: SourceSelector {$$ = $1}; NamedGraphClause: IT_NAMED SourceSelector {$$ = new Buf(2, $1, $2)}; SourceSelector: IRIref {$$ = new Buf($1->get_item()->name)}; WhereClause: _QWHERE_E_Opt { SELECT_LEX* sel = &yySparqlFrob->lex->select_lex; sel->parsing_place = 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= $3; SELECT_LEX* sel = &yySparqlFrob->lex->select_lex; BindingContext *bc= gc->get_binding_context(); Item *constraints= bc->make_item_constraints(); yySparqlFrob->add_root_constraints(bc-> get_bound_variable_constraints(constraints, gc)); Item *where = yySparqlFrob->get_root_constraints(); if (where) { where->top_level_item(); sel->where = where; String string; where->print(&string); $$ = new Buf(4, $1, $3->get_Buf(), new Buf("WHERE"), new Buf(string.c_ptr())); } else { $$ = new Buf(2, $1, $3->get_Buf()); } sel->parsing_place= NO_MATTER; }; _QWHERE_E_Opt: {$$ = new Buf()} | IT_WHERE {$$ = $1}; SolutionModifier: _QOrderClause_E_Opt _QLimitClause_E_Opt _QOffsetClause_E_Opt {$$ = new Buf(3, $1, $2, $3)}; _QOrderClause_E_Opt: {$$ = new Buf()} | OrderClause {$$ = $1}; _QLimitClause_E_Opt: {$$ = new Buf();} | LimitClause {$$ = $1}; _QOffsetClause_E_Opt: {$$ = new Buf()} | OffsetClause {$$ = $1}; OrderClause: IT_ORDER IT_BY _QOrderCondition_E_Plus {$$ = new Buf(3, $1, $2, $3)}; _QOrderCondition_E_Plus: OrderCondition {$$ = $1} | _QOrderCondition_E_Plus OrderCondition {$$ = new Buf(2, $1, $2)}; OrderCondition: _O_QASC_E__Or__QDESC_E____QBrackettedExpression_E__C {$$ = $1} | _O_QFunctionCall_E__Or__QVar_E__Or__QBrackettedExpression_E__C {$$ = new Buf("!!!")}; _O_QASC_E__Or__QDESC_E__C: IT_ASC {$$ =1} | IT_DESC {$$ =0}; _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); $$ = new Buf(2, new Buf((char*)($1 ? "ASK" : "DESC")), new Buf(string.c_ptr())); }; _O_QFunctionCall_E__Or__QVar_E__Or__QBrackettedExpression_E__C: FunctionCall {$$ = $1} | Var {$$ = $1->get_item()} | BrackettedExpression {$$ = $1}; LimitClause: IT_LIMIT INTEGER { SELECT_LEX *sel = &yySparqlFrob->lex->select_lex; sel->select_limit = new Item_uint($2.str, $2.length); sel->explicit_limit= 1; $$ = new Buf(2, $1, new Buf($2.str)); }; OffsetClause: IT_OFFSET INTEGER { SELECT_LEX *sel = &yySparqlFrob->lex->select_lex; sel->offset_limit = new Item_uint($2.str, $2.length); sel->explicit_limit= 1; $$ = new Buf(2, $1, new Buf($2.str)); }; GroupGraphPattern: GT_LCURLEY { GraphContext *gc = yySparqlFrob->was_next_GC(); yySparqlFrob->push_context(gc ? gc : new Union1GraphContext(yySparqlFrob->head_context(), yySparqlFrob)); } GraphPattern GT_RCURLEY { if (yySparqlFrob->get_distinct()) yySparqlFrob->lex->current_select->options|= SELECT_DISTINCT; $$= yySparqlFrob->pop_context(); $$->set_Buf(new Buf(3, $1, $3, $4)); $$->close(); }; GraphPattern: FilteredBasicGraphPattern _Q_O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C_E_Opt {$$ = new Buf(2, $1, $2)}; _QDOT_E_Opt: {$$ = new Buf()} | GT_DOT {$$ = $1}; _O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C: GraphPatternNotTriples _QDOT_E_Opt GraphPattern {$$ = new Buf(3, $1, $2, $3)}; _Q_O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C_E_Opt: {$$ = new Buf()} | _O_QGraphPatternNotTriples_E____QDOT_E_Opt___QGraphPattern_E__C {$$ = $1}; FilteredBasicGraphPattern: _QBlockOfTriples_E_Opt _Q_O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C_E_Opt {$$ = new Buf(2, $1, $2)}; _QBlockOfTriples_E_Opt: {$$ = new Buf()} | BlockOfTriples {$$ = $1}; _O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C: Constraint _QDOT_E_Opt FilteredBasicGraphPattern {$$ = new Buf(3, $1, $2, $3)}; _Q_O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C_E_Opt: {$$ = new Buf()} | _O_QConstraint_E____QDOT_E_Opt___QFilteredBasicGraphPattern_E__C {$$ = $1}; BlockOfTriples: TriplesSameSubject _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star {$$ = new Buf(2, $1, $2)}; _QTriplesSameSubject_E_Opt: {$$ = new Buf()} | TriplesSameSubject {$$ = $1}; _O_QDOT_E____QTriplesSameSubject_E_Opt_C: GT_DOT _QTriplesSameSubject_E_Opt {$$ = new Buf(2, $1, $2)}; _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star: {$$ = new Buf()} | _Q_O_QDOT_E____QTriplesSameSubject_E_Opt_C_E_Star _O_QDOT_E____QTriplesSameSubject_E_Opt_C {$$ = new Buf(2, $1, $2)}; GraphPatternNotTriples: OptionalGraphPattern {$$ = $1} | GroupOrUnionGraphPattern {$$ = $1} | GraphGraphPattern {$$ = $1}; OptionalGraphPattern: IT_OPTIONAL { yySparqlFrob->lex->select_lex.init_nested_join(yySparqlFrob->thd); yySparqlFrob->set_next_GC( new OptionalGraphContext(yySparqlFrob->head_context(), yySparqlFrob)); } GroupGraphPattern { GraphContext *gc= $3; SELECT_LEX* sel= &yySparqlFrob->lex->select_lex; BindingContext *bc= gc->get_binding_context(); Item *constraints= bc->make_item_constraints(); Item *constraint= bc->get_bound_variable_constraints(constraints, gc); yySparqlFrob->add_root_constraints(constraint); String string; if (constraint) constraint->print(&string); yySparqlFrob->lex->select_lex.end_nested_join(yySparqlFrob->thd); $$ = 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(), yySparqlFrob)); } GroupGraphPattern { $$ = new Buf(3, $1, $2, $4->get_Buf()); }; GroupOrUnionGraphPattern: GroupGraphPattern { cout << "look for UNIONs in \"" << yySparqlFrob->lex->ptr << "\"?" << endl; } _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star { $$= $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= 1; List_iterator item_list_it(*$3); GraphContext* gc= item_list_it++; while ((gc= item_list_it++)) { cout << i++ << ": " << (void*)gc << ": " << gc->get_Buf()->str() << endl; $$= 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(), yySparqlFrob)); //cout << " found UNION start \"" << yySparqlFrob->lex->ptr << "\"?" << endl; } GroupGraphPattern { $$ = (BindingGraphContext*)$3; //cout << " UNION end at \"" << yySparqlFrob->lex->ptr << "\"?" << endl; }; _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star: { $$= NULL; } | _Q_O_QUNION_E____QGroupGraphPattern_E__C_E_Star _O_QUNION_E____QGroupGraphPattern_E__C { //cout << " UNION found before \"" << yySparqlFrob->lex->ptr << "\"?" << endl; $$= $1 ? $1 : new List; $$->push_back($2); }; Constraint: IT_FILTER _O_QBrackettedExpression_E__Or__QBuiltInCall_E__Or__QFunctionCall_E__C { LEX *lex = yySparqlFrob->lex; SELECT_LEX* sel = &lex->select_lex; sel->expr_list.head()->push_back($2); String string; $2->print(&string); $$ = new Buf(string.c_ptr()); }; _O_QBrackettedExpression_E__Or__QBuiltInCall_E__Or__QFunctionCall_E__C: BrackettedExpression {$$ = $1} | BuiltInCall {$$ = $1} | FunctionCall {$$ = $1}; FunctionCall: IRIref ArgList {$$ = NULL; // new Item_func_call(yySparqlFrob->lex->current_context(), $1, $2); YYABORT /* !!! NI */}; ArgList: _O_QNIL_E__Or__QLPAREN_E____QExpression_E____QCOMMA_E____QExpression_E_Star___QRPAREN_E__C {$$ = $1}; _O_QCOMMA_E____QExpression_E__C: GT_COMMA Expression {$$ = $2}; _Q_O_QCOMMA_E____QExpression_E__C_E_Star: {} | _Q_O_QCOMMA_E____QExpression_E__C_E_Star _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_Star___QRPAREN_E__C: NIL {$$ = 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 { $$ = yySparqlFrob->lex->select_lex.expr_list.pop(); $$->push_front($3); }; ConstructTemplate: GT_LCURLEY ConstructTriples GT_RCURLEY {$$ = new Buf(3, $1, $2, $3)}; ConstructTriples: _Q_O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C_E_Opt {$$ = $1}; _O_QDOT_E____QConstructTriples_E__C: GT_DOT ConstructTriples {$$ = new Buf(2, $1, $2)}; _Q_O_QDOT_E____QConstructTriples_E__C_E_Opt: {$$ = new Buf()} | _O_QDOT_E____QConstructTriples_E__C {$$ = $1}; _O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C: TriplesSameSubject _Q_O_QDOT_E____QConstructTriples_E__C_E_Opt {$$ = new Buf(2, $1, $2)}; _Q_O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C_E_Opt: {$$ = new Buf()} | _O_QTriplesSameSubject_E____QDOT_E____QConstructTriples_E_Opt_C {$$ = $1}; TriplesSameSubject: VarOrTerm { yySparqlFrob->push_subject($1); } PropertyListNotEmpty { yySparqlFrob->pop_subject(); $$ = new Buf(2, new Buf($1->get_item()->name), $3); } | TriplesNode { yySparqlFrob->push_subject($1); } PropertyList { yySparqlFrob->pop_subject(); $$ = new Buf(2, new Buf($1->get_item()->name), $3); }; PropertyList: _QPropertyListNotEmpty_E_Opt {$$ = $1}; _QPropertyListNotEmpty_E_Opt: {$$ = new Buf()} | PropertyListNotEmpty {$$ = $1}; PropertyListNotEmpty: Verb { yySparqlFrob->push_predicate($1); } ObjectList _Q_O_QSEMI_E____QPropertyList_E__C_E_Opt { yySparqlFrob->pop_predicate(); $$ = new Buf(3, new Buf($1->get_item()->name), $3, $4); }; _O_QSEMI_E____QPropertyList_E__C: GT_SEMI PropertyList {$$ = new Buf(2, $1, $2)}; _Q_O_QSEMI_E____QPropertyList_E__C_E_Opt: {$$ = new Buf()} | _O_QSEMI_E____QPropertyList_E__C {$$ = $1}; ObjectList: GraphNode { if (yySparqlFrob->object($1)) YYABORT; } _Q_O_QCOMMA_E____QObjectList_E__C_E_Opt {$$ = new Buf(2, new Buf($1->get_item()->name), $3)}; _O_QCOMMA_E____QObjectList_E__C: GT_COMMA ObjectList {$$ = new Buf(2, $1, $2)}; _Q_O_QCOMMA_E____QObjectList_E__C_E_Opt: {$$ = new Buf()} | _O_QCOMMA_E____QObjectList_E__C {$$ = $1}; Verb: VarOrIRIref {$$ = $1} | IT_a {$$ = $1}; TriplesNode: Collection {$$ = $1} | BlankNodePropertyList {$$ = $1}; BlankNodePropertyList: GT_LBRACKET { yySparqlFrob->push_subject(yySparqlFrob->make_blank_node()); } PropertyListNotEmpty GT_RBRACKET { //Buf* t = new Buf(3, $1, $3, $4); $$ = 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 = new Buf(3, $1, $3, $4); $$ = yySparqlFrob->pop_subject(); }; _QGraphNode_E_Plus: GraphNode { if (yySparqlFrob->add_listElement($1)) YYABORT; } | _QGraphNode_E_Plus GraphNode { if (yySparqlFrob->add_listElement($2)) YYABORT; $$ = new Buf(2, $1, new Buf($2->get_item()->name)); }; GraphNode: VarOrTerm {$$ = $1} | TriplesNode {$$ = $1}; VarOrTerm: Var {$$ = $1} | GraphTerm {$$ = $1}; VarOrIRIref: Var {$$ = $1} | IRIref {$$ = $1}; VarOrBlankNodeOrIRIref: Var {$$ = new Buf($1->get_item()->name)} | BlankNode {$$ = new Buf($1->get_item()->name)} | IRIref {$$ = new Buf($1->get_item()->name)}; Var: VAR1 { $$ = yySparqlFrob->ensure_variable($1.str); } | VAR2 { $$ = yySparqlFrob->ensure_variable($1.str); }; GraphTerm: IRIref {$$ = $1} | RDFLiteral {$$ = $1} | _Q_O_QMINUS_E__Or__QPLUS_E__C_E_Opt NumericLiteral {$$ = $2 /* !!! */} | BooleanLiteral {$$ = $1} | BlankNode {$$ = $1} | NIL {$$ = $1}; _O_QMINUS_E__Or__QPLUS_E__C: GT_MINUS {$$ = $1} | GT_PLUS {$$ = $1}; _Q_O_QMINUS_E__Or__QPLUS_E__C_E_Opt: {$$ = new Buf()} | _O_QMINUS_E__Or__QPLUS_E__C {$$ = $1}; Expression: ConditionalOrExpression {$$ = $1} ConditionalOrExpression: ConditionalAndExpression { yySparqlFrob->lex->select_lex.expr_list.push_front(new List); } _Q_O_QOR_E____QConditionalAndExpression_E__C_E_Star { List *list= yySparqlFrob->lex->select_lex.expr_list.pop(); if (list->elements) { list->push_front($1); $$= new Item_cond_or(*list); } else $$= $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 _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= yySparqlFrob->lex->select_lex.expr_list.pop(); if (list->elements) { list->push_front($1); $$= new Item_cond_and(*list); } else $$= $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 _O_QAND_E____QValueLogical_E__C {}; ValueLogical: RelationalExpression {$$ = $1}; RelationalExpression: NumericExpression { // Stick " = 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____QNumericExpression_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= yySparqlFrob->lex->select_lex.expr_list.pop(); if (list->elements) { chooser_compare_func_creator op = (chooser_compare_func_creator)list->pop(); Item* value = list->pop(); // chooser_compare_func_creator eq = &comp_eq_creator; // Item* test = eq(0)->create($1, value); $$= op(0)->create($1, value); } else $$= $1; delete list; }; _O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C: GT_EQUAL NumericExpression { 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 { 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 { 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 { 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 { 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 { 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____QNumericExpression_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C_E_Opt: {} | _O_QEQUAL_E____QNumericExpression_E__Or__QNEQUAL_E____QNumericExpression_E__Or__QLT_E____QNumericExpression_E__Or__QGT_E____QNumericExpression_E__Or__QLE_E____QNumericExpression_E__Or__QGE_E____QNumericExpression_E__C {}; NumericExpression: AdditiveExpression {$$ = $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____QMultiplicativeExpression_E__C_E_Star { List *list= yySparqlFrob->lex->select_lex.expr_list.pop(); if (list->elements) { // chooser_compare_func_creator *op = (chooser_compare_func_creator*)list->pop(); char *op = (char*)list->pop(); Item* value = list->pop(); if (op[0] == '+') { $$= new Item_func_plus($1, value); } else { $$= new Item_func_minus($1, value); } // $$= (*op)(0)->create($1, value); } else $$= $1; delete list; }; _O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicativeExpression_E__C: GT_PLUS MultiplicativeExpression { // yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_plus_creator); yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)"+"); yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); } | GT_MINUS MultiplicativeExpression { // yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_minus_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____QMultiplicativeExpression_E__C_E_Star: {} | _Q_O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicativeExpression_E__C_E_Star _O_QPLUS_E____QMultiplicativeExpression_E__Or__QMINUS_E____QMultiplicativeExpression_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= yySparqlFrob->lex->select_lex.expr_list.pop(); if (list->elements) { // chooser_compare_func_creator *op = (chooser_compare_func_creator*)list->pop(); char *op = (char*)list->pop(); Item* value = list->pop(); if (op[0] == '*') { $$= new Item_func_mul($1, value); } else { $$= new Item_func_div($1, value); } // $$= (*op)(0)->create($1, value); } else $$= $1; delete list; }; _O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__C: GT_TIMES UnaryExpression { // yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_times_creator); yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)"*"); yySparqlFrob->lex->select_lex.expr_list.head()->push_back($2); } | GT_DIVIDE UnaryExpression { // yySparqlFrob->lex->select_lex.expr_list.head()->push_back((Item*)&comp_divide_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: {} | _Q_O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__C_E_Star _O_QTIMES_E____QUnaryExpression_E__Or__QDIVIDE_E____QUnaryExpression_E__C {}; UnaryExpression: GT_NOT PrimaryExpression { new Item_func_not($2); } | GT_PLUS PrimaryExpression {$$ = $2} | GT_MINUS PrimaryExpression { new Item_func_neg($2); } | PrimaryExpression {$$ = $1}; PrimaryExpression: BrackettedExpression {$$ = $1} | BuiltInCall {$$ = $1} | IRIrefOrFunction {$$ = $1} | RDFLiteral {$$ = $1->get_item()} | NumericLiteral {$$ = $1->get_item()} | BooleanLiteral {$$ = $1->get_item()} | BlankNode {$$ = $1->get_item()} | Var {$$ = $1->get_item()}; BrackettedExpression: GT_LPAREN Expression GT_RPAREN {$$ = $2}; BuiltInCall: IT_STR GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_LANG GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_LANGMATCHES GT_LPAREN Expression GT_COMMA Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_DATATYPE GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_BOUND GT_LPAREN Var GT_RPAREN {$$ = new Item_func_isnotnull($3->get_item());} | IT_isIRI GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_isURI GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_isBLANK GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | IT_isLITERAL GT_LPAREN Expression GT_RPAREN {$$ = $3; YYABORT /* !!! NI */} | RegexExpression {$$ = $1}; RegexExpression: IT_REGEX GT_LPAREN Expression GT_COMMA Expression _Q_O_QCOMMA_E____QExpression_E__C_E_Opt GT_RPAREN {$$ = $3; YYABORT /* !!! NI */}; _Q_O_QCOMMA_E____QExpression_E__C_E_Opt: {$$ = NULL} | _O_QCOMMA_E____QExpression_E__C {$$ = $1}; IRIrefOrFunction: IRIref _QArgList_E_Opt {$$ = NULL; // new Item_func_call(yySparqlFrob->lex->current_context(), $1, $2); YYABORT /* !!! NI */}; _QArgList_E_Opt: {$$ = NULL} | ArgList {$$ = $1}; RDFLiteral: String _Q_O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C_E_Opt {$$ = yySparqlFrob->ensure_string($1, $2) /* !!! */}; _O_QDTYPE_E____QIRIref_E__C: GT_DTYPE IRIref {$$ = $2}; _O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C: LANGTAG {$$ = $1} | _O_QDTYPE_E____QIRIref_E__C {$$ = $1}; _Q_O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C_E_Opt: {$$ = NULL} | _O_QLANGTAG_E__Or__QDTYPE_E____QIRIref_E__C {$$ = $1}; NumericLiteral: INTEGER {$$ = yySparqlFrob->ensure_int($1, NULL) /* !!! */} | DECIMAL {$$ = yySparqlFrob->ensure_decimal($1, NULL) /* !!! */} | DOUBLE {$$ = yySparqlFrob->ensure_float($1, NULL) /* !!! */}; BooleanLiteral: IT_true {$$ = $1} | IT_false {$$ = $1}; String: STRING_LITERAL1 {$$ = $1} | STRING_LITERAL2 {$$ = $1} | STRING_LITERAL_LONG1 {$$ = $1} | STRING_LITERAL_LONG2 {$$ = $1}; IRIref: Q_IRI_REF {$$ = yySparqlFrob->ensure_URI($1)} | QName {$$ = $1}; QName: QNAME {$$ = yySparqlFrob->ensure_URI($1)} | QNAME_NS {$$ = yySparqlFrob->ensure_URI($1)}; BlankNode: BLANK_NODE_LABEL {$$ = yySparqlFrob->ensure_blank_node($1.str)} | ANON {$$ = yySparqlFrob->make_blank_node()}; %% #define YY_DECL int yyFlexLexer::yylex(YY_sparqlParser_STYPE *val, void *yythd) //int yylex(void *yylval, void *yythd); const LEX_STRING null_lex_str={0,0}; // -------------------------------------- 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 = thd; }; }; int sparqlParserPackage::sparqllex() { return theScanner.yylex(&yylval); } void sparqlParserPackage::yyerror(char *s) { char *yytext= theScanner.get_last_word(); my_printf_error(ER_PARSE_ERROR, ER(ER_PARSE_ERROR), MYF(0), s, (yytext ? (char*) yytext : ""), thd->lex->yylineno); } // Move this class definition into sparqlFrob.h and uncomment the #include // below. See http://www.w3.org/1999/02/26-modules/User/Yacker#encap for more // details. sparqlFrob::sparqlFrob(THD *thd, char** ptr) { // stringstream* ss = new stringstream(buf, stringstream::in); this->thd= thd; lex= thd ? thd->lex : NULL; distinct= false; sparqlParserPackage* aCompiler= new sparqlParserPackage(thd, ptr); parser= aCompiler; next_union_alias_index= 0; } sparqlFrob::~sparqlFrob() { } int sparqlFrob::parse() { sparqlParserPackage* aCompiler = (sparqlParserPackage*) parser; return aCompiler->yyparse(this); } const char* sparqlFrob::get_primary_key(const char *table_name) { TABLE_LIST *entry = thd->main_lex.select_lex.context.table_list; while (entry) { if (!strcmp(table_name, entry->table_name)) { KEY *key= entry->table->key_info; /* Search table structure for PRIMARY KEY. Taken from sql_show.cc::2905 get_schema_stat_record */ for (unsigned i= 0; i < entry->table->s->keys; i++) { if (!strcmp(key[i].name, "PRIMARY")) { const char *ret = key[i].key_part->field->field_name; if (key[i].key_parts != 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 = entry->table->s->fieldnames.type_names[0]; cout << "SPARQL: could not find " << table_name << ". -- trying " << ret << endl; return ret; } entry= entry->next_global; } my_printf_error(1, "SPARQL: could not find table entry for %s. "PLS_REPORT, MYF(0), table_name); return NULL; } LEX_STRING* sparqlFrob::next_union_alias () { char space[3]; space[0]= 'U'; space[1]= '0'+next_union_alias_index++; space[2]= 0; LEX_STRING *alias = new LEX_STRING; alias->str= thd->strmake(space, 3); alias->length = 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 = 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 = 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 = item_list_it++)) { if (!strcmp(ret->name, label)) { return ret; } // if (curr_item->eq(this, 1)) // DBUG_RETURN(FALSE); /* Already in the set. */ } ret = new Item_blank_node(lex->current_context(), label, this); blank_nodes.push_back(ret); return ret; } bool Item_primary_key_field::fix_fields(THD *thd, Item **reference) { field_name = frob->get_primary_key(real_table_name); return Item_field::fix_fields(thd, reference); } Item_POS_string* sparqlFrob::ensure_string (LEX_STRING str, Item_POS *lang_or_datatype) { Item_POS_string* ret; List_iterator item_list_it(strings); while ((ret = item_list_it++)) if (!strncmp(ret->name, str.str, str.length) && ret->get_language_or_datatype() == lang_or_datatype) // !!! check len or "foo1"="foo" return ret; ret = new Item_POS_string(str, lang_or_datatype, thd->charset()); strings.push_back(ret); return ret; } Item_POS_int* sparqlFrob::ensure_int (LEX_STRING str, Item_POS *lang_or_datatype) { Item_POS_int* ret; List_iterator item_list_it(ints); while ((ret = item_list_it++)) if (!strncmp(ret->name, str.str, str.length)) // !!! check len or "foo1"="foo" return ret; ret = new Item_POS_int(str, lang_or_datatype, thd->charset()); ints.push_back(ret); return ret; } Item_POS_decimal* sparqlFrob::ensure_decimal (LEX_STRING str, Item_POS *lang_or_datatype) { Item_POS_decimal* ret; List_iterator item_list_it(decimals); while ((ret = item_list_it++)) if (!strncmp(ret->name, str.str, str.length)) // !!! check len or "foo1"="foo" return ret; ret = new Item_POS_decimal(str, lang_or_datatype, thd->charset()); decimals.push_back(ret); return ret; } Item_POS_float* sparqlFrob::ensure_float (LEX_STRING str, Item_POS *lang_or_datatype) { Item_POS_float* ret; List_iterator item_list_it(floats); while ((ret = item_list_it++)) if (!strncmp(ret->name, str.str, str.length)) // !!! check len or "foo1"="foo" return ret; ret = new Item_POS_float(str, lang_or_datatype, thd->charset()); floats.push_back(ret); return ret; } void sparqlFrob::select_variables () { SELECT_LEX *sel= lex->current_select; sel->parsing_place= SELECT_LIST; BindingContext *bc = last_context()->get_binding_context(); // If nothing was selected, we know there was a "SELECT *". bool select_star= !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= list_it++)) { // Assemble a list of selected variables. List selected_vars; // List of BindingGraphContexts that need newly added vars (starts with ()). List passed_gcs; // For each BindingGraphContext... List_iterator gc_it(*list); BindingGraphContext *gc; while ((gc= gc_it++)) { // Walk variables bound in this context. List *known_vars= gc->get_binding_context()->get_item_variables(); List_iterator known_vars_it(*known_vars); Item_variable *known_var; while ((known_var= 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= false; // C doesn't have a labeled continue. List_iterator selected_vars_it(selected_vars); Item_variable *selected_var; while ((selected_var= selected_vars_it++)) if (selected_var->same_variable(known_var->name)) { stupid_continue_flag= 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= passed_gcs_it++)) passed_gc->select_var(known_var, false);// also sets binding in parent. // ...and future gcs. List_iterator future_gcs_it= gc_it; // @@@ ca marche? BindingGraphContext *future_gc; while ((future_gc= future_gcs_it++)) { bool exists= Item_variable::match_var_in_list(future_gc->get_binding_context()->get_item_variables(), known_var->name) != NULL; future_gc->select_var(known_var, exists); } selected_vars.push_front(known_var); // It's selected now. } passed_gcs.push_front(gc); } } if (select_star) // Select known vars and update reference counts. bc->select_star(thd); sel->parsing_place= 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(); } 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 *start, const char *end, const char look_for) { const char *ptr = end; lex_string->length = 0; for (; ; ) { if (ptr == start) { if (look_for) { // we didn't find it ptr = NULL; lex_string->length = 0; return NULL; } else { lex_string->str = thd->strmake(ptr, lex_string->length); return ptr; } } if (*ptr == look_for) { --lex_string->length; lex_string->str = thd->strmake(ptr+1, lex_string->length); return ptr; } --ptr; ++lex_string->length; } } bool sparqlFrob::object (Item_POS *object) { Item_POS* subject = subjects.head(); if (!predicates.head()->is_URI()) return Item_error("predicate must be a URI, not \"%s\"", predicates.head()->get_item()); Item_URI* predicate = (Item_URI*)predicates.head(); BindingContext *bc= head_context()->get_binding_context(); Alias_info *ai= bc->get_table_alias(thd, subject, predicate, object); const char *ptr = head_context()->get_alias_string(ai, subject, thd); if (!ptr) return true; object->bind_field(predicate->get_table().str, ptr, 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\"", item->get_item()); } Alias_info* BindingContext::get_table_alias (THD *thd, Item_POS *s, Item_URI *p, Item_POS *o) { LEX_STRING table = p->get_table(); Alias_info *ai = NULL; List_iterator item_list_it(aliases); Alias_info *t; while ((t = item_list_it++)) { if (t->same_table(table)) { ai = t; break; } } if (!ai) { ai = new Alias_info(table); aliases.push_front(ai); } return ai; } /* ref_count -- 0: child context looking for the variable in a parent context. 1: normal use */ Item_variable* BindingContext::ensure_bound_item_variable (const char *var, sparqlFrob *sparql_frob, int ref_count) { List_iterator item_list_it(item_variables); Item_variable* ret; while ((ret= item_list_it++)) if (ret->same_variable(var)) { ret->add_ref_count(ref_count); return ret; } Item_variable *outer= parent ? parent->ensure_bound_item_variable(var, sparql_frob, 0) : NULL; ret= new Item_variable(name_res_context, var, outer, sparql_frob, ref_count); item_variables.push_back(ret); return ret; } Item* BindingContext::get_bound_variable_constraints (Item *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 = 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 = nulls.elements ? new Item_cond_and(nulls) : NULL; Item *notNulls_cond = notNulls.elements ? new Item_cond_and(notNulls) : NULL; if (nulls_cond && notNulls_cond) { List *or_cond = 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 notNulls. return notNulls_cond; } void Item_URI::bind_field (const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) { LEX *lex= thd->lex; SELECT_LEX *sel= lex->current_select; chooser_compare_func_creator eq = &comp_eq_creator; LEX_STRING value = get_value(); cout << "WHERE " << alias << "." << get_field().str << "=" << value.str << endl; Item* idI = new Item_field(lex->current_context(), NullS, alias, get_field().str); int error; Item* val = new Item_int(value.str, (longlong) my_strtoll10(value.str, NULL, &error), value.length); Item* test = eq(0)->create(idI, val); sel->expr_list.head()->push_back(test); test->top_level_item(); if (jt) { SELECT_LEX *sel= lex->current_select; sel->add_joined_table(jt); } } void Item_URI::print(String *str) { str->append('<'); str->append(name); str->append('>'); } Item* Item_variable::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) { return field_name_arg ? new Item_field(context_arg, db_arg, table_name_arg, field_name_arg) : new Item_primary_key_field(context_arg, db_arg, table_name_arg, frob, real_table_name); } void Item_variable::bind_field(const char *table_name_arg, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt_param) { LEX *lex= thd->lex; if (jt_param && (!jt || trump)) { // assert(!jt); jt = jt_param; SELECT_LEX *sel= lex->current_select; sel->add_joined_table(jt); } if (jt && bound) { cout << " ON " << table_name << "." << (primary_key ? "" : field_name) << " = " << alias << "." << (field_name_arg ? field_name_arg : "") << endl; // !!! Item* l = make_Item_field(lex->current_context(), NullS, table_name, primary_key ? NULL : field_name, real_table_name); Item* r = make_Item_field(lex->current_context(), NullS, alias, field_name_arg, table_name_arg); chooser_compare_func_creator eq = &comp_eq_creator; Item* on = eq(0)->create(l, r); add_join_on(jt, on); } if (!bound || trump) { cout << " " << alias << "." << (field_name_arg ? field_name_arg : "") << " AS \"" << name << "\"" << endl; table_name = (char*) alias; if (field_name_arg) { field_name = (char*) field_name_arg; primary_key = false; } else { primary_key = true; real_table_name = table_name_arg; } bound = true; // name = (char*) field_name; } } bool Item_variable::fix_fields(THD *thd, Item **reference) { if (primary_key) if (!(field_name = get_primary_key())) return true; // signal an error return Item_field::fix_fields(thd, reference); } void Item_variable::print(String *str) { Item::print(str); str->append("{?"); str->append(name); str->append('}'); } Item_variable* Item_variable::match_var_in_list (List *p_item_variables, const char *var) { List_iterator item_list_it(*p_item_variables); Item_variable* ret; while ((ret= item_list_it++)) if (ret->same_variable(var)) { return ret; } return NULL; } void Item_blank_node::print(String *str) { Item::print(str); str->append("[_:"); str->append(name); str->append(']'); } void Item_POS_string::bind_field (const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) { cout << "WHERE " << alias << "." << field_name_arg << "=\"" << name << "\"" << endl; LEX *lex= thd->lex; Item* idI = new Item_field(lex->current_context(), NullS, alias, field_name_arg); chooser_compare_func_creator eq = &comp_eq_creator; Item* test = eq(0)->create(idI, get_item()); SELECT_LEX *sel= lex->current_select; sel->expr_list.head()->push_back(test); test->top_level_item(); if (jt) { sel->add_joined_table(jt); } } void Item_POS_string::print(String *str) { str->append('\''); str->append(name); str->append('\''); } void Item_POS_int::bind_field (const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) { cout << "WHERE " << alias << "." << field_name_arg << "=\"" << name << "\"" << endl; LEX *lex= thd->lex; Item* idI = new Item_field(lex->current_context(), NullS, alias, field_name_arg); chooser_compare_func_creator eq = &comp_eq_creator; Item* test = eq(0)->create(idI, get_item()); SELECT_LEX *sel= lex->current_select; sel->expr_list.head()->push_back(test); test->top_level_item(); if (jt) { sel->add_joined_table(jt); } } void Item_POS_int::print(String *str) { str->append(name); } void Item_POS_decimal::bind_field (const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) { cout << "WHERE " << alias << "." << field_name_arg << "=\"" << name << "\"" << endl; LEX *lex= thd->lex; Item* idI = new Item_field(lex->current_context(), NullS, alias, field_name_arg); chooser_compare_func_creator eq = &comp_eq_creator; Item* test = eq(0)->create(idI, get_item()); SELECT_LEX *sel= lex->current_select; sel->expr_list.head()->push_back(test); test->top_level_item(); if (jt) { sel->add_joined_table(jt); } } void Item_POS_decimal::print(String *str) { str->append(name); } void Item_POS_float::bind_field (const char *table_name, const char *alias, const char *field_name_arg, bool trump, THD *thd, TABLE_LIST *jt) { cout << "WHERE " << alias << "." << field_name_arg << "=\"" << name << "\"" << endl; LEX *lex= thd->lex; Item* idI = new Item_field(lex->current_context(), NullS, alias, field_name_arg); chooser_compare_func_creator eq = &comp_eq_creator; Item* test = eq(0)->create(idI, get_item()); SELECT_LEX *sel= lex->current_select; sel->expr_list.head()->push_back(test); test->top_level_item(); if (jt) { sel->add_joined_table(jt); } } void Item_POS_float::print(String *str) { str->append(name); } const char* GraphContext::get_alias_string (Alias_info *ai, Item_POS *s, THD *thd) { List_iterator item_list_it(ai->subjects); Item_POS *t; size_t i= 0; bool found= false; while ((t= item_list_it++)) { if (t == s) { found= true; break; } ++i; } char space[ai->table.length+1+1+1]; strncpy(space, ai->table.str, ai->table.length); space[ai->table.length]= '_'; space[ai->table.length+1]= '0'+i; space[ai->table.length+2]= 0; const char *ret= thd->strmake(space, ai->table.length+1+1+1); if (!found) { ai->subjects.push_front(s); Table_ident* table_i= new Table_ident(ai->table); LEX *lex= thd->lex; SELECT_LEX* sel= lex->current_select; // &lex->select_lex; LEX_STRING *alias= new LEX_STRING; alias->str= (char*)ret; alias->length= ai->table.length+2; cout << "FROM " << ai->table.str << " AS " << alias->str << endl; TABLE_LIST *jt= sel->add_table_to_list(lex->thd, table_i, alias, sel->get_table_join_options(), lex->lock_option, sel->get_use_index(), sel->get_ignore_index()); if (!jt) return NULL; if (is_optional()) jt->outer_join|=JOIN_TYPE_LEFT; if (s->is_URI()) { Item_URI *sURI= (Item_URI*)s; chooser_compare_func_creator eq= &comp_eq_creator; LEX_STRING value= sURI->get_value(); cout << "WHERE " << alias->str << "." << sURI->get_field().str << "=" << value.str << endl; Item* idI= new Item_field(lex->current_context(), NullS, alias->str, sURI->get_field().str); int error; Item* val= new Item_int(value.str, (longlong) my_strtoll10(value.str, NULL, &error), value.length); Item* test= 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; } void BindingGraphContext::select_var (Item_variable *var, bool exists) { cout << (void*)this << " SELECTs " << (exists ? "" : "NULL AS ") << var->name << endl; current_select->add_item_to_list(thd, exists ? var->get_item() : var->get_null_item()); } Item_URI *XSD_integer= NULL; Item_URI *XSD_float= NULL; Item_URI *XSD_decimal= NULL; String Global_string; // $Log: sparqlParser.y,v $ // 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 another // - YYTHD macros // // Revision 1.29 2006/04/29 16:53:27 eric // ~ simplified get_primary_key (complicated by previous extension tables commit) // // Revision 1.28 2006/04/29 16:45:03 eric // + extension tables (tables with the same primary key as another -- both 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 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 => YYABORT // // Revision 1.14 2006/04/11 11:46:45 eric // added CVS tags // //