mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-04 12:56:14 +01:00 
			
		
		
		
	get_all_tables() skipped tables if the user has no privileges on the schema itself and no granted privilege on any tables in the schema. that is, it was skipping performance_schema tables (privileges on them aren't explicitly granted, but internally hard-coded) To fix: * extend ACL_internal_table_access::check() method with `bool any_combination_will_do` * fix all perfschema privilege checks to take it into account. * don't reuse table_acl_check object for all tables, initialize it for every table otherwise GRANT_INTERNAL_INFO will leak * remove incorrect privilege check from get_all_tables()
		
			
				
	
	
		
			629 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			629 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/* Copyright (c) 2008, 2023, Oracle and/or its affiliates.
 | 
						|
 | 
						|
  This program is free software; you can redistribute it and/or modify
 | 
						|
  it under the terms of the GNU General Public License, version 2.0,
 | 
						|
  as published by the Free Software Foundation.
 | 
						|
 | 
						|
  This program is also distributed with certain software (including
 | 
						|
  but not limited to OpenSSL) that is licensed under separate terms,
 | 
						|
  as designated in a particular file or component or in included license
 | 
						|
  documentation.  The authors of MySQL hereby grant you an additional
 | 
						|
  permission to link the program and your derivative works with the
 | 
						|
  separately licensed software that they have included with MySQL.
 | 
						|
 | 
						|
  This program is distributed in the hope that it will be useful,
 | 
						|
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
  GNU General Public License, version 2.0, for more details.
 | 
						|
 | 
						|
  You should have received a copy of the GNU General Public License
 | 
						|
  along with this program; if not, write to the Free Software Foundation,
 | 
						|
  51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */
 | 
						|
 | 
						|
#ifndef PFS_ENGINE_TABLE_H
 | 
						|
#define PFS_ENGINE_TABLE_H
 | 
						|
 | 
						|
#include "table.h"
 | 
						|
#include "sql_acl.h"
 | 
						|
/**
 | 
						|
  @file storage/perfschema/pfs_engine_table.h
 | 
						|
  Performance schema tables (declarations).
 | 
						|
*/
 | 
						|
 | 
						|
#include "pfs_instr_class.h"
 | 
						|
extern pthread_key_t THR_PFS_VG;   // global_variables
 | 
						|
extern pthread_key_t THR_PFS_SV;   // session_variables
 | 
						|
extern pthread_key_t THR_PFS_VBT;  // variables_by_thread
 | 
						|
extern pthread_key_t THR_PFS_SG;   // global_status
 | 
						|
extern pthread_key_t THR_PFS_SS;   // session_status
 | 
						|
extern pthread_key_t THR_PFS_SBT;  // status_by_thread
 | 
						|
extern pthread_key_t THR_PFS_SBU;  // status_by_user
 | 
						|
extern pthread_key_t THR_PFS_SBH;  // status_by_host
 | 
						|
extern pthread_key_t THR_PFS_SBA;  // status_by_account
 | 
						|
 | 
						|
class Field;
 | 
						|
struct PFS_engine_table_share;
 | 
						|
struct time_normalizer;
 | 
						|
 | 
						|
/**
 | 
						|
  @addtogroup Performance_schema_engine
 | 
						|
  @{
 | 
						|
*/
 | 
						|
 | 
						|
/**
 | 
						|
  Store and retrieve table state information during a query.
 | 
						|
*/
 | 
						|
class PFS_table_context
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_table_context(ulonglong current_version, bool restore, pthread_key_t key);
 | 
						|
  PFS_table_context(ulonglong current_version, ulong map_size, bool restore, pthread_key_t key);
 | 
						|
~PFS_table_context(void);
 | 
						|
 | 
						|
  bool initialize(void);
 | 
						|
  bool is_initialized(void) { return m_initialized; }
 | 
						|
  ulonglong current_version(void) { return m_current_version; }
 | 
						|
  ulonglong last_version(void) { return m_last_version; }
 | 
						|
  bool versions_match(void) { return m_last_version == m_current_version; }
 | 
						|
  void set_item(ulong n);
 | 
						|
  bool is_item_set(ulong n);
 | 
						|
  pthread_key_t m_thr_key;
 | 
						|
 | 
						|
private:
 | 
						|
  ulonglong m_current_version;
 | 
						|
  ulonglong m_last_version;
 | 
						|
  ulong *m_map;
 | 
						|
  ulong m_map_size;
 | 
						|
  static constexpr ulong m_word_size= 8 * sizeof(ulong);
 | 
						|
  bool m_restore;
 | 
						|
  bool m_initialized;
 | 
						|
  ulong m_last_item;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  An abstract PERFORMANCE_SCHEMA table.
 | 
						|
  Every table implemented in the performance schema schema and storage engine
 | 
						|
  derives from this class.
 | 
						|
*/
 | 
						|
class PFS_engine_table
 | 
						|
{
 | 
						|
public:
 | 
						|
  static const PFS_engine_table_share*
 | 
						|
    find_engine_table_share(const char *name);
 | 
						|
 | 
						|
  int read_row(TABLE *table, unsigned char *buf, Field **fields);
 | 
						|
 | 
						|
  int update_row(TABLE *table, const unsigned char *old_buf,
 | 
						|
                 const unsigned char *new_buf, Field **fields);
 | 
						|
 | 
						|
  /**
 | 
						|
    Delete a row from this table.
 | 
						|
    @param table Table handle
 | 
						|
    @param buf the row buffer to delete
 | 
						|
    @param fields Table fields
 | 
						|
    @return 0 on success
 | 
						|
  */
 | 
						|
  int delete_row(TABLE *table, const unsigned char *buf, Field **fields);
 | 
						|
 | 
						|
  /** Initialize table scan. */
 | 
						|
  virtual int rnd_init(bool scan){return 0;};
 | 
						|
 | 
						|
  /** Fetch the next row in this cursor. */
 | 
						|
  virtual int rnd_next(void)= 0;
 | 
						|
  /**
 | 
						|
    Fetch a row by position.
 | 
						|
    @param pos              position to fetch
 | 
						|
  */
 | 
						|
  virtual int rnd_pos(const void *pos)= 0;
 | 
						|
 | 
						|
  void get_position(void *ref);
 | 
						|
  void set_position(const void *ref);
 | 
						|
  /** Reset the cursor position to the beginning of the table. */
 | 
						|
  virtual void reset_position(void)= 0;
 | 
						|
 | 
						|
  /** Get the normalizer and class type for the current row. */
 | 
						|
  void get_normalizer(PFS_instr_class *instr_class);
 | 
						|
 | 
						|
  /** Destructor. */
 | 
						|
  virtual ~PFS_engine_table() = default;
 | 
						|
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a long field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_long(Field *f, long value);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a ulong field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_ulong(Field *f, ulong value);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a longlong field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_longlong(Field *f, longlong value);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a ulonglong field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_ulonglong(Field *f, ulonglong value);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a char utf8 field.
 | 
						|
    @param f the field to set
 | 
						|
    @param str the string to assign
 | 
						|
    @param len the length of the string to assign
 | 
						|
  */
 | 
						|
  static void set_field_char_utf8(Field *f, const char *str, uint len);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a varchar utf8 field.
 | 
						|
    @param f the field to set
 | 
						|
    @param cs the string character set
 | 
						|
    @param str the string to assign
 | 
						|
    @param len the length of the string to assign
 | 
						|
  */
 | 
						|
  static void set_field_varchar(Field *f, const CHARSET_INFO *cs, const char *str, uint len);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a varchar utf8 field.
 | 
						|
    @param f the field to set
 | 
						|
    @param str the string to assign
 | 
						|
    @param len the length of the string to assign
 | 
						|
  */
 | 
						|
  static void set_field_varchar_utf8(Field *f, const char *str, uint len);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a longtext utf8 field.
 | 
						|
    @param f the field to set
 | 
						|
    @param str the string to assign
 | 
						|
    @param len the length of the string to assign
 | 
						|
  */
 | 
						|
  static void set_field_longtext_utf8(Field *f, const char *str, uint len);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a blob field.
 | 
						|
    @param f the field to set
 | 
						|
    @param val the value to assign
 | 
						|
    @param len the length of the string to assign
 | 
						|
  */
 | 
						|
  static void set_field_blob(Field *f, const char *val, uint len);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to an enum field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_enum(Field *f, ulonglong value);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a timestamp field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_timestamp(Field *f, ulonglong value);
 | 
						|
  /**
 | 
						|
    Helper, assign a value to a double field.
 | 
						|
    @param f the field to set
 | 
						|
    @param value the value to assign
 | 
						|
  */
 | 
						|
  static void set_field_double(Field *f, double value);
 | 
						|
  /**
 | 
						|
    Helper, read a value from an enum field.
 | 
						|
    @param f the field to read
 | 
						|
    @return the field value
 | 
						|
  */
 | 
						|
  static ulonglong get_field_enum(Field *f);
 | 
						|
  /**
 | 
						|
    Helper, read a value from a char utf8 field.
 | 
						|
    @param f the field to read
 | 
						|
    @param[out] val the field value
 | 
						|
    @return the field value
 | 
						|
  */
 | 
						|
  static String *get_field_char_utf8(Field *f, String *val);
 | 
						|
  /**
 | 
						|
    Helper, read a value from a varchar utf8 field.
 | 
						|
    @param f the field to read
 | 
						|
    @param[out] val the field value
 | 
						|
    @return the field value
 | 
						|
  */
 | 
						|
  static String *get_field_varchar_utf8(Field *f, String *val);
 | 
						|
 | 
						|
protected:
 | 
						|
  /**
 | 
						|
    Read the current row values.
 | 
						|
    @param table            Table handle
 | 
						|
    @param buf              row buffer
 | 
						|
    @param fields           Table fields
 | 
						|
    @param read_all         true if all columns are read.
 | 
						|
  */
 | 
						|
  virtual int read_row_values(TABLE *table, unsigned char *buf,
 | 
						|
                              Field **fields, bool read_all)= 0;
 | 
						|
 | 
						|
  /**
 | 
						|
    Update the current row values.
 | 
						|
    @param table            Table handle
 | 
						|
    @param old_buf          old row buffer
 | 
						|
    @param new_buf          new row buffer
 | 
						|
    @param fields           Table fields
 | 
						|
  */
 | 
						|
  virtual int update_row_values(TABLE *table, const unsigned char *old_buf,
 | 
						|
                                const unsigned char *new_buf, Field **fields);
 | 
						|
 | 
						|
  /**
 | 
						|
    Delete a row.
 | 
						|
    @param table            Table handle
 | 
						|
    @param buf              Row buffer
 | 
						|
    @param fields           Table fields
 | 
						|
  */
 | 
						|
  virtual int delete_row_values(TABLE *table, const unsigned char *buf,
 | 
						|
                                Field **fields);
 | 
						|
  /**
 | 
						|
    Constructor.
 | 
						|
    @param share            table share
 | 
						|
    @param pos              address of the m_pos position member
 | 
						|
  */
 | 
						|
  PFS_engine_table(const PFS_engine_table_share *share, void *pos)
 | 
						|
    : m_share_ptr(share), m_pos_ptr(pos),
 | 
						|
      m_normalizer(NULL), m_class_type(PFS_CLASS_NONE)
 | 
						|
  {}
 | 
						|
 | 
						|
  /** Table share. */
 | 
						|
  const PFS_engine_table_share *m_share_ptr;
 | 
						|
  /** Opaque pointer to the m_pos position of this cursor. */
 | 
						|
  void *m_pos_ptr;
 | 
						|
  /** Current normalizer */
 | 
						|
  time_normalizer *m_normalizer;
 | 
						|
  /** Current class type */
 | 
						|
  enum PFS_class_type m_class_type;
 | 
						|
};
 | 
						|
 | 
						|
/** Callback to open a table. */
 | 
						|
typedef PFS_engine_table* (*pfs_open_table_t)(void);
 | 
						|
/** Callback to write a row. */
 | 
						|
typedef int (*pfs_write_row_t)(TABLE *table,
 | 
						|
                               const unsigned char *buf, Field **fields);
 | 
						|
/** Callback to delete all rows. */
 | 
						|
typedef int (*pfs_delete_all_rows_t)(void);
 | 
						|
/** Callback to get a row count. */
 | 
						|
typedef ha_rows (*pfs_get_row_count_t)(void);
 | 
						|
 | 
						|
struct PFS_engine_table_share_state {
 | 
						|
  /** Schema integrity flag. */
 | 
						|
  bool m_checked;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  A PERFORMANCE_SCHEMA table share.
 | 
						|
  This data is shared by all the table handles opened on the same table.
 | 
						|
*/
 | 
						|
struct PFS_engine_table_share
 | 
						|
{
 | 
						|
  static void init_all_locks(void);
 | 
						|
  static void delete_all_locks(void);
 | 
						|
  /** Get the row count. */
 | 
						|
  ha_rows get_row_count(void) const;
 | 
						|
  /** Write a row. */
 | 
						|
  int write_row(TABLE *table, const unsigned char *buf, Field **fields) const;
 | 
						|
 | 
						|
  /** Table name. */
 | 
						|
  LEX_STRING m_name;
 | 
						|
  /** Table ACL. */
 | 
						|
  const ACL_internal_table_access *m_acl;
 | 
						|
  /** Open table function. */
 | 
						|
  pfs_open_table_t m_open_table;
 | 
						|
  /** Write row function. */
 | 
						|
  pfs_write_row_t m_write_row;
 | 
						|
  /** Delete all rows function. */
 | 
						|
  pfs_delete_all_rows_t m_delete_all_rows;
 | 
						|
  /** Get rows count function. */
 | 
						|
  pfs_get_row_count_t m_get_row_count;
 | 
						|
  /** Length of the m_pos position structure. */
 | 
						|
  uint m_ref_length;
 | 
						|
  /** The lock, stored on behalf of the SQL layer. */
 | 
						|
  THR_LOCK *m_thr_lock_ptr;
 | 
						|
  /** Table definition. */
 | 
						|
  LEX_STRING sql;
 | 
						|
  /** Table is available even if the Performance Schema is disabled. */
 | 
						|
  bool m_perpetual;
 | 
						|
  /** Table is optional. */
 | 
						|
  bool m_optional;
 | 
						|
  /** Dynamic state. */
 | 
						|
  PFS_engine_table_share_state *m_state;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for read only tables.
 | 
						|
  The only operation allowed is SELECT.
 | 
						|
*/
 | 
						|
class PFS_readonly_acl : public ACL_internal_table_access
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_readonly_acl() = default;
 | 
						|
 | 
						|
  ~PFS_readonly_acl() = default;
 | 
						|
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
/** Singleton instance of PFS_readonly_acl. */
 | 
						|
extern PFS_readonly_acl pfs_readonly_acl;
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for truncatable tables.
 | 
						|
  Operations allowed are SELECT and TRUNCATE.
 | 
						|
*/
 | 
						|
class PFS_truncatable_acl : public ACL_internal_table_access
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_truncatable_acl() = default;
 | 
						|
 | 
						|
  ~PFS_truncatable_acl() = default;
 | 
						|
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
/** Singleton instance of PFS_truncatable_acl. */
 | 
						|
extern PFS_truncatable_acl pfs_truncatable_acl;
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for updatable tables.
 | 
						|
  Operations allowed are SELECT and UPDATE.
 | 
						|
*/
 | 
						|
class PFS_updatable_acl : public ACL_internal_table_access
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_updatable_acl() = default;
 | 
						|
 | 
						|
  ~PFS_updatable_acl() = default;
 | 
						|
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
/** Singleton instance of PFS_updatable_acl. */
 | 
						|
extern PFS_updatable_acl pfs_updatable_acl;
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for editable tables.
 | 
						|
  Operations allowed are SELECT, INSERT, UPDATE, DELETE and TRUNCATE.
 | 
						|
*/
 | 
						|
class PFS_editable_acl : public ACL_internal_table_access
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_editable_acl() = default;
 | 
						|
 | 
						|
  ~PFS_editable_acl() = default;
 | 
						|
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
/** Singleton instance of PFS_editable_acl. */
 | 
						|
extern PFS_editable_acl pfs_editable_acl;
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for unknown tables.
 | 
						|
*/
 | 
						|
class PFS_unknown_acl : public ACL_internal_table_access
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_unknown_acl() = default;
 | 
						|
 | 
						|
  ~PFS_unknown_acl() = default;
 | 
						|
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
/** Singleton instance of PFS_unknown_acl. */
 | 
						|
extern PFS_unknown_acl pfs_unknown_acl;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for world readable tables.
 | 
						|
*/
 | 
						|
class PFS_readonly_world_acl : public PFS_readonly_acl
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_readonly_world_acl()
 | 
						|
  {}
 | 
						|
 | 
						|
  ~PFS_readonly_world_acl()
 | 
						|
  {}
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/** Singleton instance of PFS_readonly_world_acl */
 | 
						|
extern PFS_readonly_world_acl pfs_readonly_world_acl;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
Privileges for world readable truncatable tables.
 | 
						|
*/
 | 
						|
class PFS_truncatable_world_acl : public PFS_truncatable_acl
 | 
						|
{
 | 
						|
public:
 | 
						|
  PFS_truncatable_world_acl()
 | 
						|
  {}
 | 
						|
 | 
						|
  ~PFS_truncatable_world_acl()
 | 
						|
  {}
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
/** Singleton instance of PFS_readonly_world_acl */
 | 
						|
extern PFS_truncatable_world_acl pfs_truncatable_world_acl;
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Privileges for readable processlist tables.
 | 
						|
*/
 | 
						|
class PFS_readonly_processlist_acl : public PFS_readonly_acl {
 | 
						|
 public:
 | 
						|
  PFS_readonly_processlist_acl()
 | 
						|
  {}
 | 
						|
 | 
						|
  ~PFS_readonly_processlist_acl()
 | 
						|
  {}
 | 
						|
 | 
						|
  ACL_internal_access_result check(privilege_t want_access,
 | 
						|
    privilege_t *save_priv, bool any_combination_will_do) const override;
 | 
						|
};
 | 
						|
 | 
						|
/** Singleton instance of PFS_readonly_processlist_acl */
 | 
						|
extern PFS_readonly_processlist_acl pfs_readonly_processlist_acl;
 | 
						|
 | 
						|
 | 
						|
/** Position of a cursor, for simple iterations. */
 | 
						|
struct PFS_simple_index
 | 
						|
{
 | 
						|
  /** Current row index. */
 | 
						|
  uint m_index;
 | 
						|
 | 
						|
  /**
 | 
						|
    Constructor.
 | 
						|
    @param index the index initial value.
 | 
						|
  */
 | 
						|
  PFS_simple_index(uint index)
 | 
						|
    : m_index(index)
 | 
						|
  {}
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index at a given position.
 | 
						|
    @param index an index
 | 
						|
  */
 | 
						|
  void set_at(uint index)
 | 
						|
  { m_index= index; }
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index at a given position.
 | 
						|
    @param other a position
 | 
						|
  */
 | 
						|
  void set_at(const struct PFS_simple_index *other)
 | 
						|
  { m_index= other->m_index; }
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index after a given position.
 | 
						|
    @param other a position
 | 
						|
  */
 | 
						|
  void set_after(const struct PFS_simple_index *other)
 | 
						|
  { m_index= other->m_index + 1; }
 | 
						|
 | 
						|
  /** Set this index to the next record. */
 | 
						|
  void next(void)
 | 
						|
  { m_index++; }
 | 
						|
};
 | 
						|
 | 
						|
/** Position of a double cursor, for iterations using 2 nested loops. */
 | 
						|
struct PFS_double_index
 | 
						|
{
 | 
						|
  /** Outer index. */
 | 
						|
  uint m_index_1;
 | 
						|
  /** Current index within index_1. */
 | 
						|
  uint m_index_2;
 | 
						|
 | 
						|
  /**
 | 
						|
    Constructor.
 | 
						|
    @param index_1 the first index initial value.
 | 
						|
    @param index_2 the second index initial value.
 | 
						|
  */
 | 
						|
  PFS_double_index(uint index_1, uint index_2)
 | 
						|
    : m_index_1(index_1), m_index_2(index_2)
 | 
						|
  {}
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index at a given position.
 | 
						|
  */
 | 
						|
  void set_at(uint index_1, uint index_2)
 | 
						|
  {
 | 
						|
    m_index_1= index_1;
 | 
						|
    m_index_2= index_2;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index at a given position.
 | 
						|
    @param other a position
 | 
						|
  */
 | 
						|
  void set_at(const struct PFS_double_index *other)
 | 
						|
  {
 | 
						|
    m_index_1= other->m_index_1;
 | 
						|
    m_index_2= other->m_index_2;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index after a given position.
 | 
						|
    @param other a position
 | 
						|
  */
 | 
						|
  void set_after(const struct PFS_double_index *other)
 | 
						|
  {
 | 
						|
    m_index_1= other->m_index_1;
 | 
						|
    m_index_2= other->m_index_2 + 1;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
/** Position of a triple cursor, for iterations using 3 nested loops. */
 | 
						|
struct PFS_triple_index
 | 
						|
{
 | 
						|
  /** Outer index. */
 | 
						|
  uint m_index_1;
 | 
						|
  /** Current index within index_1. */
 | 
						|
  uint m_index_2;
 | 
						|
  /** Current index within index_2. */
 | 
						|
  uint m_index_3;
 | 
						|
 | 
						|
  /**
 | 
						|
    Constructor.
 | 
						|
    @param index_1 the first index initial value.
 | 
						|
    @param index_2 the second index initial value.
 | 
						|
    @param index_3 the third index initial value.
 | 
						|
  */
 | 
						|
  PFS_triple_index(uint index_1, uint index_2, uint index_3)
 | 
						|
    : m_index_1(index_1), m_index_2(index_2), m_index_3(index_3)
 | 
						|
  {}
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index at a given position.
 | 
						|
  */
 | 
						|
  void set_at(uint index_1, uint index_2, uint index_3)
 | 
						|
  {
 | 
						|
    m_index_1= index_1;
 | 
						|
    m_index_2= index_2;
 | 
						|
    m_index_3= index_3;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index at a given position.
 | 
						|
    @param other a position
 | 
						|
  */
 | 
						|
  void set_at(const struct PFS_triple_index *other)
 | 
						|
  {
 | 
						|
    m_index_1= other->m_index_1;
 | 
						|
    m_index_2= other->m_index_2;
 | 
						|
    m_index_3= other->m_index_3;
 | 
						|
  }
 | 
						|
 | 
						|
  /**
 | 
						|
    Set this index after a given position.
 | 
						|
    @param other a position
 | 
						|
  */
 | 
						|
  void set_after(const struct PFS_triple_index *other)
 | 
						|
  {
 | 
						|
    m_index_1= other->m_index_1;
 | 
						|
    m_index_2= other->m_index_2;
 | 
						|
    m_index_3= other->m_index_3 + 1;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
bool pfs_show_status(handlerton *hton, THD *thd,
 | 
						|
                     stat_print_fn *print, enum ha_stat_type stat);
 | 
						|
 | 
						|
int pfs_discover_table_names(handlerton *hton, LEX_CSTRING *db,
 | 
						|
                             MY_DIR *dir,
 | 
						|
                             handlerton::discovered_list *result);
 | 
						|
 | 
						|
/** @} */
 | 
						|
#endif
 |