CUBRID Engine  latest
esql_cursor.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * esql_cursor.c - Preprocessor routines for manipulating and
21  * storing cursor definitions.
22  */
23 
24 #ident "$Id$"
25 
26 #include "config.h"
27 
28 #include <stdlib.h>
29 #include "esql_misc.h"
30 #include "memory_alloc.h"
31 
32 enum
33 {
37 };
38 
41 static int next_cid = 0;
42 
43 static void pp_print_cursor (void *cp, void *fp);
44 /*
45  * pp_new_cursor() - Allocate (and enter in pp_cursor_table) a new CURSOR
46  * struct, initializing it with the given name and initialize the static
47  * and dynamic fields accordingly.
48  * return : CURSOR *
49  * name(in): A character string.
50  * static_stmt(in): A prepared CSQL SELECT statement, or NULL.
51  * length(in) :
52  * dynamic_stmt(in): A STMT pointer, or NULL.
53  * host_refs(in):
54  */
55 CURSOR *
56 pp_new_cursor (char *name, char *static_stmt, int length, STMT * dynamic_stmt, HOST_LOD * host_refs)
57 {
58  CURSOR *cursor;
59 
60  cursor = pp_lookup_cursor (name);
61  if (cursor && cursor->level >= pp_nesting_level)
62  {
64  return NULL;
65  }
66 
67  cursor = (CURSOR *) es_ht_alloc_new_symbol (sizeof (CURSOR));
68 
69  cursor->name = (unsigned char *) strdup (name);
70  cursor->cid = next_cid++;
71  cursor->level = pp_nesting_level;
72  cursor->next = NULL;
73  cursor->host_refs = host_refs;
74  cursor->static_stmt = (unsigned char *) (static_stmt ? strdup (static_stmt) : NULL);
75  cursor->stmtLength = length;
76  cursor->dynamic_stmt = dynamic_stmt;
77 
78  pp_cursor_table->add_symbol (pp_cursor_table, cursor);
79  pp_add_cursor_to_scope (cursor);
80 
81  return cursor;
82 }
83 
84 /*
85  * pp_free_cursor() - Free the given cursor.
86  * return : void
87  * cur(in): The cursor object to be freed.
88  */
89 void
91 {
92  free_and_init (cursor->name);
93 
94  if (cursor->static_stmt)
95  {
96  free_and_init (cursor->static_stmt);
97  }
98  if (cursor->host_refs)
99  {
100  pp_free_host_lod (cursor->host_refs);
101  }
102  /*
103  * Don't free any dynamic statement associated with this cursor;
104  * those statements have lifetimes that differ from the lifetimes of
105  * cursors.
106  */
107 
108  es_ht_free_symbol (cursor);
109 }
110 
111 /*
112  * pp_lookup_cursor() - Return the cursor structure with the given name,
113  * or NULL if not found.
114  * return : CURSOR *
115  * name(in): The name of the cursor to be found.
116  */
117 CURSOR *
118 pp_lookup_cursor (char *name)
119 {
120  CURSOR dummy;
121 
122  dummy.name = (unsigned char *) name;
123  return (CURSOR *) pp_cursor_table->find_symbol (pp_cursor_table, &dummy);
124 
125 }
126 
127 /*
128  * pp_cursor_init() - Initialize various module data.
129  * return : void
130  */
131 void
133 {
136 }
137 
138 /*
139  * pp_cursor_finish() - Teardown various module data.
140  * return : nothing
141  */
142 void
144 {
145  if (pp_cursor_table)
146  {
147  pp_cursor_table->free_table (pp_cursor_table, (HT_FREE_FN) pp_free_cursor);
148  }
149  if (pp_stmt_table)
150  {
151  pp_stmt_table->free_table (pp_stmt_table, (HT_FREE_FN) pp_free_stmt);
152  }
153  pp_cursor_table = NULL;
154  pp_stmt_table = NULL;
155 }
156 
157 /*
158  * pp_print_cursor() - Dump a printed representation of the cursor structure
159  * to the designated stream.
160  * return : nothing
161  * cursor(in): A pointer to a cursor to be printed.
162  * fp(in): The stream to print it on.
163  */
164 static void
165 pp_print_cursor (void *cp, void *fp)
166 {
167  CURSOR *cursor = (CURSOR *) cp;
168  FILE *stream = (FILE *) fp;
169 
170  fprintf (stream, " * %s (cid %d, level %d):\n", cursor->name, cursor->cid, cursor->level);
171 
172  if (cursor->static_stmt)
173  {
174  int i;
175  fprintf (stream, " *\t%s\n", cursor->static_stmt);
176  if (cursor->host_refs)
177  {
178  for (i = 0; i < cursor->host_refs->n_refs; ++i)
179  {
180  fprintf (stream, " *\thv[%d]: ", i);
181  pp_print_host_ref (&cursor->host_refs->refs[i], stream);
182  fputs ("\n", stream);
183  }
184  }
185  }
186  else
187  fprintf (stream, pp_get_msg (EX_CURSOR_SET, MSG_STMT_TITLE), cursor->dynamic_stmt->name);
188 
189  fputs (" *\n", stream);
190 }
191 
192 /*
193  * pp_print_cursors() - Print a representation of every declared cursor
194  * on the given stream.
195  * return : void
196  * fp(in): The stream on which to print the contents of the cursor table.
197  */
198 void
199 pp_print_cursors (FILE * fp)
200 {
201  if (!fp)
202  {
203  fp = stdout;
204  }
205 
206  if (pp_cursor_table->get_symbol_count (pp_cursor_table))
207  {
209  pp_cursor_table->print_table (pp_cursor_table, (void (*)()) pp_print_cursor, fp, 1); //TODO: get rid of function pointer conversion
210  }
211 }
212 
213 /*
214  * pp_remove_cursors_from_table() -
215  * returns/side-effects: nothing
216  * chain(in): The head of a list of cursors to be removed from
217  * the cursor table.
218  */
219 void
221 {
222  CURSOR *next = NULL;
223 
224  while (chain)
225  {
226  next = chain->next;
227  pp_cursor_table->remove_symbol (pp_cursor_table, chain);
228  chain = next;
229  }
230 
231 }
232 
233 /*
234  * pp_discard_cursor_chain() - Discard all of the cursors in the chain.
235  * return : void
236  * chain(in): The head of a list of cursors to be discarded.
237  */
238 void
240 {
241  CURSOR *next = NULL;
242 
243  while (chain)
244  {
245  next = chain->next;
246  pp_free_cursor (chain);
247  chain = next;
248  }
249 
250 }
251 
252 /*
253  * pp_new_stmt() - Build a new STMT record for an embedded dynamic statement
254  * (e.g., the thing that arises from an esql statement such as
255  * "PREPARE stmt FROM :buffer").
256  * return : STMT *
257  * name(in): The name of the dynamic statement.
258  *
259  */
260 STMT *
261 pp_new_stmt (char *name)
262 {
263  static int sid = 0;
264  STMT *stmt;
265  STMT dummy;
266 
267  dummy.name = (unsigned char *) name;
268  stmt = (STMT *) pp_stmt_table->find_symbol (pp_stmt_table, &dummy);
269  if (stmt != NULL)
270  {
271  return stmt;
272  }
273 
274  stmt = (STMT *) es_ht_alloc_new_symbol (sizeof (STMT));
275 
276  stmt->name = (unsigned char *) strdup (name);
277  stmt->sid = sid++;
278 
279  pp_stmt_table->add_symbol (pp_stmt_table, stmt);
280 
281  return stmt;
282 }
283 
284 /*
285  * pp_free_stmt() - Free the indicated structure.
286  * It is assumed to have already been removed from pp_stmt_table
287  * if it was ever in there.
288  * return : void
289  * stmt(in): A pointer to a STMT struct to be freed.
290  */
291 void
293 {
294  if (stmt == NULL)
295  {
296  return;
297  }
298 
299  free_and_init (stmt->name);
300  es_ht_free_symbol (stmt);
301 }
HASH_TAB * es_ht_make_table(unsigned maxsym, HT_HASH_FN hash_function, HT_CMP_FN cmp_function)
Definition: esql_hash.c:383
unsigned int pp_generic_case_hash(void *p)
Definition: esql_misc.c:70
void *(* add_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:37
void pp_print_host_ref(HOST_REF *ref, FILE *fp)
void pp_cursor_finish(void)
Definition: esql_cursor.c:143
static HASH_TAB * pp_stmt_table
Definition: esql_cursor.c:40
void *(* find_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:38
unsigned char * static_stmt
struct cursor * next
Definition: esql_cli.c:326
int(* get_symbol_count)(HASH_TAB *tbl)
Definition: esql_hash.h:42
int(* print_table)(HASH_TAB *tbl, void(*prnt)(), void *par, int srt)
Definition: esql_hash.h:41
void esql_yyverror(const char *,...)
static void pp_print_cursor(void *cp, void *fp)
Definition: esql_cursor.c:165
const char * pp_get_msg(int msg_set, int msg_num)
int pp_generic_case_cmp(void *p1, void *p2)
Definition: esql_misc.c:115
HOST_REF * refs
void pp_remove_cursors_from_table(CURSOR *chain)
Definition: esql_cursor.c:220
void(* HT_FREE_FN)(void *)
Definition: esql_hash.h:31
void es_ht_free_symbol(void *sym)
Definition: esql_hash.c:369
void pp_cursor_init(void)
Definition: esql_cursor.c:132
CURSOR * pp_new_cursor(char *name, char *static_stmt, int length, STMT *dynamic_stmt, HOST_LOD *host_refs)
Definition: esql_cursor.c:56
unsigned char * name
void(* remove_symbol)(HASH_TAB *tbl, void *sym)
Definition: esql_hash.h:40
#define NULL
Definition: freelistheap.h:34
static HASH_TAB * pp_cursor_table
Definition: esql_cursor.c:39
static int next_cid
Definition: esql_cursor.c:41
void pp_free_stmt(STMT *stmt)
Definition: esql_cursor.c:292
STMT * pp_new_stmt(char *name)
Definition: esql_cursor.c:261
CURSOR * pp_lookup_cursor(char *name)
Definition: esql_cursor.c:118
void pp_discard_cursor_chain(CURSOR *chain)
Definition: esql_cursor.c:239
void pp_print_cursors(FILE *fp)
Definition: esql_cursor.c:199
HOST_LOD * host_refs
#define free_and_init(ptr)
Definition: memory_alloc.h:147
void pp_add_cursor_to_scope(CURSOR *cursor)
void pp_free_host_lod(HOST_LOD *lod)
unsigned char * name
int i
Definition: dynamic_load.c:954
char * strdup(const char *str)
Definition: porting.c:901
void * es_ht_alloc_new_symbol(int size)
Definition: esql_hash.c:351
void(* free_table)(HASH_TAB *tbl, HT_FREE_FN free)
Definition: esql_hash.h:36
int pp_nesting_level
Definition: esql_declare.c:114
STMT * dynamic_stmt
void pp_free_cursor(CURSOR *cursor)
Definition: esql_cursor.c:90