~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to libdrizzle/drizzle.h

  • 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:
1
 
/*
2
 
 * Drizzle Client & Protocol Library
3
 
 *
4
 
 * Copyright (C) 2008 Eric Day (eday@oddments.org)
5
 
 * All rights reserved.
6
 
 *
7
 
 * Redistribution and use in source and binary forms, with or without
8
 
 * modification, are permitted provided that the following conditions are
9
 
 * met:
10
 
 *
11
 
 *     * Redistributions of source code must retain the above copyright
12
 
 * notice, this list of conditions and the following disclaimer.
13
 
 *
14
 
 *     * Redistributions in binary form must reproduce the above
15
 
 * copyright notice, this list of conditions and the following disclaimer
16
 
 * in the documentation and/or other materials provided with the
17
 
 * distribution.
18
 
 *
19
 
 *     * The names of its contributors may not be used to endorse or
20
 
 * promote products derived from this software without specific prior
21
 
 * written permission.
22
 
 *
23
 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29
 
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30
 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31
 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33
 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 
 *
35
 
 */
36
 
 
37
 
/**
38
 
 * @file
39
 
 * @brief Drizzle Declarations
40
 
 */
41
 
 
42
 
#ifndef __DRIZZLE_H
43
 
#define __DRIZZLE_H
44
 
 
45
 
#if !defined(__cplusplus)
46
 
# include <stdbool.h>
47
 
#endif
48
 
 
49
 
#include <inttypes.h>
50
 
#include <sys/types.h>
51
 
 
52
 
#ifdef _WIN32
53
 
# include <winsock2.h>
54
 
# include <ws2tcpip.h>
55
 
 
56
 
# include <errno.h>
57
 
# define EINPROGRESS WSAEINPROGRESS
58
 
# define EALREADY WSAEALREADY
59
 
# define EISCONN WSAEISCONN
60
 
# define ENOBUFS WSAENOBUFS
61
 
# define ECONNREFUSED WSAECONNREFUSED
62
 
# define ENETUNREACH WSAENETUNREACH
63
 
# define ETIMEDOUT WSAETIMEDOUT
64
 
# define ECONNRESET WSAECONNRESET 
65
 
# define EADDRINUSE WSAEADDRINUSE
66
 
# define EOPNOTSUPP WSAEOPNOTSUPP
67
 
# define ENOPROTOOPT WSAENOPROTOOPT
68
 
 
69
 
typedef unsigned int in_port_t;
70
 
 
71
 
struct sockaddr_un
72
 
{
73
 
  short int sun_family;
74
 
  char sun_path[108];
75
 
};
76
 
 
77
 
 
78
 
#else
79
 
# include <sys/socket.h>
80
 
# include <netinet/in.h>
81
 
# include <arpa/inet.h>
82
 
# include <sys/un.h>
83
 
# include <netdb.h>
84
 
#endif
85
 
 
86
 
#include <poll.h>
87
 
 
88
 
#include <libdrizzle/visibility.h>
89
 
#include <libdrizzle/constants.h>
90
 
#include <libdrizzle/structs.h>
91
 
#include <libdrizzle/conn.h>
92
 
#include <libdrizzle/result.h>
93
 
#include <libdrizzle/column.h>
94
 
 
95
 
#ifdef  __cplusplus
96
 
extern "C" {
97
 
#endif
98
 
 
99
 
/**
100
 
 * @addtogroup drizzle Drizzle Declarations
101
 
 * @ingroup drizzle_client_interface
102
 
 * @ingroup drizzle_server_interface
103
 
 *
104
 
 * This is the core library structure that other structures (such as
105
 
 * connections) are created from.
106
 
 *
107
 
 * There is no locking within a single drizzle_st structure, so for threaded
108
 
 * applications you must either ensure isolation in the application or use
109
 
 * multiple drizzle_st structures (for example, one for each thread).
110
 
 * @{
111
 
 */
112
 
 
113
 
/**
114
 
 * Get library version string.
115
 
 *
116
 
 * @return Pointer to static buffer in library that holds the version string.
117
 
 */
118
 
DRIZZLE_API
119
 
const char *drizzle_version(void);
120
 
 
121
 
/**
122
 
 * Get bug report URL.
123
 
 *
124
 
 * @return Bug report URL string.
125
 
 */
126
 
DRIZZLE_API
127
 
const char *drizzle_bugreport(void);
128
 
 
129
 
/**
130
 
 * Get string with the name of the given verbose level.
131
 
 *
132
 
 * @param[in] verbose Verbose logging level.
133
 
 * @return String form of verbose level.
134
 
 */
135
 
DRIZZLE_API
136
 
const char *drizzle_verbose_name(drizzle_verbose_t verbose);
137
 
 
138
 
/**
139
 
 * Initialize a drizzle structure. Always check the return value even if passing
140
 
 * in a pre-allocated structure. Some other initialization may have failed.
141
 
 *
142
 
 * @param[in] drizzle Caller allocated structure, or NULL to allocate one.
143
 
 * @return On success, a pointer to the (possibly allocated) structure. On
144
 
 * failure this will be NULL.
145
 
 */
146
 
DRIZZLE_API
147
 
drizzle_st *drizzle_create(drizzle_st *drizzle);
148
 
 
149
 
/**
150
 
 * Clone a drizzle structure.
151
 
 *
152
 
 * @param[in] drizzle Caller allocated structure, or NULL to allocate one.
153
 
 * @param[in] from Drizzle structure to use as a source to clone from.
154
 
 * @return Same return as drizzle_create().
155
 
 */
156
 
DRIZZLE_API
157
 
drizzle_st *drizzle_clone(drizzle_st *drizzle, const drizzle_st *from);
158
 
 
159
 
/**
160
 
 * Free a drizzle structure.
161
 
 *
162
 
 * @param[in] drizzle Drizzle structure previously initialized with
163
 
 *  drizzle_create() or drizzle_clone().
164
 
 */
165
 
DRIZZLE_API
166
 
void drizzle_free(drizzle_st *drizzle);
167
 
 
168
 
/**
169
 
 * Return an error string for last error encountered.
170
 
 *
171
 
 * @param[in] drizzle Drizzle structure previously initialized with
172
 
 *  drizzle_create() or drizzle_clone().
173
 
 * @return Pointer to static buffer in library that holds an error string.
174
 
 */
175
 
DRIZZLE_API
176
 
const char *drizzle_error(const drizzle_st *drizzle);
177
 
 
178
 
/**
179
 
 * Value of errno in the case of a DRIZZLE_RETURN_ERRNO return value.
180
 
 *
181
 
 * @param[in] drizzle Drizzle structure previously initialized with
182
 
 *  drizzle_create() or drizzle_clone().
183
 
 * @return An errno value as defined in your system errno.h file.
184
 
 */
185
 
DRIZZLE_API
186
 
int drizzle_errno(const drizzle_st *drizzle);
187
 
 
188
 
/**
189
 
 * Get server defined error code for the last result read.
190
 
 *
191
 
 * @param[in] drizzle Drizzle structure previously initialized with
192
 
 *  drizzle_create() or drizzle_clone().
193
 
 * @return An error code given back in the server response.
194
 
 */
195
 
DRIZZLE_API
196
 
uint16_t drizzle_error_code(const drizzle_st *drizzle);
197
 
 
198
 
/**
199
 
 * Get SQL state code for the last result read.
200
 
 *
201
 
 * @param[in] drizzle Drizzle structure previously initialized with
202
 
 *  drizzle_create() or drizzle_clone().
203
 
 * @return A SQLSTATE code given back in the server response.
204
 
 */
205
 
DRIZZLE_API
206
 
const char *drizzle_sqlstate(const drizzle_st *drizzle);
207
 
 
208
 
/**
209
 
 * Get options for a drizzle structure.
210
 
 *
211
 
 * @param[in] drizzle Drizzle structure previously initialized with
212
 
 *  drizzle_create() or drizzle_clone().
213
 
 * @return Options set for the drizzle structure.
214
 
 */
215
 
DRIZZLE_API
216
 
drizzle_options_t drizzle_options(const drizzle_st *drizzle);
217
 
 
218
 
/**
219
 
 * Set options for a drizzle structure.
220
 
 *
221
 
 * @param[in] drizzle Drizzle structure previously initialized with
222
 
 *  drizzle_create() or drizzle_clone().
223
 
 * @param[in] options Available options for drizzle structure to set.
224
 
 */
225
 
DRIZZLE_API
226
 
void drizzle_set_options(drizzle_st *drizzle, drizzle_options_t options);
227
 
 
228
 
/**
229
 
 * Add options for a drizzle structure.
230
 
 *
231
 
 * @param[in] drizzle Drizzle structure previously initialized with
232
 
 *  drizzle_create() or drizzle_clone().
233
 
 * @param[in] options Available options for drizzle structure to add.
234
 
 */
235
 
DRIZZLE_API
236
 
void drizzle_add_options(drizzle_st *drizzle, drizzle_options_t options);
237
 
 
238
 
/**
239
 
 * Remove options for a drizzle structure.
240
 
 *
241
 
 * @param[in] drizzle Drizzle structure previously initialized with
242
 
 *  drizzle_create() or drizzle_clone().
243
 
 * @param[in] options Available options for drizzle structure to remove.
244
 
 */
245
 
DRIZZLE_API
246
 
void drizzle_remove_options(drizzle_st *drizzle, drizzle_options_t options);
247
 
 
248
 
/**
249
 
 * Get application context pointer.
250
 
 *
251
 
 * @param[in] drizzle Drizzle structure previously initialized with
252
 
 *  drizzle_create() or drizzle_clone().
253
 
 * @return Application context that was previously set, or NULL.
254
 
 */
255
 
DRIZZLE_API
256
 
void *drizzle_context(const drizzle_st *drizzle);
257
 
 
258
 
/**
259
 
 * Set application context pointer.
260
 
 *
261
 
 * @param[in] drizzle Drizzle structure previously initialized with
262
 
 *  drizzle_create() or drizzle_clone().
263
 
 * @param[in] context Application context to set.
264
 
 */
265
 
DRIZZLE_API
266
 
void drizzle_set_context(drizzle_st *drizzle, void *context);
267
 
 
268
 
/**
269
 
 * Set function to call when the drizzle structure is being cleaned up so
270
 
 * the application can clean up the context pointer.
271
 
 *
272
 
 * @param[in] drizzle Drizzle structure previously initialized with
273
 
 *  drizzle_create() or drizzle_clone().
274
 
 * @param[in] function Function to call to clean up drizzle context.
275
 
 */
276
 
DRIZZLE_API
277
 
void drizzle_set_context_free_fn(drizzle_st *drizzle,
278
 
                                 drizzle_context_free_fn *function);
279
 
 
280
 
/**
281
 
 * Get current socket I/O activity timeout value.
282
 
 *
283
 
 * @param[in] drizzle Drizzle structure previously initialized with
284
 
 *  drizzle_create() or drizzle_clone().
285
 
 * @return Timeout in milliseconds to wait for I/O activity. A negative value
286
 
 *  means an infinite timeout.
287
 
 */
288
 
DRIZZLE_API
289
 
int drizzle_timeout(const drizzle_st *drizzle);
290
 
 
291
 
/**
292
 
 * Set socket I/O activity timeout for connections in a Drizzle structure.
293
 
 *
294
 
 * @param[in] drizzle Drizzle structure previously initialized with
295
 
 *  drizzle_create() or drizzle_clone().
296
 
 * @param[in] timeout Milliseconds to wait for I/O activity. A negative value
297
 
 *  means an infinite timeout.
298
 
 */
299
 
DRIZZLE_API
300
 
void drizzle_set_timeout(drizzle_st *drizzle, int timeout);
301
 
 
302
 
/**
303
 
 * Get current verbosity threshold for logging messages.
304
 
 *
305
 
 * @param[in] drizzle Drizzle structure previously initialized with
306
 
 *  drizzle_create() or drizzle_clone().
307
 
 * @return Current verbosity threshold.
308
 
 */
309
 
DRIZZLE_API
310
 
drizzle_verbose_t drizzle_verbose(const drizzle_st *drizzle);
311
 
 
312
 
/**
313
 
 * Set verbosity threshold for logging messages. If this is set above
314
 
 * DRIZZLE_VERBOSE_NEVER and the drizzle_set_log_fn() callback is set to NULL,
315
 
 * messages are printed to STDOUT.
316
 
 *
317
 
 * @param[in] drizzle Drizzle structure previously initialized with
318
 
 *  drizzle_create() or drizzle_clone().
319
 
 * @param[in] verbose Verbosity threshold of what to log.
320
 
 */
321
 
DRIZZLE_API
322
 
void drizzle_set_verbose(drizzle_st *drizzle, drizzle_verbose_t verbose);
323
 
 
324
 
/**
325
 
 * Set logging function for a drizzle structure. This function is only called
326
 
 * for log messages that are above the verbosity threshold set with
327
 
 * drizzle_set_verbose().
328
 
 *
329
 
 * @param[in] drizzle Drizzle structure previously initialized with
330
 
 *  drizzle_create() or drizzle_clone().
331
 
 * @param[in] function Function to call when there is a logging message.
332
 
 * @param[in] context Argument to pass into the callback function.
333
 
 */
334
 
DRIZZLE_API
335
 
void drizzle_set_log_fn(drizzle_st *drizzle, drizzle_log_fn *function,
336
 
                        void *context);
337
 
 
338
 
/**
339
 
 * Set a custom I/O event watcher function for a drizzle structure. Used to
340
 
 * integrate libdrizzle with a custom event loop. The callback will be invoked
341
 
 * to register or deregister interest in events for a connection. When the
342
 
 * events are triggered, drizzle_con_set_revents() should be called to
343
 
 * indicate which events are ready. The event loop should stop waiting for
344
 
 * these events, as libdrizzle will call the callback again if it is still
345
 
 * interested. To resume processing, the libdrizzle function that returned
346
 
 * DRIZZLE_RETURN_IO_WAIT should be called again. See drizzle_event_watch_fn().
347
 
 *
348
 
 * @param[in] drizzle Drizzle structure previously initialized with
349
 
 *  drizzle_create() or drizzle_clone().
350
 
 * @param[in] function Function to call when there is an I/O event.
351
 
 * @param[in] context Argument to pass into the callback function.
352
 
 */
353
 
DRIZZLE_API
354
 
void drizzle_set_event_watch_fn(drizzle_st *drizzle,
355
 
                                drizzle_event_watch_fn *function,
356
 
                                void *context);
357
 
 
358
 
/**
359
 
 * Initialize a connection structure. Always check the return value even if
360
 
 * passing in a pre-allocated structure. Some other initialization may have
361
 
 * failed.
362
 
 *
363
 
 * @param[in] drizzle Drizzle structure previously initialized with
364
 
 *  drizzle_create() or drizzle_clone().
365
 
 * @param[in] con Caller allocated structure, or NULL to allocate one.
366
 
 * @return On success, a pointer to the (possibly allocated) structure. On
367
 
 *  failure this will be NULL.
368
 
 */
369
 
DRIZZLE_API
370
 
drizzle_con_st *drizzle_con_create(drizzle_st *drizzle, drizzle_con_st *con);
371
 
 
372
 
/**
373
 
 * Clone a connection structure.
374
 
 *
375
 
 * @param[in] drizzle Drizzle structure previously initialized with
376
 
 *  drizzle_create() or drizzle_clone().
377
 
 * @param[in] con Caller allocated structure, or NULL to allocate one.
378
 
 * @param[in] from Connection structure to use as a source to clone from.
379
 
 * @return Same return as drizzle_con_create().
380
 
 */
381
 
DRIZZLE_API
382
 
drizzle_con_st *drizzle_con_clone(drizzle_st *drizzle, drizzle_con_st *con,
383
 
                                  const drizzle_con_st *from);
384
 
 
385
 
/**
386
 
 * Free a connection structure.
387
 
 *
388
 
 * @param[in] con Connection structure previously initialized with
389
 
 *  drizzle_con_create(), drizzle_con_clone(), or related functions.
390
 
 */
391
 
DRIZZLE_API
392
 
void drizzle_con_free(drizzle_con_st *con);
393
 
 
394
 
/**
395
 
 * Free all connections in a drizzle structure.
396
 
 *
397
 
 * @param[in] drizzle Drizzle structure previously initialized with
398
 
 *  drizzle_create() or drizzle_clone().
399
 
 */
400
 
DRIZZLE_API
401
 
void drizzle_con_free_all(drizzle_st *drizzle);
402
 
 
403
 
/**
404
 
 * Wait for I/O on connections.
405
 
 *
406
 
 * @param[in] drizzle Drizzle structure previously initialized with
407
 
 *  drizzle_create() or drizzle_clone().
408
 
 * @return Standard drizzle return value.
409
 
 */
410
 
DRIZZLE_API
411
 
drizzle_return_t drizzle_con_wait(drizzle_st *drizzle);
412
 
 
413
 
/**
414
 
 * Get next connection that is ready for I/O.
415
 
 *
416
 
 * @param[in] drizzle Drizzle structure previously initialized with
417
 
 *  drizzle_create() or drizzle_clone().
418
 
 * @return Connection that is ready for I/O, or NULL if there are none.
419
 
 */
420
 
DRIZZLE_API
421
 
drizzle_con_st *drizzle_con_ready(drizzle_st *drizzle);
422
 
 
423
 
/** @} */
424
 
 
425
 
#ifdef  __cplusplus
426
 
}
427
 
#endif
428
 
 
429
 
#endif /* __DRIZZLE_H */