1 /* Generated by re2c 0.13.5 on Thu Apr 19 12:42:11 2012 */
2 #line 1 "ext/pdo/pdo_sql_parser.re"
3 /*
4 +----------------------------------------------------------------------+
5 | PHP Version 5 |
6 +----------------------------------------------------------------------+
7 | Copyright (c) 1997-2013 The PHP Group |
8 +----------------------------------------------------------------------+
9 | This source file is subject to version 3.01 of the PHP license, |
10 | that is bundled with this package in the file LICENSE, and is |
11 | available through the world-wide-web at the following url: |
12 | http://www.php.net/license/3_01.txt |
13 | If you did not receive a copy of the PHP license and are unable to |
14 | obtain it through the world-wide-web, please send a note to |
15 | license@php.net so we can mail you a copy immediately. |
16 +----------------------------------------------------------------------+
17 | Author: George Schlossnagle <george@omniti.com> |
18 +----------------------------------------------------------------------+
19 */
20
21 /* $Id$ */
22
23 #include "php.h"
24 #include "php_pdo_driver.h"
25 #include "php_pdo_int.h"
26
27 #define PDO_PARSER_TEXT 1
28 #define PDO_PARSER_BIND 2
29 #define PDO_PARSER_BIND_POS 3
30 #define PDO_PARSER_EOI 4
31
32 #define RET(i) {s->cur = cursor; return i; }
33 #define SKIP_ONE(i) {s->cur = s->tok + 1; return i; }
34
35 #define YYCTYPE unsigned char
36 #define YYCURSOR cursor
37 #define YYLIMIT s->end
38 #define YYMARKER s->ptr
39 #define YYFILL(n) { RET(PDO_PARSER_EOI); }
40
41 typedef struct Scanner {
42 char *ptr, *cur, *tok, *end;
43 } Scanner;
44
scan(Scanner * s)45 static int scan(Scanner *s)
46 {
47 char *cursor = s->cur;
48
49 s->tok = cursor;
50 #line 55 "ext/pdo/pdo_sql_parser.re"
51
52
53
54 #line 55 "ext/pdo/pdo_sql_parser.c"
55 {
56 YYCTYPE yych;
57 unsigned int yyaccept = 0;
58
59 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
60 yych = *YYCURSOR;
61 switch (yych) {
62 case 0x00: goto yy2;
63 case '"': goto yy3;
64 case '\'': goto yy5;
65 case '-': goto yy11;
66 case '/': goto yy9;
67 case ':': goto yy6;
68 case '?': goto yy7;
69 default: goto yy12;
70 }
71 yy2:
72 YYCURSOR = YYMARKER;
73 switch (yyaccept) {
74 case 0: goto yy4;
75 case 1: goto yy10;
76 }
77 yy3:
78 yyaccept = 0;
79 yych = *(YYMARKER = ++YYCURSOR);
80 if (yych >= 0x01) goto yy41;
81 yy4:
82 #line 63 "ext/pdo/pdo_sql_parser.re"
83 { SKIP_ONE(PDO_PARSER_TEXT); }
84 #line 85 "ext/pdo/pdo_sql_parser.c"
85 yy5:
86 yyaccept = 0;
87 yych = *(YYMARKER = ++YYCURSOR);
88 if (yych <= 0x00) goto yy4;
89 goto yy36;
90 yy6:
91 yych = *++YYCURSOR;
92 switch (yych) {
93 case '0':
94 case '1':
95 case '2':
96 case '3':
97 case '4':
98 case '5':
99 case '6':
100 case '7':
101 case '8':
102 case '9':
103 case 'A':
104 case 'B':
105 case 'C':
106 case 'D':
107 case 'E':
108 case 'F':
109 case 'G':
110 case 'H':
111 case 'I':
112 case 'J':
113 case 'K':
114 case 'L':
115 case 'M':
116 case 'N':
117 case 'O':
118 case 'P':
119 case 'Q':
120 case 'R':
121 case 'S':
122 case 'T':
123 case 'U':
124 case 'V':
125 case 'W':
126 case 'X':
127 case 'Y':
128 case 'Z':
129 case '_':
130 case 'a':
131 case 'b':
132 case 'c':
133 case 'd':
134 case 'e':
135 case 'f':
136 case 'g':
137 case 'h':
138 case 'i':
139 case 'j':
140 case 'k':
141 case 'l':
142 case 'm':
143 case 'n':
144 case 'o':
145 case 'p':
146 case 'q':
147 case 'r':
148 case 's':
149 case 't':
150 case 'u':
151 case 'v':
152 case 'w':
153 case 'x':
154 case 'y':
155 case 'z': goto yy32;
156 case ':':
157 case '?': goto yy29;
158 default: goto yy4;
159 }
160 yy7:
161 ++YYCURSOR;
162 switch ((yych = *YYCURSOR)) {
163 case ':':
164 case '?': goto yy29;
165 default: goto yy8;
166 }
167 yy8:
168 #line 62 "ext/pdo/pdo_sql_parser.re"
169 { RET(PDO_PARSER_BIND_POS); }
170 #line 171 "ext/pdo/pdo_sql_parser.c"
171 yy9:
172 ++YYCURSOR;
173 switch ((yych = *YYCURSOR)) {
174 case '*': goto yy19;
175 default: goto yy13;
176 }
177 yy10:
178 #line 65 "ext/pdo/pdo_sql_parser.re"
179 { RET(PDO_PARSER_TEXT); }
180 #line 181 "ext/pdo/pdo_sql_parser.c"
181 yy11:
182 yych = *++YYCURSOR;
183 switch (yych) {
184 case '-': goto yy14;
185 default: goto yy13;
186 }
187 yy12:
188 ++YYCURSOR;
189 if (YYLIMIT <= YYCURSOR) YYFILL(1);
190 yych = *YYCURSOR;
191 yy13:
192 switch (yych) {
193 case 0x00:
194 case '"':
195 case '\'':
196 case ':':
197 case '?': goto yy10;
198 default: goto yy12;
199 }
200 yy14:
201 ++YYCURSOR;
202 if (YYLIMIT <= YYCURSOR) YYFILL(1);
203 yych = *YYCURSOR;
204 switch (yych) {
205 case 0x00:
206 case '"':
207 case '\'':
208 case ':':
209 case '?': goto yy17;
210 case '\n':
211 case '\r': goto yy12;
212 default: goto yy14;
213 }
214 yy16:
215 #line 64 "ext/pdo/pdo_sql_parser.re"
216 { RET(PDO_PARSER_TEXT); }
217 #line 218 "ext/pdo/pdo_sql_parser.c"
218 yy17:
219 ++YYCURSOR;
220 if (YYLIMIT <= YYCURSOR) YYFILL(1);
221 yych = *YYCURSOR;
222 switch (yych) {
223 case '\n':
224 case '\r': goto yy16;
225 default: goto yy17;
226 }
227 yy19:
228 yyaccept = 1;
229 YYMARKER = ++YYCURSOR;
230 if (YYLIMIT <= YYCURSOR) YYFILL(1);
231 yych = *YYCURSOR;
232 switch (yych) {
233 case 0x00:
234 case '"':
235 case '\'':
236 case ':':
237 case '?': goto yy21;
238 case '*': goto yy23;
239 default: goto yy19;
240 }
241 yy21:
242 ++YYCURSOR;
243 if (YYLIMIT <= YYCURSOR) YYFILL(1);
244 yych = *YYCURSOR;
245 switch (yych) {
246 case '*': goto yy26;
247 default: goto yy21;
248 }
249 yy23:
250 yyaccept = 1;
251 YYMARKER = ++YYCURSOR;
252 if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
253 yych = *YYCURSOR;
254 switch (yych) {
255 case 0x00:
256 case '"':
257 case '\'':
258 case ':':
259 case '?': goto yy21;
260 case '*': goto yy23;
261 case '/': goto yy25;
262 default: goto yy19;
263 }
264 yy25:
265 yych = *++YYCURSOR;
266 switch (yych) {
267 case 0x00:
268 case '"':
269 case '\'':
270 case ':':
271 case '?': goto yy16;
272 default: goto yy12;
273 }
274 yy26:
275 ++YYCURSOR;
276 if (YYLIMIT <= YYCURSOR) YYFILL(1);
277 yych = *YYCURSOR;
278 switch (yych) {
279 case '*': goto yy26;
280 case '/': goto yy28;
281 default: goto yy21;
282 }
283 yy28:
284 yych = *++YYCURSOR;
285 goto yy16;
286 yy29:
287 ++YYCURSOR;
288 if (YYLIMIT <= YYCURSOR) YYFILL(1);
289 yych = *YYCURSOR;
290 switch (yych) {
291 case ':':
292 case '?': goto yy29;
293 default: goto yy31;
294 }
295 yy31:
296 #line 60 "ext/pdo/pdo_sql_parser.re"
297 { RET(PDO_PARSER_TEXT); }
298 #line 299 "ext/pdo/pdo_sql_parser.c"
299 yy32:
300 ++YYCURSOR;
301 if (YYLIMIT <= YYCURSOR) YYFILL(1);
302 yych = *YYCURSOR;
303 switch (yych) {
304 case '0':
305 case '1':
306 case '2':
307 case '3':
308 case '4':
309 case '5':
310 case '6':
311 case '7':
312 case '8':
313 case '9':
314 case 'A':
315 case 'B':
316 case 'C':
317 case 'D':
318 case 'E':
319 case 'F':
320 case 'G':
321 case 'H':
322 case 'I':
323 case 'J':
324 case 'K':
325 case 'L':
326 case 'M':
327 case 'N':
328 case 'O':
329 case 'P':
330 case 'Q':
331 case 'R':
332 case 'S':
333 case 'T':
334 case 'U':
335 case 'V':
336 case 'W':
337 case 'X':
338 case 'Y':
339 case 'Z':
340 case '_':
341 case 'a':
342 case 'b':
343 case 'c':
344 case 'd':
345 case 'e':
346 case 'f':
347 case 'g':
348 case 'h':
349 case 'i':
350 case 'j':
351 case 'k':
352 case 'l':
353 case 'm':
354 case 'n':
355 case 'o':
356 case 'p':
357 case 'q':
358 case 'r':
359 case 's':
360 case 't':
361 case 'u':
362 case 'v':
363 case 'w':
364 case 'x':
365 case 'y':
366 case 'z': goto yy32;
367 default: goto yy34;
368 }
369 yy34:
370 #line 61 "ext/pdo/pdo_sql_parser.re"
371 { RET(PDO_PARSER_BIND); }
372 #line 373 "ext/pdo/pdo_sql_parser.c"
373 yy35:
374 ++YYCURSOR;
375 if (YYLIMIT <= YYCURSOR) YYFILL(1);
376 yych = *YYCURSOR;
377 yy36:
378 switch (yych) {
379 case 0x00: goto yy2;
380 case '\'': goto yy38;
381 case '\\': goto yy37;
382 default: goto yy35;
383 }
384 yy37:
385 ++YYCURSOR;
386 if (YYLIMIT <= YYCURSOR) YYFILL(1);
387 yych = *YYCURSOR;
388 if (yych <= 0x00) goto yy2;
389 goto yy35;
390 yy38:
391 ++YYCURSOR;
392 #line 59 "ext/pdo/pdo_sql_parser.re"
393 { RET(PDO_PARSER_TEXT); }
394 #line 395 "ext/pdo/pdo_sql_parser.c"
395 yy40:
396 ++YYCURSOR;
397 if (YYLIMIT <= YYCURSOR) YYFILL(1);
398 yych = *YYCURSOR;
399 yy41:
400 switch (yych) {
401 case 0x00: goto yy2;
402 case '"': goto yy43;
403 case '\\': goto yy42;
404 default: goto yy40;
405 }
406 yy42:
407 ++YYCURSOR;
408 if (YYLIMIT <= YYCURSOR) YYFILL(1);
409 yych = *YYCURSOR;
410 if (yych <= 0x00) goto yy2;
411 goto yy40;
412 yy43:
413 ++YYCURSOR;
414 #line 58 "ext/pdo/pdo_sql_parser.re"
415 { RET(PDO_PARSER_TEXT); }
416 #line 417 "ext/pdo/pdo_sql_parser.c"
417 }
418 #line 66 "ext/pdo/pdo_sql_parser.re"
419
420 }
421
422 struct placeholder {
423 char *pos;
424 int len;
425 int bindno;
426 int qlen; /* quoted length of value */
427 char *quoted; /* quoted value */
428 int freeq;
429 struct placeholder *next;
430 };
431
pdo_parse_params(pdo_stmt_t * stmt,char * inquery,int inquery_len,char ** outquery,int * outquery_len TSRMLS_DC)432 PDO_API int pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len,
433 char **outquery, int *outquery_len TSRMLS_DC)
434 {
435 Scanner s;
436 char *ptr, *newbuffer;
437 int t;
438 int bindno = 0;
439 int ret = 0;
440 int newbuffer_len;
441 HashTable *params;
442 struct pdo_bound_param_data *param;
443 int query_type = PDO_PLACEHOLDER_NONE;
444 struct placeholder *placeholders = NULL, *placetail = NULL, *plc = NULL;
445
446 ptr = *outquery;
447 s.cur = inquery;
448 s.end = inquery + inquery_len + 1;
449
450 /* phase 1: look for args */
451 while((t = scan(&s)) != PDO_PARSER_EOI) {
452 if (t == PDO_PARSER_BIND || t == PDO_PARSER_BIND_POS) {
453 if (t == PDO_PARSER_BIND) {
454 int len = s.cur - s.tok;
455 if ((inquery < (s.cur - len)) && isalnum(*(s.cur - len - 1))) {
456 continue;
457 }
458 query_type |= PDO_PLACEHOLDER_NAMED;
459 } else {
460 query_type |= PDO_PLACEHOLDER_POSITIONAL;
461 }
462
463 plc = emalloc(sizeof(*plc));
464 memset(plc, 0, sizeof(*plc));
465 plc->next = NULL;
466 plc->pos = s.tok;
467 plc->len = s.cur - s.tok;
468 plc->bindno = bindno++;
469
470 if (placetail) {
471 placetail->next = plc;
472 } else {
473 placeholders = plc;
474 }
475 placetail = plc;
476 }
477 }
478
479 if (bindno == 0) {
480 /* nothing to do; good! */
481 return 0;
482 }
483
484 /* did the query make sense to me? */
485 if (query_type == (PDO_PLACEHOLDER_NAMED|PDO_PLACEHOLDER_POSITIONAL)) {
486 /* they mixed both types; punt */
487 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "mixed named and positional parameters" TSRMLS_CC);
488 ret = -1;
489 goto clean_up;
490 }
491
492 if (stmt->supports_placeholders == query_type && !stmt->named_rewrite_template) {
493 /* query matches native syntax */
494 ret = 0;
495 goto clean_up;
496 }
497
498 if (stmt->named_rewrite_template) {
499 /* magic/hack.
500 * We we pretend that the query was positional even if
501 * it was named so that we fall into the
502 * named rewrite case below. Not too pretty,
503 * but it works. */
504 query_type = PDO_PLACEHOLDER_POSITIONAL;
505 }
506
507 params = stmt->bound_params;
508
509 /* Do we have placeholders but no bound params */
510 if (bindno && !params && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
511 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "no parameters were bound" TSRMLS_CC);
512 ret = -1;
513 goto clean_up;
514 }
515
516 if (params && bindno != zend_hash_num_elements(params) && stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
517 /* extra bit of validation for instances when same params are bound more then once */
518 if (query_type != PDO_PLACEHOLDER_POSITIONAL && bindno > zend_hash_num_elements(params)) {
519 int ok = 1;
520 for (plc = placeholders; plc; plc = plc->next) {
521 if (zend_hash_find(params, plc->pos, plc->len, (void**) ¶m) == FAILURE) {
522 ok = 0;
523 break;
524 }
525 }
526 if (ok) {
527 goto safe;
528 }
529 }
530 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "number of bound variables does not match number of tokens" TSRMLS_CC);
531 ret = -1;
532 goto clean_up;
533 }
534 safe:
535 /* what are we going to do ? */
536 if (stmt->supports_placeholders == PDO_PLACEHOLDER_NONE) {
537 /* query generation */
538
539 newbuffer_len = inquery_len;
540
541 /* let's quote all the values */
542 for (plc = placeholders; plc; plc = plc->next) {
543 if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
544 ret = zend_hash_index_find(params, plc->bindno, (void**) ¶m);
545 } else {
546 ret = zend_hash_find(params, plc->pos, plc->len, (void**) ¶m);
547 }
548 if (ret == FAILURE) {
549 /* parameter was not defined */
550 ret = -1;
551 pdo_raise_impl_error(stmt->dbh, stmt, "HY093", "parameter was not defined" TSRMLS_CC);
552 goto clean_up;
553 }
554 if (stmt->dbh->methods->quoter) {
555 if (param->param_type == PDO_PARAM_LOB && Z_TYPE_P(param->parameter) == IS_RESOURCE) {
556 php_stream *stm;
557
558 php_stream_from_zval_no_verify(stm, ¶m->parameter);
559 if (stm) {
560 size_t len;
561 char *buf = NULL;
562
563 len = php_stream_copy_to_mem(stm, &buf, PHP_STREAM_COPY_ALL, 0);
564 if (!stmt->dbh->methods->quoter(stmt->dbh, buf, len, &plc->quoted, &plc->qlen,
565 param->param_type TSRMLS_CC)) {
566 /* bork */
567 ret = -1;
568 strncpy(stmt->error_code, stmt->dbh->error_code, 6);
569 if (buf) {
570 efree(buf);
571 }
572 goto clean_up;
573 }
574 if (buf) {
575 efree(buf);
576 }
577 } else {
578 pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource" TSRMLS_CC);
579 ret = -1;
580 goto clean_up;
581 }
582 plc->freeq = 1;
583 } else {
584 switch (Z_TYPE_P(param->parameter)) {
585 case IS_NULL:
586 plc->quoted = "NULL";
587 plc->qlen = sizeof("NULL")-1;
588 plc->freeq = 0;
589 break;
590
591 case IS_BOOL:
592 convert_to_long(param->parameter);
593
594 case IS_LONG:
595 case IS_DOUBLE:
596 convert_to_string(param->parameter);
597 plc->qlen = Z_STRLEN_P(param->parameter);
598 plc->quoted = Z_STRVAL_P(param->parameter);
599 plc->freeq = 0;
600 break;
601
602 default:
603 convert_to_string(param->parameter);
604 if (!stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
605 Z_STRLEN_P(param->parameter), &plc->quoted, &plc->qlen,
606 param->param_type TSRMLS_CC)) {
607 /* bork */
608 ret = -1;
609 strncpy(stmt->error_code, stmt->dbh->error_code, 6);
610 goto clean_up;
611 }
612 plc->freeq = 1;
613 }
614 }
615 } else {
616 plc->quoted = Z_STRVAL_P(param->parameter);
617 plc->qlen = Z_STRLEN_P(param->parameter);
618 }
619 newbuffer_len += plc->qlen;
620 }
621
622 rewrite:
623 /* allocate output buffer */
624 newbuffer = emalloc(newbuffer_len + 1);
625 *outquery = newbuffer;
626
627 /* and build the query */
628 plc = placeholders;
629 ptr = inquery;
630
631 do {
632 t = plc->pos - ptr;
633 if (t) {
634 memcpy(newbuffer, ptr, t);
635 newbuffer += t;
636 }
637 memcpy(newbuffer, plc->quoted, plc->qlen);
638 newbuffer += plc->qlen;
639 ptr = plc->pos + plc->len;
640
641 plc = plc->next;
642 } while (plc);
643
644 t = (inquery + inquery_len) - ptr;
645 if (t) {
646 memcpy(newbuffer, ptr, t);
647 newbuffer += t;
648 }
649 *newbuffer = '\0';
650 *outquery_len = newbuffer - *outquery;
651
652 ret = 1;
653 goto clean_up;
654
655 } else if (query_type == PDO_PLACEHOLDER_POSITIONAL) {
656 /* rewrite ? to :pdoX */
657 char *name, *idxbuf;
658 const char *tmpl = stmt->named_rewrite_template ? stmt->named_rewrite_template : ":pdo%d";
659 int bind_no = 1;
660
661 newbuffer_len = inquery_len;
662
663 if (stmt->bound_param_map == NULL) {
664 ALLOC_HASHTABLE(stmt->bound_param_map);
665 zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
666 }
667
668 for (plc = placeholders; plc; plc = plc->next) {
669 int skip_map = 0;
670 char *p;
671 name = estrndup(plc->pos, plc->len);
672
673 /* check if bound parameter is already available */
674 if (!strcmp(name, "?") || zend_hash_find(stmt->bound_param_map, name, plc->len + 1, (void**) &p) == FAILURE) {
675 spprintf(&idxbuf, 0, tmpl, bind_no++);
676 } else {
677 idxbuf = estrdup(p);
678 skip_map = 1;
679 }
680
681 plc->quoted = idxbuf;
682 plc->qlen = strlen(plc->quoted);
683 plc->freeq = 1;
684 newbuffer_len += plc->qlen;
685
686 if (!skip_map && stmt->named_rewrite_template) {
687 /* create a mapping */
688 zend_hash_update(stmt->bound_param_map, name, plc->len + 1, idxbuf, plc->qlen + 1, NULL);
689 }
690
691 /* map number to name */
692 zend_hash_index_update(stmt->bound_param_map, plc->bindno, idxbuf, plc->qlen + 1, NULL);
693
694 efree(name);
695 }
696
697 goto rewrite;
698
699 } else {
700 /* rewrite :name to ? */
701
702 newbuffer_len = inquery_len;
703
704 if (stmt->bound_param_map == NULL) {
705 ALLOC_HASHTABLE(stmt->bound_param_map);
706 zend_hash_init(stmt->bound_param_map, 13, NULL, NULL, 0);
707 }
708
709 for (plc = placeholders; plc; plc = plc->next) {
710 char *name;
711
712 name = estrndup(plc->pos, plc->len);
713 zend_hash_index_update(stmt->bound_param_map, plc->bindno, name, plc->len + 1, NULL);
714 efree(name);
715 plc->quoted = "?";
716 plc->qlen = 1;
717 }
718
719 goto rewrite;
720 }
721
722 clean_up:
723
724 while (placeholders) {
725 plc = placeholders;
726 placeholders = plc->next;
727
728 if (plc->freeq) {
729 efree(plc->quoted);
730 }
731
732 efree(plc);
733 }
734
735 return ret;
736 }
737
738 #if 0
739 int old_pdo_parse_params(pdo_stmt_t *stmt, char *inquery, int inquery_len, char **outquery,
740 int *outquery_len TSRMLS_DC)
741 {
742 Scanner s;
743 char *ptr;
744 int t;
745 int bindno = 0;
746 int newbuffer_len;
747 int padding;
748 HashTable *params = stmt->bound_params;
749 struct pdo_bound_param_data *param;
750 /* allocate buffer for query with expanded binds, ptr is our writing pointer */
751 newbuffer_len = inquery_len;
752
753 /* calculate the possible padding factor due to quoting */
754 if(stmt->dbh->max_escaped_char_length) {
755 padding = stmt->dbh->max_escaped_char_length;
756 } else {
757 padding = 3;
758 }
759 if(params) {
760 zend_hash_internal_pointer_reset(params);
761 while (SUCCESS == zend_hash_get_current_data(params, (void**)¶m)) {
762 if(param->parameter) {
763 convert_to_string(param->parameter);
764 /* accomodate a string that needs to be fully quoted
765 bind placeholders are at least 2 characters, so
766 the accomodate their own "'s
767 */
768 newbuffer_len += padding * Z_STRLEN_P(param->parameter);
769 }
770 zend_hash_move_forward(params);
771 }
772 }
773 *outquery = (char *) emalloc(newbuffer_len + 1);
774 *outquery_len = 0;
775
776 ptr = *outquery;
777 s.cur = inquery;
778 while((t = scan(&s)) != PDO_PARSER_EOI) {
779 if(t == PDO_PARSER_TEXT) {
780 memcpy(ptr, s.tok, s.cur - s.tok);
781 ptr += (s.cur - s.tok);
782 *outquery_len += (s.cur - s.tok);
783 }
784 else if(t == PDO_PARSER_BIND) {
785 if(!params) {
786 /* error */
787 efree(*outquery);
788 *outquery = NULL;
789 return (int) (s.cur - inquery);
790 }
791 /* lookup bind first via hash and then index */
792 /* stupid keys need to be null-terminated, even though we know their length */
793 if((SUCCESS == zend_hash_find(params, s.tok, s.cur-s.tok,(void **)¶m))
794 ||
795 (SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m)))
796 {
797 char *quotedstr;
798 int quotedstrlen;
799 /* restore the in-string key, doesn't need null-termination here */
800 /* currently everything is a string here */
801
802 /* quote the bind value if necessary */
803 if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
804 Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
805 {
806 memcpy(ptr, quotedstr, quotedstrlen);
807 ptr += quotedstrlen;
808 *outquery_len += quotedstrlen;
809 efree(quotedstr);
810 } else {
811 memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
812 ptr += Z_STRLEN_P(param->parameter);
813 *outquery_len += (Z_STRLEN_P(param->parameter));
814 }
815 }
816 else {
817 /* error and cleanup */
818 efree(*outquery);
819 *outquery = NULL;
820 return (int) (s.cur - inquery);
821 }
822 bindno++;
823 }
824 else if(t == PDO_PARSER_BIND_POS) {
825 if(!params) {
826 /* error */
827 efree(*outquery);
828 *outquery = NULL;
829 return (int) (s.cur - inquery);
830 }
831 /* lookup bind by index */
832 if(SUCCESS == zend_hash_index_find(params, bindno, (void **)¶m))
833 {
834 char *quotedstr;
835 int quotedstrlen;
836 /* currently everything is a string here */
837
838 /* quote the bind value if necessary */
839 if(stmt->dbh->methods->quoter(stmt->dbh, Z_STRVAL_P(param->parameter),
840 Z_STRLEN_P(param->parameter), "edstr, "edstrlen TSRMLS_CC))
841 {
842 memcpy(ptr, quotedstr, quotedstrlen);
843 ptr += quotedstrlen;
844 *outquery_len += quotedstrlen;
845 efree(quotedstr);
846 } else {
847 memcpy(ptr, Z_STRVAL_P(param->parameter), Z_STRLEN_P(param->parameter));
848 ptr += Z_STRLEN_P(param->parameter);
849 *outquery_len += (Z_STRLEN_P(param->parameter));
850 }
851 }
852 else {
853 /* error and cleanup */
854 efree(*outquery);
855 *outquery = NULL;
856 return (int) (s.cur - inquery);
857 }
858 bindno++;
859 }
860 }
861 *ptr = '\0';
862 return 0;
863 }
864 #endif
865
866 /*
867 * Local variables:
868 * tab-width: 4
869 * c-basic-offset: 4
870 * End:
871 * vim600: noet sw=4 ts=4 fdm=marker ft=c
872 * vim<600: noet sw=4 ts=4
873 */
874