GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
sql.c
Go to the documentation of this file.
1 
2 /*****************************************************************************
3 *
4 * MODULE: SQL statement parser library
5 *
6 * AUTHOR(S): lex.l and yac.y were originaly taken from unixODBC and
7 * probably written by Peter Harvey <pharvey@codebydesigns.com>,
8 * original modifications & added code by
9 * Radim Blazek <radim.blazek gmail.com>
10 * Glynn Clements <glynn gclements.plus.com>,
11 * Markus Neteler <neteler itc.it>,
12 * Martin Landa <landa.martin gmail.com>,
13 * Moritz Lennert <mlennert club.worldonline.be>,
14 * Hamish Bowman <hamish_b yahoo.com>,
15 * Daniel Calvelo Aros <dca.gis gmail.com>,
16 * Paul Kelly <paul-grass stjohnspoint.co.uk>,
17 * Alex Shevlakov <sixote yahoo.com>
18 *
19 * PURPOSE: Parse input string containing SQL statement to
20 * SQLPSTMT structure.
21 * SQL parser may be used by simple database drivers.
22 *
23 * COPYRIGHT: (C) 2000-2007 by the GRASS Development Team
24 *
25 * This program is free software under the GNU General Public
26 * License (>=v2). Read the file COPYING that comes with GRASS
27 * for details.
28 *
29 *****************************************************************************/
30 
31 #define SQLP_MAIN
32 
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <string.h>
36 #include <ctype.h>
37 #include <assert.h>
38 #include <grass/sqlp.h>
39 
40 /* save string to value */
41 int sqpSaveStr(SQLPVALUE * val, char *c)
42 {
43  int len = 0;
44 
45  len = strlen(c) + 1;
46  val->s = (char *)realloc(val->s, len);
47 
48  strcpy(val->s, c);
49 
50  return (1);
51 }
52 
53 void sqpInitValue(SQLPVALUE * val)
54 {
55  val->type = SQLP_NULL;
56  val->s = NULL;
57  val->i = 0;
58  val->d = 0.0;
59 }
60 
61 void sqpCopyValue(SQLPVALUE * from, SQLPVALUE * to)
62 {
63  to->type = from->type;
64 
65  if (to->s)
66  free(to->s);
67 
68  if (from->s)
69  to->s = strdup(from->s);
70 
71  to->i = from->i;
72  to->d = from->d;
73 }
74 
75 int sqpInitParser(SQLPSTMT * st)
76 {
77  sqlpStmt = st;
78  sqlpStmt->cur = sqlpStmt->stmt;
79 
80  sqlpStmt->errmsg[0] = '\0';
81  sqlpStmt->table[0] = '\0';
82  sqlpStmt->nCol = 0;
83  sqlpStmt->nVal = 0;
84  sqlpStmt->upperNodeptr = NULL;
85  sqlpStmt->orderCol = NULL;
86 
87  return (1);
88 }
89 
91 {
92  sqlpStmt->command = command;
93  return;
94 }
95 
96 void sqpTable(char *tbl)
97 {
98  strncpy(sqlpStmt->table, tbl, SQLP_MAX_TABLE);
99  return;
100 }
101 
102 void sqpColumn(char *col)
103 {
104  int i;
105 
106  i = sqlpStmt->nCol;
107  sqpAllocCol(sqlpStmt, i + 1);
108  sqpSaveStr(&(sqlpStmt->Col[i]), col);
109 
110  sqlpStmt->nCol++;
111  return;
112 }
113 
114 void sqpColumnDef(char *col, int type, int width, int decimals)
115 {
116  int i;
117 
118  i = sqlpStmt->nCol;
119  sqpAllocCol(sqlpStmt, i + 1);
120  sqpSaveStr(&(sqlpStmt->Col[i]), col);
121  sqlpStmt->ColType[i] = type;
122  sqlpStmt->ColWidth[i] = width;
123  sqlpStmt->ColDecim[i] = decimals;
124 
125  sqlpStmt->nCol++;
126  return;
127 }
128 
129 void sqpValue(char *strval, int intval, double dblval, int type)
130 {
131  int i;
132 
133  i = sqlpStmt->nVal;
134 
135  /* allocate space for cols because if in INSERT cols were not
136  * specified array for ColNum would not be allocated */
137  sqpAllocCol(sqlpStmt, i + 1);
138 
139  sqpAllocVal(sqlpStmt, i + 1);
140  sqlpStmt->Val[i].s = NULL;
141  sqlpStmt->Val[i].i = 0; /* not necessay I think */
142  sqlpStmt->Val[i].d = 0.0; /* not necessay I think */
143 
144  sqlpStmt->Val[i].type = type;
145  switch (type) {
146  case (SQLP_S):
147  sqpSaveStr(&(sqlpStmt->Val[i]), strval);
148  break;
149  case (SQLP_I):
150  sqlpStmt->Val[i].i = intval;
151  break;
152  case (SQLP_D):
153  sqlpStmt->Val[i].d = dblval;
154  break;
155  /* SQLP_NULL, nothing to do */
156  }
157 
158  sqlpStmt->nVal++;
159  return;
160 }
161 
162 void sqpAssignment(char *col, char *strval, int intval, double dblval,
163  SQLPNODE * expval, int type)
164 {
165  int i;
166 
167  i = sqlpStmt->nCol;
168 
169  sqpAllocCol(sqlpStmt, i + 1);
170  sqpSaveStr(&(sqlpStmt->Col[i]), col);
171 
172  sqpAllocVal(sqlpStmt, i + 1);
173  sqlpStmt->Val[i].s = NULL;
174  sqlpStmt->Val[i].i = 0; /* not necessay I think */
175  sqlpStmt->Val[i].d = 0.0; /* not necessay I think */
176 
177  sqlpStmt->Val[i].type = type;
178  switch (type) {
179  case (SQLP_S):
180  sqpSaveStr(&(sqlpStmt->Val[i]), strval);
181  break;
182  case (SQLP_I):
183  sqlpStmt->Val[i].i = intval;
184  break;
185  case (SQLP_D):
186  sqlpStmt->Val[i].d = dblval;
187  break;
188  case (SQLP_EXPR):
189  sqlpStmt->Val[i].expr = expval;
190  /* Don't do anything right now; come back to this when executing */
191  break;
192  /* SQLP_NULL, nothing to do */
193  }
194 
195  sqlpStmt->nCol++;
196  sqlpStmt->nVal++;
197  return;
198 }
199 
200 void sqpOrderColumn(char *col, int dir)
201 {
202  sqlpStmt->orderCol = (char *)realloc(sqlpStmt->orderCol, strlen(col) + 1);
203  strcpy(sqlpStmt->orderCol, col);
204  sqlpStmt->orderDir = dir;
205  return;
206 }
207 
208 /* Create and init new node */
209 SQLPNODE *sqpNewNode(void)
210 {
211  SQLPNODE *np;
212 
213  np = (SQLPNODE *) calloc(1, sizeof(SQLPNODE));
214  return np;
215 }
216 
217 SQLPNODE *sqpNewExpressionNode(int oper, SQLPNODE * left, SQLPNODE * right)
218 {
219  SQLPNODE *np;
220 
221  np = sqpNewNode();
222 
223  np->node_type = SQLP_NODE_EXPRESSION;
224  np->oper = oper;
225  np->left = left;
226  np->right = right;
227 
228  return np;
229 }
230 
231 SQLPNODE *sqpNewColumnNode(char *name)
232 {
233  SQLPNODE *np;
234 
235  np = sqpNewNode();
236 
237  np->node_type = SQLP_NODE_COLUMN;
238  np->column_name = strdup(name);
239 
240  return np;
241 }
242 
243 SQLPNODE *sqpNewValueNode(char *strval, int intval, double dblval, int type)
244 {
245  SQLPNODE *np;
246 
247  np = sqpNewNode();
248 
249  np->node_type = SQLP_NODE_VALUE;
250 
251  np->value.type = type;
252  if (strval)
253  np->value.s = strdup(strval);
254  np->value.i = intval;
255  np->value.d = dblval;
256 
257  return np;
258 }
259 
260 void sqpFreeNode(SQLPNODE * np)
261 {
262  if (!np)
263  return;
264 
265  if (np->left)
266  sqpFreeNode(np->left);
267 
268  if (np->right)
269  sqpFreeNode(np->right);
270 
271  if (np->column_name)
272  free(np->column_name);
273 
274  if (np->value.s)
275  free(np->value.s);
276 
277  free(np);
278 }
279 
280 int sqpOperatorCode(char *oper)
281 {
282  char *tmp, *ptr;
283 
284  /* Convert to lower case */
285  tmp = strdup(oper);
286  ptr = tmp;
287  while (*ptr) {
288  *ptr = tolower(*ptr);
289  ptr++;
290  }
291 
292  if (strcmp(oper, "=") == 0)
293  return SQLP_EQ;
294  else if (strcmp(oper, "<") == 0)
295  return SQLP_LT;
296  else if (strcmp(oper, "<=") == 0)
297  return SQLP_LE;
298  else if (strcmp(oper, ">") == 0)
299  return SQLP_GT;
300  else if (strcmp(oper, ">=") == 0)
301  return SQLP_GE;
302  else if (strcmp(oper, "<>") == 0)
303  return SQLP_NE;
304  else if (strcmp(oper, "~") == 0)
305  return SQLP_MTCH;
306  else if (strcmp(oper, "+") == 0)
307  return SQLP_ADD;
308  else if (strcmp(oper, "-") == 0)
309  return SQLP_SUBTR;
310  else if (strcmp(oper, "*") == 0)
311  return SQLP_MLTP;
312  else if (strcmp(oper, "/") == 0)
313  return SQLP_DIV;
314  else if (strcmp(oper, "and") == 0)
315  return SQLP_AND;
316  else if (strcmp(oper, "or") == 0)
317  return SQLP_OR;
318  else if (strcmp(oper, "not") == 0)
319  return SQLP_NOT;
320 
321  free(tmp);
322 
323  return 0;
324 }
325 
326 char *sqpOperatorName(int oper)
327 {
328  switch (oper) {
329  case SQLP_EQ:
330  return "=";
331  break;
332  case SQLP_LT:
333  return "<";
334  break;
335  case SQLP_LE:
336  return "<=";
337  break;
338  case SQLP_GT:
339  return ">";
340  break;
341  case SQLP_GE:
342  return ">=";
343  break;
344  case SQLP_NE:
345  return "<>";
346  break;
347  case SQLP_MTCH:
348  return "~";
349  break;
350  case SQLP_ADD:
351  return "+";
352  break;
353  case SQLP_SUBTR:
354  return "-";
355  break;
356  case SQLP_MLTP:
357  return "*";
358  break;
359  case SQLP_DIV:
360  return "/";
361  break;
362  case SQLP_AND:
363  return "AND";
364  break;
365  case SQLP_OR:
366  return "OR";
367  break;
368  case SQLP_NOT:
369  return "NOT";
370  break;
371  }
372  return "?";
373 }
int sqpAllocVal(SQLPSTMT *st, int n)
Definition: db/sqlp/alloc.c:58
string name
Definition: render.py:1314
void sqpColumn(char *col)
Definition: sql.c:102
void sqpFreeNode(SQLPNODE *np)
Definition: sql.c:260
SQLPNODE * sqpNewColumnNode(char *name)
Definition: sql.c:231
int sqpInitParser(SQLPSTMT *st)
Definition: sql.c:75
void sqpColumnDef(char *col, int type, int width, int decimals)
Definition: sql.c:114
tuple width
void sqpInitValue(SQLPVALUE *val)
Definition: sql.c:53
list command
Definition: render.py:1315
char * sqpOperatorName(int oper)
Definition: sql.c:326
int sqpOperatorCode(char *oper)
Definition: sql.c:280
void sqpTable(char *tbl)
Definition: sql.c:96
SQLPNODE * sqpNewValueNode(char *strval, int intval, double dblval, int type)
Definition: sql.c:243
SQLPNODE * sqpNewNode(void)
Definition: sql.c:209
void sqpOrderColumn(char *col, int dir)
Definition: sql.c:200
void sqpCopyValue(SQLPVALUE *from, SQLPVALUE *to)
Definition: sql.c:61
int sqpAllocCol(SQLPSTMT *st, int n)
Definition: db/sqlp/alloc.c:37
return NULL
Definition: dbfopen.c:1394
SQLPNODE * sqpNewExpressionNode(int oper, SQLPNODE *left, SQLPNODE *right)
Definition: sql.c:217
void free(void *)
int sqpSaveStr(SQLPVALUE *val, char *c)
Definition: sql.c:41
void sqpAssignment(char *col, char *strval, int intval, double dblval, SQLPNODE *expval, int type)
Definition: sql.c:162
void sqpValue(char *strval, int intval, double dblval, int type)
Definition: sql.c:129
void sqpCommand(int command)
Definition: sql.c:90