You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

769 lines
17 KiB

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