prestogres 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (393) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +20 -0
  4. data/LICENSE +202 -0
  5. data/NOTICE +22 -0
  6. data/README.md +217 -0
  7. data/Rakefile +13 -0
  8. data/VERSION +1 -0
  9. data/bin/prestogres +254 -0
  10. data/config/pcp.conf.sample +28 -0
  11. data/config/pgpool.conf +678 -0
  12. data/config/pool_hba.conf +84 -0
  13. data/config/pool_passwd +0 -0
  14. data/config/postgresql.conf +2 -0
  15. data/ext/.gitignore +6 -0
  16. data/ext/depend +26 -0
  17. data/ext/extconf.rb +4 -0
  18. data/ext/prestogres_config.c +12 -0
  19. data/pgpool2/.gitignore +36 -0
  20. data/pgpool2/AUTHORS +4 -0
  21. data/pgpool2/COPYING +12 -0
  22. data/pgpool2/ChangeLog +1 -0
  23. data/pgpool2/INSTALL +1 -0
  24. data/pgpool2/Makefile.am +159 -0
  25. data/pgpool2/Makefile.in +1187 -0
  26. data/pgpool2/NEWS +4960 -0
  27. data/pgpool2/README +1 -0
  28. data/pgpool2/README.euc_jp +1 -0
  29. data/pgpool2/README.online-recovery +62 -0
  30. data/pgpool2/TODO +103 -0
  31. data/pgpool2/ac_func_accept_argtypes.m4 +85 -0
  32. data/pgpool2/aclocal.m4 +1088 -0
  33. data/pgpool2/c-compiler.m4 +134 -0
  34. data/pgpool2/c-library.m4 +325 -0
  35. data/pgpool2/child.c +2097 -0
  36. data/pgpool2/config.guess +1532 -0
  37. data/pgpool2/config.h.in +332 -0
  38. data/pgpool2/config.sub +1640 -0
  39. data/pgpool2/configure +15752 -0
  40. data/pgpool2/configure.in +392 -0
  41. data/pgpool2/depcomp +522 -0
  42. data/pgpool2/doc/basebackup.sh +17 -0
  43. data/pgpool2/doc/pgpool-de.html +4220 -0
  44. data/pgpool2/doc/pgpool-en.html +5738 -0
  45. data/pgpool2/doc/pgpool-fr.html +4118 -0
  46. data/pgpool2/doc/pgpool-ja.css +198 -0
  47. data/pgpool2/doc/pgpool-ja.html +11279 -0
  48. data/pgpool2/doc/pgpool-zh_cn.html +4445 -0
  49. data/pgpool2/doc/pgpool.css +280 -0
  50. data/pgpool2/doc/pgpool_remote_start +13 -0
  51. data/pgpool2/doc/recovery.conf.sample +117 -0
  52. data/pgpool2/doc/tutorial-en.html +707 -0
  53. data/pgpool2/doc/tutorial-ja.html +422 -0
  54. data/pgpool2/doc/tutorial-memqcache-en.html +325 -0
  55. data/pgpool2/doc/tutorial-memqcache-ja.html +370 -0
  56. data/pgpool2/doc/tutorial-memqcache-zh_cn.html +322 -0
  57. data/pgpool2/doc/tutorial-watchdog-en.html +306 -0
  58. data/pgpool2/doc/tutorial-watchdog-ja.html +343 -0
  59. data/pgpool2/doc/tutorial-watchdog-zh_cn.html +301 -0
  60. data/pgpool2/doc/tutorial-zh_cn.html +537 -0
  61. data/pgpool2/doc/watchdog.png +0 -0
  62. data/pgpool2/doc/wd-en.html +236 -0
  63. data/pgpool2/doc/wd-en.jpg +0 -0
  64. data/pgpool2/doc/wd-ja.html +219 -0
  65. data/pgpool2/doc/wd-ja.jpg +0 -0
  66. data/pgpool2/doc/wd-zh_cn.html +201 -0
  67. data/pgpool2/doc/where_to_send_queries.odg +0 -0
  68. data/pgpool2/doc/where_to_send_queries.pdf +0 -0
  69. data/pgpool2/general.m4 +166 -0
  70. data/pgpool2/getopt_long.c +200 -0
  71. data/pgpool2/getopt_long.h +44 -0
  72. data/pgpool2/install-sh +251 -0
  73. data/pgpool2/ltmain.sh +8406 -0
  74. data/pgpool2/m4/libtool.m4 +7360 -0
  75. data/pgpool2/m4/ltoptions.m4 +368 -0
  76. data/pgpool2/m4/ltsugar.m4 +123 -0
  77. data/pgpool2/m4/ltversion.m4 +23 -0
  78. data/pgpool2/m4/lt~obsolete.m4 +92 -0
  79. data/pgpool2/main.c +2971 -0
  80. data/pgpool2/md5.c +444 -0
  81. data/pgpool2/md5.h +28 -0
  82. data/pgpool2/missing +360 -0
  83. data/pgpool2/mkinstalldirs +40 -0
  84. data/pgpool2/parser/Makefile.am +50 -0
  85. data/pgpool2/parser/Makefile.in +559 -0
  86. data/pgpool2/parser/copyfuncs.c +3310 -0
  87. data/pgpool2/parser/gram.c +39100 -0
  88. data/pgpool2/parser/gram.h +940 -0
  89. data/pgpool2/parser/gram.y +13408 -0
  90. data/pgpool2/parser/gramparse.h +74 -0
  91. data/pgpool2/parser/keywords.c +32 -0
  92. data/pgpool2/parser/keywords.h +39 -0
  93. data/pgpool2/parser/kwlist.h +425 -0
  94. data/pgpool2/parser/kwlookup.c +88 -0
  95. data/pgpool2/parser/list.c +1156 -0
  96. data/pgpool2/parser/makefuncs.c +518 -0
  97. data/pgpool2/parser/makefuncs.h +83 -0
  98. data/pgpool2/parser/memnodes.h +79 -0
  99. data/pgpool2/parser/nodes.c +29 -0
  100. data/pgpool2/parser/nodes.h +609 -0
  101. data/pgpool2/parser/outfuncs.c +5790 -0
  102. data/pgpool2/parser/parsenodes.h +2615 -0
  103. data/pgpool2/parser/parser.c +262 -0
  104. data/pgpool2/parser/parser.h +46 -0
  105. data/pgpool2/parser/pg_class.h +158 -0
  106. data/pgpool2/parser/pg_config_manual.h +273 -0
  107. data/pgpool2/parser/pg_list.h +352 -0
  108. data/pgpool2/parser/pg_trigger.h +147 -0
  109. data/pgpool2/parser/pg_wchar.h +492 -0
  110. data/pgpool2/parser/pool_memory.c +342 -0
  111. data/pgpool2/parser/pool_memory.h +77 -0
  112. data/pgpool2/parser/pool_parser.h +222 -0
  113. data/pgpool2/parser/pool_string.c +121 -0
  114. data/pgpool2/parser/pool_string.h +37 -0
  115. data/pgpool2/parser/primnodes.h +1280 -0
  116. data/pgpool2/parser/scan.c +4094 -0
  117. data/pgpool2/parser/scan.l +1451 -0
  118. data/pgpool2/parser/scanner.h +120 -0
  119. data/pgpool2/parser/scansup.c +221 -0
  120. data/pgpool2/parser/scansup.h +28 -0
  121. data/pgpool2/parser/snprintf.c +1102 -0
  122. data/pgpool2/parser/stringinfo.c +294 -0
  123. data/pgpool2/parser/stringinfo.h +178 -0
  124. data/pgpool2/parser/value.c +78 -0
  125. data/pgpool2/parser/value.h +62 -0
  126. data/pgpool2/parser/wchar.c +2048 -0
  127. data/pgpool2/pcp.conf.sample +28 -0
  128. data/pgpool2/pcp/Makefile.am +40 -0
  129. data/pgpool2/pcp/Makefile.in +771 -0
  130. data/pgpool2/pcp/libpcp_ext.h +250 -0
  131. data/pgpool2/pcp/md5.c +444 -0
  132. data/pgpool2/pcp/md5.h +28 -0
  133. data/pgpool2/pcp/pcp.c +1652 -0
  134. data/pgpool2/pcp/pcp.h +61 -0
  135. data/pgpool2/pcp/pcp_attach_node.c +172 -0
  136. data/pgpool2/pcp/pcp_detach_node.c +185 -0
  137. data/pgpool2/pcp/pcp_error.c +87 -0
  138. data/pgpool2/pcp/pcp_node_count.c +160 -0
  139. data/pgpool2/pcp/pcp_node_info.c +198 -0
  140. data/pgpool2/pcp/pcp_pool_status.c +166 -0
  141. data/pgpool2/pcp/pcp_proc_count.c +166 -0
  142. data/pgpool2/pcp/pcp_proc_info.c +261 -0
  143. data/pgpool2/pcp/pcp_promote_node.c +185 -0
  144. data/pgpool2/pcp/pcp_recovery_node.c +172 -0
  145. data/pgpool2/pcp/pcp_stop_pgpool.c +179 -0
  146. data/pgpool2/pcp/pcp_stream.c +385 -0
  147. data/pgpool2/pcp/pcp_stream.h +52 -0
  148. data/pgpool2/pcp/pcp_systemdb_info.c +194 -0
  149. data/pgpool2/pcp/pcp_watchdog_info.c +211 -0
  150. data/pgpool2/pcp_child.c +1493 -0
  151. data/pgpool2/pg_md5.c +305 -0
  152. data/pgpool2/pgpool.8.in +121 -0
  153. data/pgpool2/pgpool.conf +553 -0
  154. data/pgpool2/pgpool.conf.sample +666 -0
  155. data/pgpool2/pgpool.conf.sample-master-slave +665 -0
  156. data/pgpool2/pgpool.conf.sample-replication +664 -0
  157. data/pgpool2/pgpool.conf.sample-stream +664 -0
  158. data/pgpool2/pgpool.spec +264 -0
  159. data/pgpool2/pgpool_adm/TODO +7 -0
  160. data/pgpool2/pgpool_adm/pgpool_adm--1.0.sql +85 -0
  161. data/pgpool2/pgpool_adm/pgpool_adm.c +558 -0
  162. data/pgpool2/pgpool_adm/pgpool_adm.control +5 -0
  163. data/pgpool2/pgpool_adm/pgpool_adm.h +46 -0
  164. data/pgpool2/pgpool_adm/pgpool_adm.sql.in +85 -0
  165. data/pgpool2/pool.h +655 -0
  166. data/pgpool2/pool_auth.c +1390 -0
  167. data/pgpool2/pool_config.c +5007 -0
  168. data/pgpool2/pool_config.h +284 -0
  169. data/pgpool2/pool_config.l +3281 -0
  170. data/pgpool2/pool_config_md5.c +29 -0
  171. data/pgpool2/pool_connection_pool.c +812 -0
  172. data/pgpool2/pool_error.c +242 -0
  173. data/pgpool2/pool_globals.c +27 -0
  174. data/pgpool2/pool_hba.c +1723 -0
  175. data/pgpool2/pool_hba.conf.sample +67 -0
  176. data/pgpool2/pool_ip.c +567 -0
  177. data/pgpool2/pool_ip.h +65 -0
  178. data/pgpool2/pool_ipc.h +38 -0
  179. data/pgpool2/pool_lobj.c +242 -0
  180. data/pgpool2/pool_lobj.h +32 -0
  181. data/pgpool2/pool_memqcache.c +3818 -0
  182. data/pgpool2/pool_memqcache.h +268 -0
  183. data/pgpool2/pool_params.c +163 -0
  184. data/pgpool2/pool_passwd.c +249 -0
  185. data/pgpool2/pool_passwd.h +41 -0
  186. data/pgpool2/pool_path.c +193 -0
  187. data/pgpool2/pool_path.h +81 -0
  188. data/pgpool2/pool_process_context.c +247 -0
  189. data/pgpool2/pool_process_context.h +62 -0
  190. data/pgpool2/pool_process_query.c +5001 -0
  191. data/pgpool2/pool_process_reporting.c +1671 -0
  192. data/pgpool2/pool_process_reporting.h +44 -0
  193. data/pgpool2/pool_proto2.c +671 -0
  194. data/pgpool2/pool_proto_modules.c +3524 -0
  195. data/pgpool2/pool_proto_modules.h +185 -0
  196. data/pgpool2/pool_query_cache.c +1020 -0
  197. data/pgpool2/pool_query_context.c +1871 -0
  198. data/pgpool2/pool_query_context.h +105 -0
  199. data/pgpool2/pool_relcache.c +284 -0
  200. data/pgpool2/pool_relcache.h +78 -0
  201. data/pgpool2/pool_rewrite_outfuncs.c +9060 -0
  202. data/pgpool2/pool_rewrite_query.c +715 -0
  203. data/pgpool2/pool_rewrite_query.h +192 -0
  204. data/pgpool2/pool_select_walker.c +1150 -0
  205. data/pgpool2/pool_select_walker.h +68 -0
  206. data/pgpool2/pool_sema.c +161 -0
  207. data/pgpool2/pool_session_context.c +952 -0
  208. data/pgpool2/pool_session_context.h +203 -0
  209. data/pgpool2/pool_shmem.c +185 -0
  210. data/pgpool2/pool_signal.c +158 -0
  211. data/pgpool2/pool_signal.h +61 -0
  212. data/pgpool2/pool_ssl.c +339 -0
  213. data/pgpool2/pool_stream.c +962 -0
  214. data/pgpool2/pool_stream.h +61 -0
  215. data/pgpool2/pool_system.c +659 -0
  216. data/pgpool2/pool_timestamp.c +1215 -0
  217. data/pgpool2/pool_timestamp.h +38 -0
  218. data/pgpool2/pool_type.h +171 -0
  219. data/pgpool2/pool_worker_child.c +384 -0
  220. data/pgpool2/ps_status.c +404 -0
  221. data/pgpool2/recovery.c +435 -0
  222. data/pgpool2/redhat/pgpool.conf.sample.patch +52 -0
  223. data/pgpool2/redhat/pgpool.init +201 -0
  224. data/pgpool2/redhat/pgpool.sysconfig +7 -0
  225. data/pgpool2/redhat/rpm_installer/basebackup-replication.sh +53 -0
  226. data/pgpool2/redhat/rpm_installer/basebackup-stream.sh +55 -0
  227. data/pgpool2/redhat/rpm_installer/config_for_script +17 -0
  228. data/pgpool2/redhat/rpm_installer/failover.sh +64 -0
  229. data/pgpool2/redhat/rpm_installer/getsources.sh +141 -0
  230. data/pgpool2/redhat/rpm_installer/install.sh +1363 -0
  231. data/pgpool2/redhat/rpm_installer/pgpool_recovery_pitr +47 -0
  232. data/pgpool2/redhat/rpm_installer/pgpool_remote_start +15 -0
  233. data/pgpool2/redhat/rpm_installer/recovery.conf +4 -0
  234. data/pgpool2/redhat/rpm_installer/uninstall.sh +57 -0
  235. data/pgpool2/sample/dist_def_pgbench.sql +73 -0
  236. data/pgpool2/sample/pgpool.pam +3 -0
  237. data/pgpool2/sample/pgpool_recovery +20 -0
  238. data/pgpool2/sample/pgpool_recovery_pitr +19 -0
  239. data/pgpool2/sample/pgpool_remote_start +13 -0
  240. data/pgpool2/sample/replicate_def_pgbench.sql +18 -0
  241. data/pgpool2/sql/insert_lock.sql +15 -0
  242. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.c +280 -0
  243. data/pgpool2/sql/pgpool-recovery/pgpool-recovery.sql.in +19 -0
  244. data/pgpool2/sql/pgpool-recovery/pgpool_recovery--1.0.sql +24 -0
  245. data/pgpool2/sql/pgpool-recovery/pgpool_recovery.control +5 -0
  246. data/pgpool2/sql/pgpool-recovery/uninstall_pgpool-recovery.sql +3 -0
  247. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.c +206 -0
  248. data/pgpool2/sql/pgpool-regclass/pgpool-regclass.sql.in +4 -0
  249. data/pgpool2/sql/pgpool-regclass/pgpool_regclass--1.0.sql +7 -0
  250. data/pgpool2/sql/pgpool-regclass/pgpool_regclass.control +5 -0
  251. data/pgpool2/sql/pgpool-regclass/uninstall_pgpool-regclass.sql +1 -0
  252. data/pgpool2/sql/system_db.sql +38 -0
  253. data/pgpool2/strlcpy.c +85 -0
  254. data/pgpool2/test/C/test_extended.c +98 -0
  255. data/pgpool2/test/jdbc/.cvsignore +2 -0
  256. data/pgpool2/test/jdbc/AutoCommitTest.java +45 -0
  257. data/pgpool2/test/jdbc/BatchTest.java +55 -0
  258. data/pgpool2/test/jdbc/ColumnTest.java +60 -0
  259. data/pgpool2/test/jdbc/CreateTempTableTest.java +48 -0
  260. data/pgpool2/test/jdbc/InsertTest.java +34 -0
  261. data/pgpool2/test/jdbc/LockTest.java +36 -0
  262. data/pgpool2/test/jdbc/PgpoolTest.java +75 -0
  263. data/pgpool2/test/jdbc/README.euc_jp +73 -0
  264. data/pgpool2/test/jdbc/RunTest.java +83 -0
  265. data/pgpool2/test/jdbc/SelectTest.java +37 -0
  266. data/pgpool2/test/jdbc/UpdateTest.java +32 -0
  267. data/pgpool2/test/jdbc/expected/CreateTempTable +1 -0
  268. data/pgpool2/test/jdbc/expected/autocommit +10 -0
  269. data/pgpool2/test/jdbc/expected/batch +1 -0
  270. data/pgpool2/test/jdbc/expected/column +100 -0
  271. data/pgpool2/test/jdbc/expected/insert +1 -0
  272. data/pgpool2/test/jdbc/expected/lock +100 -0
  273. data/pgpool2/test/jdbc/expected/select +2 -0
  274. data/pgpool2/test/jdbc/expected/update +1 -0
  275. data/pgpool2/test/jdbc/pgpool.properties +7 -0
  276. data/pgpool2/test/jdbc/prepare.sql +54 -0
  277. data/pgpool2/test/jdbc/run.sh +6 -0
  278. data/pgpool2/test/parser/.cvsignore +6 -0
  279. data/pgpool2/test/parser/README +32 -0
  280. data/pgpool2/test/parser/expected/copy.out +17 -0
  281. data/pgpool2/test/parser/expected/create.out +64 -0
  282. data/pgpool2/test/parser/expected/cursor.out +37 -0
  283. data/pgpool2/test/parser/expected/delete.out +10 -0
  284. data/pgpool2/test/parser/expected/drop.out +12 -0
  285. data/pgpool2/test/parser/expected/insert.out +13 -0
  286. data/pgpool2/test/parser/expected/misc.out +28 -0
  287. data/pgpool2/test/parser/expected/prepare.out +4 -0
  288. data/pgpool2/test/parser/expected/privileges.out +31 -0
  289. data/pgpool2/test/parser/expected/scanner.out +30 -0
  290. data/pgpool2/test/parser/expected/select.out +89 -0
  291. data/pgpool2/test/parser/expected/transaction.out +38 -0
  292. data/pgpool2/test/parser/expected/update.out +11 -0
  293. data/pgpool2/test/parser/expected/v84.out +37 -0
  294. data/pgpool2/test/parser/expected/v90.out +25 -0
  295. data/pgpool2/test/parser/expected/var.out +22 -0
  296. data/pgpool2/test/parser/input/alter.sql +2 -0
  297. data/pgpool2/test/parser/input/copy.sql +17 -0
  298. data/pgpool2/test/parser/input/create.sql +64 -0
  299. data/pgpool2/test/parser/input/cursor.sql +37 -0
  300. data/pgpool2/test/parser/input/delete.sql +10 -0
  301. data/pgpool2/test/parser/input/drop.sql +12 -0
  302. data/pgpool2/test/parser/input/insert.sql +13 -0
  303. data/pgpool2/test/parser/input/misc.sql +28 -0
  304. data/pgpool2/test/parser/input/prepare.sql +4 -0
  305. data/pgpool2/test/parser/input/privileges.sql +31 -0
  306. data/pgpool2/test/parser/input/scanner.sql +34 -0
  307. data/pgpool2/test/parser/input/select.sql +89 -0
  308. data/pgpool2/test/parser/input/transaction.sql +38 -0
  309. data/pgpool2/test/parser/input/update.sql +11 -0
  310. data/pgpool2/test/parser/input/v84.sql +37 -0
  311. data/pgpool2/test/parser/input/v90.sql +38 -0
  312. data/pgpool2/test/parser/input/var.sql +22 -0
  313. data/pgpool2/test/parser/main.c +96 -0
  314. data/pgpool2/test/parser/parse_schedule +16 -0
  315. data/pgpool2/test/parser/pool.h +13 -0
  316. data/pgpool2/test/parser/run-test +62 -0
  317. data/pgpool2/test/pdo-test/README.euc_jp +58 -0
  318. data/pgpool2/test/pdo-test/SQLlist/test1.sql +3 -0
  319. data/pgpool2/test/pdo-test/SQLlist/test2.sql +3 -0
  320. data/pgpool2/test/pdo-test/collections.inc +11 -0
  321. data/pgpool2/test/pdo-test/def.inc +7 -0
  322. data/pgpool2/test/pdo-test/log.txt +0 -0
  323. data/pgpool2/test/pdo-test/mod/database.inc +36 -0
  324. data/pgpool2/test/pdo-test/mod/def.inc +0 -0
  325. data/pgpool2/test/pdo-test/mod/errorhandler.inc +27 -0
  326. data/pgpool2/test/pdo-test/pdotest.php +11 -0
  327. data/pgpool2/test/pdo-test/regsql.inc +56 -0
  328. data/pgpool2/test/pgpool_setup +898 -0
  329. data/pgpool2/test/regression/README +39 -0
  330. data/pgpool2/test/regression/clean.sh +21 -0
  331. data/pgpool2/test/regression/libs.sh +16 -0
  332. data/pgpool2/test/regression/regress.sh +166 -0
  333. data/pgpool2/test/regression/tests/001.load_balance/test.sh +128 -0
  334. data/pgpool2/test/regression/tests/002.native_replication/PgTester.java +47 -0
  335. data/pgpool2/test/regression/tests/002.native_replication/create.sql +6 -0
  336. data/pgpool2/test/regression/tests/002.native_replication/test.sh +71 -0
  337. data/pgpool2/test/regression/tests/003.failover/expected.r +6 -0
  338. data/pgpool2/test/regression/tests/003.failover/expected.s +6 -0
  339. data/pgpool2/test/regression/tests/003.failover/test.sh +45 -0
  340. data/pgpool2/test/regression/tests/004.watchdog/master.conf +12 -0
  341. data/pgpool2/test/regression/tests/004.watchdog/standby.conf +19 -0
  342. data/pgpool2/test/regression/tests/004.watchdog/test.sh +52 -0
  343. data/pgpool2/test/regression/tests/050.bug58/test.sh +50 -0
  344. data/pgpool2/test/regression/tests/051.bug60/bug.sql +12 -0
  345. data/pgpool2/test/regression/tests/051.bug60/database-clean.sql +6 -0
  346. data/pgpool2/test/regression/tests/051.bug60/database-setup.sql +28 -0
  347. data/pgpool2/test/regression/tests/051.bug60/test.sh +79 -0
  348. data/pgpool2/test/regression/tests/052.do_query/test.sh +44 -0
  349. data/pgpool2/test/regression/tests/053.insert_lock_hangs/test.sh +81 -0
  350. data/pgpool2/test/regression/tests/054.postgres_fdw/test.sh +67 -0
  351. data/pgpool2/test/regression/tests/055.backend_all_down/test.sh +52 -0
  352. data/pgpool2/test/regression/tests/056.bug63/jdbctest2.java +66 -0
  353. data/pgpool2/test/regression/tests/056.bug63/test.sh +47 -0
  354. data/pgpool2/test/regression/tests/057.bug61/test.sh +40 -0
  355. data/pgpool2/test/regression/tests/058.bug68/jdbctest3.java +45 -0
  356. data/pgpool2/test/regression/tests/058.bug68/test.sh +47 -0
  357. data/pgpool2/test/timestamp/expected/insert.out +16 -0
  358. data/pgpool2/test/timestamp/expected/misc.out +3 -0
  359. data/pgpool2/test/timestamp/expected/update.out +6 -0
  360. data/pgpool2/test/timestamp/input/insert.sql +16 -0
  361. data/pgpool2/test/timestamp/input/misc.sql +3 -0
  362. data/pgpool2/test/timestamp/input/update.sql +6 -0
  363. data/pgpool2/test/timestamp/main.c +129 -0
  364. data/pgpool2/test/timestamp/parse_schedule +3 -0
  365. data/pgpool2/test/timestamp/run-test +69 -0
  366. data/pgpool2/version.h +1 -0
  367. data/pgpool2/watchdog/Makefile.am +17 -0
  368. data/pgpool2/watchdog/Makefile.in +505 -0
  369. data/pgpool2/watchdog/test/stab.c +266 -0
  370. data/pgpool2/watchdog/test/test.c +85 -0
  371. data/pgpool2/watchdog/test/wd_child_t.c +87 -0
  372. data/pgpool2/watchdog/test/wd_lifecheck_t.c +87 -0
  373. data/pgpool2/watchdog/test/wd_packet_t.c +87 -0
  374. data/pgpool2/watchdog/test/wd_ping_t.c +20 -0
  375. data/pgpool2/watchdog/watchdog.c +408 -0
  376. data/pgpool2/watchdog/watchdog.h +209 -0
  377. data/pgpool2/watchdog/wd_child.c +444 -0
  378. data/pgpool2/watchdog/wd_ext.h +123 -0
  379. data/pgpool2/watchdog/wd_heartbeat.c +577 -0
  380. data/pgpool2/watchdog/wd_if.c +216 -0
  381. data/pgpool2/watchdog/wd_init.c +126 -0
  382. data/pgpool2/watchdog/wd_interlock.c +347 -0
  383. data/pgpool2/watchdog/wd_lifecheck.c +512 -0
  384. data/pgpool2/watchdog/wd_list.c +429 -0
  385. data/pgpool2/watchdog/wd_packet.c +1159 -0
  386. data/pgpool2/watchdog/wd_ping.c +330 -0
  387. data/pgpool2/ylwrap +223 -0
  388. data/pgsql/presto_client.py +346 -0
  389. data/pgsql/prestogres.py +156 -0
  390. data/pgsql/setup_functions.sql +21 -0
  391. data/pgsql/setup_language.sql +3 -0
  392. data/prestogres.gemspec +23 -0
  393. metadata +496 -0
@@ -0,0 +1,1451 @@
1
+ %{
2
+ /*-------------------------------------------------------------------------
3
+ *
4
+ * scan.l
5
+ * lexical scanner for PostgreSQL
6
+ *
7
+ * NOTE NOTE NOTE:
8
+ *
9
+ * The rules in this file must be kept in sync with psql's lexer!!!
10
+ *
11
+ * The rules are designed so that the scanner never has to backtrack,
12
+ * in the sense that there is always a rule that can match the input
13
+ * consumed so far (the rule action may internally throw back some input
14
+ * with yyless(), however). As explained in the flex manual, this makes
15
+ * for a useful speed increase --- about a third faster than a plain -CF
16
+ * lexer, in simple testing. The extra complexity is mostly in the rules
17
+ * for handling float numbers and continued string literals. If you change
18
+ * the lexical rules, verify that you haven't broken the no-backtrack
19
+ * property by running flex with the "-b" option and checking that the
20
+ * resulting "lex.backup" file says that no backing up is needed.
21
+ *
22
+ *
23
+ * Portions Copyright (c) 2003-2013, PgPool Global Development Group
24
+ * Portions Copyright (c) 1996-2012, PostgreSQL Global Development Group
25
+ * Portions Copyright (c) 1994, Regents of the University of California
26
+ *
27
+ * IDENTIFICATION
28
+ * src/backend/parser/scan.l
29
+ *
30
+ *-------------------------------------------------------------------------
31
+ */
32
+ #include "pool_parser.h"
33
+
34
+ #include <ctype.h>
35
+ #include <unistd.h>
36
+ #include <errno.h>
37
+ #include <string.h>
38
+
39
+ /* Not needed now that this file is compiled as part of gram.y */
40
+ /* #include "parser/parse.h" */
41
+ #include "parser.h"
42
+ #include "gram.h"
43
+ #include "scanner.h"
44
+ #include "scansup.h"
45
+
46
+ #include "pool_memory.h"
47
+ #include "pg_wchar.h"
48
+
49
+
50
+
51
+
52
+ /* Avoid exit() on fatal scanner errors (a bit ugly -- see yy_fatal_error) */
53
+ #undef fprintf
54
+ #define fprintf(file, fmt, msg) ereport(ERROR, (errmsg_internal("%s", msg)))
55
+
56
+ /*
57
+ * GUC variables. This is a DIRECT violation of the warning given at the
58
+ * head of gram.y, ie flex/bison code must not depend on any GUC variables;
59
+ * as such, changing their values can induce very unintuitive behavior.
60
+ * But we shall have to live with it as a short-term thing until the switch
61
+ * to SQL-standard string syntax is complete.
62
+ */
63
+ int backslash_quote = BACKSLASH_QUOTE_SAFE_ENCODING;
64
+ bool escape_string_warning = true;
65
+ bool standard_conforming_strings = false;
66
+
67
+ /*
68
+ * Set the type of YYSTYPE.
69
+ */
70
+ #define YYSTYPE core_YYSTYPE
71
+
72
+ /*
73
+ * Set the type of yyextra. All state variables used by the scanner should
74
+ * be in yyextra, *not* statically allocated.
75
+ */
76
+ #define YY_EXTRA_TYPE core_yy_extra_type *
77
+
78
+ /*
79
+ * Each call to yylex must set yylloc to the location of the found token
80
+ * (expressed as a byte offset from the start of the input text).
81
+ * When we parse a token that requires multiple lexer rules to process,
82
+ * this should be done in the first such rule, else yylloc will point
83
+ * into the middle of the token.
84
+ */
85
+ #define SET_YYLLOC() (*(yylloc) = yytext - yyextra->scanbuf)
86
+
87
+ /*
88
+ * Advance yylloc by the given number of bytes.
89
+ */
90
+ #define ADVANCE_YYLLOC(delta) ( *(yylloc) += (delta) )
91
+
92
+ #define startlit() ( yyextra->literallen = 0 )
93
+ static void addlit(char *ytext, int yleng, core_yyscan_t yyscanner);
94
+ static void addlitchar(unsigned char ychar, core_yyscan_t yyscanner);
95
+ static char *litbufdup(core_yyscan_t yyscanner);
96
+ static char *litbuf_udeescape(unsigned char escape, core_yyscan_t yyscanner);
97
+ static unsigned char unescape_single_char(unsigned char c, core_yyscan_t yyscanner);
98
+ static int process_integer_literal(const char *token, YYSTYPE *lval);
99
+ static bool is_utf16_surrogate_first(pg_wchar c);
100
+ static bool is_utf16_surrogate_second(pg_wchar c);
101
+ static pg_wchar surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second);
102
+ static void addunicode(pg_wchar c, yyscan_t yyscanner);
103
+
104
+ #define yyerror(msg) scanner_yyerror(msg, yyscanner)
105
+
106
+ #define lexer_errposition() scanner_errposition(*(yylloc), yyscanner)
107
+
108
+ static void check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner);
109
+ static void check_escape_warning(core_yyscan_t yyscanner);
110
+
111
+ /*
112
+ * Work around a bug in flex 2.5.35: it emits a couple of functions that
113
+ * it forgets to emit declarations for. Since we use -Wmissing-prototypes,
114
+ * this would cause warnings. Providing our own declarations should be
115
+ * harmless even when the bug gets fixed.
116
+ */
117
+ extern int core_yyget_column(yyscan_t yyscanner);
118
+ extern void core_yyset_column(int column_no, yyscan_t yyscanner);
119
+
120
+ %}
121
+
122
+ %option reentrant
123
+ %option bison-bridge
124
+ %option bison-locations
125
+ %option 8bit
126
+ %option never-interactive
127
+ %option nodefault
128
+ %option noinput
129
+ %option nounput
130
+ %option noyywrap
131
+ %option noyyalloc
132
+ %option noyyrealloc
133
+ %option noyyfree
134
+ %option warn
135
+ %option prefix="core_yy"
136
+
137
+ /*
138
+ * OK, here is a short description of lex/flex rules behavior.
139
+ * The longest pattern which matches an input string is always chosen.
140
+ * For equal-length patterns, the first occurring in the rules list is chosen.
141
+ * INITIAL is the starting state, to which all non-conditional rules apply.
142
+ * Exclusive states change parsing rules while the state is active. When in
143
+ * an exclusive state, only those rules defined for that state apply.
144
+ *
145
+ * We use exclusive states for quoted strings, extended comments,
146
+ * and to eliminate parsing troubles for numeric strings.
147
+ * Exclusive states:
148
+ * <xb> bit string literal
149
+ * <xc> extended C-style comments
150
+ * <xd> delimited identifiers (double-quoted identifiers)
151
+ * <xh> hexadecimal numeric string
152
+ * <xq> standard quoted strings
153
+ * <xe> extended quoted strings (support backslash escape sequences)
154
+ * <xdolq> $foo$ quoted strings
155
+ * <xui> quoted identifier with Unicode escapes
156
+ * <xus> quoted string with Unicode escapes
157
+ * <xeu> Unicode surrogate pair in extended quoted string
158
+ */
159
+
160
+ %x xb
161
+ %x xc
162
+ %x xd
163
+ %x xh
164
+ %x xe
165
+ %x xq
166
+ %x xdolq
167
+ %x xui
168
+ %x xus
169
+ %x xeu
170
+
171
+ /*
172
+ * In order to make the world safe for Windows and Mac clients as well as
173
+ * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n
174
+ * sequence will be seen as two successive newlines, but that doesn't cause
175
+ * any problems. Comments that start with -- and extend to the next
176
+ * newline are treated as equivalent to a single whitespace character.
177
+ *
178
+ * NOTE a fine point: if there is no newline following --, we will absorb
179
+ * everything to the end of the input as a comment. This is correct. Older
180
+ * versions of Postgres failed to recognize -- as a comment if the input
181
+ * did not end with a newline.
182
+ *
183
+ * XXX perhaps \f (formfeed) should be treated as a newline as well?
184
+ *
185
+ * XXX if you change the set of whitespace characters, fix scanner_isspace()
186
+ * to agree, and see also the plpgsql lexer.
187
+ */
188
+
189
+ space [ \t\n\r\f]
190
+ horiz_space [ \t\f]
191
+ newline [\n\r]
192
+ non_newline [^\n\r]
193
+
194
+ comment ("--"{non_newline}*)
195
+
196
+ whitespace ({space}+|{comment})
197
+
198
+ /*
199
+ * SQL requires at least one newline in the whitespace separating
200
+ * string literals that are to be concatenated. Silly, but who are we
201
+ * to argue? Note that {whitespace_with_newline} should not have * after
202
+ * it, whereas {whitespace} should generally have a * after it...
203
+ */
204
+
205
+ special_whitespace ({space}+|{comment}{newline})
206
+ horiz_whitespace ({horiz_space}|{comment})
207
+ whitespace_with_newline ({horiz_whitespace}*{newline}{special_whitespace}*)
208
+
209
+ /*
210
+ * To ensure that {quotecontinue} can be scanned without having to back up
211
+ * if the full pattern isn't matched, we include trailing whitespace in
212
+ * {quotestop}. This matches all cases where {quotecontinue} fails to match,
213
+ * except for {quote} followed by whitespace and just one "-" (not two,
214
+ * which would start a {comment}). To cover that we have {quotefail}.
215
+ * The actions for {quotestop} and {quotefail} must throw back characters
216
+ * beyond the quote proper.
217
+ */
218
+ quote '
219
+ quotestop {quote}{whitespace}*
220
+ quotecontinue {quote}{whitespace_with_newline}{quote}
221
+ quotefail {quote}{whitespace}*"-"
222
+
223
+ /* Bit string
224
+ * It is tempting to scan the string for only those characters
225
+ * which are allowed. However, this leads to silently swallowed
226
+ * characters if illegal characters are included in the string.
227
+ * For example, if xbinside is [01] then B'ABCD' is interpreted
228
+ * as a zero-length string, and the ABCD' is lost!
229
+ * Better to pass the string forward and let the input routines
230
+ * validate the contents.
231
+ */
232
+ xbstart [bB]{quote}
233
+ xbinside [^']*
234
+
235
+ /* Hexadecimal number */
236
+ xhstart [xX]{quote}
237
+ xhinside [^']*
238
+
239
+ /* National character */
240
+ xnstart [nN]{quote}
241
+
242
+ /* Quoted string that allows backslash escapes */
243
+ xestart [eE]{quote}
244
+ xeinside [^\\']+
245
+ xeescape [\\][^0-7]
246
+ xeoctesc [\\][0-7]{1,3}
247
+ xehexesc [\\]x[0-9A-Fa-f]{1,2}
248
+ xeunicode [\\](u[0-9A-Fa-f]{4}|U[0-9A-Fa-f]{8})
249
+ xeunicodefail [\\](u[0-9A-Fa-f]{0,3}|U[0-9A-Fa-f]{0,7})
250
+
251
+ /* Extended quote
252
+ * xqdouble implements embedded quote, ''''
253
+ */
254
+ xqstart {quote}
255
+ xqdouble {quote}{quote}
256
+ xqinside [^']+
257
+
258
+ /* $foo$ style quotes ("dollar quoting")
259
+ * The quoted string starts with $foo$ where "foo" is an optional string
260
+ * in the form of an identifier, except that it may not contain "$",
261
+ * and extends to the first occurrence of an identical string.
262
+ * There is *no* processing of the quoted text.
263
+ *
264
+ * {dolqfailed} is an error rule to avoid scanner backup when {dolqdelim}
265
+ * fails to match its trailing "$".
266
+ */
267
+ dolq_start [A-Za-z\200-\377_]
268
+ dolq_cont [A-Za-z\200-\377_0-9]
269
+ dolqdelim \$({dolq_start}{dolq_cont}*)?\$
270
+ dolqfailed \${dolq_start}{dolq_cont}*
271
+ dolqinside [^$]+
272
+
273
+ /* Double quote
274
+ * Allows embedded spaces and other special characters into identifiers.
275
+ */
276
+ dquote \"
277
+ xdstart {dquote}
278
+ xdstop {dquote}
279
+ xddouble {dquote}{dquote}
280
+ xdinside [^"]+
281
+
282
+ /* Unicode escapes */
283
+ uescape [uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']{quote}
284
+ /* error rule to avoid backup */
285
+ uescapefail ("-"|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*"-"|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}[^']|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*{quote}|[uU][eE][sS][cC][aA][pP][eE]{whitespace}*|[uU][eE][sS][cC][aA][pP]|[uU][eE][sS][cC][aA]|[uU][eE][sS][cC]|[uU][eE][sS]|[uU][eE]|[uU])
286
+
287
+ /* Quoted identifier with Unicode escapes */
288
+ xuistart [uU]&{dquote}
289
+ xuistop1 {dquote}{whitespace}*{uescapefail}?
290
+ xuistop2 {dquote}{whitespace}*{uescape}
291
+
292
+ /* Quoted string with Unicode escapes */
293
+ xusstart [uU]&{quote}
294
+ xusstop1 {quote}{whitespace}*{uescapefail}?
295
+ xusstop2 {quote}{whitespace}*{uescape}
296
+
297
+ /* error rule to avoid backup */
298
+ xufailed [uU]&
299
+
300
+
301
+ /* C-style comments
302
+ *
303
+ * The "extended comment" syntax closely resembles allowable operator syntax.
304
+ * The tricky part here is to get lex to recognize a string starting with
305
+ * slash-star as a comment, when interpreting it as an operator would produce
306
+ * a longer match --- remember lex will prefer a longer match! Also, if we
307
+ * have something like plus-slash-star, lex will think this is a 3-character
308
+ * operator whereas we want to see it as a + operator and a comment start.
309
+ * The solution is two-fold:
310
+ * 1. append {op_chars}* to xcstart so that it matches as much text as
311
+ * {operator} would. Then the tie-breaker (first matching rule of same
312
+ * length) ensures xcstart wins. We put back the extra stuff with yyless()
313
+ * in case it contains a star-slash that should terminate the comment.
314
+ * 2. In the operator rule, check for slash-star within the operator, and
315
+ * if found throw it back with yyless(). This handles the plus-slash-star
316
+ * problem.
317
+ * Dash-dash comments have similar interactions with the operator rule.
318
+ */
319
+ xcstart \/\*{op_chars}*
320
+ xcstop \*+\/
321
+ xcinside [^*/]+
322
+
323
+ digit [0-9]
324
+ ident_start [A-Za-z\200-\377_]
325
+ ident_cont [A-Za-z\200-\377_0-9\$]
326
+
327
+ identifier {ident_start}{ident_cont}*
328
+
329
+ typecast "::"
330
+ dot_dot \.\.
331
+ colon_equals ":="
332
+
333
+ /*
334
+ * "self" is the set of chars that should be returned as single-character
335
+ * tokens. "op_chars" is the set of chars that can make up "Op" tokens,
336
+ * which can be one or more characters long (but if a single-char token
337
+ * appears in the "self" set, it is not to be returned as an Op). Note
338
+ * that the sets overlap, but each has some chars that are not in the other.
339
+ *
340
+ * If you change either set, adjust the character lists appearing in the
341
+ * rule for "operator"!
342
+ */
343
+ self [,()\[\].;\:\+\-\*\/\%\^\<\>\=]
344
+ op_chars [\~\!\@\#\^\&\|\`\?\+\-\*\/\%\<\>\=]
345
+ operator {op_chars}+
346
+
347
+ /* we no longer allow unary minus in numbers.
348
+ * instead we pass it separately to parser. there it gets
349
+ * coerced via doNegate() -- Leon aug 20 1999
350
+ *
351
+ * {decimalfail} is used because we would like "1..10" to lex as 1, dot_dot, 10.
352
+ *
353
+ * {realfail1} and {realfail2} are added to prevent the need for scanner
354
+ * backup when the {real} rule fails to match completely.
355
+ */
356
+
357
+ integer {digit}+
358
+ decimal (({digit}*\.{digit}+)|({digit}+\.{digit}*))
359
+ decimalfail {digit}+\.\.
360
+ real ({integer}|{decimal})[Ee][-+]?{digit}+
361
+ realfail1 ({integer}|{decimal})[Ee]
362
+ realfail2 ({integer}|{decimal})[Ee][-+]
363
+
364
+ param \${integer}
365
+
366
+ other .
367
+
368
+ /*
369
+ * Dollar quoted strings are totally opaque, and no escaping is done on them.
370
+ * Other quoted strings must allow some special characters such as single-quote
371
+ * and newline.
372
+ * Embedded single-quotes are implemented both in the SQL standard
373
+ * style of two adjacent single quotes "''" and in the Postgres/Java style
374
+ * of escaped-quote "\'".
375
+ * Other embedded escaped characters are matched explicitly and the leading
376
+ * backslash is dropped from the string.
377
+ * Note that xcstart must appear before operator, as explained above!
378
+ * Also whitespace (comment) must appear before operator.
379
+ */
380
+
381
+ %%
382
+
383
+ {whitespace} {
384
+ /* ignore */
385
+ }
386
+
387
+ {xcstart} {
388
+ /* Set location in case of syntax error in comment */
389
+ SET_YYLLOC();
390
+ yyextra->xcdepth = 0;
391
+ BEGIN(xc);
392
+ /* Put back any characters past slash-star; see above */
393
+ yyless(2);
394
+ }
395
+
396
+ <xc>{xcstart} {
397
+ (yyextra->xcdepth)++;
398
+ /* Put back any characters past slash-star; see above */
399
+ yyless(2);
400
+ }
401
+
402
+ <xc>{xcstop} {
403
+ if (yyextra->xcdepth <= 0)
404
+ BEGIN(INITIAL);
405
+ else
406
+ (yyextra->xcdepth)--;
407
+ }
408
+
409
+ <xc>{xcinside} {
410
+ /* ignore */
411
+ }
412
+
413
+ <xc>{op_chars} {
414
+ /* ignore */
415
+ }
416
+
417
+ <xc>\*+ {
418
+ /* ignore */
419
+ }
420
+
421
+ <xc><<EOF>> { yyerror("unterminated /* comment"); }
422
+
423
+ {xbstart} {
424
+ /* Binary bit type.
425
+ * At some point we should simply pass the string
426
+ * forward to the parser and label it there.
427
+ * In the meantime, place a leading "b" on the string
428
+ * to mark it for the input routine as a binary string.
429
+ */
430
+ SET_YYLLOC();
431
+ BEGIN(xb);
432
+ startlit();
433
+ addlitchar('b', yyscanner);
434
+ }
435
+ <xb>{quotestop} |
436
+ <xb>{quotefail} {
437
+ yyless(1);
438
+ BEGIN(INITIAL);
439
+ yylval->str = litbufdup(yyscanner);
440
+ return BCONST;
441
+ }
442
+ <xh>{xhinside} |
443
+ <xb>{xbinside} {
444
+ addlit(yytext, yyleng, yyscanner);
445
+ }
446
+ <xh>{quotecontinue} |
447
+ <xb>{quotecontinue} {
448
+ /* ignore */
449
+ }
450
+ <xb><<EOF>> { yyerror("unterminated bit string literal"); }
451
+
452
+ {xhstart} {
453
+ /* Hexadecimal bit type.
454
+ * At some point we should simply pass the string
455
+ * forward to the parser and label it there.
456
+ * In the meantime, place a leading "x" on the string
457
+ * to mark it for the input routine as a hex string.
458
+ */
459
+ SET_YYLLOC();
460
+ BEGIN(xh);
461
+ startlit();
462
+ addlitchar('x', yyscanner);
463
+ }
464
+ <xh>{quotestop} |
465
+ <xh>{quotefail} {
466
+ yyless(1);
467
+ BEGIN(INITIAL);
468
+ yylval->str = litbufdup(yyscanner);
469
+ return XCONST;
470
+ }
471
+ <xh><<EOF>> { yyerror("unterminated hexadecimal string literal"); }
472
+
473
+ {xnstart} {
474
+ /* National character.
475
+ * We will pass this along as a normal character string,
476
+ * but preceded with an internally-generated "NCHAR".
477
+ */
478
+ const ScanKeyword *keyword;
479
+
480
+ SET_YYLLOC();
481
+ yyless(1); /* eat only 'n' this time */
482
+
483
+ keyword = ScanKeywordLookup("nchar",
484
+ yyextra->keywords,
485
+ yyextra->num_keywords);
486
+ if (keyword != NULL)
487
+ {
488
+ yylval->keyword = keyword->name;
489
+ return keyword->value;
490
+ }
491
+ else
492
+ {
493
+ /* If NCHAR isn't a keyword, just return "n" */
494
+ yylval->str = pstrdup("n");
495
+ return IDENT;
496
+ }
497
+ }
498
+
499
+ {xqstart} {
500
+ yyextra->warn_on_first_escape = true;
501
+ yyextra->saw_non_ascii = false;
502
+ SET_YYLLOC();
503
+ if (standard_conforming_strings)
504
+ BEGIN(xq);
505
+ else
506
+ BEGIN(xe);
507
+ startlit();
508
+ }
509
+ {xestart} {
510
+ yyextra->warn_on_first_escape = false;
511
+ yyextra->saw_non_ascii = false;
512
+ SET_YYLLOC();
513
+ BEGIN(xe);
514
+ startlit();
515
+ }
516
+ {xusstart} {
517
+ SET_YYLLOC();
518
+ if (!standard_conforming_strings)
519
+ ereport(ERROR,
520
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
521
+ errmsg("unsafe use of string constant with Unicode escapes"),
522
+ errdetail("String constants with Unicode escapes cannot be used when standard_conforming_strings is off."),
523
+ lexer_errposition()));
524
+ BEGIN(xus);
525
+ startlit();
526
+ }
527
+ <xq,xe>{quotestop} |
528
+ <xq,xe>{quotefail} {
529
+ yyless(1);
530
+ BEGIN(INITIAL);
531
+ /*
532
+ * check that the data remains valid if it might have been
533
+ * made invalid by unescaping any chars.
534
+ */
535
+ if (yyextra->saw_non_ascii)
536
+ pg_verifymbstr(yyextra->literalbuf,
537
+ yyextra->literallen,
538
+ false);
539
+ yylval->str = litbufdup(yyscanner);
540
+ return SCONST;
541
+ }
542
+ <xus>{xusstop1} {
543
+ /* throw back all but the quote */
544
+ yyless(1);
545
+ BEGIN(INITIAL);
546
+ yylval->str = litbuf_udeescape('\\', yyscanner);
547
+ return SCONST;
548
+ }
549
+ <xus>{xusstop2} {
550
+ BEGIN(INITIAL);
551
+ yylval->str = litbuf_udeescape(yytext[yyleng-2], yyscanner);
552
+ return SCONST;
553
+ }
554
+ <xq,xe,xus>{xqdouble} {
555
+ addlitchar('\'', yyscanner);
556
+ }
557
+ <xq,xus>{xqinside} {
558
+ addlit(yytext, yyleng, yyscanner);
559
+ }
560
+ <xe>{xeinside} {
561
+ addlit(yytext, yyleng, yyscanner);
562
+ }
563
+ <xe>{xeunicode} {
564
+ pg_wchar c = strtoul(yytext+2, NULL, 16);
565
+
566
+ check_escape_warning(yyscanner);
567
+
568
+ if (is_utf16_surrogate_first(c))
569
+ {
570
+ yyextra->utf16_first_part = c;
571
+ BEGIN(xeu);
572
+ }
573
+ else if (is_utf16_surrogate_second(c))
574
+ yyerror("invalid Unicode surrogate pair");
575
+ else
576
+ addunicode(c, yyscanner);
577
+ }
578
+ <xeu>{xeunicode} {
579
+ pg_wchar c = strtoul(yytext+2, NULL, 16);
580
+
581
+ if (!is_utf16_surrogate_second(c))
582
+ yyerror("invalid Unicode surrogate pair");
583
+
584
+ c = surrogate_pair_to_codepoint(yyextra->utf16_first_part, c);
585
+
586
+ addunicode(c, yyscanner);
587
+
588
+ BEGIN(xe);
589
+ }
590
+ <xeu>. { yyerror("invalid Unicode surrogate pair"); }
591
+ <xeu>\n { yyerror("invalid Unicode surrogate pair"); }
592
+ <xeu><<EOF>> { yyerror("invalid Unicode surrogate pair"); }
593
+ <xe,xeu>{xeunicodefail} {
594
+ ereport(ERROR,
595
+ (errcode(ERRCODE_INVALID_ESCAPE_SEQUENCE),
596
+ errmsg("invalid Unicode escape"),
597
+ errhint("Unicode escapes must be \\uXXXX or \\UXXXXXXXX."),
598
+ lexer_errposition()));
599
+ }
600
+ <xe>{xeescape} {
601
+ #ifdef PGPOOL_NOT_USED
602
+ if (yytext[1] == '\'')
603
+ {
604
+ if (backslash_quote == BACKSLASH_QUOTE_OFF ||
605
+ (backslash_quote == BACKSLASH_QUOTE_SAFE_ENCODING &&
606
+ PG_ENCODING_IS_CLIENT_ONLY(pg_get_client_encoding())))
607
+ ereport(ERROR,
608
+ (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
609
+ errmsg("unsafe use of \\' in a string literal"),
610
+ errhint("Use '' to write quotes in strings. \\' is insecure in client-only encodings."),
611
+ lexer_errposition()));
612
+ }
613
+ #endif
614
+ check_string_escape_warning(yytext[1], yyscanner);
615
+ addlitchar(unescape_single_char(yytext[1], yyscanner),
616
+ yyscanner);
617
+ }
618
+ <xe>{xeoctesc} {
619
+ unsigned char c = strtoul(yytext+1, NULL, 8);
620
+
621
+ check_escape_warning(yyscanner);
622
+ addlitchar(c, yyscanner);
623
+ if (c == '\0' || IS_HIGHBIT_SET(c))
624
+ yyextra->saw_non_ascii = true;
625
+ }
626
+ <xe>{xehexesc} {
627
+ unsigned char c = strtoul(yytext+2, NULL, 16);
628
+
629
+ check_escape_warning(yyscanner);
630
+ addlitchar(c, yyscanner);
631
+ if (c == '\0' || IS_HIGHBIT_SET(c))
632
+ yyextra->saw_non_ascii = true;
633
+ }
634
+ <xq,xe,xus>{quotecontinue} {
635
+ /* ignore */
636
+ }
637
+ <xe>. {
638
+ /* This is only needed for \ just before EOF */
639
+ addlitchar(yytext[0], yyscanner);
640
+ }
641
+ <xq,xe,xus><<EOF>> { yyerror("unterminated quoted string"); }
642
+
643
+ {dolqdelim} {
644
+ SET_YYLLOC();
645
+ yyextra->dolqstart = pstrdup(yytext);
646
+ BEGIN(xdolq);
647
+ startlit();
648
+ }
649
+ {dolqfailed} {
650
+ SET_YYLLOC();
651
+ /* throw back all but the initial "$" */
652
+ yyless(1);
653
+ /* and treat it as {other} */
654
+ return yytext[0];
655
+ }
656
+ <xdolq>{dolqdelim} {
657
+ if (strcmp(yytext, yyextra->dolqstart) == 0)
658
+ {
659
+ pfree(yyextra->dolqstart);
660
+ yyextra->dolqstart = NULL;
661
+ BEGIN(INITIAL);
662
+ yylval->str = litbufdup(yyscanner);
663
+ return SCONST;
664
+ }
665
+ else
666
+ {
667
+ /*
668
+ * When we fail to match $...$ to dolqstart, transfer
669
+ * the $... part to the output, but put back the final
670
+ * $ for rescanning. Consider $delim$...$junk$delim$
671
+ */
672
+ addlit(yytext, yyleng-1, yyscanner);
673
+ yyless(yyleng-1);
674
+ }
675
+ }
676
+ <xdolq>{dolqinside} {
677
+ addlit(yytext, yyleng, yyscanner);
678
+ }
679
+ <xdolq>{dolqfailed} {
680
+ addlit(yytext, yyleng, yyscanner);
681
+ }
682
+ <xdolq>. {
683
+ /* This is only needed for $ inside the quoted text */
684
+ addlitchar(yytext[0], yyscanner);
685
+ }
686
+ <xdolq><<EOF>> { yyerror("unterminated dollar-quoted string"); }
687
+
688
+ {xdstart} {
689
+ SET_YYLLOC();
690
+ BEGIN(xd);
691
+ startlit();
692
+ }
693
+ {xuistart} {
694
+ SET_YYLLOC();
695
+ BEGIN(xui);
696
+ startlit();
697
+ }
698
+ <xd>{xdstop} {
699
+ char *ident;
700
+
701
+ BEGIN(INITIAL);
702
+ if (yyextra->literallen == 0)
703
+ yyerror("zero-length delimited identifier");
704
+ ident = litbufdup(yyscanner);
705
+ if (yyextra->literallen >= NAMEDATALEN)
706
+ truncate_identifier(ident, yyextra->literallen, true);
707
+ yylval->str = ident;
708
+ return IDENT;
709
+ }
710
+ <xui>{xuistop1} {
711
+ char *ident;
712
+
713
+ BEGIN(INITIAL);
714
+ if (yyextra->literallen == 0)
715
+ yyerror("zero-length delimited identifier");
716
+ ident = litbuf_udeescape('\\', yyscanner);
717
+ if (yyextra->literallen >= NAMEDATALEN)
718
+ truncate_identifier(ident, yyextra->literallen, true);
719
+ yylval->str = ident;
720
+ /* throw back all but the quote */
721
+ yyless(1);
722
+ return IDENT;
723
+ }
724
+ <xui>{xuistop2} {
725
+ char *ident;
726
+
727
+ BEGIN(INITIAL);
728
+ if (yyextra->literallen == 0)
729
+ yyerror("zero-length delimited identifier");
730
+ ident = litbuf_udeescape(yytext[yyleng - 2], yyscanner);
731
+ if (yyextra->literallen >= NAMEDATALEN)
732
+ truncate_identifier(ident, yyextra->literallen, true);
733
+ yylval->str = ident;
734
+ return IDENT;
735
+ }
736
+ <xd,xui>{xddouble} {
737
+ addlitchar('"', yyscanner);
738
+ }
739
+ <xd,xui>{xdinside} {
740
+ addlit(yytext, yyleng, yyscanner);
741
+ }
742
+ <xd,xui><<EOF>> { yyerror("unterminated quoted identifier"); }
743
+
744
+ {xufailed} {
745
+ char *ident;
746
+
747
+ SET_YYLLOC();
748
+ /* throw back all but the initial u/U */
749
+ yyless(1);
750
+ /* and treat it as {identifier} */
751
+ ident = downcase_truncate_identifier(yytext, yyleng, true);
752
+ yylval->str = ident;
753
+ return IDENT;
754
+ }
755
+
756
+ {typecast} {
757
+ SET_YYLLOC();
758
+ return TYPECAST;
759
+ }
760
+
761
+ {dot_dot} {
762
+ SET_YYLLOC();
763
+ return DOT_DOT;
764
+ }
765
+
766
+ {colon_equals} {
767
+ SET_YYLLOC();
768
+ return COLON_EQUALS;
769
+ }
770
+
771
+ {self} {
772
+ SET_YYLLOC();
773
+ return yytext[0];
774
+ }
775
+
776
+ {operator} {
777
+ /*
778
+ * Check for embedded slash-star or dash-dash; those
779
+ * are comment starts, so operator must stop there.
780
+ * Note that slash-star or dash-dash at the first
781
+ * character will match a prior rule, not this one.
782
+ */
783
+ int nchars = yyleng;
784
+ char *slashstar = strstr(yytext, "/*");
785
+ char *dashdash = strstr(yytext, "--");
786
+
787
+ if (slashstar && dashdash)
788
+ {
789
+ /* if both appear, take the first one */
790
+ if (slashstar > dashdash)
791
+ slashstar = dashdash;
792
+ }
793
+ else if (!slashstar)
794
+ slashstar = dashdash;
795
+ if (slashstar)
796
+ nchars = slashstar - yytext;
797
+
798
+ /*
799
+ * For SQL compatibility, '+' and '-' cannot be the
800
+ * last char of a multi-char operator unless the operator
801
+ * contains chars that are not in SQL operators.
802
+ * The idea is to lex '=-' as two operators, but not
803
+ * to forbid operator names like '?-' that could not be
804
+ * sequences of SQL operators.
805
+ */
806
+ while (nchars > 1 &&
807
+ (yytext[nchars-1] == '+' ||
808
+ yytext[nchars-1] == '-'))
809
+ {
810
+ int ic;
811
+
812
+ for (ic = nchars-2; ic >= 0; ic--)
813
+ {
814
+ if (strchr("~!@#^&|`?%", yytext[ic]))
815
+ break;
816
+ }
817
+ if (ic >= 0)
818
+ break; /* found a char that makes it OK */
819
+ nchars--; /* else remove the +/-, and check again */
820
+ }
821
+
822
+ SET_YYLLOC();
823
+
824
+ if (nchars < yyleng)
825
+ {
826
+ /* Strip the unwanted chars from the token */
827
+ yyless(nchars);
828
+ /*
829
+ * If what we have left is only one char, and it's
830
+ * one of the characters matching "self", then
831
+ * return it as a character token the same way
832
+ * that the "self" rule would have.
833
+ */
834
+ if (nchars == 1 &&
835
+ strchr(",()[].;:+-*/%^<>=", yytext[0]))
836
+ return yytext[0];
837
+ }
838
+
839
+ /*
840
+ * Complain if operator is too long. Unlike the case
841
+ * for identifiers, we make this an error not a notice-
842
+ * and-truncate, because the odds are we are looking at
843
+ * a syntactic mistake anyway.
844
+ */
845
+ if (nchars >= NAMEDATALEN)
846
+ yyerror("operator too long");
847
+
848
+ /* Convert "!=" operator to "<>" for compatibility */
849
+ if (strcmp(yytext, "!=") == 0)
850
+ yylval->str = pstrdup("<>");
851
+ else
852
+ yylval->str = pstrdup(yytext);
853
+ return Op;
854
+ }
855
+
856
+ {param} {
857
+ SET_YYLLOC();
858
+ yylval->ival = atol(yytext + 1);
859
+ return PARAM;
860
+ }
861
+
862
+ {integer} {
863
+ SET_YYLLOC();
864
+ return process_integer_literal(yytext, yylval);
865
+ }
866
+ {decimal} {
867
+ SET_YYLLOC();
868
+ yylval->str = pstrdup(yytext);
869
+ return FCONST;
870
+ }
871
+ {decimalfail} {
872
+ /* throw back the .., and treat as integer */
873
+ yyless(yyleng-2);
874
+ SET_YYLLOC();
875
+ return process_integer_literal(yytext, yylval);
876
+ }
877
+ {real} {
878
+ SET_YYLLOC();
879
+ yylval->str = pstrdup(yytext);
880
+ return FCONST;
881
+ }
882
+ {realfail1} {
883
+ /*
884
+ * throw back the [Ee], and treat as {decimal}. Note
885
+ * that it is possible the input is actually {integer},
886
+ * but since this case will almost certainly lead to a
887
+ * syntax error anyway, we don't bother to distinguish.
888
+ */
889
+ yyless(yyleng-1);
890
+ SET_YYLLOC();
891
+ yylval->str = pstrdup(yytext);
892
+ return FCONST;
893
+ }
894
+ {realfail2} {
895
+ /* throw back the [Ee][+-], and proceed as above */
896
+ yyless(yyleng-2);
897
+ SET_YYLLOC();
898
+ yylval->str = pstrdup(yytext);
899
+ return FCONST;
900
+ }
901
+
902
+
903
+ {identifier} {
904
+ const ScanKeyword *keyword;
905
+ char *ident;
906
+
907
+ SET_YYLLOC();
908
+
909
+ /* Is it a keyword? */
910
+ keyword = ScanKeywordLookup(yytext,
911
+ yyextra->keywords,
912
+ yyextra->num_keywords);
913
+ if (keyword != NULL)
914
+ {
915
+ yylval->keyword = keyword->name;
916
+ return keyword->value;
917
+ }
918
+
919
+ /*
920
+ * No. Convert the identifier to lower case, and truncate
921
+ * if necessary.
922
+ */
923
+ ident = downcase_truncate_identifier(yytext, yyleng, true);
924
+ yylval->str = ident;
925
+ return IDENT;
926
+ }
927
+
928
+ {other} {
929
+ SET_YYLLOC();
930
+ return yytext[0];
931
+ }
932
+
933
+ <<EOF>> {
934
+ SET_YYLLOC();
935
+ yyterminate();
936
+ }
937
+
938
+ %%
939
+
940
+ /*
941
+ * Arrange access to yyextra for subroutines of the main yylex() function.
942
+ * We expect each subroutine to have a yyscanner parameter. Rather than
943
+ * use the yyget_xxx functions, which might or might not get inlined by the
944
+ * compiler, we cheat just a bit and cast yyscanner to the right type.
945
+ */
946
+ #undef yyextra
947
+ #define yyextra (((struct yyguts_t *) yyscanner)->yyextra_r)
948
+
949
+ /* Likewise for a couple of other things we need. */
950
+ #undef yylloc
951
+ #define yylloc (((struct yyguts_t *) yyscanner)->yylloc_r)
952
+ #undef yyleng
953
+ #define yyleng (((struct yyguts_t *) yyscanner)->yyleng_r)
954
+
955
+
956
+ /*
957
+ * scanner_errposition
958
+ * Report a lexer or grammar error cursor position, if possible.
959
+ *
960
+ * This is expected to be used within an ereport() call. The return value
961
+ * is a dummy (always 0, in fact).
962
+ *
963
+ * Note that this can only be used for messages emitted during raw parsing
964
+ * (essentially, scan.l and gram.y), since it requires the yyscanner struct
965
+ * to still be available.
966
+ */
967
+ int
968
+ scanner_errposition(int location, core_yyscan_t yyscanner)
969
+ {
970
+ #ifdef PGPOOL_NOT_USED
971
+ int pos;
972
+
973
+ if (location < 0)
974
+ return 0; /* no-op if location is unknown */
975
+
976
+ /* Convert byte offset to character number */
977
+ pos = pg_mbstrlen_with_len(yyextra->scanbuf, location) + 1;
978
+ /* And pass it to the ereport mechanism */
979
+ return errposition(pos);
980
+ #endif
981
+ return 0;
982
+ }
983
+
984
+ /*
985
+ * scanner_yyerror
986
+ * Report a lexer or grammar error.
987
+ *
988
+ * The message's cursor position is whatever YYLLOC was last set to,
989
+ * ie, the start of the current token if called within yylex(), or the
990
+ * most recently lexed token if called from the grammar.
991
+ * This is OK for syntax error messages from the Bison parser, because Bison
992
+ * parsers report error as soon as the first unparsable token is reached.
993
+ * Beware of using yyerror for other purposes, as the cursor position might
994
+ * be misleading!
995
+ */
996
+ void
997
+ scanner_yyerror(const char *message, core_yyscan_t yyscanner)
998
+ {
999
+ const char *loc = yyextra->scanbuf + *yylloc;
1000
+
1001
+ if (*loc == YY_END_OF_BUFFER_CHAR)
1002
+ {
1003
+ ereport(ERROR,
1004
+ (errcode(ERRCODE_SYNTAX_ERROR),
1005
+ /* translator: %s is typically the translation of "syntax error" */
1006
+ errmsg("%s at end of input", _(message)),
1007
+ lexer_errposition()));
1008
+ }
1009
+ else
1010
+ {
1011
+ ereport(ERROR,
1012
+ (errcode(ERRCODE_SYNTAX_ERROR),
1013
+ /* translator: first %s is typically the translation of "syntax error" */
1014
+ errmsg("%s at or near \"%s\"", _(message), loc),
1015
+ lexer_errposition()));
1016
+ }
1017
+ }
1018
+
1019
+
1020
+ /*
1021
+ * Called before any actual parsing is done
1022
+ */
1023
+ core_yyscan_t
1024
+ scanner_init(const char *str,
1025
+ core_yy_extra_type *yyext,
1026
+ const ScanKeyword *keywords,
1027
+ int num_keywords)
1028
+ {
1029
+ Size slen = strlen(str);
1030
+ yyscan_t scanner;
1031
+
1032
+ if (yylex_init(&scanner) != 0)
1033
+ elog(ERROR, "yylex_init() failed: %m");
1034
+
1035
+ core_yyset_extra(yyext, scanner);
1036
+
1037
+ yyext->keywords = keywords;
1038
+ yyext->num_keywords = num_keywords;
1039
+
1040
+ /*
1041
+ * Make a scan buffer with special termination needed by flex.
1042
+ */
1043
+ yyext->scanbuf = (char *) palloc(slen + 2);
1044
+ yyext->scanbuflen = slen;
1045
+ memcpy(yyext->scanbuf, str, slen);
1046
+ yyext->scanbuf[slen] = yyext->scanbuf[slen + 1] = YY_END_OF_BUFFER_CHAR;
1047
+ yy_scan_buffer(yyext->scanbuf, slen + 2, scanner);
1048
+
1049
+ /* initialize literal buffer to a reasonable but expansible size */
1050
+ yyext->literalalloc = 1024;
1051
+ yyext->literalbuf = (char *) palloc(yyext->literalalloc);
1052
+ yyext->literallen = 0;
1053
+
1054
+ return scanner;
1055
+ }
1056
+
1057
+
1058
+ /*
1059
+ * Called after parsing is done to clean up after scanner_init()
1060
+ */
1061
+ void
1062
+ scanner_finish(core_yyscan_t yyscanner)
1063
+ {
1064
+ /*
1065
+ * We don't bother to call yylex_destroy(), because all it would do
1066
+ * is pfree a small amount of control storage. It's cheaper to leak
1067
+ * the storage until the parsing context is destroyed. The amount of
1068
+ * space involved is usually negligible compared to the output parse
1069
+ * tree anyway.
1070
+ *
1071
+ * We do bother to pfree the scanbuf and literal buffer, but only if they
1072
+ * represent a nontrivial amount of space. The 8K cutoff is arbitrary.
1073
+ */
1074
+ if (yyextra->scanbuflen >= 8192)
1075
+ pfree(yyextra->scanbuf);
1076
+ if (yyextra->literalalloc >= 8192)
1077
+ pfree(yyextra->literalbuf);
1078
+ }
1079
+
1080
+
1081
+ static void
1082
+ addlit(char *ytext, int yleng, core_yyscan_t yyscanner)
1083
+ {
1084
+ /* enlarge buffer if needed */
1085
+ if ((yyextra->literallen + yleng) >= yyextra->literalalloc)
1086
+ {
1087
+ do {
1088
+ yyextra->literalalloc *= 2;
1089
+ } while ((yyextra->literallen + yleng) >= yyextra->literalalloc);
1090
+ yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
1091
+ yyextra->literalalloc);
1092
+ }
1093
+ /* append new data */
1094
+ memcpy(yyextra->literalbuf + yyextra->literallen, ytext, yleng);
1095
+ yyextra->literallen += yleng;
1096
+ }
1097
+
1098
+
1099
+ static void
1100
+ addlitchar(unsigned char ychar, core_yyscan_t yyscanner)
1101
+ {
1102
+ /* enlarge buffer if needed */
1103
+ if ((yyextra->literallen + 1) >= yyextra->literalalloc)
1104
+ {
1105
+ yyextra->literalalloc *= 2;
1106
+ yyextra->literalbuf = (char *) repalloc(yyextra->literalbuf,
1107
+ yyextra->literalalloc);
1108
+ }
1109
+ /* append new data */
1110
+ yyextra->literalbuf[yyextra->literallen] = ychar;
1111
+ yyextra->literallen += 1;
1112
+ }
1113
+
1114
+
1115
+ /*
1116
+ * Create a palloc'd copy of literalbuf, adding a trailing null.
1117
+ */
1118
+ static char *
1119
+ litbufdup(core_yyscan_t yyscanner)
1120
+ {
1121
+ int llen = yyextra->literallen;
1122
+ char *new;
1123
+
1124
+ new = palloc(llen + 1);
1125
+ memcpy(new, yyextra->literalbuf, llen);
1126
+ new[llen] = '\0';
1127
+ return new;
1128
+ }
1129
+
1130
+ static int
1131
+ process_integer_literal(const char *token, YYSTYPE *lval)
1132
+ {
1133
+ long val;
1134
+ char *endptr;
1135
+
1136
+ errno = 0;
1137
+ val = strtol(token, &endptr, 10);
1138
+ if (*endptr != '\0' || errno == ERANGE
1139
+ #ifdef HAVE_LONG_INT_64
1140
+ /* if long > 32 bits, check for overflow of int4 */
1141
+ || val != (long) ((int32) val)
1142
+ #endif
1143
+ )
1144
+ {
1145
+ /* integer too large, treat it as a float */
1146
+ lval->str = pstrdup(token);
1147
+ return FCONST;
1148
+ }
1149
+ lval->ival = val;
1150
+ return ICONST;
1151
+ }
1152
+
1153
+ static unsigned int
1154
+ hexval(unsigned char c)
1155
+ {
1156
+ if (c >= '0' && c <= '9')
1157
+ return c - '0';
1158
+ if (c >= 'a' && c <= 'f')
1159
+ return c - 'a' + 0xA;
1160
+ if (c >= 'A' && c <= 'F')
1161
+ return c - 'A' + 0xA;
1162
+ elog(ERROR, "invalid hexadecimal digit");
1163
+ return 0; /* not reached */
1164
+ }
1165
+
1166
+ static void
1167
+ check_unicode_value(pg_wchar c, char *loc, core_yyscan_t yyscanner)
1168
+ {
1169
+ if (GetDatabaseEncoding() == PG_UTF8)
1170
+ return;
1171
+
1172
+ if (c > 0x7F)
1173
+ {
1174
+ ADVANCE_YYLLOC(loc - yyextra->literalbuf + 3); /* 3 for U&" */
1175
+ yyerror("Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8");
1176
+ }
1177
+ }
1178
+
1179
+ static bool
1180
+ is_utf16_surrogate_first(pg_wchar c)
1181
+ {
1182
+ return (c >= 0xD800 && c <= 0xDBFF);
1183
+ }
1184
+
1185
+ static bool
1186
+ is_utf16_surrogate_second(pg_wchar c)
1187
+ {
1188
+ return (c >= 0xDC00 && c <= 0xDFFF);
1189
+ }
1190
+
1191
+ static pg_wchar
1192
+ surrogate_pair_to_codepoint(pg_wchar first, pg_wchar second)
1193
+ {
1194
+ return ((first & 0x3FF) << 10) + 0x10000 + (second & 0x3FF);
1195
+ }
1196
+
1197
+ static void
1198
+ addunicode(pg_wchar c, core_yyscan_t yyscanner)
1199
+ {
1200
+ char buf[8];
1201
+
1202
+ if (c == 0 || c > 0x10FFFF)
1203
+ yyerror("invalid Unicode escape value");
1204
+ if (c > 0x7F)
1205
+ {
1206
+ if (GetDatabaseEncoding() != PG_UTF8)
1207
+ yyerror("Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8");
1208
+ yyextra->saw_non_ascii = true;
1209
+ }
1210
+ unicode_to_utf8(c, (unsigned char *) buf);
1211
+ addlit(buf, pg_mblen(buf), yyscanner);
1212
+ }
1213
+
1214
+ static char *
1215
+ litbuf_udeescape(unsigned char escape, core_yyscan_t yyscanner)
1216
+ {
1217
+ char *new;
1218
+ char *litbuf, *in, *out;
1219
+ pg_wchar pair_first = 0;
1220
+
1221
+ if (isxdigit(escape)
1222
+ || escape == '+'
1223
+ || escape == '\''
1224
+ || escape == '"'
1225
+ || scanner_isspace(escape))
1226
+ {
1227
+ ADVANCE_YYLLOC(yyextra->literallen + yyleng + 1);
1228
+ yyerror("invalid Unicode escape character");
1229
+ }
1230
+
1231
+ /* Make literalbuf null-terminated to simplify the scanning loop */
1232
+ litbuf = yyextra->literalbuf;
1233
+ litbuf[yyextra->literallen] = '\0';
1234
+
1235
+ /*
1236
+ * This relies on the subtle assumption that a UTF-8 expansion
1237
+ * cannot be longer than its escaped representation.
1238
+ */
1239
+ new = palloc(yyextra->literallen + 1);
1240
+
1241
+ in = litbuf;
1242
+ out = new;
1243
+ while (*in)
1244
+ {
1245
+ if (in[0] == escape)
1246
+ {
1247
+ if (in[1] == escape)
1248
+ {
1249
+ if (pair_first)
1250
+ {
1251
+ ADVANCE_YYLLOC(in - litbuf + 3); /* 3 for U&" */
1252
+ yyerror("invalid Unicode surrogate pair");
1253
+ }
1254
+ *out++ = escape;
1255
+ in += 2;
1256
+ }
1257
+ else if (isxdigit((unsigned char) in[1]) &&
1258
+ isxdigit((unsigned char) in[2]) &&
1259
+ isxdigit((unsigned char) in[3]) &&
1260
+ isxdigit((unsigned char) in[4]))
1261
+ {
1262
+ pg_wchar unicode;
1263
+
1264
+ unicode = (hexval(in[1]) << 12) +
1265
+ (hexval(in[2]) << 8) +
1266
+ (hexval(in[3]) << 4) +
1267
+ hexval(in[4]);
1268
+ check_unicode_value(unicode, in, yyscanner);
1269
+ if (pair_first)
1270
+ {
1271
+ if (is_utf16_surrogate_second(unicode))
1272
+ {
1273
+ unicode = surrogate_pair_to_codepoint(pair_first, unicode);
1274
+ pair_first = 0;
1275
+ }
1276
+ else
1277
+ {
1278
+ ADVANCE_YYLLOC(in - litbuf + 3); /* 3 for U&" */
1279
+ yyerror("invalid Unicode surrogate pair");
1280
+ }
1281
+ }
1282
+ else if (is_utf16_surrogate_second(unicode))
1283
+ yyerror("invalid Unicode surrogate pair");
1284
+
1285
+ if (is_utf16_surrogate_first(unicode))
1286
+ pair_first = unicode;
1287
+ else
1288
+ {
1289
+ unicode_to_utf8(unicode, (unsigned char *) out);
1290
+ out += pg_mblen(out);
1291
+ }
1292
+ in += 5;
1293
+ }
1294
+ else if (in[1] == '+' &&
1295
+ isxdigit((unsigned char) in[2]) &&
1296
+ isxdigit((unsigned char) in[3]) &&
1297
+ isxdigit((unsigned char) in[4]) &&
1298
+ isxdigit((unsigned char) in[5]) &&
1299
+ isxdigit((unsigned char) in[6]) &&
1300
+ isxdigit((unsigned char) in[7]))
1301
+ {
1302
+ pg_wchar unicode;
1303
+
1304
+ unicode = (hexval(in[2]) << 20) +
1305
+ (hexval(in[3]) << 16) +
1306
+ (hexval(in[4]) << 12) +
1307
+ (hexval(in[5]) << 8) +
1308
+ (hexval(in[6]) << 4) +
1309
+ hexval(in[7]);
1310
+ check_unicode_value(unicode, in, yyscanner);
1311
+ if (pair_first)
1312
+ {
1313
+ if (is_utf16_surrogate_second(unicode))
1314
+ {
1315
+ unicode = surrogate_pair_to_codepoint(pair_first, unicode);
1316
+ pair_first = 0;
1317
+ }
1318
+ else
1319
+ {
1320
+ ADVANCE_YYLLOC(in - litbuf + 3); /* 3 for U&" */
1321
+ yyerror("invalid Unicode surrogate pair");
1322
+ }
1323
+ }
1324
+ else if (is_utf16_surrogate_second(unicode))
1325
+ yyerror("invalid Unicode surrogate pair");
1326
+
1327
+ if (is_utf16_surrogate_first(unicode))
1328
+ pair_first = unicode;
1329
+ else
1330
+ {
1331
+ unicode_to_utf8(unicode, (unsigned char *) out);
1332
+ out += pg_mblen(out);
1333
+ }
1334
+ in += 8;
1335
+ }
1336
+ else
1337
+ {
1338
+ ADVANCE_YYLLOC(in - litbuf + 3); /* 3 for U&" */
1339
+ yyerror("invalid Unicode escape value");
1340
+ }
1341
+ }
1342
+ else
1343
+ {
1344
+ if (pair_first)
1345
+ {
1346
+ ADVANCE_YYLLOC(in - litbuf + 3); /* 3 for U&" */
1347
+ yyerror("invalid Unicode surrogate pair");
1348
+ }
1349
+ *out++ = *in++;
1350
+ }
1351
+ }
1352
+
1353
+ *out = '\0';
1354
+ /*
1355
+ * We could skip pg_verifymbstr if we didn't process any non-7-bit-ASCII
1356
+ * codes; but it's probably not worth the trouble, since this isn't
1357
+ * likely to be a performance-critical path.
1358
+ */
1359
+ pg_verifymbstr(new, out - new, false);
1360
+ return new;
1361
+ }
1362
+
1363
+ static unsigned char
1364
+ unescape_single_char(unsigned char c, core_yyscan_t yyscanner)
1365
+ {
1366
+ switch (c)
1367
+ {
1368
+ case 'b':
1369
+ return '\b';
1370
+ case 'f':
1371
+ return '\f';
1372
+ case 'n':
1373
+ return '\n';
1374
+ case 'r':
1375
+ return '\r';
1376
+ case 't':
1377
+ return '\t';
1378
+ default:
1379
+ /* check for backslash followed by non-7-bit-ASCII */
1380
+ if (c == '\0' || IS_HIGHBIT_SET(c))
1381
+ yyextra->saw_non_ascii = true;
1382
+
1383
+ return c;
1384
+ }
1385
+ }
1386
+
1387
+ static void
1388
+ check_string_escape_warning(unsigned char ychar, core_yyscan_t yyscanner)
1389
+ {
1390
+ if (ychar == '\'')
1391
+ {
1392
+ if (yyextra->warn_on_first_escape && escape_string_warning)
1393
+ ereport(WARNING,
1394
+ (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
1395
+ errmsg("nonstandard use of \\' in a string literal"),
1396
+ errhint("Use '' to write quotes in strings, or use the escape string syntax (E'...')."),
1397
+ lexer_errposition()));
1398
+ yyextra->warn_on_first_escape = false; /* warn only once per string */
1399
+ }
1400
+ else if (ychar == '\\')
1401
+ {
1402
+ if (yyextra->warn_on_first_escape && escape_string_warning)
1403
+ ereport(WARNING,
1404
+ (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
1405
+ errmsg("nonstandard use of \\\\ in a string literal"),
1406
+ errhint("Use the escape string syntax for backslashes, e.g., E'\\\\'."),
1407
+ lexer_errposition()));
1408
+ yyextra->warn_on_first_escape = false; /* warn only once per string */
1409
+ }
1410
+ else
1411
+ check_escape_warning(yyscanner);
1412
+ }
1413
+
1414
+ static void
1415
+ check_escape_warning(core_yyscan_t yyscanner)
1416
+ {
1417
+ if (yyextra->warn_on_first_escape && escape_string_warning)
1418
+ ereport(WARNING,
1419
+ (errcode(ERRCODE_NONSTANDARD_USE_OF_ESCAPE_CHARACTER),
1420
+ errmsg("nonstandard use of escape in a string literal"),
1421
+ errhint("Use the escape string syntax for escapes, e.g., E'\\r\\n'."),
1422
+ lexer_errposition()));
1423
+ yyextra->warn_on_first_escape = false; /* warn only once per string */
1424
+ }
1425
+
1426
+ /*
1427
+ * Interface functions to make flex use palloc() instead of malloc().
1428
+ * It'd be better to make these static, but flex insists otherwise.
1429
+ */
1430
+
1431
+ void *
1432
+ core_yyalloc(yy_size_t bytes, core_yyscan_t yyscanner)
1433
+ {
1434
+ return palloc(bytes);
1435
+ }
1436
+
1437
+ void *
1438
+ core_yyrealloc(void *ptr, yy_size_t bytes, core_yyscan_t yyscanner)
1439
+ {
1440
+ if (ptr)
1441
+ return repalloc(ptr, bytes);
1442
+ else
1443
+ return palloc(bytes);
1444
+ }
1445
+
1446
+ void
1447
+ core_yyfree(void *ptr, core_yyscan_t yyscanner)
1448
+ {
1449
+ if (ptr)
1450
+ pfree(ptr);
1451
+ }