~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/auth_file/auth_file.cc

  • Committer: Stewart Smith
  • Date: 2010-08-12 16:48:46 UTC
  • mto: This revision was merged to the branch mainline in revision 1707.
  • Revision ID: stewart@flamingspork.com-20100812164846-s9bhy47g60bvqs41
bug lp:611379 Equivalent queries with Impossible where return different results

The following two equivalent queries return different results in maria 5.2 and 5.3 (and identical results in mysql 5.5.5) :

SELECT SUM( DISTINCT table1 .`pk` ) FROM B table1 STRAIGHT_JOIN ( BB table2 JOIN CC ON table2 .`col_varchar_key` ) ON table2 .`pk` ;

SELECT * FROM ( SELECT SUM( DISTINCT table1 .`pk` ) FROM B table1 STRAIGHT_JOIN ( BB table2 JOIN CC ON table2 .`col_varchar_key` ) ON table2 .`pk` );

MariaDB returns 0 on the second query and NULL on the first, whereas MySQL returns NULL on both. In MariaDB, both EXPLAIN plans agree that "Impossible WHERE noticed after reading const tables"



We have some slightly different output in drizzle:

main.bug_lp611379 [ fail ]
drizzletest: At line 9: query 'explain select * from (select sum(distinct t1.a) from t1,t2 where t1.a=t2.a)
as t' failed: 1048: Column 'sum(distinct t1.a)' cannot be null

but the fix gets us the correct query results, although with slightly different execution plans.



This fix is directly ported from MariaDB.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#include <fstream>
23
23
#include <map>
24
24
#include <string>
25
 
#include <iostream>
26
 
 
27
 
#include <boost/program_options.hpp>
28
 
#include <boost/filesystem.hpp>
29
25
 
30
26
#include "drizzled/configmake.h"
31
27
#include "drizzled/plugin/authentication.h"
32
28
#include "drizzled/security_context.h"
33
29
#include "drizzled/util/convert.h"
34
30
#include "drizzled/algorithm/sha1.h"
35
 
#include "drizzled/module/option_map.h"
36
 
 
37
 
namespace po= boost::program_options;
38
 
namespace fs= boost::filesystem;
39
31
 
40
32
using namespace std;
41
33
using namespace drizzled;
43
35
namespace auth_file
44
36
{
45
37
 
46
 
static const fs::path DEFAULT_USERS_FILE= SYSCONFDIR "/drizzle.users";
 
38
static char* users_file= NULL;
 
39
static const char DEFAULT_USERS_FILE[]= SYSCONFDIR "/drizzle.users";
47
40
 
48
41
class AuthFile: public plugin::Authentication
49
42
{
50
 
  const fs::path users_file;
51
 
 
52
43
public:
53
44
 
54
 
  AuthFile(string name_arg, fs::path users_file_arg);
 
45
  AuthFile(string name_arg);
55
46
 
56
47
  /**
57
48
   * Retrieve the last error encountered in the class.
93
84
  /**
94
85
   * Cache or username:password entries from the file.
95
86
   */
96
 
  std::map<string, string> users;
 
87
  map<string, string> users;
97
88
};
98
89
 
99
 
AuthFile::AuthFile(string name_arg, fs::path users_file_arg):
 
90
AuthFile::AuthFile(string name_arg):
100
91
  plugin::Authentication(name_arg),
101
 
  users_file(users_file_arg),
102
92
  error(),
103
93
  users()
104
94
{
111
101
 
112
102
bool AuthFile::loadFile(void)
113
103
{
114
 
  ifstream file(users_file.string().c_str());
 
104
  ifstream file(users_file);
115
105
 
116
106
  if (!file.is_open())
117
107
  {
118
108
    error = "Could not open users file: ";
119
 
    error += users_file.string();
 
109
    error += users_file;
120
110
    return false;
121
111
  }
122
112
 
140
130
      password = string(line, password_offset + 1);
141
131
    }
142
132
 
143
 
    std::pair<std::map<std::string, std::string>::iterator, bool> result=
144
 
      users.insert(std::pair<std::string, std::string>(username, password));
145
 
 
 
133
    pair<map<string, string>::iterator, bool> result;
 
134
    result = users.insert(pair<string, string>(username, password));
146
135
    if (result.second == false)
147
136
    {
148
137
      error = "Duplicate entry found in users file: ";
204
193
 
205
194
bool AuthFile::authenticate(const SecurityContext &sctx, const string &password)
206
195
{
207
 
  std::map<std::string, std::string>::const_iterator user= users.find(sctx.getUser());
 
196
  map<string, string>::const_iterator user = users.find(sctx.getUser());
208
197
  if (user == users.end())
209
198
    return false;
210
199
 
219
208
 
220
209
static int init(module::Context &context)
221
210
{
222
 
  const module::option_map &vm= context.getOptions();
223
 
 
224
 
  AuthFile *auth_file = new AuthFile("auth_file", fs::path(vm["users"].as<string>()));
 
211
  AuthFile *auth_file = new AuthFile("auth_file");
225
212
  if (!auth_file->loadFile())
226
213
  {
227
214
    errmsg_printf(ERRMSG_LVL_ERROR, _("Could not load auth file: %s\n"),
231
218
  }
232
219
 
233
220
  context.add(auth_file);
234
 
  context.registerVariable(new sys_var_const_string_val("users", vm["users"].as<string>()));
235
221
  return 0;
236
222
}
237
223
 
 
224
static DRIZZLE_SYSVAR_STR(users,
 
225
                          users_file,
 
226
                          PLUGIN_VAR_READONLY,
 
227
                          N_("File to load for usernames and passwords"),
 
228
                          NULL, /* check func */
 
229
                          NULL, /* update func*/
 
230
                          DEFAULT_USERS_FILE /* default */);
238
231
 
239
 
static void init_options(drizzled::module::option_context &context)
 
232
static drizzle_sys_var* sys_variables[]=
240
233
{
241
 
  context("users", 
242
 
          po::value<string>()->default_value(DEFAULT_USERS_FILE.string()),
243
 
          N_("File to load for usernames and passwords"));
244
 
}
 
234
  DRIZZLE_SYSVAR(users),
 
235
  NULL
 
236
};
245
237
 
246
238
} /* namespace auth_file */
247
239
 
248
 
DRIZZLE_PLUGIN(auth_file::init, NULL, auth_file::init_options);
 
240
DRIZZLE_PLUGIN(auth_file::init, auth_file::sys_variables, NULL);