summaryrefslogtreecommitdiff
path: root/sql/sql_base.cc
diff options
context:
space:
mode:
authorunknown <timour@mysql.com>2004-11-02 18:23:15 +0200
committerunknown <timour@mysql.com>2004-11-02 18:23:15 +0200
commit048d731a3112e5745038f422da3f1a5c1fadde81 (patch)
treef36fd67db9dbc59a015a4fa4d848db945a5c8bd9 /sql/sql_base.cc
parent637c08d7cc0d462e445c68307d0c206fbf4f743b (diff)
downloadmariadb-git-048d731a3112e5745038f422da3f1a5c1fadde81.tar.gz
WL#1972 "Evaluate HAVING before SELECT select-list"
- Changed name resolution for GROUP BY so that derived columns do not shadow table columns from the FROM clause. As a result GROUP BY now is handled as a true ANSI extentsion. - Issue a warning when HAVING is resolved into ambiguous columns, and prefer the columns from the GROUP BY clause over SELECT columns. mysql-test/r/having.result: Correct result for updated GROUP BY name resolution. sql/item.cc: - prefer GROUP columns, but if none is found use SELECT list - issue a waring when a field may be resolved ambiguously - more/fixed comments sql/mysql_priv.h: More flexible find_field_in_tables(). sql/sp.cc: More flexible find_field_in_tables(). sql/sql_base.cc: More flexible find_field_in_tables(). sql/sql_help.cc: More flexible find_field_in_tables(). sql/sql_select.cc: - name resolution of GROUP/ORDER BY column references is differentiated: - GROUP BY is resolved in SELECT and FROM clauses - ORDER BY is resolved only in SELECT (as before) - more informative variable names - more comments
Diffstat (limited to 'sql/sql_base.cc')
-rw-r--r--sql/sql_base.cc64
1 files changed, 40 insertions, 24 deletions
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 4f273fbd0c4..a8a44205b64 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2173,25 +2173,33 @@ Field *find_field_in_real_table(THD *thd, TABLE *table,
find_field_in_tables()
thd Pointer to current thread structure
item Field item that should be found
- tables Tables for scanning
- ref if view field is found, pointer to view item will
- be returned via this parameter
- report_error If FALSE then do not report error if item not found
- and return not_found_field
+ tables Tables to be searched for item
+ ref If 'item' is resolved to a view field, ref is set to
+ point to the found view field
+ report_error Degree of error reporting:
+ - IGNORE_ERRORS then do not report any error
+ - IGNORE_EXCEPT_NON_UNIQUE report only non-unique
+ fields, suppress all other errors
+ - REPORT_EXCEPT_NON_UNIQUE report all other errors
+ except when non-unique fields were found
+ - REPORT_ALL_ERRORS
check_privileges need to check privileges
RETURN VALUES
- 0 Field is not found or field is not unique- error
- message is reported
- not_found_field Function was called with report_error == FALSE and
- field was not found. no error message reported.
- view_ref_found view field is found, item passed through ref parameter
- found field
+ 0 No field was found, or the found field is not unique, or
+ there are no sufficient access priviligaes for the
+ found field, or the field is qualified with non-existing
+ table.
+ not_found_field The function was called with report_error ==
+ (IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a
+ field was not found.
+ view_ref_found View field is found, item passed through ref parameter
+ found field If a item was resolved to some field
*/
Field *
find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
- Item **ref, bool report_error,
+ Item **ref, find_item_error_report_type report_error,
bool check_privileges)
{
Field *found=0;
@@ -2268,8 +2276,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
return find;
if (found)
{
- my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
- item->full_name(),thd->where);
+ if (report_error == REPORT_ALL_ERRORS ||
+ report_error == IGNORE_EXCEPT_NON_UNIQUE)
+ my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
+ item->full_name(),thd->where);
return (Field*) 0;
}
found=find;
@@ -2278,7 +2288,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
}
if (found)
return found;
- if (!found_table && report_error)
+ if (!found_table && (report_error == REPORT_ALL_ERRORS ||
+ report_error == REPORT_EXCEPT_NON_UNIQUE))
{
char buff[NAME_LEN*2+1];
if (db && db[0])
@@ -2286,28 +2297,30 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
strxnmov(buff,sizeof(buff)-1,db,".",table_name,NullS);
table_name=buff;
}
- if (report_error)
- {
+ if (report_error == REPORT_ALL_ERRORS ||
+ report_error == REPORT_EXCEPT_NON_UNIQUE)
my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
table_name, thd->where);
- }
else
return (Field*) not_found_field;
}
else
- if (report_error)
+ if (report_error == REPORT_ALL_ERRORS ||
+ report_error == REPORT_EXCEPT_NON_UNIQUE)
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
item->full_name(),thd->where);
else
return (Field*) not_found_field;
return (Field*) 0;
}
+
bool allow_rowid= tables && !tables->next_local; // Only one table
for (; tables ; tables= tables->next_local)
{
if (!tables->table)
{
- if (report_error)
+ if (report_error == REPORT_ALL_ERRORS ||
+ report_error == REPORT_EXCEPT_NON_UNIQUE)
my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0),
item->full_name(),thd->where);
return (Field*) not_found_field;
@@ -2332,8 +2345,10 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
{
if (!thd->where) // Returns first found
break;
- my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
- name,thd->where);
+ if (report_error == REPORT_ALL_ERRORS ||
+ report_error == IGNORE_EXCEPT_NON_UNIQUE)
+ my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0),
+ name,thd->where);
return (Field*) 0;
}
found=field;
@@ -2341,7 +2356,8 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
}
if (found)
return found;
- if (report_error)
+ if (report_error == REPORT_ALL_ERRORS ||
+ report_error == REPORT_EXCEPT_NON_UNIQUE)
my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR),
MYF(0), item->full_name(), thd->where);
else
@@ -2377,7 +2393,7 @@ find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
found field
*/
-// Special Item pointer for find_item_in_list returning
+/* Special Item pointer to serve as a return value from find_item_in_list(). */
const Item **not_found_item= (const Item**) 0x1;