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