1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
/*
* Routines for handling of SET var TO statements
*
* $Id: variable.c,v 1.4 1997/04/23 03:17:16 scrappy Exp $
*
* $Log: variable.c,v $
* Revision 1.4 1997/04/23 03:17:16 scrappy
* To: Thomas Lockhart <Thomas.G.Lockhart@jpl.nasa.gov>
* Subject: Re: [PATCHES] SET DateStyle patches
*
* On Tue, 22 Apr 1997, Thomas Lockhart wrote:
*
* > Some more patches! These (try to) finish implementing SET variable TO value
* > for "DateStyle" (changed the name from simply "date" to be more descriptive).
* > This is based on code from Martin and Bruce (?), which was easy to modify.
* > The syntax is
* >
* > SET DateStyle TO 'iso'
* > SET DateStyle TO 'postgres'
* > SET DateStyle TO 'sql'
* > SET DateStyle TO 'european'
* > SET DateStyle TO 'noneuropean'
* > SET DateStyle TO 'us' (same as "noneuropean")
* > SET DateStyle TO 'default' (current same as "postgres,us")
* >
* > ("european" is just compared for the first 4 characters, and "noneuropean"
* > is compared for the first 7 to allow less typing).
* >
* > Multiple arguments are allowed, so SET datestyle TO 'sql,euro' is valid.
* >
* > My mods also try to implement "SHOW variable" and "RESET variable", but
* > that part just core dumps at the moment. I would guess that my errors
* > are obvious to someone who knows what they are doing with the parser stuff,
* > so if someone (Bruce and/or Martin??) could have it do the right thing
* > we will have a more complete set of what we need.
* >
* > Also, I would like to have a floating point precision global variable to
* > implement "SET precision TO 10" and perhaps "SET precision TO 10,2" for
* > float8 and float4, but I don't know how to do that for integer types rather
* > than strings. If someone is fixing the SHOW and RESET code, perhaps they can
* > add some hooks for me to do the floats while they are at it.
* >
* > I've left some remnants of variable structures in the source code which
* > I did not use in the interests of getting something working for v6.1.
* > We'll have time to clean things up for the next release...
*
* Revision 1.3 1997/04/17 13:50:30 scrappy
* From: "Martin J. Laubach" <mjl@CSlab.tuwien.ac.at>
* Subject: [HACKERS] Patch: set date to euro/us postgres/iso/sql
*
* Here a patch that implements a SET date for use by the datetime
* stuff. The syntax is
*
* SET date TO 'val[,val,...]'
*
* where val is us (us dates), euro (european dates), postgres,
* iso or sql.
*
* Thomas is working on the integration in his datetime module.
* I just needed to get the patch out before it went stale :)
*
* Revision 1.1 1997/04/10 16:52:07 mjl
* Initial revision
*/
/*-----------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "postgres.h"
#include "miscadmin.h"
#include "tcop/variable.h"
/*-----------------------------------------------------------------------*/
#if USE_EURODATES
#define DATE_EURO TRUE
#else
#define DATE_EURO FALSE
#endif
/*-----------------------------------------------------------------------*/
struct PGVariables PGVariables =
{
{ DATE_EURO, Date_Postgres }
};
/*-----------------------------------------------------------------------*/
static const char *get_token(char *buf, int size, const char *str)
{
if(!*str)
return NULL;
/* skip white space */
while(*str && (*str == ' ' || *str == '\t'))
str++;
/* copy until we hit white space or comma or end of string */
while(*str && *str != ' ' && *str != '\t' && *str != ',' && size-- > 1)
*buf++ = *str++;
*buf = '\0';
/* skip white space and comma*/
while(*str && (*str == ' ' || *str == '\t' || *str == ','))
str++;
return str;
}
/*-----------------------------------------------------------------------*/
static bool parse_null(const char *value)
{
return TRUE;
}
static bool show_null(const char *value)
{
return TRUE;
}
static bool reset_null(const char *value)
{
return TRUE;
}
static bool parse_date(const char *value)
{
char tok[32];
int dcnt = 0, ecnt = 0;
while((value = get_token(tok, sizeof(tok), value)) != 0)
{
/* Ugh. Somebody ought to write a table driven version -- mjl */
if(!strcasecmp(tok, "iso"))
{
DateStyle = USE_ISO_DATES;
dcnt++;
}
else if(!strcasecmp(tok, "sql"))
{
DateStyle = USE_SQL_DATES;
dcnt++;
}
else if(!strcasecmp(tok, "postgres"))
{
DateStyle = USE_POSTGRES_DATES;
dcnt++;
}
else if(!strncasecmp(tok, "euro", 4))
{
EuroDates = TRUE;
ecnt++;
}
else if((!strcasecmp(tok, "us"))
|| (!strncasecmp(tok, "noneuro", 7)))
{
EuroDates = FALSE;
ecnt++;
}
else if(!strcasecmp(tok, "default"))
{
DateStyle = USE_POSTGRES_DATES;
EuroDates = FALSE;
ecnt++;
}
else
{
elog(WARN, "Bad value for date (%s)", tok);
}
}
if(dcnt > 1 || ecnt > 1)
elog(NOTICE, "Conflicting settings for date");
return TRUE;
}
static bool show_date()
{
char buf[64];
sprintf( buf, "Date style is %s with%s European conventions",
((DateStyle == USE_ISO_DATES)? "iso": ((DateStyle == USE_ISO_DATES)? "sql": "postgres")),
((EuroDates)? "": "out"));
elog(NOTICE, buf, NULL);
return TRUE;
}
static bool reset_date()
{
DateStyle = USE_POSTGRES_DATES;
EuroDates = FALSE;
return TRUE;
}
/*-----------------------------------------------------------------------*/
struct VariableParsers
{
const char *name;
bool (*parser)(const char *);
bool (*show)();
bool (*reset)();
} VariableParsers[] =
{
{ "datestyle", parse_date, show_date, reset_date },
{ "timezone", parse_null, show_null, reset_null },
{ NULL, NULL, NULL }
};
/*-----------------------------------------------------------------------*/
bool SetPGVariable(const char *name, const char *value)
{
struct VariableParsers *vp;
for(vp = VariableParsers; vp->name; vp++)
{
if(!strcasecmp(vp->name, name))
return (vp->parser)(value);
}
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
}
/*-----------------------------------------------------------------------*/
bool GetPGVariable(const char *name)
{
struct VariableParsers *vp;
for(vp = VariableParsers; vp->name; vp++)
{
if(!strcasecmp(vp->name, name))
return (vp->show)();
}
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
}
/*-----------------------------------------------------------------------*/
bool ResetPGVariable(const char *name)
{
struct VariableParsers *vp;
for(vp = VariableParsers; vp->name; vp++)
{
if(!strcasecmp(vp->name, name))
return (vp->reset)();
}
elog(NOTICE, "Unrecognized variable %s", name);
return TRUE;
}
|