~ubuntu-branches/ubuntu/wily/mysql-5.6/wily

« back to all changes in this revision

Viewing changes to sql/sql_parse.cc

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-04-16 20:07:10 UTC
  • mto: (1.3.9 vivid-proposed)
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: package-import@ubuntu.com-20150416200710-pcrsa022082zj46k
Tags: upstream-5.6.24
ImportĀ upstreamĀ versionĀ 5.6.24

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
 
1
/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
2
2
 
3
3
   This program is free software; you can redistribute it and/or modify
4
4
   it under the terms of the GNU General Public License as published by
101
101
#include "sql_analyse.h"
102
102
#include "table_cache.h" // table_cache_manager
103
103
 
 
104
#include "sql_digest.h"
 
105
 
104
106
#include <algorithm>
105
107
using std::max;
106
108
using std::min;
987
989
    /* Mark the statement completed. */
988
990
    MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
989
991
    thd->m_statement_psi= NULL;
 
992
    thd->m_digest= NULL;
990
993
 
991
994
    if (net->error != 3)
992
995
    {
1035
1038
 
1036
1039
out:
1037
1040
  /* The statement instrumentation must be closed in all cases. */
 
1041
  DBUG_ASSERT(thd->m_digest == NULL);
1038
1042
  DBUG_ASSERT(thd->m_statement_psi == NULL);
1039
1043
  DBUG_RETURN(return_value);
1040
1044
}
1306
1310
  }
1307
1311
  case COM_QUERY:
1308
1312
  {
 
1313
    DBUG_ASSERT(thd->m_digest == NULL);
 
1314
    thd->m_digest= & thd->m_digest_state;
 
1315
    thd->m_digest->reset(thd->m_token_array, max_digest_length);
 
1316
 
1309
1317
    if (alloc_query(thd, packet, packet_length))
1310
1318
      break;                                    // fatal error is set
1311
1319
    MYSQL_QUERY_START(thd->query(), thd->thread_id,
1363
1371
/* PSI end */
1364
1372
      MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1365
1373
      thd->m_statement_psi= NULL;
 
1374
      thd->m_digest= NULL;
1366
1375
 
1367
1376
/* DTRACE end */
1368
1377
      if (MYSQL_QUERY_DONE_ENABLED())
1388
1397
                        (char *) thd->security_ctx->host_or_ip);
1389
1398
 
1390
1399
/* PSI begin */
 
1400
      thd->m_digest= & thd->m_digest_state;
 
1401
 
1391
1402
      thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
1392
1403
                                                  com_statement_info[command].m_key,
1393
1404
                                                  thd->db, thd->db_length,
1777
1788
  /* Performance Schema Interface instrumentation, end */
1778
1789
  MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
1779
1790
  thd->m_statement_psi= NULL;
 
1791
  thd->m_digest= NULL;
1780
1792
 
1781
1793
  dec_thread_running();
1782
1794
  thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
4247
4259
    LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
4248
4260
    if (!grant_user)
4249
4261
      goto error;
4250
 
    if ((thd->security_ctx->priv_user &&
4251
 
         !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
 
4262
    if (!strcmp(thd->security_ctx->priv_user, grant_user->user.str) ||
4252
4263
        !check_access(thd, SELECT_ACL, "mysql", NULL, NULL, 1, 0))
4253
4264
    {
4254
4265
      res = mysql_show_grants(thd, grant_user);
4386
4397
    if (sp_process_definer(thd))
4387
4398
      goto create_sp_error;
4388
4399
 
 
4400
    /*
 
4401
      Record the CURRENT_USER in binlog. The CURRENT_USER is used on slave to
 
4402
      grant default privileges when sp_automatic_privileges variable is set.
 
4403
    */
 
4404
    thd->binlog_invoker();
 
4405
 
4389
4406
    res= (sp_result= sp_create_routine(thd, lex->sphead));
4390
4407
    switch (sp_result) {
4391
4408
    case SP_OK: {
4395
4412
      Security_context security_context;
4396
4413
      bool restore_backup_context= false;
4397
4414
      Security_context *backup= NULL;
4398
 
      LEX_USER *definer= thd->lex->definer;
4399
4415
      /*
4400
4416
        We're going to issue an implicit GRANT statement so we close all
4401
4417
        open tables. We have to keep metadata locks as this ensures that
4414
4430
      DBUG_ASSERT(thd->transaction.stmt.is_empty());
4415
4431
      close_thread_tables(thd);
4416
4432
      /*
4417
 
        Check if the definer exists on slave, 
 
4433
        Check if invoker exists on slave, then use invoker privilege to
 
4434
        insert routine privileges to mysql.procs_priv. If invoker is not
 
4435
        available then consider using definer.
 
4436
 
 
4437
        Check if the definer exists on slave,
4418
4438
        then use definer privilege to insert routine privileges to mysql.procs_priv.
4419
4439
 
4420
 
        For current user of SQL thread has GLOBAL_ACL privilege, 
4421
 
        which doesn't any check routine privileges, 
 
4440
        For current user of SQL thread has GLOBAL_ACL privilege,
 
4441
        which doesn't any check routine privileges,
4422
4442
        so no routine privilege record  will insert into mysql.procs_priv.
4423
4443
      */
4424
 
      if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
 
4444
 
 
4445
      if (thd->slave_thread)
4425
4446
      {
4426
 
        security_context.change_security_context(thd, 
4427
 
                                                 &thd->lex->definer->user,
4428
 
                                                 &thd->lex->definer->host,
4429
 
                                                 &thd->lex->sphead->m_db,
4430
 
                                                 &backup);
4431
 
        restore_backup_context= true;
 
4447
        LEX_STRING current_user;
 
4448
        LEX_STRING current_host;
 
4449
        if (thd->has_invoker())
 
4450
        {
 
4451
          current_host= thd->get_invoker_host();
 
4452
          current_user= thd->get_invoker_user();
 
4453
        }
 
4454
        else
 
4455
        {
 
4456
          current_host= lex->definer->host;
 
4457
          current_user= lex->definer->user;
 
4458
        }
 
4459
        if (is_acl_user(current_host.str, current_user.str))
 
4460
        {
 
4461
          security_context.change_security_context(thd,
 
4462
                                                   &current_user,
 
4463
                                                   &current_host,
 
4464
                                                   &thd->lex->sphead->m_db,
 
4465
                                                   &backup);
 
4466
          restore_backup_context= true;
 
4467
        }
4432
4468
      }
4433
4469
 
4434
4470
      if (sp_automatic_privileges && !opt_noacl &&
6282
6318
        no logging happens at all. If rewriting does not happen here,
6283
6319
        thd->rewritten_query is still empty from being reset in alloc_query().
6284
6320
      */
6285
 
      bool general= (opt_log && ! (opt_log_raw || thd->slave_thread));
6286
 
 
6287
 
      if (general || opt_slow_log || opt_bin_log)
 
6321
      if (!(opt_log_raw || thd->slave_thread) || opt_slow_log || opt_bin_log)
6288
6322
      {
6289
6323
        mysql_rewrite_query(thd);
6290
6324
 
6292
6326
          lex->safe_to_cache_query= false; // see comments below
6293
6327
      }
6294
6328
 
6295
 
      if (general)
 
6329
      if (!(opt_log_raw || thd->slave_thread))
6296
6330
      {
6297
6331
        if (thd->rewritten_query.length())
6298
6332
          general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
6446
6480
{
6447
6481
  LEX *lex= thd->lex;
6448
6482
  bool ignorable= false;
 
6483
  sql_digest_state *parent_digest= thd->m_digest;
6449
6484
  PSI_statement_locker *parent_locker= thd->m_statement_psi;
6450
6485
  DBUG_ENTER("mysql_test_parse_for_slave");
6451
6486
 
6457
6492
    lex_start(thd);
6458
6493
    mysql_reset_thd_for_next_command(thd);
6459
6494
 
 
6495
    thd->m_digest= NULL;
6460
6496
    thd->m_statement_psi= NULL;
6461
6497
    if (parse_sql(thd, & parser_state, NULL) == 0)
6462
6498
    {
6470
6506
               !rpl_filter->db_ok(thd->db))
6471
6507
        ignorable= true;
6472
6508
    }
 
6509
    thd->m_digest= parent_digest;
6473
6510
    thd->m_statement_psi= parent_locker;
6474
6511
    thd->end_statement();
6475
6512
  }
8301
8338
 
8302
8339
  thd->m_parser_state= parser_state;
8303
8340
 
8304
 
#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
8305
 
  /* Start Digest */
8306
 
  thd->m_parser_state->m_lip.m_digest_psi= MYSQL_DIGEST_START(thd->m_statement_psi);
8307
 
#endif
 
8341
  parser_state->m_digest_psi= NULL;
 
8342
  parser_state->m_lip.m_digest= NULL;
 
8343
 
 
8344
  if (thd->m_digest != NULL)
 
8345
  {
 
8346
    /* Start Digest */
 
8347
    parser_state->m_digest_psi= MYSQL_DIGEST_START(thd->m_statement_psi);
 
8348
 
 
8349
    if (parser_state->m_input.m_compute_digest ||
 
8350
       (parser_state->m_digest_psi != NULL))
 
8351
    {
 
8352
      /*
 
8353
        If either:
 
8354
        - the caller wants to compute a digest
 
8355
        - the performance schema wants to compute a digest
 
8356
        set the digest listener in the lexer.
 
8357
      */
 
8358
      parser_state->m_lip.m_digest= thd->m_digest;
 
8359
      parser_state->m_lip.m_digest->m_digest_storage.m_charset_number= thd->charset()->number;
 
8360
    }
 
8361
  }
8308
8362
 
8309
8363
  /* Parse the query. */
8310
8364
 
8337
8391
  /* That's it. */
8338
8392
 
8339
8393
  ret_value= mysql_parse_status || thd->is_fatal_error;
 
8394
 
 
8395
  if ((ret_value == 0) &&
 
8396
      (parser_state->m_digest_psi != NULL))
 
8397
  {
 
8398
    /*
 
8399
      On parsing success, record the digest in the performance schema.
 
8400
    */
 
8401
    DBUG_ASSERT(thd->m_digest != NULL);
 
8402
    MYSQL_DIGEST_END(parser_state->m_digest_psi,
 
8403
                     & thd->m_digest->m_digest_storage);
 
8404
  }
 
8405
 
8340
8406
  MYSQL_QUERY_PARSE_DONE(ret_value);
8341
8407
  return ret_value;
8342
8408
}