Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support SELECT ..where not like #796

Open
2 of 3 tasks
shangyanwen opened this issue Oct 25, 2022 · 9 comments
Open
2 of 3 tasks

feat: support SELECT ..where not like #796

shangyanwen opened this issue Oct 25, 2022 · 9 comments
Assignees
Labels
A-feature feature with good idea B-SQL SQL layer prio: low Low priority

Comments

@shangyanwen
Copy link
Contributor

Have you read the Contributing Guidelines on issues?

Please confirm if bug report does NOT exists already ?

  • I confirm there is no existing issue for this

Describe the problem

mysql> SELECT * FROM t1 WHERE t1_int NOT LIKE 1;

ERROR 6 (HY000): The query includes syntax that is not supported by the storage engine. Either restructure the query with supported syntax, or enable the MySQL core::Query Path in config file to execute the query with reduced performance.

Expected behavior

mysql> SELECT * FROM t1 WHERE t1_int NOT LIKE 1;
+--------+---------+
| t1_int | t1_char |
+--------+---------+
|      2 | aaa     |
|      3 | bbb     |
|      4 | ccc     |
|      5 | ddd     |
+--------+---------+
4 rows in set (0.00 sec)

How To Reproduce

CREATE TABLE t1(t1_int INT, t1_char CHAR(5))ENGINE=tianmu;
INSERT INTO t1 VALUES(1,'aaa'),(2,'aaa'),(3,'bbb'),(4,'ccc'),(5,'ddd');
SELECT * FROM t1 WHERE t1_int NOT LIKE 1;

Environment

Ver 14.14 Distrib 5.7.36-StoneDB, for Linux (x86_64) using  EditLine wrapper

【notes】The debug version will crash

Are you interested in submitting a PR to solve the problem?

  • Yes, I will!
@shangyanwen shangyanwen added the A-bug Something isn't working label Oct 25, 2022
@RingsC RingsC added the prio: normal Medium priority label Nov 1, 2022
@DandreChen
Copy link
Collaborator

ACK

@DandreChen
Copy link
Collaborator

like or not like don't support int type, only support string VARCHAR BLOBtype

@DandreChen
Copy link
Collaborator

code :

      if ((op == common::Operator::O_LIKE || op == common::Operator::O_NOT_LIKE) &&
          !(an_arg->field_type() == MYSQL_TYPE_VARCHAR || an_arg->field_type() == MYSQL_TYPE_STRING ||
            an_arg->field_type() == MYSQL_TYPE_VAR_STRING || an_arg->field_type() == MYSQL_TYPE_BLOB)) {
        return CondID(-1);  // Argument of LIKE is not a string, return to MySQL.
      }

@RingsC
Copy link
Contributor

RingsC commented Dec 1, 2022

It returns to MySQL, mysql should handle this case, and why stonedb issue this error message. @DandreChen

@RingsC
Copy link
Contributor

RingsC commented Dec 1, 2022

And in debug mode, StoneDB crashes, Pls find out which assert failed. @DandreChen

@DandreChen
Copy link
Collaborator

OK,I will fix it.

@DandreChen
Copy link
Collaborator

using test case,the latest code will not crash in debug mode .

@DandreChen
Copy link
Collaborator

DandreChen commented Dec 5, 2022

but when set tianmu_ini_allowmysqlquerypath=1, running test case lead to cash

st_select_lex::prepare(st_select_lex * const this, THD * thd) (\opt\github\stonedb57\sql\sql_resolver.cc:110)
handle_query(THD * thd, LEX * lex, Query_result * result, ulonglong added_options, ulonglong removed_options, int optimize_after_bh, int free_join_from_bh) (\opt\github\stonedb57\sql\sql_select.cc:139)
execute_sqlcom_select(THD * thd, TABLE_LIST * all_tables) (\opt\github\stonedb57\sql\sql_parse.cc:5218)
mysql_execute_command(THD * thd, bool first_level) (\opt\github\stonedb57\sql\sql_parse.cc:2856)
mysql_parse(THD * thd, Parser_state * parser_state) (\opt\github\stonedb57\sql\sql_parse.cc:5655)
dispatch_command(THD * thd, const COM_DATA * com_data, enum_server_command command) (\opt\github\stonedb57\sql\sql_parse.cc:1495)
do_command(THD * thd) (\opt\github\stonedb57\sql\sql_parse.cc:1034)
handle_connection(void * arg) (\opt\github\stonedb57\sql\conn_handler\connection_handler_per_thread.cc:313)
pfs_spawn_thread(void * arg) (\opt\github\stonedb57\storage\perfschema\pfs.cc:2197)
libpthread.so.0!start_thread (未知源:0)
libc.so.6!clone (未知源:0)

@DandreChen DandreChen reopened this Jan 6, 2023
@wisehead wisehead added this to the stonedb_5.7_v1.0.3 milestone Jan 6, 2023
@wisehead wisehead added the B-SQL SQL layer label Jan 9, 2023
@hustjieke hustjieke added B-storage data type, data storage, insert,update,delete, transactions and removed B-storage data type, data storage, insert,update,delete, transactions labels Jan 30, 2023
@wisehead wisehead assigned isredstar and unassigned DandreChen and isredstar Jan 31, 2023
@isredstar
Copy link
Collaborator

else if ((d.op == common::Operator::O_LIKE || d.op == common::Operator::O_NOT_LIKE) &&
               (GetPackType() == common::PackType::STR )) {
      DEBUG_ASSERT(vc1->IsConst());
      types::BString pat;
      vc1->GetValueString(pat, mit);
      common::RoughSetValue res = common::RoughSetValue::RS_SOME;
      // here: check min, max
      uint pattern_prefix = 0;        // e.g. "ab_cd_e%f"  -> 7
      uint pattern_fixed_prefix = 0;  // e.g. "ab_cd_e%f"  -> 2
      uint pack_prefix;
      if (types::RequiresUTFConversions(d.GetCollation())) {
        my_match_t mm;
        if (d.GetCollation().collation->coll->instr(d.GetCollation().collation, pat.val_, pat.len_, "%", 1, &mm, 1) ==
            2)
          pattern_prefix = pattern_fixed_prefix = mm.end;

        if (d.GetCollation().collation->coll->instr(d.GetCollation().collation, pat.val_, pat.len_, "_", 1, &mm, 1) ==
            2)
          if (mm.end < pattern_fixed_prefix)
            pattern_fixed_prefix = mm.end;

        if ((pattern_fixed_prefix > 0) &&
            types::BString(pat.val_, pattern_fixed_prefix).LessEqThanMaxUTF(dpn.max_s, Type().GetCollation()) == false)
          res = common::RoughSetValue::RS_NONE;

        if (pattern_fixed_prefix > GetActualSize(pack))
          res = common::RoughSetValue::RS_NONE;
        pack_prefix = GetPrefixLength(pack);
        if (res == common::RoughSetValue::RS_SOME && pack_prefix > 0 &&
            pattern_fixed_prefix <= pack_prefix  // special case: "xyz%" and the
                                                 // pack prefix is at least 3
            && pattern_fixed_prefix + 1 == pat.len_ && pat[pattern_fixed_prefix] == '%') {
          if (d.GetCollation().collation->coll->strnncoll(d.GetCollation().collation, (const uchar *)pat.val_,
                                                          pattern_fixed_prefix, (const uchar *)dpn.min_s,
                                                          pattern_fixed_prefix, 0) == 0)
            res = common::RoughSetValue::RS_ALL;
          else
            res = common::RoughSetValue::RS_NONE;  // prefix and pattern are different
        }

      } else {
        while (pattern_prefix < pat.len_ && pat[pattern_prefix] != '%') pattern_prefix++;
        while (pattern_fixed_prefix < pat.len_ && pat[pattern_fixed_prefix] != '%' && pat[pattern_fixed_prefix] != '_')
          pattern_fixed_prefix++;

        if ((pattern_fixed_prefix > 0) && types::BString(pat.val_, pattern_fixed_prefix).LessEqThanMax(dpn.max_s) ==
                                              false)  // val_t==nullptr means +/-infty
          res = common::RoughSetValue::RS_NONE;
        if (pattern_fixed_prefix > GetActualSize(pack))
          res = common::RoughSetValue::RS_NONE;
        pack_prefix = GetPrefixLength(pack);
        if (res == common::RoughSetValue::RS_SOME && pack_prefix > 0 &&
            pattern_fixed_prefix <= pack_prefix  // special case: "xyz%" and the
                                                 // pack prefix is at least 3
            && pattern_fixed_prefix + 1 == pat.len_ && pat[pattern_fixed_prefix] == '%') {
          if (std::memcmp(pat.val_, dpn.min_s, pattern_fixed_prefix) == 0)  // pattern is equal to the prefix
            res = common::RoughSetValue::RS_ALL;
          else
            res = common::RoughSetValue::RS_NONE;  // prefix and pattern are different
        }
      }

      if (res == common::RoughSetValue::RS_SOME && std::min(pattern_prefix, pack_prefix) < pat.len_ &&
          !types::RequiresUTFConversions(d.GetCollation())) {
        types::BString pattern_for_cmap;  // note that cmap is shifted by a common prefix!
        if (pattern_prefix > pack_prefix)
          pattern_for_cmap = types::BString(pat.val_ + pack_prefix,
                                            pat.len_ - pack_prefix);  // "xyz%abc" -> "z%abc"
        else
          pattern_for_cmap = types::BString(pat.val_ + pattern_prefix,
                                            pat.len_ - pattern_prefix);  // "xyz%abc" -> "%abc"

        if (!(pattern_for_cmap.len_ == 1 && pattern_for_cmap[0] == '%')) {  // i.e. "%" => all is matching
          if (auto sp = GetFilter_CMap())
            res = sp->IsLike(pattern_for_cmap, pack, d.like_esc);
        } else
          res = common::RoughSetValue::RS_ALL;
      }
      if (d.op == common::Operator::O_NOT_LIKE) {
        if (res == common::RoughSetValue::RS_ALL)
          res = common::RoughSetValue::RS_NONE;
        else if (res == common::RoughSetValue::RS_NONE)
          res = common::RoughSetValue::RS_ALL;
      }
      if ((dpn.numOfNulls != 0 || additional_nulls_possible) && res == common::RoughSetValue::RS_ALL)
        res = common::RoughSetValue::RS_SOME;
      return res;
    } 

The handling of INT type about like and not like doesn't exist.

@isredstar isredstar added prio: low Low priority and removed prio: normal Medium priority labels Feb 1, 2023
@hustjieke hustjieke added the A-feature feature with good idea label May 29, 2023
@hustjieke hustjieke changed the title bug: SELECT ..where not like,Prompt not supported feat: support SELECT ..where not like May 29, 2023
@hustjieke hustjieke removed the A-bug Something isn't working label May 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-feature feature with good idea B-SQL SQL layer prio: low Low priority
Projects
Development

No branches or pull requests

6 participants