gitlab-pg_query 1.3.1 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +217 -99
- data/README.md +92 -69
- data/Rakefile +85 -5
- data/ext/pg_query/extconf.rb +3 -40
- data/ext/pg_query/guc-file.c +0 -0
- data/ext/pg_query/include/access/amapi.h +246 -0
- data/ext/pg_query/include/access/attmap.h +52 -0
- data/ext/pg_query/include/access/attnum.h +64 -0
- data/ext/pg_query/include/access/clog.h +61 -0
- data/ext/pg_query/include/access/commit_ts.h +77 -0
- data/ext/pg_query/include/access/detoast.h +92 -0
- data/ext/pg_query/include/access/genam.h +228 -0
- data/ext/pg_query/include/access/gin.h +78 -0
- data/ext/pg_query/include/access/htup.h +89 -0
- data/ext/pg_query/include/access/htup_details.h +819 -0
- data/ext/pg_query/include/access/itup.h +161 -0
- data/ext/pg_query/include/access/parallel.h +82 -0
- data/ext/pg_query/include/access/printtup.h +35 -0
- data/ext/pg_query/include/access/relation.h +28 -0
- data/ext/pg_query/include/access/relscan.h +176 -0
- data/ext/pg_query/include/access/rmgr.h +35 -0
- data/ext/pg_query/include/access/rmgrlist.h +49 -0
- data/ext/pg_query/include/access/sdir.h +58 -0
- data/ext/pg_query/include/access/skey.h +151 -0
- data/ext/pg_query/include/access/stratnum.h +83 -0
- data/ext/pg_query/include/access/sysattr.h +29 -0
- data/ext/pg_query/include/access/table.h +27 -0
- data/ext/pg_query/include/access/tableam.h +1825 -0
- data/ext/pg_query/include/access/transam.h +265 -0
- data/ext/pg_query/include/access/tupconvert.h +51 -0
- data/ext/pg_query/include/access/tupdesc.h +154 -0
- data/ext/pg_query/include/access/tupmacs.h +247 -0
- data/ext/pg_query/include/access/twophase.h +61 -0
- data/ext/pg_query/include/access/xact.h +463 -0
- data/ext/pg_query/include/access/xlog.h +398 -0
- data/ext/pg_query/include/access/xlog_internal.h +330 -0
- data/ext/pg_query/include/access/xlogdefs.h +109 -0
- data/ext/pg_query/include/access/xloginsert.h +64 -0
- data/ext/pg_query/include/access/xlogreader.h +327 -0
- data/ext/pg_query/include/access/xlogrecord.h +227 -0
- data/ext/pg_query/include/bootstrap/bootstrap.h +62 -0
- data/ext/pg_query/include/c.h +1322 -0
- data/ext/pg_query/include/catalog/catalog.h +42 -0
- data/ext/pg_query/include/catalog/catversion.h +58 -0
- data/ext/pg_query/include/catalog/dependency.h +275 -0
- data/ext/pg_query/include/catalog/genbki.h +64 -0
- data/ext/pg_query/include/catalog/index.h +199 -0
- data/ext/pg_query/include/catalog/indexing.h +366 -0
- data/ext/pg_query/include/catalog/namespace.h +188 -0
- data/ext/pg_query/include/catalog/objectaccess.h +197 -0
- data/ext/pg_query/include/catalog/objectaddress.h +84 -0
- data/ext/pg_query/include/catalog/pg_aggregate.h +176 -0
- data/ext/pg_query/include/catalog/pg_aggregate_d.h +77 -0
- data/ext/pg_query/include/catalog/pg_am.h +60 -0
- data/ext/pg_query/include/catalog/pg_am_d.h +45 -0
- data/ext/pg_query/include/catalog/pg_attribute.h +204 -0
- data/ext/pg_query/include/catalog/pg_attribute_d.h +59 -0
- data/ext/pg_query/include/catalog/pg_authid.h +58 -0
- data/ext/pg_query/include/catalog/pg_authid_d.h +49 -0
- data/ext/pg_query/include/catalog/pg_class.h +200 -0
- data/ext/pg_query/include/catalog/pg_class_d.h +103 -0
- data/ext/pg_query/include/catalog/pg_collation.h +73 -0
- data/ext/pg_query/include/catalog/pg_collation_d.h +45 -0
- data/ext/pg_query/include/catalog/pg_constraint.h +247 -0
- data/ext/pg_query/include/catalog/pg_constraint_d.h +67 -0
- data/ext/pg_query/include/catalog/pg_control.h +250 -0
- data/ext/pg_query/include/catalog/pg_conversion.h +72 -0
- data/ext/pg_query/include/catalog/pg_conversion_d.h +35 -0
- data/ext/pg_query/include/catalog/pg_depend.h +73 -0
- data/ext/pg_query/include/catalog/pg_depend_d.h +34 -0
- data/ext/pg_query/include/catalog/pg_event_trigger.h +51 -0
- data/ext/pg_query/include/catalog/pg_event_trigger_d.h +34 -0
- data/ext/pg_query/include/catalog/pg_index.h +80 -0
- data/ext/pg_query/include/catalog/pg_index_d.h +56 -0
- data/ext/pg_query/include/catalog/pg_language.h +67 -0
- data/ext/pg_query/include/catalog/pg_language_d.h +39 -0
- data/ext/pg_query/include/catalog/pg_namespace.h +59 -0
- data/ext/pg_query/include/catalog/pg_namespace_d.h +34 -0
- data/ext/pg_query/include/catalog/pg_opclass.h +85 -0
- data/ext/pg_query/include/catalog/pg_opclass_d.h +49 -0
- data/ext/pg_query/include/catalog/pg_operator.h +102 -0
- data/ext/pg_query/include/catalog/pg_operator_d.h +106 -0
- data/ext/pg_query/include/catalog/pg_opfamily.h +60 -0
- data/ext/pg_query/include/catalog/pg_opfamily_d.h +47 -0
- data/ext/pg_query/include/catalog/pg_partitioned_table.h +63 -0
- data/ext/pg_query/include/catalog/pg_partitioned_table_d.h +35 -0
- data/ext/pg_query/include/catalog/pg_proc.h +211 -0
- data/ext/pg_query/include/catalog/pg_proc_d.h +99 -0
- data/ext/pg_query/include/catalog/pg_publication.h +115 -0
- data/ext/pg_query/include/catalog/pg_publication_d.h +36 -0
- data/ext/pg_query/include/catalog/pg_replication_origin.h +57 -0
- data/ext/pg_query/include/catalog/pg_replication_origin_d.h +29 -0
- data/ext/pg_query/include/catalog/pg_statistic.h +275 -0
- data/ext/pg_query/include/catalog/pg_statistic_d.h +194 -0
- data/ext/pg_query/include/catalog/pg_statistic_ext.h +74 -0
- data/ext/pg_query/include/catalog/pg_statistic_ext_d.h +40 -0
- data/ext/pg_query/include/catalog/pg_transform.h +45 -0
- data/ext/pg_query/include/catalog/pg_transform_d.h +32 -0
- data/ext/pg_query/include/catalog/pg_trigger.h +137 -0
- data/ext/pg_query/include/catalog/pg_trigger_d.h +106 -0
- data/ext/pg_query/include/catalog/pg_ts_config.h +50 -0
- data/ext/pg_query/include/catalog/pg_ts_config_d.h +32 -0
- data/ext/pg_query/include/catalog/pg_ts_dict.h +54 -0
- data/ext/pg_query/include/catalog/pg_ts_dict_d.h +33 -0
- data/ext/pg_query/include/catalog/pg_ts_parser.h +57 -0
- data/ext/pg_query/include/catalog/pg_ts_parser_d.h +35 -0
- data/ext/pg_query/include/catalog/pg_ts_template.h +48 -0
- data/ext/pg_query/include/catalog/pg_ts_template_d.h +32 -0
- data/ext/pg_query/include/catalog/pg_type.h +372 -0
- data/ext/pg_query/include/catalog/pg_type_d.h +285 -0
- data/ext/pg_query/include/catalog/storage.h +48 -0
- data/ext/pg_query/include/commands/async.h +54 -0
- data/ext/pg_query/include/commands/dbcommands.h +35 -0
- data/ext/pg_query/include/commands/defrem.h +173 -0
- data/ext/pg_query/include/commands/event_trigger.h +88 -0
- data/ext/pg_query/include/commands/explain.h +127 -0
- data/ext/pg_query/include/commands/prepare.h +61 -0
- data/ext/pg_query/include/commands/tablespace.h +67 -0
- data/ext/pg_query/include/commands/trigger.h +277 -0
- data/ext/pg_query/include/commands/user.h +37 -0
- data/ext/pg_query/include/commands/vacuum.h +293 -0
- data/ext/pg_query/include/commands/variable.h +38 -0
- data/ext/pg_query/include/common/file_perm.h +56 -0
- data/ext/pg_query/include/common/hashfn.h +104 -0
- data/ext/pg_query/include/common/ip.h +37 -0
- data/ext/pg_query/include/common/keywords.h +33 -0
- data/ext/pg_query/include/common/kwlookup.h +44 -0
- data/ext/pg_query/include/common/relpath.h +90 -0
- data/ext/pg_query/include/common/string.h +19 -0
- data/ext/pg_query/include/common/unicode_combining_table.h +196 -0
- data/ext/pg_query/include/datatype/timestamp.h +197 -0
- data/ext/pg_query/include/executor/execdesc.h +70 -0
- data/ext/pg_query/include/executor/executor.h +614 -0
- data/ext/pg_query/include/executor/functions.h +41 -0
- data/ext/pg_query/include/executor/instrument.h +101 -0
- data/ext/pg_query/include/executor/spi.h +175 -0
- data/ext/pg_query/include/executor/tablefunc.h +67 -0
- data/ext/pg_query/include/executor/tuptable.h +487 -0
- data/ext/pg_query/include/fmgr.h +775 -0
- data/ext/pg_query/include/funcapi.h +348 -0
- data/ext/pg_query/include/getaddrinfo.h +162 -0
- data/ext/pg_query/include/jit/jit.h +105 -0
- data/ext/pg_query/include/kwlist_d.h +1072 -0
- data/ext/pg_query/include/lib/ilist.h +727 -0
- data/ext/pg_query/include/lib/pairingheap.h +102 -0
- data/ext/pg_query/include/lib/simplehash.h +1059 -0
- data/ext/pg_query/include/lib/stringinfo.h +161 -0
- data/ext/pg_query/include/libpq/auth.h +29 -0
- data/ext/pg_query/include/libpq/crypt.h +46 -0
- data/ext/pg_query/include/libpq/hba.h +140 -0
- data/ext/pg_query/include/libpq/libpq-be.h +326 -0
- data/ext/pg_query/include/libpq/libpq.h +133 -0
- data/ext/pg_query/include/libpq/pqcomm.h +208 -0
- data/ext/pg_query/include/libpq/pqformat.h +210 -0
- data/ext/pg_query/include/libpq/pqsignal.h +42 -0
- data/ext/pg_query/include/mb/pg_wchar.h +672 -0
- data/ext/pg_query/include/mb/stringinfo_mb.h +24 -0
- data/ext/pg_query/include/miscadmin.h +476 -0
- data/ext/pg_query/include/nodes/bitmapset.h +122 -0
- data/ext/pg_query/include/nodes/execnodes.h +2520 -0
- data/ext/pg_query/include/nodes/extensible.h +160 -0
- data/ext/pg_query/include/nodes/lockoptions.h +61 -0
- data/ext/pg_query/include/nodes/makefuncs.h +108 -0
- data/ext/pg_query/include/nodes/memnodes.h +108 -0
- data/ext/pg_query/include/nodes/nodeFuncs.h +162 -0
- data/ext/pg_query/include/nodes/nodes.h +842 -0
- data/ext/pg_query/include/nodes/params.h +170 -0
- data/ext/pg_query/include/nodes/parsenodes.h +3579 -0
- data/ext/pg_query/include/nodes/pathnodes.h +2556 -0
- data/ext/pg_query/include/nodes/pg_list.h +605 -0
- data/ext/pg_query/include/nodes/plannodes.h +1251 -0
- data/ext/pg_query/include/nodes/primnodes.h +1541 -0
- data/ext/pg_query/include/nodes/print.h +34 -0
- data/ext/pg_query/include/nodes/tidbitmap.h +75 -0
- data/ext/pg_query/include/nodes/value.h +61 -0
- data/ext/pg_query/include/optimizer/cost.h +206 -0
- data/ext/pg_query/include/optimizer/geqo.h +88 -0
- data/ext/pg_query/include/optimizer/geqo_gene.h +45 -0
- data/ext/pg_query/include/optimizer/optimizer.h +199 -0
- data/ext/pg_query/include/optimizer/paths.h +249 -0
- data/ext/pg_query/include/optimizer/planmain.h +119 -0
- data/ext/pg_query/include/parser/analyze.h +49 -0
- data/ext/pg_query/include/parser/gram.h +1067 -0
- data/ext/pg_query/include/parser/gramparse.h +75 -0
- data/ext/pg_query/include/parser/kwlist.h +477 -0
- data/ext/pg_query/include/parser/parse_agg.h +68 -0
- data/ext/pg_query/include/parser/parse_clause.h +54 -0
- data/ext/pg_query/include/parser/parse_coerce.h +97 -0
- data/ext/pg_query/include/parser/parse_collate.h +27 -0
- data/ext/pg_query/include/parser/parse_expr.h +26 -0
- data/ext/pg_query/include/parser/parse_func.h +73 -0
- data/ext/pg_query/include/parser/parse_node.h +327 -0
- data/ext/pg_query/include/parser/parse_oper.h +67 -0
- data/ext/pg_query/include/parser/parse_relation.h +123 -0
- data/ext/pg_query/include/parser/parse_target.h +46 -0
- data/ext/pg_query/include/parser/parse_type.h +60 -0
- data/ext/pg_query/include/parser/parser.h +41 -0
- data/ext/pg_query/include/parser/parsetree.h +61 -0
- data/ext/pg_query/include/parser/scanner.h +152 -0
- data/ext/pg_query/include/parser/scansup.h +30 -0
- data/ext/pg_query/include/partitioning/partdefs.h +26 -0
- data/ext/pg_query/include/pg_config.h +989 -0
- data/ext/pg_query/include/pg_config_ext.h +8 -0
- data/ext/pg_query/include/pg_config_manual.h +350 -0
- data/ext/pg_query/include/pg_config_os.h +8 -0
- data/ext/pg_query/include/pg_getopt.h +56 -0
- data/ext/pg_query/include/pg_query.h +121 -0
- data/ext/pg_query/include/pg_query_enum_defs.c +2454 -0
- data/ext/pg_query/include/pg_query_fingerprint_conds.c +875 -0
- data/ext/pg_query/include/pg_query_fingerprint_defs.c +12413 -0
- data/ext/pg_query/include/pg_query_json_helper.c +61 -0
- data/ext/pg_query/include/pg_query_outfuncs_conds.c +686 -0
- data/ext/pg_query/include/pg_query_outfuncs_defs.c +2437 -0
- data/ext/pg_query/include/pg_query_readfuncs_conds.c +222 -0
- data/ext/pg_query/include/pg_query_readfuncs_defs.c +2878 -0
- data/ext/pg_query/include/pg_trace.h +17 -0
- data/ext/pg_query/include/pgstat.h +1487 -0
- data/ext/pg_query/include/pgtime.h +84 -0
- data/ext/pg_query/include/pl_gram.h +385 -0
- data/ext/pg_query/include/pl_reserved_kwlist.h +52 -0
- data/ext/pg_query/include/pl_reserved_kwlist_d.h +114 -0
- data/ext/pg_query/include/pl_unreserved_kwlist.h +112 -0
- data/ext/pg_query/include/pl_unreserved_kwlist_d.h +246 -0
- data/ext/pg_query/include/plerrcodes.h +990 -0
- data/ext/pg_query/include/plpgsql.h +1347 -0
- data/ext/pg_query/include/port.h +524 -0
- data/ext/pg_query/include/port/atomics.h +524 -0
- data/ext/pg_query/include/port/atomics/arch-arm.h +26 -0
- data/ext/pg_query/include/port/atomics/arch-ppc.h +254 -0
- data/ext/pg_query/include/port/atomics/arch-x86.h +252 -0
- data/ext/pg_query/include/port/atomics/fallback.h +170 -0
- data/ext/pg_query/include/port/atomics/generic-gcc.h +286 -0
- data/ext/pg_query/include/port/atomics/generic.h +401 -0
- data/ext/pg_query/include/port/pg_bitutils.h +226 -0
- data/ext/pg_query/include/port/pg_bswap.h +161 -0
- data/ext/pg_query/include/port/pg_crc32c.h +101 -0
- data/ext/pg_query/include/portability/instr_time.h +256 -0
- data/ext/pg_query/include/postgres.h +764 -0
- data/ext/pg_query/include/postgres_ext.h +74 -0
- data/ext/pg_query/include/postmaster/autovacuum.h +83 -0
- data/ext/pg_query/include/postmaster/bgworker.h +161 -0
- data/ext/pg_query/include/postmaster/bgworker_internals.h +64 -0
- data/ext/pg_query/include/postmaster/bgwriter.h +45 -0
- data/ext/pg_query/include/postmaster/fork_process.h +17 -0
- data/ext/pg_query/include/postmaster/interrupt.h +32 -0
- data/ext/pg_query/include/postmaster/pgarch.h +39 -0
- data/ext/pg_query/include/postmaster/postmaster.h +77 -0
- data/ext/pg_query/include/postmaster/syslogger.h +98 -0
- data/ext/pg_query/include/postmaster/walwriter.h +21 -0
- data/ext/pg_query/include/protobuf-c.h +1106 -0
- data/ext/pg_query/include/protobuf-c/protobuf-c.h +1106 -0
- data/ext/pg_query/include/protobuf/pg_query.pb-c.h +10846 -0
- data/ext/pg_query/include/protobuf/pg_query.pb.h +124718 -0
- data/ext/pg_query/include/regex/regex.h +184 -0
- data/ext/pg_query/include/replication/logicallauncher.h +31 -0
- data/ext/pg_query/include/replication/logicalproto.h +110 -0
- data/ext/pg_query/include/replication/logicalworker.h +19 -0
- data/ext/pg_query/include/replication/origin.h +73 -0
- data/ext/pg_query/include/replication/reorderbuffer.h +467 -0
- data/ext/pg_query/include/replication/slot.h +219 -0
- data/ext/pg_query/include/replication/syncrep.h +115 -0
- data/ext/pg_query/include/replication/walreceiver.h +340 -0
- data/ext/pg_query/include/replication/walsender.h +74 -0
- data/ext/pg_query/include/rewrite/prs2lock.h +46 -0
- data/ext/pg_query/include/rewrite/rewriteHandler.h +40 -0
- data/ext/pg_query/include/rewrite/rewriteManip.h +87 -0
- data/ext/pg_query/include/rewrite/rewriteSupport.h +26 -0
- data/ext/pg_query/include/storage/backendid.h +37 -0
- data/ext/pg_query/include/storage/block.h +121 -0
- data/ext/pg_query/include/storage/buf.h +46 -0
- data/ext/pg_query/include/storage/bufmgr.h +292 -0
- data/ext/pg_query/include/storage/bufpage.h +459 -0
- data/ext/pg_query/include/storage/condition_variable.h +62 -0
- data/ext/pg_query/include/storage/dsm.h +61 -0
- data/ext/pg_query/include/storage/dsm_impl.h +75 -0
- data/ext/pg_query/include/storage/fd.h +168 -0
- data/ext/pg_query/include/storage/ipc.h +81 -0
- data/ext/pg_query/include/storage/item.h +19 -0
- data/ext/pg_query/include/storage/itemid.h +184 -0
- data/ext/pg_query/include/storage/itemptr.h +206 -0
- data/ext/pg_query/include/storage/large_object.h +100 -0
- data/ext/pg_query/include/storage/latch.h +190 -0
- data/ext/pg_query/include/storage/lmgr.h +114 -0
- data/ext/pg_query/include/storage/lock.h +612 -0
- data/ext/pg_query/include/storage/lockdefs.h +59 -0
- data/ext/pg_query/include/storage/lwlock.h +232 -0
- data/ext/pg_query/include/storage/lwlocknames.h +51 -0
- data/ext/pg_query/include/storage/off.h +57 -0
- data/ext/pg_query/include/storage/pg_sema.h +61 -0
- data/ext/pg_query/include/storage/pg_shmem.h +90 -0
- data/ext/pg_query/include/storage/pmsignal.h +94 -0
- data/ext/pg_query/include/storage/predicate.h +87 -0
- data/ext/pg_query/include/storage/proc.h +333 -0
- data/ext/pg_query/include/storage/proclist_types.h +51 -0
- data/ext/pg_query/include/storage/procsignal.h +75 -0
- data/ext/pg_query/include/storage/relfilenode.h +99 -0
- data/ext/pg_query/include/storage/s_lock.h +1047 -0
- data/ext/pg_query/include/storage/sharedfileset.h +45 -0
- data/ext/pg_query/include/storage/shm_mq.h +85 -0
- data/ext/pg_query/include/storage/shm_toc.h +58 -0
- data/ext/pg_query/include/storage/shmem.h +81 -0
- data/ext/pg_query/include/storage/sinval.h +153 -0
- data/ext/pg_query/include/storage/sinvaladt.h +43 -0
- data/ext/pg_query/include/storage/smgr.h +109 -0
- data/ext/pg_query/include/storage/spin.h +77 -0
- data/ext/pg_query/include/storage/standby.h +91 -0
- data/ext/pg_query/include/storage/standbydefs.h +74 -0
- data/ext/pg_query/include/storage/sync.h +62 -0
- data/ext/pg_query/include/tcop/cmdtag.h +58 -0
- data/ext/pg_query/include/tcop/cmdtaglist.h +217 -0
- data/ext/pg_query/include/tcop/deparse_utility.h +108 -0
- data/ext/pg_query/include/tcop/dest.h +149 -0
- data/ext/pg_query/include/tcop/fastpath.h +21 -0
- data/ext/pg_query/include/tcop/pquery.h +45 -0
- data/ext/pg_query/include/tcop/tcopprot.h +89 -0
- data/ext/pg_query/include/tcop/utility.h +108 -0
- data/ext/pg_query/include/tsearch/ts_cache.h +98 -0
- data/ext/pg_query/include/utils/acl.h +312 -0
- data/ext/pg_query/include/utils/aclchk_internal.h +45 -0
- data/ext/pg_query/include/utils/array.h +458 -0
- data/ext/pg_query/include/utils/builtins.h +127 -0
- data/ext/pg_query/include/utils/bytea.h +27 -0
- data/ext/pg_query/include/utils/catcache.h +231 -0
- data/ext/pg_query/include/utils/date.h +90 -0
- data/ext/pg_query/include/utils/datetime.h +343 -0
- data/ext/pg_query/include/utils/datum.h +68 -0
- data/ext/pg_query/include/utils/dsa.h +123 -0
- data/ext/pg_query/include/utils/dynahash.h +19 -0
- data/ext/pg_query/include/utils/elog.h +439 -0
- data/ext/pg_query/include/utils/errcodes.h +352 -0
- data/ext/pg_query/include/utils/expandeddatum.h +159 -0
- data/ext/pg_query/include/utils/expandedrecord.h +231 -0
- data/ext/pg_query/include/utils/float.h +356 -0
- data/ext/pg_query/include/utils/fmgroids.h +2657 -0
- data/ext/pg_query/include/utils/fmgrprotos.h +2646 -0
- data/ext/pg_query/include/utils/fmgrtab.h +48 -0
- data/ext/pg_query/include/utils/guc.h +443 -0
- data/ext/pg_query/include/utils/guc_tables.h +272 -0
- data/ext/pg_query/include/utils/hsearch.h +149 -0
- data/ext/pg_query/include/utils/inval.h +64 -0
- data/ext/pg_query/include/utils/lsyscache.h +197 -0
- data/ext/pg_query/include/utils/memdebug.h +82 -0
- data/ext/pg_query/include/utils/memutils.h +225 -0
- data/ext/pg_query/include/utils/numeric.h +76 -0
- data/ext/pg_query/include/utils/palloc.h +136 -0
- data/ext/pg_query/include/utils/partcache.h +102 -0
- data/ext/pg_query/include/utils/pg_locale.h +119 -0
- data/ext/pg_query/include/utils/pg_lsn.h +29 -0
- data/ext/pg_query/include/utils/pidfile.h +56 -0
- data/ext/pg_query/include/utils/plancache.h +235 -0
- data/ext/pg_query/include/utils/portal.h +241 -0
- data/ext/pg_query/include/utils/probes.h +114 -0
- data/ext/pg_query/include/utils/ps_status.h +25 -0
- data/ext/pg_query/include/utils/queryenvironment.h +74 -0
- data/ext/pg_query/include/utils/regproc.h +28 -0
- data/ext/pg_query/include/utils/rel.h +644 -0
- data/ext/pg_query/include/utils/relcache.h +151 -0
- data/ext/pg_query/include/utils/reltrigger.h +81 -0
- data/ext/pg_query/include/utils/resowner.h +86 -0
- data/ext/pg_query/include/utils/rls.h +50 -0
- data/ext/pg_query/include/utils/ruleutils.h +44 -0
- data/ext/pg_query/include/utils/sharedtuplestore.h +61 -0
- data/ext/pg_query/include/utils/snapmgr.h +158 -0
- data/ext/pg_query/include/utils/snapshot.h +206 -0
- data/ext/pg_query/include/utils/sortsupport.h +276 -0
- data/ext/pg_query/include/utils/syscache.h +219 -0
- data/ext/pg_query/include/utils/timeout.h +88 -0
- data/ext/pg_query/include/utils/timestamp.h +116 -0
- data/ext/pg_query/include/utils/tuplesort.h +277 -0
- data/ext/pg_query/include/utils/tuplestore.h +91 -0
- data/ext/pg_query/include/utils/typcache.h +202 -0
- data/ext/pg_query/include/utils/tzparser.h +39 -0
- data/ext/pg_query/include/utils/varlena.h +39 -0
- data/ext/pg_query/include/utils/xml.h +84 -0
- data/ext/pg_query/include/xxhash.h +5445 -0
- data/ext/pg_query/include/xxhash/xxhash.h +5445 -0
- data/ext/pg_query/pg_query.c +104 -0
- data/ext/pg_query/pg_query.pb-c.c +37628 -0
- data/ext/pg_query/pg_query_deparse.c +9959 -0
- data/ext/pg_query/pg_query_fingerprint.c +295 -0
- data/ext/pg_query/pg_query_fingerprint.h +8 -0
- data/ext/pg_query/pg_query_internal.h +24 -0
- data/ext/pg_query/pg_query_json_plpgsql.c +738 -0
- data/ext/pg_query/pg_query_json_plpgsql.h +9 -0
- data/ext/pg_query/pg_query_normalize.c +439 -0
- data/ext/pg_query/pg_query_outfuncs.h +10 -0
- data/ext/pg_query/pg_query_outfuncs_json.c +297 -0
- data/ext/pg_query/pg_query_outfuncs_protobuf.c +237 -0
- data/ext/pg_query/pg_query_parse.c +148 -0
- data/ext/pg_query/pg_query_parse_plpgsql.c +460 -0
- data/ext/pg_query/pg_query_readfuncs.h +11 -0
- data/ext/pg_query/pg_query_readfuncs_protobuf.c +142 -0
- data/ext/pg_query/pg_query_ruby.c +108 -12
- data/ext/pg_query/pg_query_scan.c +173 -0
- data/ext/pg_query/pg_query_split.c +221 -0
- data/ext/pg_query/protobuf-c.c +3660 -0
- data/ext/pg_query/src_backend_catalog_namespace.c +1051 -0
- data/ext/pg_query/src_backend_catalog_pg_proc.c +142 -0
- data/ext/pg_query/src_backend_commands_define.c +117 -0
- data/ext/pg_query/src_backend_libpq_pqcomm.c +651 -0
- data/ext/pg_query/src_backend_nodes_bitmapset.c +513 -0
- data/ext/pg_query/src_backend_nodes_copyfuncs.c +6013 -0
- data/ext/pg_query/src_backend_nodes_equalfuncs.c +4003 -0
- data/ext/pg_query/src_backend_nodes_extensible.c +99 -0
- data/ext/pg_query/src_backend_nodes_list.c +922 -0
- data/ext/pg_query/src_backend_nodes_makefuncs.c +417 -0
- data/ext/pg_query/src_backend_nodes_nodeFuncs.c +1363 -0
- data/ext/pg_query/src_backend_nodes_value.c +84 -0
- data/ext/pg_query/src_backend_parser_gram.c +47456 -0
- data/ext/pg_query/src_backend_parser_parse_expr.c +313 -0
- data/ext/pg_query/src_backend_parser_parser.c +497 -0
- data/ext/pg_query/src_backend_parser_scan.c +7091 -0
- data/ext/pg_query/src_backend_parser_scansup.c +160 -0
- data/ext/pg_query/src_backend_postmaster_postmaster.c +2230 -0
- data/ext/pg_query/src_backend_storage_ipc_ipc.c +192 -0
- data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +370 -0
- data/ext/pg_query/src_backend_tcop_postgres.c +776 -0
- data/ext/pg_query/src_backend_utils_adt_datum.c +326 -0
- data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +98 -0
- data/ext/pg_query/src_backend_utils_adt_format_type.c +136 -0
- data/ext/pg_query/src_backend_utils_adt_ruleutils.c +1683 -0
- data/ext/pg_query/src_backend_utils_error_assert.c +74 -0
- data/ext/pg_query/src_backend_utils_error_elog.c +1748 -0
- data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +570 -0
- data/ext/pg_query/src_backend_utils_hash_dynahash.c +1086 -0
- data/ext/pg_query/src_backend_utils_init_globals.c +168 -0
- data/ext/pg_query/src_backend_utils_mb_mbutils.c +839 -0
- data/ext/pg_query/src_backend_utils_misc_guc.c +1831 -0
- data/ext/pg_query/src_backend_utils_mmgr_aset.c +1560 -0
- data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +1006 -0
- data/ext/pg_query/src_common_encnames.c +158 -0
- data/ext/pg_query/src_common_keywords.c +39 -0
- data/ext/pg_query/src_common_kwlist_d.h +1081 -0
- data/ext/pg_query/src_common_kwlookup.c +91 -0
- data/ext/pg_query/src_common_psprintf.c +158 -0
- data/ext/pg_query/src_common_string.c +86 -0
- data/ext/pg_query/src_common_stringinfo.c +336 -0
- data/ext/pg_query/src_common_wchar.c +1651 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +1133 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +877 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +6533 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +107 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +123 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +671 -0
- data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +255 -0
- data/ext/pg_query/src_port_erand48.c +127 -0
- data/ext/pg_query/src_port_pg_bitutils.c +246 -0
- data/ext/pg_query/src_port_pgsleep.c +69 -0
- data/ext/pg_query/src_port_pgstrcasecmp.c +83 -0
- data/ext/pg_query/src_port_qsort.c +240 -0
- data/ext/pg_query/src_port_random.c +31 -0
- data/ext/pg_query/src_port_snprintf.c +1449 -0
- data/ext/pg_query/src_port_strerror.c +324 -0
- data/ext/pg_query/src_port_strnlen.c +39 -0
- data/ext/pg_query/xxhash.c +43 -0
- data/lib/pg_query.rb +7 -4
- data/lib/pg_query/constants.rb +21 -0
- data/lib/pg_query/deparse.rb +15 -1581
- data/lib/pg_query/filter_columns.rb +88 -85
- data/lib/pg_query/fingerprint.rb +122 -87
- data/lib/pg_query/json_field_names.rb +1402 -0
- data/lib/pg_query/node.rb +31 -0
- data/lib/pg_query/param_refs.rb +42 -37
- data/lib/pg_query/parse.rb +220 -203
- data/lib/pg_query/parse_error.rb +1 -1
- data/lib/pg_query/pg_query_pb.rb +3211 -0
- data/lib/pg_query/scan.rb +23 -0
- data/lib/pg_query/treewalker.rb +24 -40
- data/lib/pg_query/truncate.rb +71 -42
- data/lib/pg_query/version.rb +2 -2
- metadata +472 -11
- data/ext/pg_query/pg_query_ruby.h +0 -10
- data/lib/pg_query/deep_dup.rb +0 -16
- data/lib/pg_query/deparse/alter_table.rb +0 -42
- data/lib/pg_query/deparse/interval.rb +0 -105
- data/lib/pg_query/deparse/keywords.rb +0 -159
- data/lib/pg_query/deparse/rename.rb +0 -41
- data/lib/pg_query/legacy_parsetree.rb +0 -109
- data/lib/pg_query/node_types.rb +0 -296
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/*--------------------------------------------------------------------
|
|
2
|
+
* Symbols referenced in this file:
|
|
3
|
+
* - CritSectionCount
|
|
4
|
+
* - ExitOnAnyError
|
|
5
|
+
* - InterruptHoldoffCount
|
|
6
|
+
* - QueryCancelHoldoffCount
|
|
7
|
+
* - IsPostmasterEnvironment
|
|
8
|
+
* - InterruptPending
|
|
9
|
+
*--------------------------------------------------------------------
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/*-------------------------------------------------------------------------
|
|
13
|
+
*
|
|
14
|
+
* globals.c
|
|
15
|
+
* global variable declarations
|
|
16
|
+
*
|
|
17
|
+
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
|
18
|
+
* Portions Copyright (c) 1994, Regents of the University of California
|
|
19
|
+
*
|
|
20
|
+
*
|
|
21
|
+
* IDENTIFICATION
|
|
22
|
+
* src/backend/utils/init/globals.c
|
|
23
|
+
*
|
|
24
|
+
* NOTES
|
|
25
|
+
* Globals used all over the place should be declared here and not
|
|
26
|
+
* in other modules.
|
|
27
|
+
*
|
|
28
|
+
*-------------------------------------------------------------------------
|
|
29
|
+
*/
|
|
30
|
+
#include "postgres.h"
|
|
31
|
+
|
|
32
|
+
#include "common/file_perm.h"
|
|
33
|
+
#include "libpq/libpq-be.h"
|
|
34
|
+
#include "libpq/pqcomm.h"
|
|
35
|
+
#include "miscadmin.h"
|
|
36
|
+
#include "storage/backendid.h"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
__thread volatile sig_atomic_t InterruptPending = false;
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
__thread volatile uint32 InterruptHoldoffCount = 0;
|
|
49
|
+
|
|
50
|
+
__thread volatile uint32 QueryCancelHoldoffCount = 0;
|
|
51
|
+
|
|
52
|
+
__thread volatile uint32 CritSectionCount = 0;
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* MyLatch points to the latch that should be used for signal handling by the
|
|
64
|
+
* current process. It will either point to a process local latch if the
|
|
65
|
+
* current process does not have a PGPROC entry in that moment, or to
|
|
66
|
+
* PGPROC->procLatch if it has. Thus it can always be used in signal handlers,
|
|
67
|
+
* without checking for its existence.
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
/*
|
|
72
|
+
* DataDir is the absolute path to the top level of the PGDATA directory tree.
|
|
73
|
+
* Except during early startup, this is also the server's working directory;
|
|
74
|
+
* most code therefore can simply use relative paths and not reference DataDir
|
|
75
|
+
* explicitly.
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
* Mode of the data directory. The default is 0700 but it may be changed in
|
|
81
|
+
* checkDataDir() to 0750 if the data directory actually has that mode.
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
/* debugging output file */
|
|
86
|
+
|
|
87
|
+
/* full path to my executable */
|
|
88
|
+
/* full path to lib directory */
|
|
89
|
+
|
|
90
|
+
#ifdef EXEC_BACKEND
|
|
91
|
+
char postgres_exec_path[MAXPGPATH]; /* full path to backend */
|
|
92
|
+
|
|
93
|
+
/* note: currently this is not valid in backend processes */
|
|
94
|
+
#endif
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* DatabasePath is the path (relative to DataDir) of my database's
|
|
106
|
+
* primary directory, ie, its directory in the default tablespace.
|
|
107
|
+
*/
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
* IsPostmasterEnvironment is true in a postmaster process and any postmaster
|
|
114
|
+
* child process; it is false in a standalone process (bootstrap or
|
|
115
|
+
* standalone backend). IsUnderPostmaster is true in postmaster child
|
|
116
|
+
* processes. Note that "child process" includes all children, not only
|
|
117
|
+
* regular backends. These should be set correctly as early as possible
|
|
118
|
+
* in the execution of a process, so that error handling will do the right
|
|
119
|
+
* things if an error should occur during process initialization.
|
|
120
|
+
*
|
|
121
|
+
* These are initialized for the bootstrap/standalone case.
|
|
122
|
+
*/
|
|
123
|
+
__thread bool IsPostmasterEnvironment = false;
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
__thread bool ExitOnAnyError = false;
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
/*
|
|
144
|
+
* Primary determinants of sizes of shared-memory structures.
|
|
145
|
+
*
|
|
146
|
+
* MaxBackends is computed by PostmasterMain after modules have had a chance to
|
|
147
|
+
* register background workers.
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
/* GUC parameters for vacuum */
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
/* working state for vacuum */
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
|
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
/*--------------------------------------------------------------------
|
|
2
|
+
* Symbols referenced in this file:
|
|
3
|
+
* - pg_mbcliplen
|
|
4
|
+
* - pg_encoding_mbcliplen
|
|
5
|
+
* - cliplen
|
|
6
|
+
* - DatabaseEncoding
|
|
7
|
+
* - pg_verifymbstr
|
|
8
|
+
* - pg_verify_mbstr_len
|
|
9
|
+
* - report_invalid_encoding
|
|
10
|
+
* - GetDatabaseEncoding
|
|
11
|
+
* - pg_get_client_encoding
|
|
12
|
+
* - ClientEncoding
|
|
13
|
+
* - pg_database_encoding_max_length
|
|
14
|
+
* - pg_unicode_to_server
|
|
15
|
+
* - GetDatabaseEncodingName
|
|
16
|
+
* - Utf8ToServerConvProc
|
|
17
|
+
* - pg_mbstrlen_with_len
|
|
18
|
+
* - pg_mblen
|
|
19
|
+
* - SetDatabaseEncoding
|
|
20
|
+
*--------------------------------------------------------------------
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/*-------------------------------------------------------------------------
|
|
24
|
+
*
|
|
25
|
+
* mbutils.c
|
|
26
|
+
* This file contains functions for encoding conversion.
|
|
27
|
+
*
|
|
28
|
+
* The string-conversion functions in this file share some API quirks.
|
|
29
|
+
* Note the following:
|
|
30
|
+
*
|
|
31
|
+
* The functions return a palloc'd, null-terminated string if conversion
|
|
32
|
+
* is required. However, if no conversion is performed, the given source
|
|
33
|
+
* string pointer is returned as-is.
|
|
34
|
+
*
|
|
35
|
+
* Although the presence of a length argument means that callers can pass
|
|
36
|
+
* non-null-terminated strings, care is required because the same string
|
|
37
|
+
* will be passed back if no conversion occurs. Such callers *must* check
|
|
38
|
+
* whether result == src and handle that case differently.
|
|
39
|
+
*
|
|
40
|
+
* If the source and destination encodings are the same, the source string
|
|
41
|
+
* is returned without any verification; it's assumed to be valid data.
|
|
42
|
+
* If that might not be the case, the caller is responsible for validating
|
|
43
|
+
* the string using a separate call to pg_verify_mbstr(). Whenever the
|
|
44
|
+
* source and destination encodings are different, the functions ensure that
|
|
45
|
+
* the result is validly encoded according to the destination encoding.
|
|
46
|
+
*
|
|
47
|
+
*
|
|
48
|
+
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
|
|
49
|
+
* Portions Copyright (c) 1994, Regents of the University of California
|
|
50
|
+
*
|
|
51
|
+
*
|
|
52
|
+
* IDENTIFICATION
|
|
53
|
+
* src/backend/utils/mb/mbutils.c
|
|
54
|
+
*
|
|
55
|
+
*-------------------------------------------------------------------------
|
|
56
|
+
*/
|
|
57
|
+
#include "postgres.h"
|
|
58
|
+
|
|
59
|
+
#include "access/xact.h"
|
|
60
|
+
#include "catalog/namespace.h"
|
|
61
|
+
#include "mb/pg_wchar.h"
|
|
62
|
+
#include "utils/builtins.h"
|
|
63
|
+
#include "utils/memutils.h"
|
|
64
|
+
#include "utils/syscache.h"
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* We maintain a simple linked list caching the fmgr lookup info for the
|
|
68
|
+
* currently selected conversion functions, as well as any that have been
|
|
69
|
+
* selected previously in the current session. (We remember previous
|
|
70
|
+
* settings because we must be able to restore a previous setting during
|
|
71
|
+
* transaction rollback, without doing any fresh catalog accesses.)
|
|
72
|
+
*
|
|
73
|
+
* Since we'll never release this data, we just keep it in TopMemoryContext.
|
|
74
|
+
*/
|
|
75
|
+
typedef struct ConvProcInfo
|
|
76
|
+
{
|
|
77
|
+
int s_encoding; /* server and client encoding IDs */
|
|
78
|
+
int c_encoding;
|
|
79
|
+
FmgrInfo to_server_info; /* lookup info for conversion procs */
|
|
80
|
+
FmgrInfo to_client_info;
|
|
81
|
+
} ConvProcInfo;
|
|
82
|
+
|
|
83
|
+
/* List of ConvProcInfo */
|
|
84
|
+
|
|
85
|
+
/*
|
|
86
|
+
* These variables point to the currently active conversion functions,
|
|
87
|
+
* or are NULL when no conversion is needed.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/*
|
|
93
|
+
* This variable stores the conversion function to convert from UTF-8
|
|
94
|
+
* to the server encoding. It's NULL if the server encoding *is* UTF-8,
|
|
95
|
+
* or if we lack a conversion function for this.
|
|
96
|
+
*/
|
|
97
|
+
static __thread FmgrInfo *Utf8ToServerConvProc = NULL;
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* These variables track the currently-selected encodings.
|
|
102
|
+
*/
|
|
103
|
+
static __thread const pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
|
104
|
+
|
|
105
|
+
static __thread const pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII];
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
/*
|
|
110
|
+
* During backend startup we can't set client encoding because we (a)
|
|
111
|
+
* can't look up the conversion functions, and (b) may not know the database
|
|
112
|
+
* encoding yet either. So SetClientEncoding() just accepts anything and
|
|
113
|
+
* remembers it for InitializeClientEncoding() to apply later.
|
|
114
|
+
*/
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
/* Internal functions */
|
|
120
|
+
static char *perform_default_encoding_conversion(const char *src,
|
|
121
|
+
int len, bool is_client_to_server);
|
|
122
|
+
static int cliplen(const char *str, int len, int limit);
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* Prepare for a future call to SetClientEncoding. Success should mean
|
|
127
|
+
* that SetClientEncoding is guaranteed to succeed for this encoding request.
|
|
128
|
+
*
|
|
129
|
+
* (But note that success before backend_startup_complete does not guarantee
|
|
130
|
+
* success after ...)
|
|
131
|
+
*
|
|
132
|
+
* Returns 0 if okay, -1 if not (bad encoding or can't support conversion)
|
|
133
|
+
*/
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
/*
|
|
137
|
+
* Set the active client encoding and set up the conversion-function pointers.
|
|
138
|
+
* PrepareClientEncoding should have been called previously for this encoding.
|
|
139
|
+
*
|
|
140
|
+
* Returns 0 if okay, -1 if not (bad encoding or can't support conversion)
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* Initialize client encoding conversions.
|
|
146
|
+
* Called from InitPostgres() once during backend startup.
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
/*
|
|
151
|
+
* returns the current client encoding
|
|
152
|
+
*/
|
|
153
|
+
int
|
|
154
|
+
pg_get_client_encoding(void)
|
|
155
|
+
{
|
|
156
|
+
return ClientEncoding->encoding;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* returns the current client encoding name
|
|
161
|
+
*/
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
/*
|
|
165
|
+
* Convert src string to another encoding (general case).
|
|
166
|
+
*
|
|
167
|
+
* See the notes about string conversion functions at the top of this file.
|
|
168
|
+
*/
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
* Convert string to encoding encoding_name. The source
|
|
173
|
+
* encoding is the DB encoding.
|
|
174
|
+
*
|
|
175
|
+
* BYTEA convert_to(TEXT string, NAME encoding_name) */
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
/*
|
|
179
|
+
* Convert string from encoding encoding_name. The destination
|
|
180
|
+
* encoding is the DB encoding.
|
|
181
|
+
*
|
|
182
|
+
* TEXT convert_from(BYTEA string, NAME encoding_name) */
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Convert string between two arbitrary encodings.
|
|
187
|
+
*
|
|
188
|
+
* BYTEA convert(BYTEA string, NAME src_encoding_name, NAME dest_encoding_name)
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
/*
|
|
193
|
+
* get the length of the string considered as text in the specified
|
|
194
|
+
* encoding. Raises an error if the data is not valid in that
|
|
195
|
+
* encoding.
|
|
196
|
+
*
|
|
197
|
+
* INT4 length (BYTEA string, NAME src_encoding_name)
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
/*
|
|
202
|
+
* Get maximum multibyte character length in the specified encoding.
|
|
203
|
+
*
|
|
204
|
+
* Note encoding is specified numerically, not by name as above.
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
/*
|
|
209
|
+
* Convert client encoding to server encoding.
|
|
210
|
+
*
|
|
211
|
+
* See the notes about string conversion functions at the top of this file.
|
|
212
|
+
*/
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
/*
|
|
216
|
+
* Convert any encoding to server encoding.
|
|
217
|
+
*
|
|
218
|
+
* See the notes about string conversion functions at the top of this file.
|
|
219
|
+
*
|
|
220
|
+
* Unlike the other string conversion functions, this will apply validation
|
|
221
|
+
* even if encoding == DatabaseEncoding->encoding. This is because this is
|
|
222
|
+
* used to process data coming in from outside the database, and we never
|
|
223
|
+
* want to just assume validity.
|
|
224
|
+
*/
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
/*
|
|
228
|
+
* Convert server encoding to client encoding.
|
|
229
|
+
*
|
|
230
|
+
* See the notes about string conversion functions at the top of this file.
|
|
231
|
+
*/
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
/*
|
|
235
|
+
* Convert server encoding to any encoding.
|
|
236
|
+
*
|
|
237
|
+
* See the notes about string conversion functions at the top of this file.
|
|
238
|
+
*/
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
/*
|
|
242
|
+
* Perform default encoding conversion using cached FmgrInfo. Since
|
|
243
|
+
* this function does not access database at all, it is safe to call
|
|
244
|
+
* outside transactions. If the conversion has not been set up by
|
|
245
|
+
* SetClientEncoding(), no conversion is performed.
|
|
246
|
+
*/
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
/*
|
|
250
|
+
* Convert a single Unicode code point into a string in the server encoding.
|
|
251
|
+
*
|
|
252
|
+
* The code point given by "c" is converted and stored at *s, which must
|
|
253
|
+
* have at least MAX_UNICODE_EQUIVALENT_STRING+1 bytes available.
|
|
254
|
+
* The output will have a trailing '\0'. Throws error if the conversion
|
|
255
|
+
* cannot be performed.
|
|
256
|
+
*
|
|
257
|
+
* Note that this relies on having previously looked up any required
|
|
258
|
+
* conversion function. That's partly for speed but mostly because the parser
|
|
259
|
+
* may call this outside any transaction, or in an aborted transaction.
|
|
260
|
+
*/
|
|
261
|
+
void
|
|
262
|
+
pg_unicode_to_server(pg_wchar c, unsigned char *s)
|
|
263
|
+
{
|
|
264
|
+
unsigned char c_as_utf8[MAX_MULTIBYTE_CHAR_LEN + 1];
|
|
265
|
+
int c_as_utf8_len;
|
|
266
|
+
int server_encoding;
|
|
267
|
+
|
|
268
|
+
/*
|
|
269
|
+
* Complain if invalid Unicode code point. The choice of errcode here is
|
|
270
|
+
* debatable, but really our caller should have checked this anyway.
|
|
271
|
+
*/
|
|
272
|
+
if (!is_valid_unicode_codepoint(c))
|
|
273
|
+
ereport(ERROR,
|
|
274
|
+
(errcode(ERRCODE_SYNTAX_ERROR),
|
|
275
|
+
errmsg("invalid Unicode code point")));
|
|
276
|
+
|
|
277
|
+
/* Otherwise, if it's in ASCII range, conversion is trivial */
|
|
278
|
+
if (c <= 0x7F)
|
|
279
|
+
{
|
|
280
|
+
s[0] = (unsigned char) c;
|
|
281
|
+
s[1] = '\0';
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/* If the server encoding is UTF-8, we just need to reformat the code */
|
|
286
|
+
server_encoding = GetDatabaseEncoding();
|
|
287
|
+
if (server_encoding == PG_UTF8)
|
|
288
|
+
{
|
|
289
|
+
unicode_to_utf8(c, s);
|
|
290
|
+
s[pg_utf_mblen(s)] = '\0';
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/* For all other cases, we must have a conversion function available */
|
|
295
|
+
if (Utf8ToServerConvProc == NULL)
|
|
296
|
+
ereport(ERROR,
|
|
297
|
+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
|
298
|
+
errmsg("conversion between %s and %s is not supported",
|
|
299
|
+
pg_enc2name_tbl[PG_UTF8].name,
|
|
300
|
+
GetDatabaseEncodingName())));
|
|
301
|
+
|
|
302
|
+
/* Construct UTF-8 source string */
|
|
303
|
+
unicode_to_utf8(c, c_as_utf8);
|
|
304
|
+
c_as_utf8_len = pg_utf_mblen(c_as_utf8);
|
|
305
|
+
c_as_utf8[c_as_utf8_len] = '\0';
|
|
306
|
+
|
|
307
|
+
/* Convert, or throw error if we can't */
|
|
308
|
+
FunctionCall5(Utf8ToServerConvProc,
|
|
309
|
+
Int32GetDatum(PG_UTF8),
|
|
310
|
+
Int32GetDatum(server_encoding),
|
|
311
|
+
CStringGetDatum(c_as_utf8),
|
|
312
|
+
CStringGetDatum(s),
|
|
313
|
+
Int32GetDatum(c_as_utf8_len));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
/* convert a multibyte string to a wchar */
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
/* convert a multibyte string to a wchar with a limited length */
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
/* same, with any encoding */
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
/* convert a wchar string to a multibyte */
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
/* convert a wchar string to a multibyte with a limited length */
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
/* same, with any encoding */
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
/* returns the byte length of a multibyte character */
|
|
336
|
+
int
|
|
337
|
+
pg_mblen(const char *mbstr)
|
|
338
|
+
{
|
|
339
|
+
return pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/* returns the display length of a multibyte character */
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
/* returns the length (counted in wchars) of a multibyte string */
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
/* returns the length (counted in wchars) of a multibyte string
|
|
349
|
+
* (not necessarily NULL terminated)
|
|
350
|
+
*/
|
|
351
|
+
int
|
|
352
|
+
pg_mbstrlen_with_len(const char *mbstr, int limit)
|
|
353
|
+
{
|
|
354
|
+
int len = 0;
|
|
355
|
+
|
|
356
|
+
/* optimization for single byte encoding */
|
|
357
|
+
if (pg_database_encoding_max_length() == 1)
|
|
358
|
+
return limit;
|
|
359
|
+
|
|
360
|
+
while (limit > 0 && *mbstr)
|
|
361
|
+
{
|
|
362
|
+
int l = pg_mblen(mbstr);
|
|
363
|
+
|
|
364
|
+
limit -= l;
|
|
365
|
+
mbstr += l;
|
|
366
|
+
len++;
|
|
367
|
+
}
|
|
368
|
+
return len;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/*
|
|
372
|
+
* returns the byte length of a multibyte string
|
|
373
|
+
* (not necessarily NULL terminated)
|
|
374
|
+
* that is no longer than limit.
|
|
375
|
+
* this function does not break multibyte character boundary.
|
|
376
|
+
*/
|
|
377
|
+
int
|
|
378
|
+
pg_mbcliplen(const char *mbstr, int len, int limit)
|
|
379
|
+
{
|
|
380
|
+
return pg_encoding_mbcliplen(DatabaseEncoding->encoding, mbstr,
|
|
381
|
+
len, limit);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/*
|
|
385
|
+
* pg_mbcliplen with specified encoding
|
|
386
|
+
*/
|
|
387
|
+
int
|
|
388
|
+
pg_encoding_mbcliplen(int encoding, const char *mbstr,
|
|
389
|
+
int len, int limit)
|
|
390
|
+
{
|
|
391
|
+
mblen_converter mblen_fn;
|
|
392
|
+
int clen = 0;
|
|
393
|
+
int l;
|
|
394
|
+
|
|
395
|
+
/* optimization for single byte encoding */
|
|
396
|
+
if (pg_encoding_max_length(encoding) == 1)
|
|
397
|
+
return cliplen(mbstr, len, limit);
|
|
398
|
+
|
|
399
|
+
mblen_fn = pg_wchar_table[encoding].mblen;
|
|
400
|
+
|
|
401
|
+
while (len > 0 && *mbstr)
|
|
402
|
+
{
|
|
403
|
+
l = (*mblen_fn) ((const unsigned char *) mbstr);
|
|
404
|
+
if ((clen + l) > limit)
|
|
405
|
+
break;
|
|
406
|
+
clen += l;
|
|
407
|
+
if (clen == limit)
|
|
408
|
+
break;
|
|
409
|
+
len -= l;
|
|
410
|
+
mbstr += l;
|
|
411
|
+
}
|
|
412
|
+
return clen;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/*
|
|
416
|
+
* Similar to pg_mbcliplen except the limit parameter specifies the
|
|
417
|
+
* character length, not the byte length.
|
|
418
|
+
*/
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
/* mbcliplen for any single-byte encoding */
|
|
422
|
+
static int
|
|
423
|
+
cliplen(const char *str, int len, int limit)
|
|
424
|
+
{
|
|
425
|
+
int l = 0;
|
|
426
|
+
|
|
427
|
+
len = Min(len, limit);
|
|
428
|
+
while (l < len && str[l])
|
|
429
|
+
l++;
|
|
430
|
+
return l;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
void
|
|
434
|
+
SetDatabaseEncoding(int encoding)
|
|
435
|
+
{
|
|
436
|
+
if (!PG_VALID_BE_ENCODING(encoding))
|
|
437
|
+
elog(ERROR, "invalid database encoding: %d", encoding);
|
|
438
|
+
|
|
439
|
+
DatabaseEncoding = &pg_enc2name_tbl[encoding];
|
|
440
|
+
Assert(DatabaseEncoding->encoding == encoding);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
#ifdef ENABLE_NLS
|
|
446
|
+
/*
|
|
447
|
+
* Make one bind_textdomain_codeset() call, translating a pg_enc to a gettext
|
|
448
|
+
* codeset. Fails for MULE_INTERNAL, an encoding unknown to gettext; can also
|
|
449
|
+
* fail for gettext-internal causes like out-of-memory.
|
|
450
|
+
*/
|
|
451
|
+
static bool
|
|
452
|
+
raw_pg_bind_textdomain_codeset(const char *domainname, int encoding)
|
|
453
|
+
{
|
|
454
|
+
bool elog_ok = (CurrentMemoryContext != NULL);
|
|
455
|
+
int i;
|
|
456
|
+
|
|
457
|
+
for (i = 0; pg_enc2gettext_tbl[i].name != NULL; i++)
|
|
458
|
+
{
|
|
459
|
+
if (pg_enc2gettext_tbl[i].encoding == encoding)
|
|
460
|
+
{
|
|
461
|
+
if (bind_textdomain_codeset(domainname,
|
|
462
|
+
pg_enc2gettext_tbl[i].name) != NULL)
|
|
463
|
+
return true;
|
|
464
|
+
|
|
465
|
+
if (elog_ok)
|
|
466
|
+
elog(LOG, "bind_textdomain_codeset failed");
|
|
467
|
+
else
|
|
468
|
+
write_stderr("bind_textdomain_codeset failed");
|
|
469
|
+
|
|
470
|
+
break;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/*
|
|
478
|
+
* Bind a gettext message domain to the codeset corresponding to the database
|
|
479
|
+
* encoding. For SQL_ASCII, instead bind to the codeset implied by LC_CTYPE.
|
|
480
|
+
* Return the MessageEncoding implied by the new settings.
|
|
481
|
+
*
|
|
482
|
+
* On most platforms, gettext defaults to the codeset implied by LC_CTYPE.
|
|
483
|
+
* When that matches the database encoding, we don't need to do anything. In
|
|
484
|
+
* CREATE DATABASE, we enforce or trust that the locale's codeset matches the
|
|
485
|
+
* database encoding, except for the C locale. (On Windows, we also permit a
|
|
486
|
+
* discrepancy under the UTF8 encoding.) For the C locale, explicitly bind
|
|
487
|
+
* gettext to the right codeset.
|
|
488
|
+
*
|
|
489
|
+
* On Windows, gettext defaults to the Windows ANSI code page. This is a
|
|
490
|
+
* convenient departure for software that passes the strings to Windows ANSI
|
|
491
|
+
* APIs, but we don't do that. Compel gettext to use database encoding or,
|
|
492
|
+
* failing that, the LC_CTYPE encoding as it would on other platforms.
|
|
493
|
+
*
|
|
494
|
+
* This function is called before elog() and palloc() are usable.
|
|
495
|
+
*/
|
|
496
|
+
int
|
|
497
|
+
pg_bind_textdomain_codeset(const char *domainname)
|
|
498
|
+
{
|
|
499
|
+
bool elog_ok = (CurrentMemoryContext != NULL);
|
|
500
|
+
int encoding = GetDatabaseEncoding();
|
|
501
|
+
int new_msgenc;
|
|
502
|
+
|
|
503
|
+
#ifndef WIN32
|
|
504
|
+
const char *ctype = setlocale(LC_CTYPE, NULL);
|
|
505
|
+
|
|
506
|
+
if (pg_strcasecmp(ctype, "C") == 0 || pg_strcasecmp(ctype, "POSIX") == 0)
|
|
507
|
+
#endif
|
|
508
|
+
if (encoding != PG_SQL_ASCII &&
|
|
509
|
+
raw_pg_bind_textdomain_codeset(domainname, encoding))
|
|
510
|
+
return encoding;
|
|
511
|
+
|
|
512
|
+
new_msgenc = pg_get_encoding_from_locale(NULL, elog_ok);
|
|
513
|
+
if (new_msgenc < 0)
|
|
514
|
+
new_msgenc = PG_SQL_ASCII;
|
|
515
|
+
|
|
516
|
+
#ifdef WIN32
|
|
517
|
+
if (!raw_pg_bind_textdomain_codeset(domainname, new_msgenc))
|
|
518
|
+
/* On failure, the old message encoding remains valid. */
|
|
519
|
+
return GetMessageEncoding();
|
|
520
|
+
#endif
|
|
521
|
+
|
|
522
|
+
return new_msgenc;
|
|
523
|
+
}
|
|
524
|
+
#endif
|
|
525
|
+
|
|
526
|
+
/*
|
|
527
|
+
* The database encoding, also called the server encoding, represents the
|
|
528
|
+
* encoding of data stored in text-like data types. Affected types include
|
|
529
|
+
* cstring, text, varchar, name, xml, and json.
|
|
530
|
+
*/
|
|
531
|
+
int
|
|
532
|
+
GetDatabaseEncoding(void)
|
|
533
|
+
{
|
|
534
|
+
return DatabaseEncoding->encoding;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const char *
|
|
538
|
+
GetDatabaseEncodingName(void)
|
|
539
|
+
{
|
|
540
|
+
return DatabaseEncoding->name;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
/*
|
|
552
|
+
* gettext() returns messages in this encoding. This often matches the
|
|
553
|
+
* database encoding, but it differs for SQL_ASCII databases, for processes
|
|
554
|
+
* not attached to a database, and under a database encoding lacking iconv
|
|
555
|
+
* support (MULE_INTERNAL).
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
/*
|
|
561
|
+
* Generic character incrementer function.
|
|
562
|
+
*
|
|
563
|
+
* Not knowing anything about the properties of the encoding in use, we just
|
|
564
|
+
* keep incrementing the last byte until we get a validly-encoded result,
|
|
565
|
+
* or we run out of values to try. We don't bother to try incrementing
|
|
566
|
+
* higher-order bytes, so there's no growth in runtime for wider characters.
|
|
567
|
+
* (If we did try to do that, we'd need to consider the likelihood that 255
|
|
568
|
+
* is not a valid final byte in the encoding.)
|
|
569
|
+
*/
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
/*
|
|
573
|
+
* UTF-8 character incrementer function.
|
|
574
|
+
*
|
|
575
|
+
* For a one-byte character less than 0x7F, we just increment the byte.
|
|
576
|
+
*
|
|
577
|
+
* For a multibyte character, every byte but the first must fall between 0x80
|
|
578
|
+
* and 0xBF; and the first byte must be between 0xC0 and 0xF4. We increment
|
|
579
|
+
* the last byte that's not already at its maximum value. If we can't find a
|
|
580
|
+
* byte that's less than the maximum allowable value, we simply fail. We also
|
|
581
|
+
* need some special-case logic to skip regions used for surrogate pair
|
|
582
|
+
* handling, as those should not occur in valid UTF-8.
|
|
583
|
+
*
|
|
584
|
+
* Note that we don't reset lower-order bytes back to their minimums, since
|
|
585
|
+
* we can't afford to make an exhaustive search (see make_greater_string).
|
|
586
|
+
*/
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
/*
|
|
590
|
+
* EUC-JP character incrementer function.
|
|
591
|
+
*
|
|
592
|
+
* If the sequence starts with SS2 (0x8e), it must be a two-byte sequence
|
|
593
|
+
* representing JIS X 0201 characters with the second byte ranging between
|
|
594
|
+
* 0xa1 and 0xdf. We just increment the last byte if it's less than 0xdf,
|
|
595
|
+
* and otherwise rewrite the whole sequence to 0xa1 0xa1.
|
|
596
|
+
*
|
|
597
|
+
* If the sequence starts with SS3 (0x8f), it must be a three-byte sequence
|
|
598
|
+
* in which the last two bytes range between 0xa1 and 0xfe. The last byte
|
|
599
|
+
* is incremented if possible, otherwise the second-to-last byte.
|
|
600
|
+
*
|
|
601
|
+
* If the sequence starts with a value other than the above and its MSB
|
|
602
|
+
* is set, it must be a two-byte sequence representing JIS X 0208 characters
|
|
603
|
+
* with both bytes ranging between 0xa1 and 0xfe. The last byte is
|
|
604
|
+
* incremented if possible, otherwise the second-to-last byte.
|
|
605
|
+
*
|
|
606
|
+
* Otherwise, the sequence is a single-byte ASCII character. It is
|
|
607
|
+
* incremented up to 0x7f.
|
|
608
|
+
*/
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
/*
|
|
612
|
+
* get the character incrementer for the encoding for the current database
|
|
613
|
+
*/
|
|
614
|
+
|
|
615
|
+
|
|
616
|
+
/*
|
|
617
|
+
* fetch maximum length of the encoding for the current database
|
|
618
|
+
*/
|
|
619
|
+
int
|
|
620
|
+
pg_database_encoding_max_length(void)
|
|
621
|
+
{
|
|
622
|
+
return pg_wchar_table[GetDatabaseEncoding()].maxmblen;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/*
|
|
626
|
+
* Verify mbstr to make sure that it is validly encoded in the current
|
|
627
|
+
* database encoding. Otherwise same as pg_verify_mbstr().
|
|
628
|
+
*/
|
|
629
|
+
bool
|
|
630
|
+
pg_verifymbstr(const char *mbstr, int len, bool noError)
|
|
631
|
+
{
|
|
632
|
+
return
|
|
633
|
+
pg_verify_mbstr_len(GetDatabaseEncoding(), mbstr, len, noError) >= 0;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/*
|
|
637
|
+
* Verify mbstr to make sure that it is validly encoded in the specified
|
|
638
|
+
* encoding.
|
|
639
|
+
*/
|
|
640
|
+
|
|
641
|
+
|
|
642
|
+
/*
|
|
643
|
+
* Verify mbstr to make sure that it is validly encoded in the specified
|
|
644
|
+
* encoding.
|
|
645
|
+
*
|
|
646
|
+
* mbstr is not necessarily zero terminated; length of mbstr is
|
|
647
|
+
* specified by len.
|
|
648
|
+
*
|
|
649
|
+
* If OK, return length of string in the encoding.
|
|
650
|
+
* If a problem is found, return -1 when noError is
|
|
651
|
+
* true; when noError is false, ereport() a descriptive message.
|
|
652
|
+
*/
|
|
653
|
+
int
|
|
654
|
+
pg_verify_mbstr_len(int encoding, const char *mbstr, int len, bool noError)
|
|
655
|
+
{
|
|
656
|
+
mbverifier mbverify;
|
|
657
|
+
int mb_len;
|
|
658
|
+
|
|
659
|
+
Assert(PG_VALID_ENCODING(encoding));
|
|
660
|
+
|
|
661
|
+
/*
|
|
662
|
+
* In single-byte encodings, we need only reject nulls (\0).
|
|
663
|
+
*/
|
|
664
|
+
if (pg_encoding_max_length(encoding) <= 1)
|
|
665
|
+
{
|
|
666
|
+
const char *nullpos = memchr(mbstr, 0, len);
|
|
667
|
+
|
|
668
|
+
if (nullpos == NULL)
|
|
669
|
+
return len;
|
|
670
|
+
if (noError)
|
|
671
|
+
return -1;
|
|
672
|
+
report_invalid_encoding(encoding, nullpos, 1);
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
/* fetch function pointer just once */
|
|
676
|
+
mbverify = pg_wchar_table[encoding].mbverify;
|
|
677
|
+
|
|
678
|
+
mb_len = 0;
|
|
679
|
+
|
|
680
|
+
while (len > 0)
|
|
681
|
+
{
|
|
682
|
+
int l;
|
|
683
|
+
|
|
684
|
+
/* fast path for ASCII-subset characters */
|
|
685
|
+
if (!IS_HIGHBIT_SET(*mbstr))
|
|
686
|
+
{
|
|
687
|
+
if (*mbstr != '\0')
|
|
688
|
+
{
|
|
689
|
+
mb_len++;
|
|
690
|
+
mbstr++;
|
|
691
|
+
len--;
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
if (noError)
|
|
695
|
+
return -1;
|
|
696
|
+
report_invalid_encoding(encoding, mbstr, len);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
l = (*mbverify) ((const unsigned char *) mbstr, len);
|
|
700
|
+
|
|
701
|
+
if (l < 0)
|
|
702
|
+
{
|
|
703
|
+
if (noError)
|
|
704
|
+
return -1;
|
|
705
|
+
report_invalid_encoding(encoding, mbstr, len);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
mbstr += l;
|
|
709
|
+
len -= l;
|
|
710
|
+
mb_len++;
|
|
711
|
+
}
|
|
712
|
+
return mb_len;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/*
|
|
716
|
+
* check_encoding_conversion_args: check arguments of a conversion function
|
|
717
|
+
*
|
|
718
|
+
* "expected" arguments can be either an encoding ID or -1 to indicate that
|
|
719
|
+
* the caller will check whether it accepts the ID.
|
|
720
|
+
*
|
|
721
|
+
* Note: the errors here are not really user-facing, so elog instead of
|
|
722
|
+
* ereport seems sufficient. Also, we trust that the "expected" encoding
|
|
723
|
+
* arguments are valid encoding IDs, but we don't trust the actuals.
|
|
724
|
+
*/
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
/*
|
|
728
|
+
* report_invalid_encoding: complain about invalid multibyte character
|
|
729
|
+
*
|
|
730
|
+
* note: len is remaining length of string, not length of character;
|
|
731
|
+
* len must be greater than zero, as we always examine the first byte.
|
|
732
|
+
*/
|
|
733
|
+
void
|
|
734
|
+
report_invalid_encoding(int encoding, const char *mbstr, int len)
|
|
735
|
+
{
|
|
736
|
+
int l = pg_encoding_mblen(encoding, mbstr);
|
|
737
|
+
char buf[8 * 5 + 1];
|
|
738
|
+
char *p = buf;
|
|
739
|
+
int j,
|
|
740
|
+
jlimit;
|
|
741
|
+
|
|
742
|
+
jlimit = Min(l, len);
|
|
743
|
+
jlimit = Min(jlimit, 8); /* prevent buffer overrun */
|
|
744
|
+
|
|
745
|
+
for (j = 0; j < jlimit; j++)
|
|
746
|
+
{
|
|
747
|
+
p += sprintf(p, "0x%02x", (unsigned char) mbstr[j]);
|
|
748
|
+
if (j < jlimit - 1)
|
|
749
|
+
p += sprintf(p, " ");
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
ereport(ERROR,
|
|
753
|
+
(errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
|
|
754
|
+
errmsg("invalid byte sequence for encoding \"%s\": %s",
|
|
755
|
+
pg_enc2name_tbl[encoding].name,
|
|
756
|
+
buf)));
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
/*
|
|
760
|
+
* report_untranslatable_char: complain about untranslatable character
|
|
761
|
+
*
|
|
762
|
+
* note: len is remaining length of string, not length of character;
|
|
763
|
+
* len must be greater than zero, as we always examine the first byte.
|
|
764
|
+
*/
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
#ifdef WIN32
|
|
769
|
+
/*
|
|
770
|
+
* Convert from MessageEncoding to a palloc'ed, null-terminated utf16
|
|
771
|
+
* string. The character length is also passed to utf16len if not
|
|
772
|
+
* null. Returns NULL iff failed. Before MessageEncoding initialization, "str"
|
|
773
|
+
* should be ASCII-only; this will function as though MessageEncoding is UTF8.
|
|
774
|
+
*/
|
|
775
|
+
WCHAR *
|
|
776
|
+
pgwin32_message_to_UTF16(const char *str, int len, int *utf16len)
|
|
777
|
+
{
|
|
778
|
+
int msgenc = GetMessageEncoding();
|
|
779
|
+
WCHAR *utf16;
|
|
780
|
+
int dstlen;
|
|
781
|
+
UINT codepage;
|
|
782
|
+
|
|
783
|
+
if (msgenc == PG_SQL_ASCII)
|
|
784
|
+
/* No conversion is possible, and SQL_ASCII is never utf16. */
|
|
785
|
+
return NULL;
|
|
786
|
+
|
|
787
|
+
codepage = pg_enc2name_tbl[msgenc].codepage;
|
|
788
|
+
|
|
789
|
+
/*
|
|
790
|
+
* Use MultiByteToWideChar directly if there is a corresponding codepage,
|
|
791
|
+
* or double conversion through UTF8 if not. Double conversion is needed,
|
|
792
|
+
* for example, in an ENCODING=LATIN8, LC_CTYPE=C database.
|
|
793
|
+
*/
|
|
794
|
+
if (codepage != 0)
|
|
795
|
+
{
|
|
796
|
+
utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
|
|
797
|
+
dstlen = MultiByteToWideChar(codepage, 0, str, len, utf16, len);
|
|
798
|
+
utf16[dstlen] = (WCHAR) 0;
|
|
799
|
+
}
|
|
800
|
+
else
|
|
801
|
+
{
|
|
802
|
+
char *utf8;
|
|
803
|
+
|
|
804
|
+
/*
|
|
805
|
+
* XXX pg_do_encoding_conversion() requires a transaction. In the
|
|
806
|
+
* absence of one, hope for the input to be valid UTF8.
|
|
807
|
+
*/
|
|
808
|
+
if (IsTransactionState())
|
|
809
|
+
{
|
|
810
|
+
utf8 = (char *) pg_do_encoding_conversion((unsigned char *) str,
|
|
811
|
+
len,
|
|
812
|
+
msgenc,
|
|
813
|
+
PG_UTF8);
|
|
814
|
+
if (utf8 != str)
|
|
815
|
+
len = strlen(utf8);
|
|
816
|
+
}
|
|
817
|
+
else
|
|
818
|
+
utf8 = (char *) str;
|
|
819
|
+
|
|
820
|
+
utf16 = (WCHAR *) palloc(sizeof(WCHAR) * (len + 1));
|
|
821
|
+
dstlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len);
|
|
822
|
+
utf16[dstlen] = (WCHAR) 0;
|
|
823
|
+
|
|
824
|
+
if (utf8 != str)
|
|
825
|
+
pfree(utf8);
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
if (dstlen == 0 && len > 0)
|
|
829
|
+
{
|
|
830
|
+
pfree(utf16);
|
|
831
|
+
return NULL; /* error */
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
if (utf16len)
|
|
835
|
+
*utf16len = dstlen;
|
|
836
|
+
return utf16;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
#endif /* WIN32 */
|