~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/rabbitmq/rabbitmq_log.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:
40
40
using namespace drizzled;
41
41
using namespace google;
42
42
 
43
 
namespace drizzle_plugin
44
 
{
 
43
/**
 
44
 * The hostname to connect to
 
45
 */
 
46
static char* sysvar_rabbitmq_host= NULL;
45
47
 
46
48
/**
47
49
 * rabbitmq port
48
50
 */
49
 
static port_constraint sysvar_rabbitmq_port;
50
 
 
51
 
 
52
 
RabbitMQLog::RabbitMQLog(const string &name, 
53
 
                         const std::string &exchange,
54
 
                         const std::string &routingkey,
55
 
                         RabbitMQHandler* mqHandler) :
56
 
  plugin::TransactionApplier(name),
57
 
  _rabbitMQHandler(mqHandler),
58
 
  _exchange(exchange),
59
 
  _routingkey(routingkey)
60
 
{ }
 
51
static int sysvar_rabbitmq_port= 0;
 
52
 
 
53
/**
 
54
 * rabbitmq username
 
55
 */
 
56
static char* sysvar_rabbitmq_username= NULL;
 
57
 
 
58
/**
 
59
 * rabbitmq password
 
60
 */
 
61
static char* sysvar_rabbitmq_password= NULL;
 
62
 
 
63
/**
 
64
 * rabbitmq virtualhost
 
65
 */
 
66
static char* sysvar_rabbitmq_virtualhost= NULL;
 
67
 
 
68
/**
 
69
 * rabbitmq exchangename
 
70
 */
 
71
static char* sysvar_rabbitmq_exchange= NULL;
 
72
 
 
73
/**
 
74
 * rabbitmq routing key
 
75
 */
 
76
static char* sysvar_rabbitmq_routingkey= NULL;
 
77
 
 
78
/**
 
79
 * Is the rabbitmq log enabled?
 
80
 */
 
81
static bool sysvar_rabbitmq_log_enabled= false;
 
82
 
 
83
/**
 
84
 * The name of the replicator plugin
 
85
 * to pair the rabbitmq log's applier with.
 
86
 * Defaults to "default"
 
87
 */
 
88
static char *sysvar_rabbitmq_use_replicator= NULL;
 
89
static const char DEFAULT_USE_REPLICATOR[]= "default";
 
90
 
 
91
 
 
92
RabbitMQLog::RabbitMQLog(const string name_arg, 
 
93
                         RabbitMQHandler* mqHandler)
 
94
  :plugin::TransactionApplier(name_arg)
 
95
{
 
96
  rabbitMQHandler= mqHandler;
 
97
}
61
98
 
62
99
RabbitMQLog::~RabbitMQLog() 
63
 
{ }
 
100
{
 
101
}
64
102
 
65
103
plugin::ReplicationReturnCode
66
104
RabbitMQLog::apply(Session &, const message::Transaction &to_apply)
67
105
{
68
106
  size_t message_byte_length= to_apply.ByteSize();
69
 
  uint8_t* buffer= new uint8_t[message_byte_length];
 
107
  uint8_t* buffer= static_cast<uint8_t *>(malloc(message_byte_length));
70
108
  if(buffer == NULL)
71
109
  {
72
110
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate enough memory to transaction message\n"));
77
115
  to_apply.SerializeWithCachedSizesToArray(buffer);
78
116
  try
79
117
  {
80
 
    _rabbitMQHandler->publish(buffer, 
81
 
                             int(message_byte_length), 
82
 
                             _exchange,
83
 
                             _routingkey);
 
118
    rabbitMQHandler->publish(buffer, 
 
119
                             int(message_byte_length), 
 
120
                             sysvar_rabbitmq_exchange, 
 
121
                             sysvar_rabbitmq_routingkey);
84
122
  }
85
123
  catch(exception& e)
86
124
  {
88
126
    deactivate();
89
127
    return plugin::UNKNOWN_ERROR;
90
128
  }
91
 
  delete[] buffer;
 
129
  free(buffer);
92
130
  return plugin::SUCCESS;
93
131
}
94
132
 
102
140
 */
103
141
static int init(drizzled::module::Context &context)
104
142
{
105
 
  const module::option_map &vm= context.getOptions();
106
 
  
107
 
  try 
108
 
  {
109
 
    rabbitmqHandler= new RabbitMQHandler(vm["host"].as<string>(),
110
 
                                         sysvar_rabbitmq_port, 
111
 
                                         vm["username"].as<string>(), 
112
 
                                         vm["password"].as<string>(), 
113
 
                                         vm["virtualhost"].as<string>());
114
 
  } 
115
 
  catch (exception& e) 
116
 
  {
117
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the RabbitMQHandler.  Got error: %s\n"),
118
 
                  e.what());
119
 
    return 1;
120
 
  }
121
 
  try 
122
 
  {
123
 
    rabbitmqLogger= new RabbitMQLog("rabbit_log_applier",
124
 
                                    vm["exchange"].as<string>(),
125
 
                                    vm["routingkey"].as<string>(),
126
 
                                    rabbitmqHandler);
127
 
  } 
128
 
  catch (exception& e) 
129
 
  {
130
 
    errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the RabbitMQLog instance.  Got error: %s\n"), 
131
 
                  e.what());
132
 
    return 1;
133
 
  }
134
 
 
135
 
  context.add(rabbitmqLogger);
136
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
137
 
  replication_services.attachApplier(rabbitmqLogger, vm["use-replicator"].as<string>());
138
 
 
139
 
  context.registerVariable(new sys_var_const_string_val("host", vm["host"].as<string>()));
140
 
  context.registerVariable(new sys_var_constrained_value_readonly<in_port_t>("port", sysvar_rabbitmq_port));
141
 
  context.registerVariable(new sys_var_const_string_val("username", vm["username"].as<string>()));
142
 
  context.registerVariable(new sys_var_const_string_val("password", vm["password"].as<string>()));
143
 
  context.registerVariable(new sys_var_const_string_val("virtualhost", vm["virtualhost"].as<string>()));
144
 
  context.registerVariable(new sys_var_const_string_val("exchange", vm["exchange"].as<string>()));
145
 
  context.registerVariable(new sys_var_const_string_val("routingkey", vm["routingkey"].as<string>()));
146
 
 
 
143
  if(sysvar_rabbitmq_log_enabled)
 
144
  {
 
145
    try 
 
146
    {
 
147
      rabbitmqHandler= new RabbitMQHandler(sysvar_rabbitmq_host, 
 
148
                                           sysvar_rabbitmq_port, 
 
149
                                           sysvar_rabbitmq_username, 
 
150
                                           sysvar_rabbitmq_password, 
 
151
                                           sysvar_rabbitmq_virtualhost);
 
152
    } 
 
153
    catch (exception& e) 
 
154
    {
 
155
      errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the RabbitMQHandler.  Got error: %s\n"),
 
156
                    e.what());
 
157
      return 1;
 
158
    }
 
159
    try 
 
160
    {
 
161
      rabbitmqLogger= new RabbitMQLog("rabbit_log_applier", rabbitmqHandler);
 
162
    } 
 
163
    catch (exception& e) 
 
164
    {
 
165
      errmsg_printf(ERRMSG_LVL_ERROR, _("Failed to allocate the RabbitMQLog instance.  Got error: %s\n"), 
 
166
                    e.what());
 
167
      return 1;
 
168
    }
 
169
 
 
170
    context.add(rabbitmqLogger);
 
171
    ReplicationServices &replication_services= ReplicationServices::singleton();
 
172
    string replicator_name(sysvar_rabbitmq_use_replicator);
 
173
    replication_services.attachApplier(rabbitmqLogger, replicator_name);
 
174
    return 0;
 
175
  }
147
176
  return 0;
148
177
}
149
178
 
150
179
 
 
180
static DRIZZLE_SYSVAR_BOOL(enable,
 
181
                           sysvar_rabbitmq_log_enabled,
 
182
                           PLUGIN_VAR_NOCMDARG,
 
183
                           N_("Enable rabbitmq log"),
 
184
                           NULL, /* check func */
 
185
                           NULL, /* update func */
 
186
                           false /* default */);
 
187
 
 
188
 
 
189
static DRIZZLE_SYSVAR_STR(hostname,
 
190
                          sysvar_rabbitmq_host,
 
191
                          PLUGIN_VAR_READONLY,
 
192
                          N_("Host name to connect to"),
 
193
                          NULL, /* check func */
 
194
                          NULL, /* update func*/
 
195
                          "localhost" /* default */);
 
196
 
 
197
 
 
198
static DRIZZLE_SYSVAR_INT(port,
 
199
                          sysvar_rabbitmq_port,
 
200
                          PLUGIN_VAR_READONLY,
 
201
                          N_("RabbitMQ Port"),
 
202
                          NULL, /* check func */
 
203
                          NULL, /* update func */
 
204
                          5672, /* default */
 
205
                          0,
 
206
                          65535,
 
207
                          0);
 
208
 
 
209
static DRIZZLE_SYSVAR_STR(username,
 
210
                          sysvar_rabbitmq_username,
 
211
                          PLUGIN_VAR_READONLY,
 
212
                          N_("RabbitMQ username"),
 
213
                          NULL, /* check func */
 
214
                          NULL, /* update func*/
 
215
                          "guest" /* default */);
 
216
 
 
217
static DRIZZLE_SYSVAR_STR(password,
 
218
                          sysvar_rabbitmq_password,
 
219
                          PLUGIN_VAR_READONLY,
 
220
                          N_("RabbitMQ password"),
 
221
                          NULL, /* check func */
 
222
                          NULL, /* update func*/
 
223
                          "guest" /* default */);
 
224
 
 
225
static DRIZZLE_SYSVAR_STR(virtualhost,
 
226
                          sysvar_rabbitmq_virtualhost,
 
227
                          PLUGIN_VAR_READONLY,
 
228
                          N_("RabbitMQ virtualhost"),
 
229
                          NULL, /* check func */
 
230
                          NULL, /* update func*/
 
231
                          "/" /* default */);
 
232
 
 
233
static DRIZZLE_SYSVAR_STR(exchange,
 
234
                          sysvar_rabbitmq_exchange,
 
235
                          PLUGIN_VAR_READONLY,
 
236
                          N_("Name of RabbitMQ exchange to publish to"),
 
237
                          NULL, /* check func */
 
238
                          NULL, /* update func*/
 
239
                          "ReplicationExchange" /* default */);
 
240
 
 
241
static DRIZZLE_SYSVAR_STR(routingkey,
 
242
                          sysvar_rabbitmq_routingkey,
 
243
                          PLUGIN_VAR_READONLY,
 
244
                          N_("Name of RabbitMQ routing key to use"),
 
245
                          NULL, /* check func */
 
246
                          NULL, /* update func*/
 
247
                          "ReplicationRoutingKey" /* default */);
 
248
 
 
249
static DRIZZLE_SYSVAR_STR(use_replicator,
 
250
                          sysvar_rabbitmq_use_replicator,
 
251
                          PLUGIN_VAR_READONLY,
 
252
                          N_("Name of the replicator plugin to use (default='default_replicator')"),
 
253
                          NULL, /* check func */
 
254
                          NULL, /* update func*/
 
255
                          DEFAULT_USE_REPLICATOR /* default */);
 
256
 
151
257
static void init_options(drizzled::module::option_context &context)
152
258
{
153
 
  context("host", 
154
 
          po::value<string>()->default_value("localhost"),
155
 
          N_("Host name to connect to"));
156
 
  context("port",
157
 
          po::value<port_constraint>(&sysvar_rabbitmq_port)->default_value(5672),
158
 
          N_("Port to connect to"));
159
 
  context("virtualhost",
160
 
          po::value<string>()->default_value("/"),
161
 
          N_("RabbitMQ virtualhost"));
162
 
  context("username",
163
 
          po::value<string>()->default_value("guest"),
164
 
          N_("RabbitMQ username"));
165
 
  context("password",
166
 
          po::value<string>()->default_value("guest"),
167
 
          N_("RabbitMQ password"));
168
 
  context("use-replicator",
169
 
          po::value<string>()->default_value("default_replicator"),
170
 
          N_("Name of the replicator plugin to use (default='default_replicator')"));
171
 
  context("exchange",
172
 
          po::value<string>()->default_value("ReplicationExchange"),
173
 
          N_("Name of RabbitMQ exchange to publish to"));
174
 
  context("routingkey",
175
 
          po::value<string>()->default_value("ReplicationRoutingKey"),
176
 
          N_("Name of RabbitMQ routing key to use"));
 
259
  context ("enable",
 
260
           po::value<bool>(&sysvar_rabbitmq_log_enabled)->default_value(false)->zero_tokens(),
 
261
           N_("Enable rabbitmq log"));
177
262
}
178
263
 
179
 
} /* namespace drizzle_plugin */
 
264
static drizzle_sys_var* system_variables[]= {
 
265
  DRIZZLE_SYSVAR(enable),
 
266
  DRIZZLE_SYSVAR(hostname),
 
267
  DRIZZLE_SYSVAR(port),
 
268
  DRIZZLE_SYSVAR(username),
 
269
  DRIZZLE_SYSVAR(password),
 
270
  DRIZZLE_SYSVAR(virtualhost),
 
271
  DRIZZLE_SYSVAR(exchange),
 
272
  DRIZZLE_SYSVAR(routingkey),
 
273
  DRIZZLE_SYSVAR(use_replicator),
 
274
  NULL
 
275
};
180
276
 
181
 
DRIZZLE_PLUGIN(drizzle_plugin::init, NULL, drizzle_plugin::init_options);
 
277
DRIZZLE_PLUGIN(init, system_variables, init_options);
182
278