diff --git a/mysql-test/suite/json/r/type_document_path.result b/mysql-test/suite/json/r/type_document_path.result index 5239c7a85066..a8f9b8838c7e 100644 --- a/mysql-test/suite/json/r/type_document_path.result +++ b/mysql-test/suite/json/r/type_document_path.result @@ -90,6 +90,68 @@ SET @@global.allow_document_type = false; SELECT @@global.allow_document_type; @@global.allow_document_type 0 +select b.k1 from t1; +ERROR 42S22: Unknown column 'b.k1' in 'field list' +select b.k1.k2 from t1; +ERROR 42S22: Unknown column 'b.k1.k2' in 'field list' +select b.k1.k2.k3 from t1; +ERROR HY000: Invalid field or reference. +SET @@global.allow_document_type = true; +SELECT @@global.allow_document_type; +@@global.allow_document_type +1 +select b.k1 from t1; +ERROR 42S22: Unknown column 'b.k1' in 'field list' +select b.k1.k2 from t1; +ERROR 42S22: Unknown column 'b.k1.k2' in 'field list' +select b.k1.k2.k3 from t1; +ERROR 42S22: Unknown column 'b.k1.k2.k3' in 'field list' +select a from t1 where b.k1 = 100; +ERROR 42S22: Unknown column 'b.k1' in 'where clause' +select a from t1 where b.k1.k2 = 100; +ERROR 42S22: Unknown column 'b.k1.k2' in 'where clause' +select a from t1 where b.k1.k2.k3 = 100; +ERROR 42S22: Unknown column 'b.k1.k2.k3' in 'where clause' +select a from t1 order by b.k1; +ERROR 42S22: Unknown column 'b.k1' in 'order clause' +select a from t1 order by b.k1.k2 ; +ERROR 42S22: Unknown column 'b.k1.k2' in 'order clause' +select a from t1 order by b.k1.k2.k3; +ERROR 42S22: Unknown column 'b.k1.k2.k3' in 'order clause' +select count(*), a from t1 group by b.k1; +ERROR 42S22: Unknown column 'b.k1' in 'group statement' +select count(*), a from t1 group by b.k1.k2; +ERROR 42S22: Unknown column 'b.k1.k2' in 'group statement' +select count(*), a from t1 group by b.k1.k2.k3; +ERROR 42S22: Unknown column 'b.k1.k2.k3' in 'group statement' +select count(*), a from t1 group by a having b.k1 = 100; +ERROR 42S22: Unknown column 'b.k1' in 'having clause' +select count(*), a from t1 group by a having b.k1.k2 = 100; +ERROR 42S22: Unknown column 'b.k1.k2' in 'having clause' +select count(*), a from t1 group by a having b.k1.k2.k3 = 100; +ERROR HY000: Invalid field or reference. +select a from t1 having b.k1 = 100; +ERROR 42S22: Unknown column 'b.k1' in 'having clause' +select a from t1 having b.k1.k2 = 100; +ERROR 42S22: Unknown column 'b.k1.k2' in 'having clause' +select a from t1 having b.k1.k2.k3 = 100; +ERROR HY000: Invalid field or reference. +select a from t1 where substr(b.k1, 1, 10) like 'abc'; +ERROR 42S22: Unknown column 'b.k1' in 'where clause' +select a from t1 where substr(b.k1.k2, 1, 10) like 'abc'; +ERROR 42S22: Unknown column 'b.k1.k2' in 'where clause' +select a from t1 where substr(b.k1.k2.k3, 1, 10) like 'abc'; +ERROR 42S22: Unknown column 'b.k1.k2.k3' in 'where clause' +select sum(b.k1) from t1 where a = 100; +ERROR 42S22: Unknown column 'b.k1' in 'field list' +select sum(b.k1.k2) from t1 where a = 100; +ERROR 42S22: Unknown column 'b.k1.k2' in 'field list' +select sum(b.k1.k2.k3) from t1 where a = 100; +ERROR 42S22: Unknown column 'b.k1.k2.k3' in 'field list' +SET @@global.allow_document_type = false; +SELECT @@global.allow_document_type; +@@global.allow_document_type +0 update t1 set t1.doc.id = 200 where a = 1; ERROR 42S22: Unknown column 't1.doc.id' in 'field list' SET @@global.allow_document_type = true; @@ -207,6 +269,17 @@ Warning 1292 Truncated incorrect time value: '2014-11-01' select test.t1.doc.address.houseNumber from t1 where test.t1.doc.address.zipcode = 98762; doc 1002 +select t1.a, t1.b from t1 where doc.address.zipcode = 98761; +a b +1 @1 +update t1 set t1.a = 101, t1.b = '@101' where doc.address.zipcode = 98761; +select t1.a, t1.b from t1 where doc.address.zipcode = 98761; +a b +101 @101 +update t1 set t1.a = 1, t1.b = '@1' where doc.address.zipcode = 98761; +select t1.a, t1.b from t1 where doc.address.zipcode = 98761; +a b +1 @1 select a from t1 order by test.t1.doc.NonExistent; a 1 diff --git a/mysql-test/suite/json/t/type_document_path.test b/mysql-test/suite/json/t/type_document_path.test index 85d07876e533..c96e0275c44d 100644 --- a/mysql-test/suite/json/t/type_document_path.test +++ b/mysql-test/suite/json/t/type_document_path.test @@ -120,7 +120,7 @@ select a from t1 where test.t1.doc.id = 102; --error ER_INVALID_FIELD_OR_REFERENCE select test.t1.doc.address.houseNumber from t1 where test.t1.doc.address.zipcode = 98762; -### Enable document type +### Enable document type with the new parsing logic SET @@global.allow_document_type = true; SELECT @@global.allow_document_type; @@ -130,6 +130,90 @@ select t1.doc from test.t1 where t1.a = 2; select .t1.doc from test.t1 where .t1.a = 4; +################################################################################ +### +### Invalid document path: using document path on a non-document column +### + +### Disable document type to make parser work as before +SET @@global.allow_document_type = false; +SELECT @@global.allow_document_type; + +--error ER_BAD_FIELD_ERROR +select b.k1 from t1; +--error ER_BAD_FIELD_ERROR +select b.k1.k2 from t1; +--error ER_INVALID_FIELD_OR_REFERENCE +select b.k1.k2.k3 from t1; + +### Enable document type with the new parsing logic +SET @@global.allow_document_type = true; +SELECT @@global.allow_document_type; + +## In SELECT +--error ER_BAD_FIELD_ERROR +select b.k1 from t1; +--error ER_BAD_FIELD_ERROR +select b.k1.k2 from t1; +--error ER_BAD_FIELD_ERROR +select b.k1.k2.k3 from t1; + +## In WHERE +--error ER_BAD_FIELD_ERROR +select a from t1 where b.k1 = 100; +--error ER_BAD_FIELD_ERROR +select a from t1 where b.k1.k2 = 100; +--error ER_BAD_FIELD_ERROR +select a from t1 where b.k1.k2.k3 = 100; + +## In ORDER BY +--error ER_BAD_FIELD_ERROR +select a from t1 order by b.k1; +--error ER_BAD_FIELD_ERROR +select a from t1 order by b.k1.k2 ; +--error ER_BAD_FIELD_ERROR +select a from t1 order by b.k1.k2.k3; + +## In GROUP BY +--error ER_BAD_FIELD_ERROR +select count(*), a from t1 group by b.k1; +--error ER_BAD_FIELD_ERROR +select count(*), a from t1 group by b.k1.k2; +--error ER_BAD_FIELD_ERROR +select count(*), a from t1 group by b.k1.k2.k3; + +## In HAVING +--error ER_BAD_FIELD_ERROR +select count(*), a from t1 group by a having b.k1 = 100; +--error ER_BAD_FIELD_ERROR +select count(*), a from t1 group by a having b.k1.k2 = 100; +--error ER_INVALID_FIELD_OR_REFERENCE +select count(*), a from t1 group by a having b.k1.k2.k3 = 100; + +## In HAVING without GROUP BY then HAVING clause behaves like WHERE clause +--error ER_BAD_FIELD_ERROR +select a from t1 having b.k1 = 100; +--error ER_BAD_FIELD_ERROR +select a from t1 having b.k1.k2 = 100; +--error ER_INVALID_FIELD_OR_REFERENCE +select a from t1 having b.k1.k2.k3 = 100; + +## In Functions +--error ER_BAD_FIELD_ERROR +select a from t1 where substr(b.k1, 1, 10) like 'abc'; +--error ER_BAD_FIELD_ERROR +select a from t1 where substr(b.k1.k2, 1, 10) like 'abc'; +--error ER_BAD_FIELD_ERROR +select a from t1 where substr(b.k1.k2.k3, 1, 10) like 'abc'; + +--error ER_BAD_FIELD_ERROR +select sum(b.k1) from t1 where a = 100; +--error ER_BAD_FIELD_ERROR +select sum(b.k1.k2) from t1 where a = 100; +--error ER_BAD_FIELD_ERROR +select sum(b.k1.k2.k3) from t1 where a = 100; + + ################################################################################ ### ### Document partial update by document path is not supported yet @@ -266,6 +350,13 @@ select test.t1.doc.dt from t1 where cast(test.t1.doc.dt as time) = cast('2014-11 ### Document path in both SELECT and WHERE clause: database.table.field.key1.key2 select test.t1.doc.address.houseNumber from t1 where test.t1.doc.address.zipcode = 98762; +### Document paths in WHERE clause for UPDATE statements +select t1.a, t1.b from t1 where doc.address.zipcode = 98761; +update t1 set t1.a = 101, t1.b = '@101' where doc.address.zipcode = 98761; +select t1.a, t1.b from t1 where doc.address.zipcode = 98761; +update t1 set t1.a = 1, t1.b = '@1' where doc.address.zipcode = 98761; +select t1.a, t1.b from t1 where doc.address.zipcode = 98761; + ################################################################################ ### diff --git a/sql/item.cc b/sql/item.cc index 67838c358bf9..0fcefd3482df 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2471,6 +2471,29 @@ Ident_parsing_info::Ident_parsing_info(THD *thd, Copy_ident_list(thd, &p.dot_separated_ident_list); } +const char* Ident_parsing_info::full_name(THD *thd) +{ + List_iterator_fast it(dot_separated_ident_list); + uint sz = 0; + for (One_ident *s = NULL; (s= it++);) + { + sz += s->s.length; + ++sz; /* for the '.' and the '\0' in the end */ + } + char* buf = (char *)thd->alloc(sz); + + it.rewind(); + char *p = buf; + for (One_ident *s = NULL; (s= it++);) + { + memcpy(p, s->s.str, s->s.length); + p += s->s.length; + *p++ = '.'; + } + buf[sz-1] = '\0'; + return buf; +} + void Ident_parsing_info::Parse_and_set_document_path_keys( THD *thd, List& list) { @@ -5618,15 +5641,16 @@ bool Item_field::fix_fields(THD *thd, Item **reference) DBUG_ASSERT(!ret); - if (field) + if (field && parsing_info.num_unresolved_idents > 0) { - DBUG_ASSERT(field->type() == MYSQL_TYPE_DOCUMENT || - parsing_info.num_unresolved_idents == 0); - } + if (field->type() != MYSQL_TYPE_DOCUMENT) + { + /* syntax error when using document path on a non-document column */ + my_error(ER_BAD_FIELD_ERROR, MYF(0), + parsing_info.full_name(thd), thd->where); + return true; + } - if (field && field->type() == MYSQL_TYPE_DOCUMENT && - parsing_info.num_unresolved_idents > 0) - { /* If the type of the field is document and there are still unresolved dot separated identifiers then this whole expression will be treated as a document virutal field. diff --git a/sql/item.h b/sql/item.h index d7e7043fd946..12bb41bc603d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2221,6 +2221,11 @@ class Ident_parsing_info Ident_parsing_info(THD *thd, Ident_parsing_info& p); + /* + generate the string of the dot separated expression + */ + const char* full_name(THD *thd); + /* parse the original dot-separated key tokens and set the document path keys