~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to gnulib/gettext.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
/* Convenience header for conditional use of GNU <libintl.h>.
 
2
   Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
 
3
 
 
4
   This program is free software; you can redistribute it and/or modify
 
5
   it under the terms of the GNU Lesser General Public License as published by
 
6
   the Free Software Foundation; either version 2, or (at your option)
 
7
   any later version.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
   GNU Lesser General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU Lesser General Public License along
 
15
   with this program; if not, write to the Free Software Foundation,
 
16
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
17
 
 
18
#ifndef _LIBGETTEXT_H
 
19
#define _LIBGETTEXT_H 1
 
20
 
 
21
/* NLS can be disabled through the configure --disable-nls option.  */
 
22
#if defined(ENABLE_NLS) && ENABLE_NLS
 
23
 
 
24
/* Get declarations of GNU message catalog functions.  */
 
25
# include <libintl.h>
 
26
 
 
27
/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
 
28
   the gettext() and ngettext() macros.  This is an alternative to calling
 
29
   textdomain(), and is useful for libraries.  */
 
30
# ifdef DEFAULT_TEXT_DOMAIN
 
31
#  undef gettext
 
32
#  define gettext(Msgid) \
 
33
     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
 
34
#  undef ngettext
 
35
#  define ngettext(Msgid1, Msgid2, N) \
 
36
     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
 
37
# endif
 
38
 
 
39
#else
 
40
 
 
41
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
 
42
   chokes if dcgettext is defined as a macro.  So include it now, to make
 
43
   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
 
44
   as well because people using "gettext.h" will not include <libintl.h>,
 
45
   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
 
46
   is OK.  */
 
47
#if defined(__sun)
 
48
# include <locale.h>
 
49
#endif
 
50
 
 
51
/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
 
52
   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
 
53
   it now, to make later inclusions of <libintl.h> a NOP.  */
 
54
#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
 
55
# include <cstdlib>
 
56
# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
 
57
#  include <libintl.h>
 
58
# endif
 
59
#endif
 
60
 
 
61
/* Disabled NLS.
 
62
   The casts to 'const char *' serve the purpose of producing warnings
 
63
   for invalid uses of the value returned from these functions.
 
64
   On pre-ANSI systems without 'const', the config.h file is supposed to
 
65
   contain "#define const".  */
 
66
# undef gettext
 
67
# define gettext(Msgid) ((const char *) (Msgid))
 
68
# undef dgettext
 
69
# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
 
70
# undef dcgettext
 
71
# define dcgettext(Domainname, Msgid, Category) \
 
72
    ((void) (Category), dgettext (Domainname, Msgid))
 
73
# undef ngettext
 
74
# define ngettext(Msgid1, Msgid2, N) \
 
75
    ((N) == 1 \
 
76
     ? ((void) (Msgid2), (const char *) (Msgid1)) \
 
77
     : ((void) (Msgid1), (const char *) (Msgid2)))
 
78
# undef dngettext
 
79
# define dngettext(Domainname, Msgid1, Msgid2, N) \
 
80
    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
 
81
# undef dcngettext
 
82
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
 
83
    ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
 
84
# undef textdomain
 
85
# define textdomain(Domainname) ((const char *) (Domainname))
 
86
# undef bindtextdomain
 
87
# define bindtextdomain(Domainname, Dirname) \
 
88
    ((void) (Domainname), (const char *) (Dirname))
 
89
# undef bind_textdomain_codeset
 
90
# define bind_textdomain_codeset(Domainname, Codeset) \
 
91
    ((void) (Domainname), (const char *) (Codeset))
 
92
 
 
93
#endif
 
94
 
 
95
/* A pseudo function call that serves as a marker for the automated
 
96
   extraction of messages, but does not call gettext().  The run-time
 
97
   translation is done at a different place in the code.
 
98
   The argument, String, should be a literal string.  Concatenated strings
 
99
   and other string expressions won't work.
 
100
   The macro's expansion is not parenthesized, so that it is suitable as
 
101
   initializer for static 'char[]' or 'const char[]' variables.  */
 
102
#define gettext_noop(String) String
 
103
 
 
104
/* The separator between msgctxt and msgid in a .mo file.  */
 
105
#define GETTEXT_CONTEXT_GLUE "\004"
 
106
 
 
107
/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
 
108
   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
 
109
   short and rarely need to change.
 
110
   The letter 'p' stands for 'particular' or 'special'.  */
 
111
#ifdef DEFAULT_TEXT_DOMAIN
 
112
# define pgettext(Msgctxt, Msgid) \
 
113
   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
 
114
#else
 
115
# define pgettext(Msgctxt, Msgid) \
 
116
   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
 
117
#endif
 
118
#define dpgettext(Domainname, Msgctxt, Msgid) \
 
119
  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
 
120
#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
 
121
  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
 
122
#ifdef DEFAULT_TEXT_DOMAIN
 
123
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
 
124
   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
 
125
#else
 
126
# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
 
127
   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
 
128
#endif
 
129
#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
 
130
  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
 
131
#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
 
132
  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
 
133
 
 
134
#ifdef __GNUC__
 
135
__inline
 
136
#else
 
137
#ifdef __cplusplus
 
138
inline
 
139
#endif
 
140
#endif
 
141
static const char *
 
142
pgettext_aux (const char *domain,
 
143
              const char *msg_ctxt_id, const char *msgid,
 
144
              int category)
 
145
{
 
146
  const char *translation = dcgettext (domain, msg_ctxt_id, category);
 
147
  if (translation == msg_ctxt_id)
 
148
    return msgid;
 
149
  else
 
150
    return translation;
 
151
}
 
152
 
 
153
#ifdef __GNUC__
 
154
__inline
 
155
#else
 
156
#ifdef __cplusplus
 
157
inline
 
158
#endif
 
159
#endif
 
160
static const char *
 
161
npgettext_aux (const char *domain,
 
162
               const char *msg_ctxt_id, const char *msgid,
 
163
               const char *msgid_plural, unsigned long int n,
 
164
               int category)
 
165
{
 
166
  const char *translation =
 
167
    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
 
168
  if (translation == msg_ctxt_id || translation == msgid_plural)
 
169
    return (n == 1 ? msgid : msgid_plural);
 
170
  else
 
171
    return translation;
 
172
}
 
173
 
 
174
/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
 
175
   can be arbitrary expressions.  But for string literals these macros are
 
176
   less efficient than those above.  */
 
177
 
 
178
#include <string.h>
 
179
 
 
180
#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
 
181
  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined(__STRICT_ANSI__)) \
 
182
   /* || __STDC_VERSION__ >= 199901L */ )
 
183
 
 
184
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
 
185
#include <stdlib.h>
 
186
#endif
 
187
 
 
188
#define pgettext_expr(Msgctxt, Msgid) \
 
189
  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
 
190
#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
 
191
  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
 
192
 
 
193
#ifdef __GNUC__
 
194
__inline
 
195
#else
 
196
#ifdef __cplusplus
 
197
inline
 
198
#endif
 
199
#endif
 
200
static const char *
 
201
dcpgettext_expr (const char *domain,
 
202
                 const char *msgctxt, const char *msgid,
 
203
                 int category)
 
204
{
 
205
  size_t msgctxt_len = strlen (msgctxt) + 1;
 
206
  size_t msgid_len = strlen (msgid) + 1;
 
207
  const char *translation;
 
208
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
 
209
  char msg_ctxt_id[msgctxt_len + msgid_len];
 
210
#else
 
211
  char buf[1024];
 
212
  char *msg_ctxt_id =
 
213
    (msgctxt_len + msgid_len <= sizeof (buf)
 
214
     ? buf
 
215
     : (char *) malloc (msgctxt_len + msgid_len));
 
216
  if (msg_ctxt_id != NULL)
 
217
#endif
 
218
    {
 
219
      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
 
220
      msg_ctxt_id[msgctxt_len - 1] = '\004';
 
221
      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
 
222
      translation = dcgettext (domain, msg_ctxt_id, category);
 
223
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
 
224
      if (msg_ctxt_id != buf)
 
225
        free (msg_ctxt_id);
 
226
#endif
 
227
      if (translation != msg_ctxt_id)
 
228
        return translation;
 
229
    }
 
230
  return msgid;
 
231
}
 
232
 
 
233
#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
 
234
  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
 
235
#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
 
236
  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
 
237
 
 
238
#ifdef __GNUC__
 
239
__inline
 
240
#else
 
241
#ifdef __cplusplus
 
242
inline
 
243
#endif
 
244
#endif
 
245
static const char *
 
246
dcnpgettext_expr (const char *domain,
 
247
                  const char *msgctxt, const char *msgid,
 
248
                  const char *msgid_plural, unsigned long int n,
 
249
                  int category)
 
250
{
 
251
  size_t msgctxt_len = strlen (msgctxt) + 1;
 
252
  size_t msgid_len = strlen (msgid) + 1;
 
253
  const char *translation;
 
254
#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
 
255
  char msg_ctxt_id[msgctxt_len + msgid_len];
 
256
#else
 
257
  char buf[1024];
 
258
  char *msg_ctxt_id =
 
259
    (msgctxt_len + msgid_len <= sizeof (buf)
 
260
     ? buf
 
261
     : (char *) malloc (msgctxt_len + msgid_len));
 
262
  if (msg_ctxt_id != NULL)
 
263
#endif
 
264
    {
 
265
      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
 
266
      msg_ctxt_id[msgctxt_len - 1] = '\004';
 
267
      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
 
268
      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
 
269
#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
 
270
      if (msg_ctxt_id != buf)
 
271
        free (msg_ctxt_id);
 
272
#endif
 
273
      if (!(translation == msg_ctxt_id || translation == msgid_plural))
 
274
        return translation;
 
275
    }
 
276
  return (n == 1 ? msgid : msgid_plural);
 
277
}
 
278
 
 
279
#endif /* _LIBGETTEXT_H */