List:Internals« Previous MessageNext Message »
From:Eric Prud'hommeaux Date:April 15 2006 4:03pm
Subject:Re: getting table meta data (primary key, in this case)
View as plain text  
On Mon, Apr 10, 2006 at 12:17:54PM +0200, Sergei Golubchik wrote:
> Hi!
> 
> On Apr 06, Eric Prud'hommeaux wrote:
> > On Thu, Apr 06, 2006 at 10:24:32AM +0200, Sergei Golubchik wrote:
> > > Hi!
> > > 
> > > On Apr 05, Eric Prud'hommeaux wrote:
> > > > On Mon, Apr 03, 2006 at 02:53:08AM -0400, Eric Prud'hommeaux wrote:
> > > > > On Mon, Apr 03, 2006 at 12:41:30AM -0400, SGreen@stripped
> wrote:
> > > > > 
> > > > > The problem is that I can't express higher-order-logic (symbols
> as
> > > > > values) in relational calculus. That is, I can't express like
> > > > > (inventing a $var notation here):
> > > > >   SELECT Orders.$field FROM Orders WHERE $field=(
> > > > >     SELECT Column_name SHOW INDEXES FROM Orders WHERE
> Key_name='PRIMARY')
> > > > > I don't know if SQL limits itself to relational calculus, so
> perhaps
> > > > > there is some magic to do this.
> > > 
> > > Not really :(
> > > Not with one SQL query, at least.
> > > But unless you limit yourself to rewriting-into-SQL approach, you should
> > > not really care what SQL limits are.
> > 
> > true. this approach (finding the key and joining on that field) is
> > limited only by the expressivity of the MySQL query structure.
> > However, as far as I can see, I'd need to do something like:
> >       Item* l = new Item_field(lex->current_context(), NullS,
> >                                this_alias, primary_key_name);
> >       Item* r = new Item_field(lex->current_context(), NullS,
> >                                linked_alias, linked_foreign_key_name);
> >       chooser_compare_func_creator eq = &comp_eq_creator;
> >       Item* on = eq(0)->create(l, r);
> >       add_join_on(table_list, on);
> >
> > and late bind primary_key_name. I don't think that's possible, at
> > least with an Item_field. I'd make a Item_field_late_binding and add a
> > schema table to the mix, but I can't see how I'd get select to call
> > some bind method on it while executing.
> 
> It's possible.
> 
> First - one can write SELECT * FROM t1, t2, ...
> and * will be expanded to a full list of fields after all tables are
> opened.
> 
> Then - in fact all Item_field's always use this "late binding".
> Before Item_field::fix_fields(), Item_field only knows its name,
> sometimes database name and table name, but not always. And nothing
> else. That's all that the parser can tell about the field.
> For example:
> 
>   SELECT f1, t1.f2, db1.t2.f3 FROM t1, db1.t2, t3;
> 
> and only after all tables are opened, MySQL calls
> Item_field::fix_fields() for all Item_field's, and it's the method where
> "binding" happens - a field finds what table and database it belongs to,
> finds all metadata about itself, data type, constrains, indexes, and so
> on.

worky (and quite easily)!!! Thank you SO much for the pointer!

[[
bool Item_variable::fix_fields(THD *thd, Item **reference) {
  if (primary_key)
    field_name = get_primary_key();
  return Item_field::fix_fields(thd, reference);
}

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;
      for (unsigned i = 0; i < entry->table->s->keys; i++) { // from
sql_show.cc::2905 get_schema_stat_record
	if (!strcmp(key[i].name, "PRIMARY")) {
	  assert(key[i].key_parts == 1);
	  return key[i].key_part->field->field_name;
	}
      }
      assert(0); // couldn't find PRIMARY KEY
    }
    entry = entry->next_global;
  }
  assert(0); // couldn't find table
}
]]
It brings up 2 questions:

  Is there a way to kill a thread ('cause something went horribly
  wrong), without killing the whole server? What's the polite way to
  assert(0)?

  Is there a better way to find the table_list for a thread? I feel
  like thd->main_lex.select_lex.context.table_list should really
  include some inode numbers, the process id and maybe some astrology.
-- 
-eric

office: +81.466.49.1170 W3C, Keio Research Institute at SFC,
                        Shonan Fujisawa Campus, Keio University,
                        5322 Endo, Fujisawa, Kanagawa 252-8520
                        JAPAN
        +1.617.258.5741 NE43-344, MIT, Cambridge, MA 02144 USA
cell:   +81.90.6533.3882

(eric@stripped)
Feel free to forward this message to any list for any purpose other than
email address distribution.

Attachment: [application/pgp-signature] Digital signature signature.asc
Thread
getting table meta data (primary key, in this case)Eric Prud'hommeaux1 Apr
  • Re: getting table meta data (primary key, in this case)SGreen3 Apr
    • Re: getting table meta data (primary key, in this case)Eric Prud'hommeaux3 Apr
      • Re: getting table meta data (primary key, in this case)Eric Prud'hommeaux5 Apr
        • RE: getting table meta data (primary key, in this case)Rick James5 Apr
          • RE: getting table meta data (primary key, in this case)Stewart Smith6 Apr
          • RE: getting table meta data (primary key, in this case)Stewart Smith6 Apr
        • Re: getting table meta data (primary key, in this case)Sergei Golubchik6 Apr
          • Re: getting table meta data (primary key, in this case)Eric Prud'hommeaux6 Apr
            • Re: getting table meta data (primary key, in this case)Sergei Golubchik10 Apr
              • Re: getting table meta data (primary key, in this case)Eric Prud'hommeaux15 Apr
                • Re: getting table meta data (primary key, in this case)Sergei Golubchik18 Apr
                • Re: getting table meta data (primary key, in this case)Sanja Byelkin18 Apr
  • Re: getting table meta data (primary key, in this case)Sergei Golubchik3 Apr
Re: getting table meta data (primary key, in this case)Sergei Golubchik10 Apr
  • Re: getting table meta data (primary key, in this case)Eric Prud'hommeaux10 Apr
    • Re: getting table meta data (primary key, in this case)Eric Prud'hommeaux11 Apr