summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2006-03-06 19:46:17 +0100
committerunknown <pem@mysql.com>2006-03-06 19:46:17 +0100
commit6b81326c5361a74893f53a241ce335e868a80fbd (patch)
treee07556a50cb904da00289a70fb51ea4e765e4c97 /sql/table.cc
parent29c66eea2729b0c7e8786940695967e6920aa392 (diff)
parent89378fe8f6d7e0a689cd917833dc7db04f85aca7 (diff)
downloadmariadb-git-6b81326c5361a74893f53a241ce335e868a80fbd.tar.gz
Merge mysql.com:/extern/mysql/5.0/generic/mysql-5.0
into mysql.com:/extern/mysql/5.1/generic/mysql-5.1-new libmysql/libmysql.c: Auto merged mysql-test/r/binary.result: Auto merged mysql-test/r/federated.result: Auto merged mysql-test/r/func_math.result: Auto merged mysql-test/r/grant.result: Auto merged mysql-test/r/heap.result: Auto merged mysql-test/r/sp.result: Auto merged mysql-test/r/trigger.result: Auto merged mysql-test/r/type_decimal.result: Auto merged mysql-test/t/binary.test: Auto merged mysql-test/t/federated.test: Auto merged mysql-test/t/mysql.test: Auto merged mysql-test/t/sp.test: Auto merged mysql-test/t/trigger.test: Auto merged sql/field_conv.cc: Auto merged sql/ha_federated.cc: Auto merged sql/ha_federated.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_strfunc.h: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_trigger.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.cc: Auto merged sql/table.h: Auto merged tests/mysql_client_test.c: Auto merged support-files/mysql.spec.sh: Manual merge. (use local)
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc69
1 files changed, 63 insertions, 6 deletions
diff --git a/sql/table.cc b/sql/table.cc
index d6a715ae1b4..a7b8949612e 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -3575,11 +3575,31 @@ GRANT_INFO *Field_iterator_table_ref::grant()
SYNOPSIS
Field_iterator_table_ref::get_or_create_column_ref()
- is_created [out] set to TRUE if the column was created,
- FALSE if we return an already created colum
+ parent_table_ref the parent table reference over which the
+ iterator is iterating
DESCRIPTION
- TODO
+ Create a new natural join column for the current field of the
+ iterator if no such column was created, or return an already
+ created natural join column. The former happens for base tables or
+ views, and the latter for natural/using joins. If a new field is
+ created, then the field is added to 'parent_table_ref' if it is
+ given, or to the original table referene of the field if
+ parent_table_ref == NULL.
+
+ NOTES
+ This method is designed so that when a Field_iterator_table_ref
+ walks through the fields of a table reference, all its fields
+ are created and stored as follows:
+ - If the table reference being iterated is a stored table, view or
+ natural/using join, store all natural join columns in a list
+ attached to that table reference.
+ - If the table reference being iterated is a nested join that is
+ not natural/using join, then do not materialize its result
+ fields. This is OK because for such table references
+ Field_iterator_table_ref iterates over the fields of the nested
+ table references (recursively). In this way we avoid the storage
+ of unnecessay copies of result columns of nested joins.
RETURN
# Pointer to a column of a natural join (or its operand)
@@ -3587,22 +3607,28 @@ GRANT_INFO *Field_iterator_table_ref::grant()
*/
Natural_join_column *
-Field_iterator_table_ref::get_or_create_column_ref(bool *is_created)
+Field_iterator_table_ref::get_or_create_column_ref(TABLE_LIST *parent_table_ref)
{
Natural_join_column *nj_col;
+ bool is_created= TRUE;
+ uint field_count;
+ TABLE_LIST *add_table_ref= parent_table_ref ?
+ parent_table_ref : table_ref;
- *is_created= TRUE;
if (field_it == &table_field_it)
{
/* The field belongs to a stored table. */
Field *field= table_field_it.field();
nj_col= new Natural_join_column(field, table_ref);
+ field_count= table_ref->table->s->fields;
}
else if (field_it == &view_field_it)
{
/* The field belongs to a merge view or information schema table. */
Field_translator *translated_field= view_field_it.field_translator();
nj_col= new Natural_join_column(translated_field, table_ref);
+ field_count= table_ref->field_translation_end -
+ table_ref->field_translation;
}
else
{
@@ -3611,12 +3637,43 @@ Field_iterator_table_ref::get_or_create_column_ref(bool *is_created)
already created via one of the two constructor calls above. In this case
we just return the already created column reference.
*/
- *is_created= FALSE;
+ DBUG_ASSERT(table_ref->is_join_columns_complete);
+ is_created= FALSE;
nj_col= natural_join_it.column_ref();
DBUG_ASSERT(nj_col);
}
DBUG_ASSERT(!nj_col->table_field ||
nj_col->table_ref->table == nj_col->table_field->table);
+
+ /*
+ If the natural join column was just created add it to the list of
+ natural join columns of either 'parent_table_ref' or to the table
+ reference that directly contains the original field.
+ */
+ if (is_created)
+ {
+ /* Make sure not all columns were materialized. */
+ DBUG_ASSERT(!add_table_ref->is_join_columns_complete);
+ if (!add_table_ref->join_columns)
+ {
+ /* Create a list of natural join columns on demand. */
+ if (!(add_table_ref->join_columns= new List<Natural_join_column>))
+ return NULL;
+ add_table_ref->is_join_columns_complete= FALSE;
+ }
+ add_table_ref->join_columns->push_back(nj_col);
+ /*
+ If new fields are added to their original table reference, mark if
+ all fields were added. We do it here as the caller has no easy way
+ of knowing when to do it.
+ If the fields are being added to parent_table_ref, then the caller
+ must take care to mark when all fields are created/added.
+ */
+ if (!parent_table_ref &&
+ add_table_ref->join_columns->elements == field_count)
+ add_table_ref->is_join_columns_complete= TRUE;
+ }
+
return nj_col;
}