From: Date: April 15 2006 6:03pm Subject: Re: getting table meta data (primary key, in this case) List-Archive: http://lists.mysql.com/internals/33517 Message-Id: <20060415160310.GF6355@w3.org> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="V4b9U9vrdWczvw78" --V4b9U9vrdWczvw78 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Apr 10, 2006 at 12:17:54PM +0200, Sergei Golubchik wrote: > Hi! >=20 > On Apr 06, Eric Prud'hommeaux wrote: > > On Thu, Apr 06, 2006 at 10:24:32AM +0200, Sergei Golubchik wrote: > > > Hi! > > >=20 > > > 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: > > > > >=20 > > > > > 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=3D( > > > > > SELECT Column_name SHOW INDEXES FROM Orders WHERE Key_name=3D= 'PRIMARY') > > > > > I don't know if SQL limits itself to relational calculus, so perh= aps > > > > > there is some magic to do this. > > >=20 > > > Not really :( > > > Not with one SQL query, at least. > > > But unless you limit yourself to rewriting-into-SQL approach, you sho= uld > > > not really care what SQL limits are. > >=20 > > 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 =3D new Item_field(lex->current_context(), NullS, > > this_alias, primary_key_name); > > Item* r =3D new Item_field(lex->current_context(), NullS, > > linked_alias, linked_foreign_key_name); > > chooser_compare_func_creator eq =3D &comp_eq_creator; > > Item* on =3D 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. >=20 > It's possible. >=20 > First - one can write SELECT * FROM t1, t2, ... > and * will be expanded to a full list of fields after all tables are > opened. >=20 > 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: >=20 > SELECT f1, t1.f2, db1.t2.f3 FROM t1, db1.t2, t3; >=20 > 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 =3D get_primary_key(); return Item_field::fix_fields(thd, reference); } const char* sparqlFrob::get_primary_key(const char *table_name) { TABLE_LIST *entry =3D thd->main_lex.select_lex.context.table_list; while (entry) { if (!strcmp(table_name, entry->table_name)) { KEY *key =3D entry->table->key_info; for (unsigned i =3D 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 =3D=3D 1); return key[i].key_part->field->field_name; } } assert(0); // couldn't find PRIMARY KEY } entry =3D 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. --=20 -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. --V4b9U9vrdWczvw78 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iQEVAwUBREEZPpZX2p1ccTnpAQJMnAgAge/Ss0ElNulPDaQV7as5vxfzUBPrFV/l 5L7q4MAAlGxhwR/Ji/DtDXr2+q37HWNx30fxJU5ENrkS/NeYzEN3aGsXmJestNXK XZxaajSVvwGQtl6Fj5jhO5hNgWtblnfB7LLi5RkXl59IMz4co17rAdI57R/26QQ3 2hVP8/d9qRfD6izc7PoXJqJ+jxk2FezFXIL39kj3uapbiibTz1MVcaFxx5A4m+Yo TqBE3+baZaNNT5vvpZTt0c1/rrxdz/G2cflK40/gtfuugtbwihPQ9l6UrnfI/1Np lSLviDlUSEpGrsKz2J1KQ+kp5O79zbl3MQ0VTGR8Q00OfXK9OhBd/A== =rP6N -----END PGP SIGNATURE----- --V4b9U9vrdWczvw78--