From 4ba8595ed83841d1fa240716b5652adc3772c36b Mon Sep 17 00:00:00 2001 From: Aleksandar Fabijanic Date: Fri, 8 Jul 2022 18:28:44 +0200 Subject: [PATCH] Release 1.12.0 (#3674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix a leak, add some table features * few PostgreSQL fixes * GH #2351: WebSocket docs * Rename pcre internal symbols used by Poco to avoid symbol collision https://github.com/pocoproject/poco/issues/2916 This patch was backported from https://github.com/pld-linux/poco/blob/master/pcre.patch * Fix warning in clang * Fix MSVC clang build fail * Zip and SevenZip do not depend on Util, XML, JSON * Added Test and new Pattern 'O' to only log the Filename not the full Path. * Updated Comment * Configuration to receive OCSP stapling response for client connections and callback implementation to verify the response if the server returns any response * removed SDK version from project files * run Application::initialize() in try-catch block * fix Invalid condition [ICMPv4PacketImpl.cpp:234] #2783 * style fixes for #2935; check OpenSSL version * Fixed issue 2945 (#2946) * Fixed #2945 * Added unit tests for #2945 * Dissalow iterator on empty Var (#2945) * Updated unit tests for #2945 * More concise unit tests for #2945 * Removed some more clutter (#2945) * NetSSL_Win: fix potential endless loop due to wrong error handling * fixed GH #2970: Poco::Data::TypeHandler>::prepare() must prepare with underlying type, not Poco::Data::Keywords::null * Fixed linking with Data ODBC error on some platforms * Fix set padding call for new versions of OpenSSL * PatternFormatter priorityNames fix * PKCS12Container: fix memory leaks on exceptions * Fix constness of URI::getPathSegments * Fix typo in the ThreadPool's docs * cmake: use GNUInstallDirs * Changed EventHandlerMap key (#3116) * Changed EventHandlerMap key Changed EventHandlerMap key from Socket to poco_socket_t to avoid errors in removing/access EventHandlerMap when for example we make an SSL handshake * Changed EventHandlerMap key Changed EventHandlerMap key from Socket to poco_socket_t to avoid errors in removing/access EventHandlerMap when for example we make an SSL handshake * avoid too much call to sockfd() and impl() * Fix configuration error while cross compiling (#3127) During the configuration phase in a cross compilation scenario, `include(InstallRequiredSystemLibraries)` fails even if `MSVC_REDIST_DIR` is provided. This should not be an hard error, in case someone wants to compile/use the library, and not package it. As explained on https://reviews.llvm.org/D41220, the most sensible fix is to include `InstallRequiredSystemLibraries` only on a Windows host. * crash when remove key from JSON::Object(JSON_PRESERVE_KEY_ORDER). (#3151) * #3153: Poco::Data::ODBC [N]VARCHAR(MAX) wrong maxDataSize() result * [SharedPtr] Poco::makeSharedArray #3200 * #3202: JWT: ESxxx signature must include padding for ECDSA R and S values * feat(HashRange): port HashRange from boost * chore(cmake): spelling typo fix * fix(hashRange): change function names casing * merge changes from 1.10.2 * formatting * merge JSON formatting changes from 1.10.2 * added Application::windowSize() * RemoteSyslogChannel/RemoteSyslogListener: make UDP buffer size configurable * merge fix from 1.10.2 * merge Postgres fixes from 1.10.2 * #2993: The Sec-WebSocket-Key of WebSocket is always the same one * formatting * #2927 * remove HowToGetHelp page due to outdated information * formatting * #3044: Upgrade PCRE to 8.44 * #3086: Use POCO_IOS_INIT_HACK for Linux in combination with libc++ * #3095: Digest proxy authentication does not work in 1.10.1 * #3136: Fixed null character issue when parsing a JSON * #3114: Added JSON Array::empty() method * #3230: ECDSADigestEngine: include missing header * fix include order * include order * fix(PollSet): #3248 #3249 * chore(UDPServer): fix spelling * feat(SocketReactor): extract and expose poll() as a member function * feat(Endpoint): add Endpoint (socket address directly wrapping native structures) * fix(Endpoint): osx build, align family enum with patform, some other adjustments * fix(EndpointTest): add missing include * feat(Endpoint): add some low-level accessors * feat(IPAddress): add functions returning addres as raw bytes * feat(DatagramSocket): DatagramSocket does not allow IPV6_V6ONLY #3283 * feat(SocketReactor): Add completion handling to SocketReactor #3290 * feat(SocketReactor): Add completion handling to SocketReactor #3290 (add scheduled handlers and runOne()) * chore(Net-testsuite): fix some tests warnings * feat: move semantics for sockets and addresses * fix(NetworkInterface): Unterminated string possible in NetworkInterfaceImpl::setPhyParams() #3301 * feat(Net): Add move semantics to Net (sockets and addresses) #3296 * fix(HostEntry): DNS HostEntry returns multiple entries #3303 * fix(SocketReactor): completion handling fixes and tests, separation of i/o and completion mutexes * feat(SocketReactor): execute permanent completion handlers on when there are I/O handlers and the expired ones whenever they expire * feat(Socket): expose lastError() * fix(SocketReactor): windows compile * windows fixes, remove Endnpoint * feat(Socket): expose error() * feat(PollSet): Use select() on windows for PollSet #3339 * add ci.yml * fix compile errors * revert(SocketReactor): back to devel branch * feat(SocketProactor): initial version w/ completion handler and executor * chore(SocketProactor): Sockets package * chore(ci): add dir and run script * feat(SocketProactor): add socket error handling #3357 * modify(SocketProactor): wait for completion handlers availability #3357 * feat(PollSet): Make PollSet::poll() interruptible #3359 * modify(SocketProactor): make addSend() public #3357 * modify(SocketProactor): platform non-interrupt sleep without Poco thread #3357 * modify(SocketProactor): allow restart #3357 * fix(SocketProactor): windows fixes and VS build * fix(SocketProactor): race when stop() is called before run() * fix(Socket): Windows SO_REUSEADDR is neither reliable nor safe #3380 * fix(SocketProactor): rvalue refs should not be const * fix(DNS): DNS::hostByAddress not thread-safe #3381 * chore(SocketProactor): remove unnecessary this capture * fix(IPAddress): IPAddress::tryParse does not work for :: #3385 * fix(SoccketProactor): add some try/catch safety nets; broaden the work list mutex coverage to protect all function access * fix(SocketProactor): use Poco::Mutex only * fix(SocketProactor): scheduled work skipped in the absence of socket events * fix(SocketProactor): test * chore (SocketProactor): add some state members * Fix clang linker problem by defining POCO_NO_AUTOMATIC_LIBS (#3177) * Basic support for OpenSSL 3.0.0 (#3448) * updated README.md * Create close-inactive-issues.yml * check return codes of EVP_CIPHER_CTX_new and EVP_CipherInit Especially with OpenSSL 3, it is possible that EVP_CipherInit may fail even when passed a non-null cipher[1]. Without the checking, it will finally get to a segfault. [1] https://github.com/openssl/openssl/issues/16864 * Automatically load default and legacy providers with OpenSSL 3 Without the legacy provider [1], some ciphers are not available. For example, the 'des-ecb' one used by test sutie is missed and the test will fail. [1] OSSL_PROVIDER-LEGACY(7ossl) * Make p12 ca order the same as pem OpenSSL < 3 returns p12 ca order in reversed order. This is fixed in OpenSSL 3. We work around it with old OpenSSL. See: https://github.com/openssl/openssl/issues/16421 https://github.com/openssl/openssl/pull/12641 https://github.com/jeroen/openssl/commit/f5eb85eb0fd432406a24abda6511c449eaee6162 * Implement SSL abort handling on OpenSSL 3 On an unexpected EOF, versions before OpenSSL 3.0 returned SSL_ERROR_SYSCALL, nothing was added to the error stack, and errno was 0. Since OpenSSL 3.0 the returned error is SSL_ERROR_SSL with a meaningful error on the error stack.[1] [1] SSL_GET_ERROR(3ossl) Co-authored-by: Günter Obiltschnig Co-authored-by: Robin Lee Co-authored-by: Aleksandar Fabijanic * fix(Socket): shutdown fixes from pull #3448 * chore: cleanup * fix(X509Certificate): add missing string format * feat(EVP): 3.0 support - add EVPCipher - additional EVPPKey constructors - tests - fix and improve openssl-related exceptions Transition towards 3.0 support; deprecating direct EC and RSA interface portions. * fix(openssl): pre 3.0 compile * feat(Envelope): Add envelope to crypto #3561 * fix(Envelope): mac/clang compile * fix(Any): #3297 #3514 * Refactor/any soo (#3564) * refactor(Any): SOO - encapsulate data holders - add missing gets and ops - eliminate g++ warnings with enable_if's - default enable SOO * refactor(Placeholder): encapsulate SOO memory management and fix leaks; cf. #3297 #3514 * fix(Placeholder): asan errors and add tests cf. #3297 #3514 * fix(SSLManager): Race condition in SSLManager #3558 * fix(SHA2Engine): cannot use HMACEngine with SHA2Engine #3421 * refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remove it anywhere else (#3566) * refactor(Placeholder): more SOO consolidation and optimization * fix(FPEnvironment): Visual Studio Warning C4244 #3543 * fix(Extractor): move extraction decoding to AbstractExtractor #3396 * Netssl/openssl3 (#3575) * feat(Context): DH init openssl3 port (1/2 hardcoded params) * create poco-1.11.3 branch, bump version * update copyright date * #3567: check legacy provider existence for legacy exception #3567 * fix(Placeholder): comparison for zero value * feat(Context): DH init openssl3 port (2/2 params from file) * test(HTTPSClientSession): try/catch to understand CI failure * chore(cmake): copy the DH parameters file * fix(OpenSSLInitializer): unload provider on uninitialize * chore(HTTPSClientSessionTest): remove try/catch * fix(OpenSSLInitializer): fix provider unloading * feat(CppUnit): make tests exceptions more descriptive * chore(CppUnit): a more descriptive name for callback Co-authored-by: Günter Obiltschnig * fix(Foundation): update VS 2019 platform version * chore(Data): update VS project files (add Transcoder #3396) * fix(Data): Poco::Data::ODBC-dbEncoding property not used for insert/update #3396 * fix(Data): add transcoder to Makefile #3396 * Dev/devel 1.12.0 (#3585) * fix(PollSet): #3248 #3249 * bump version to 1.11.0 * updated changelog| * #3299: NetSSL: Allow per-Context InvalidCertificateHandler * #3022: Process::isRunning(PID pid) causes handle leak on Windows * #3022: fix for WinCE * upgrade bundled pdjson to latest master * update build configs - add support for Apple Silicon * #2906, #2904: Support environments without hardware floating point * #3130: fix error handling: report original error before close() * #3107: remove unused variable * #3219: SMTPClientSession: invalid SMTP command if empty recipients list in MailMessage * Poco::trim*() code cleanup - use ptrdiff_t instead of int; additional test cases * #3182 Poco::Process:launch on MacOS BigSur: limit maximum number of file descriptors to close before exec() to 100000 * #3278: Fixing no hardware floating point support - Part II * #3090: Do not initialize value with undefined behavior * #3163: Correct Var::parse null value * #3196: std::forward for Poco::Optional ctor with rvalue * #3068: Documented ENABLE_JWT option * #3041: PostgreSQL and TEXT column type * #3099: Fixed Postgres extraction into Dynamic::Var * #3138: Add support of arch riscv32 * #2825: riscv: Enable double operations when using double float abi * #3166: Fix PostgresSQL BLOB extractor * #3237: An error in the documentation for Poco/JSON/Parser.h * #3193: ServerApplication::registerService() unquoted path security vulnerability * #3266: Order of Util::Application::uninitialize() is not in reverse as documented * #3215: XML parser returns item from different element in a array * #3282: Update constant in setContentType documentation * #3089: HTTPSessionFactory does not support HTTPClientSession::ProxyConfig * #2418: SecureServerSocket doesn't work with IpV6 * fix warnings * #3019: ObjectPool wait on borrow condition fix * #3224: Remove SSL23 support from Poco/Crypto * #3191: Fixing a bug in the NetSSL_Win module (Host name verification failed error) * disallow SSLv3 * #3269: Poco::Net::Context initialization with empty certificateFile * #3307: Poco::Crypto::X509Certificate: obtain certificate fingerprint * #3260: Memory leak in EVPPKey::loadKey used with files & wrong password * #3157: fix(openssl): add missing dependency to OpenSSL components * #3066: CMake warning about MYSQL casing * #3135: Poco::Data::SQLite::Utility::fileToMemory unsuccessful if journal exists * #3217: CMake: warning message with -DPOCO_STATIC confusing * #3274: Fix localtime_r for VxWorks 6.9 and later * #2746, #3169: Fix race condition on TCPServerDispatcher stop * #3092: add more detailed error description when LoadLibrary fails| * #3074: Fix sessions may not return back to the pool * #3309: optimize parsing from stream (no copying of entire JSON to memory); limit maximum depth to avoid stack overflow with malicious documents (fuzzing - #3285); code cleanup * JSON Parser performance improvements * #3310: Upgrade bundled SQLite to 3.35.5 * fix UB/bad cast in TCPServerTest.cpp * add comment regarding potential UB in AnyTest::testCastToReference() * support sanitizers in build configs * bump version * fix 'catching polymorphic type by value' warnings * fix 'catching polymorphic type by value' warnings * fix 'catching polymorphic type by value' warnings * remove failing Android build; add sanitizer builds * update postgres version * fix warning * fix warning * add GitHub workflow * fix ci.yml * fix ci.yml * additional ci builds * fix ci.yml for macos and windows * fix(double-conversion): Upgrade bundled double-conversion #3313 * ci fixes * #3314: NetSSL_OpenSSL: any.pem certificate error: ca md too weak * testReuseSession: remove bad checks for session reuse * investigate failing test * investigate failing test * investigate failing test * investigate failing test * ci * remove travis and appveyor * ci, readme * ci fixes * fix ci * fix ci * fix ci * fix memory leak when ignoring test error/failure * fix ci * don't define UNREACHABLE as poco_bugcheck as it triggers 'control reaches end of non-void function' warning * add Linux cross build, build Data libs on macos * fix ci * add MySQL include/lib search paths for Homebrew * ci fixes * ci fixes * ci fixes * ci fixes * fix indluce paths for brew mysql * #3317: Data::MySQL MySQL headers and library search paths * fix ARM-Linux build config * fix MySQL.make * update FindMySQL.cmake * fix(SocketReactor): fix dataCollection test * chore: remove troubleshooting help leftovers * #3302: MSVC: Poco hides warnings (C4996) for the C++14 attribute [[deprecated]] * fix potential crash in testAsyncNotify: don't delete event object while async notification is still in progress * fix(PollSetTest): change connect to blocking * added ActiveRecord library and compiler * added dependencies file * update copyright dates * ActiveRecord: project files and fixes for MSVC * ci: enable ActiveRecord on Windows * fix(PollSetTest): remove poll timing check (fails on msvc ci) * fix ActiveRecord CMake build and configuration * feat(build): add gen directory (for generated sources) and macchina lib link dirs (if needed) * #3318: Data: Support Poco::UUID for data binding * ODBC tests for UUID, updated ActiveRecord projects * ActiveRecord user guide * update ActiveRecord documentation * documentation fixes * #3321: manually merge ODBC text encoding support * CppParser: merge changes from internal repository * updated Makefile * AbstractObserver::accepts() - add optional name parameter * fix SharedPtr::makeSharedArray() [merge from devel] * remove blank line * #2895, #2935: support OCSP stapling * style * clang support (merge from devel) * #3322: remove useless struct * link libmariadb instead of libmysql if headers indicate MariaDB * fix nullptr passed to memcmp/memcpy reported by ubsan * fix nullptr passed to memcmp/memcpy reported by ubsan * fix PageCompiler cross-compile; fix Content-Security-Policy header * remove Data release notes page * style, remove unused var * update docs * improve BLOB handling, clean-up code * fix(ICMPv4Packet): [asan] Undefined behavior in ICMPv4PacketImpl.cpp #3326 * fix(NumericString): Bug in NumericString with decSep != '.' #3159 * fix(HostEntry): DNS HostEntry returns multiple entries #3303 * fix(PollSet): #3248 #3249 * fix(NetworkInterface): Unterminated string possible in NetworkInterfaceImpl::setPhyParams() #3301 * style/whitespace * fix warnings * add version resources to executables * style * whitespace * update changelog * cpproj: also copy testsuite/include if it's there * branch off 1.11.1 * #3335: XML error when build 1.11.0 * #3353: add POCO_NO_FORK_EXEC CMake option * #3381: DNS::hostByAddress not thread-safe * #3400: fix std::localtime not thread safe * #3221: Crash reported on Windows in X509Certificate verification * #3344: [bug] MacOS bundle destination path is not set * #3360: Add POCO_PGSQL_{INCLUDE,LIB} variables * #3363: Fixed compilation error with MongoDB::Connection and Util::Application * #3377: Correct Poco::Path::configHome() and dataHome() documentation for Windows * #2823: error: implicit conversion from 'int' to 'float' changes value from 2147483647 to 2147483648 * #3425: Fixed suspend/resumeEvents pair in DirectoryWatcher * #2966: SocketReactor loads one core of CPU up to 100% * #3330: Poco::Data::ODBC::ODBCStatementImpl causes crash * use OpenSSL 1.1.1 on macOS * add missing include search path * upgrade bundled PCRE to 8.45 * upgrade bundled SQLite to 3.36.0 * updated changelog * fix brew OpenSSL version * branch off poco-1.11.2 * #3506: Upgrade bundled expat to 2.4.4 * manually merge #3448, part 1 (Crypto) * manually merge #3448, part 1 (NetSSL) * #3515: NetSSL_OpenSSL Testsuite: testInterop() and testProxy() fail due to changed certificate * #3448: fix version check * #3465: NetSSL_Win: bad error handling when decodeMessage() fails * #3458: encryptString() crash on redhat/centos 8 with FIPS enabled using md5 default digest * #3505: JSON::PrintHandler.value(bool) prints incorrect value * #3527: Upgrade bundled expat to 2.4.5 * #3470: bug in JSON ParseHandler.cpp (RFC 7159 should be valid) * #3507: Reference counting for bound configuration in Util::Option is broken * #3518: Expat version check in #defines incorrect * #3338: NamedMutex does not work on Linux distributions where fs.protected_regular=1 * CI: don't build PageCompiler in ARM cross build * detect ARM64 on Windows * updated README.md * ProGen: support generation of VS 2022 project files * ci: add windows 2022 * fix library name * remove unused CppUnit headers * added VS2022 project files * #3530: Upgrade bundled expat to 2.4.6 * #3538: Upgrade bundled expat to 2.4.7 * Add back NIOS2 double conversion detection to fix compile errors The commit https://github.com/pocoproject/poco/commit/558324f672d824300498060aff63356bc6bb8097 removed the nios2 support, which was originally added in https://github.com/pocoproject/poco/commit/e7b91e8125d6910b53f94de5be4bb53f38dc77c1 This commit add it back. Signed-off-by: Julien Olivain * #3466: DefinePlatformSpecific.cmake: handle RelWithDebInfo and MinSizeRel configurations * #3524: remove XML and Util dependencies in Zip/SevenZip * #3483: Adds Windows 11 and Server 2022 to Environment::osDisplayName() * #3495: Array::operator[] should not throw * #3268: Poco redis command set have a bug when you want to set nx ex or expireTime * #3509: fix dst and utcOffset handling for Dublin time zone * #2882: another attempt at fixing it that should also work on other platforms * remove unused method in Timezone_WIN32.cpp * use tm_gmtoff on Linux * Basic support for OpenSSL 3.0.0 (#3448) * updated README.md * Create close-inactive-issues.yml * check return codes of EVP_CIPHER_CTX_new and EVP_CipherInit Especially with OpenSSL 3, it is possible that EVP_CipherInit may fail even when passed a non-null cipher[1]. Without the checking, it will finally get to a segfault. [1] https://github.com/openssl/openssl/issues/16864 * Automatically load default and legacy providers with OpenSSL 3 Without the legacy provider [1], some ciphers are not available. For example, the 'des-ecb' one used by test sutie is missed and the test will fail. [1] OSSL_PROVIDER-LEGACY(7ossl) * Make p12 ca order the same as pem OpenSSL < 3 returns p12 ca order in reversed order. This is fixed in OpenSSL 3. We work around it with old OpenSSL. See: https://github.com/openssl/openssl/issues/16421 https://github.com/openssl/openssl/pull/12641 https://github.com/jeroen/openssl/commit/f5eb85eb0fd432406a24abda6511c449eaee6162 * Implement SSL abort handling on OpenSSL 3 On an unexpected EOF, versions before OpenSSL 3.0 returned SSL_ERROR_SYSCALL, nothing was added to the error stack, and errno was 0. Since OpenSSL 3.0 the returned error is SSL_ERROR_SSL with a meaningful error on the error stack.[1] [1] SSL_GET_ERROR(3ossl) Co-authored-by: Günter Obiltschnig Co-authored-by: Robin Lee Co-authored-by: Aleksandar Fabijanic * fix(Socket): shutdown fixes from pull #3448 * #3500: Sandbox all iFrames in PocoDoc * #3549; replace assert with assertTrue * #3553: Upgrade bundled zlib to 1.2.12 * #3525: Bad management of file in case of OpenSSLException in X509Certificate::readPEM and X509Certificate::writePEM * disable OpenSSL deprecation warnings * chore: cleanup * fix(X509Certificate): add missing string format * #3559: Poco::Data::PostgreSQL - DateTime extraction truncates fractional seconds * feat(EVP): 3.0 support - add EVPCipher - additional EVPPKey constructors - tests - fix and improve openssl-related exceptions Transition towards 3.0 support; deprecating direct EC and RSA interface portions. * fix(openssl): pre 3.0 compile * feat(Envelope): Add envelope to crypto #3561 * fix(Envelope): mac/clang compile * fix(Any): #3297 #3514 * #3562: fixed OpenSSL setup/shutdown * fix exception text * #3563: Remove support for OpenSSL < 1.0 * ci jobs for OpenSSL 1.1 and 3 * updated CHANGELOG * updated .vscode * Refactor/any soo (#3564) * refactor(Any): SOO - encapsulate data holders - add missing gets and ops - eliminate g++ warnings with enable_if's - default enable SOO * refactor(Placeholder): encapsulate SOO memory management and fix leaks; cf. #3297 #3514 * fix(Placeholder): asan errors and add tests cf. #3297 #3514 * fix(SSLManager): Race condition in SSLManager #3558 * remove unused include * updated copyright date * PocoDoc: fix iframe sandboxing * fix(SHA2Engine): cannot use HMACEngine with SHA2Engine #3421 * refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remove it anywhere else (#3566) * refactor(Placeholder): more SOO consolidation and optimization * fix(FPEnvironment): Visual Studio Warning C4244 #3543 * fix(Extractor): move extraction decoding to AbstractExtractor #3396 * Netssl/openssl3 (#3575) * feat(Context): DH init openssl3 port (1/2 hardcoded params) * create poco-1.11.3 branch, bump version * update copyright date * #3567: check legacy provider existence for legacy exception #3567 * fix(Placeholder): comparison for zero value * feat(Context): DH init openssl3 port (2/2 params from file) * test(HTTPSClientSession): try/catch to understand CI failure * chore(cmake): copy the DH parameters file * fix(OpenSSLInitializer): unload provider on uninitialize * chore(HTTPSClientSessionTest): remove try/catch * fix(OpenSSLInitializer): fix provider unloading * feat(CppUnit): make tests exceptions more descriptive * chore(CppUnit): a more descriptive name for callback Co-authored-by: Günter Obiltschnig * fix(Foundation): update VS 2019 platform version * chore(Data): update VS project files (add Transcoder #3396) * fix(Data): Poco::Data::ODBC-dbEncoding property not used for insert/update #3396 * fix(Data): add transcoder to Makefile #3396 * fix(JWT): remove duplicate test functions after merge Co-authored-by: Günter Obiltschnig Co-authored-by: Julien Olivain Co-authored-by: Robin Lee Co-authored-by: Robin Lee * #2755: Fix MySQL's LONGBLOB/LONGTEXT not allocating enough space (#3474) * Unit test for bug #2755. * Removed condition to set buffer length to 0. * Fixes to unit tests for LONGBLOB/TEXT data type. * Adjusted buffer sizes to accommodate LONGBLOBs. Co-authored-by: Hector Toledo Soto * fix(Data): MySQL UUID binding temporary string #3587 * feat(CI): add MySQL tests to CI #3588 * fix(CI): remove mysql client dev (using mariadb) #3588 * fix(CI): another shot at mysql * fix(Net/testsuite): add missing include * fix(DatagramSocket): Socket::available does not always return correct value for UDP #3589 * fix(SocketProactor): few improvements (#3357) * fix(ICMPsocketTest): change appinf (doesn't respond to ping) to github * fix(PollSet): windows fixes * fix(PollSet): windows implementation fixes (multi-fd_set select); minor reactor fixes * Extract JSON type as string (#3491) * Declared JSON as string data # Conflicts: # Data/include/Poco/Data/MetaColumn.h # Data/src/RecordSet.cpp # Data/src/StatementImpl.cpp * Added JSON extractor as string * Added unit test * Update comment * Devel (#3586) * Enable unit test in cmake build * add BLOB SQLite test * accept notifications by name (if they have one) * catch std::exception on parsing * fix a leak, add some table features * few PostgreSQL fixes * GH #2351: WebSocket docs * Rename pcre internal symbols used by Poco to avoid symbol collision https://github.com/pocoproject/poco/issues/2916 This patch was backported from https://github.com/pld-linux/poco/blob/master/pcre.patch * Fix warning in clang * Fix MSVC clang build fail * Zip and SevenZip do not depend on Util, XML, JSON * Added Test and new Pattern 'O' to only log the Filename not the full Path. * Updated Comment * Configuration to receive OCSP stapling response for client connections and callback implementation to verify the response if the server returns any response * removed SDK version from project files * run Application::initialize() in try-catch block * fix Invalid condition [ICMPv4PacketImpl.cpp:234] #2783 * style fixes for #2935; check OpenSSL version * Fixed issue 2945 (#2946) * Fixed #2945 * Added unit tests for #2945 * Dissalow iterator on empty Var (#2945) * Updated unit tests for #2945 * More concise unit tests for #2945 * Removed some more clutter (#2945) * NetSSL_Win: fix potential endless loop due to wrong error handling * fixed GH #2970: Poco::Data::TypeHandler>::prepare() must prepare with underlying type, not Poco::Data::Keywords::null * Fixed linking with Data ODBC error on some platforms * Fix set padding call for new versions of OpenSSL * PatternFormatter priorityNames fix * PKCS12Container: fix memory leaks on exceptions * Fix constness of URI::getPathSegments * Fix typo in the ThreadPool's docs * cmake: use GNUInstallDirs * Changed EventHandlerMap key (#3116) * Changed EventHandlerMap key Changed EventHandlerMap key from Socket to poco_socket_t to avoid errors in removing/access EventHandlerMap when for example we make an SSL handshake * Changed EventHandlerMap key Changed EventHandlerMap key from Socket to poco_socket_t to avoid errors in removing/access EventHandlerMap when for example we make an SSL handshake * avoid too much call to sockfd() and impl() * Fix configuration error while cross compiling (#3127) During the configuration phase in a cross compilation scenario, `include(InstallRequiredSystemLibraries)` fails even if `MSVC_REDIST_DIR` is provided. This should not be an hard error, in case someone wants to compile/use the library, and not package it. As explained on https://reviews.llvm.org/D41220, the most sensible fix is to include `InstallRequiredSystemLibraries` only on a Windows host. * crash when remove key from JSON::Object(JSON_PRESERVE_KEY_ORDER). (#3151) * #3153: Poco::Data::ODBC [N]VARCHAR(MAX) wrong maxDataSize() result * [SharedPtr] Poco::makeSharedArray #3200 * #3202: JWT: ESxxx signature must include padding for ECDSA R and S values * feat(HashRange): port HashRange from boost * chore(cmake): spelling typo fix * fix(hashRange): change function names casing * merge changes from 1.10.2 * formatting * merge JSON formatting changes from 1.10.2 * added Application::windowSize() * RemoteSyslogChannel/RemoteSyslogListener: make UDP buffer size configurable * merge fix from 1.10.2 * merge Postgres fixes from 1.10.2 * #2993: The Sec-WebSocket-Key of WebSocket is always the same one * formatting * #2927 * remove HowToGetHelp page due to outdated information * formatting * #3044: Upgrade PCRE to 8.44 * #3086: Use POCO_IOS_INIT_HACK for Linux in combination with libc++ * #3095: Digest proxy authentication does not work in 1.10.1 * #3136: Fixed null character issue when parsing a JSON * #3114: Added JSON Array::empty() method * #3230: ECDSADigestEngine: include missing header * fix include order * include order * fix(PollSet): #3248 #3249 * chore(UDPServer): fix spelling * feat(SocketReactor): extract and expose poll() as a member function * feat(Endpoint): add Endpoint (socket address directly wrapping native structures) * fix(Endpoint): osx build, align family enum with patform, some other adjustments * fix(EndpointTest): add missing include * feat(Endpoint): add some low-level accessors * feat(IPAddress): add functions returning addres as raw bytes * feat(DatagramSocket): DatagramSocket does not allow IPV6_V6ONLY #3283 * feat(SocketReactor): Add completion handling to SocketReactor #3290 * feat(SocketReactor): Add completion handling to SocketReactor #3290 (add scheduled handlers and runOne()) * chore(Net-testsuite): fix some tests warnings * feat: move semantics for sockets and addresses * fix(NetworkInterface): Unterminated string possible in NetworkInterfaceImpl::setPhyParams() #3301 * feat(Net): Add move semantics to Net (sockets and addresses) #3296 * fix(HostEntry): DNS HostEntry returns multiple entries #3303 * fix(SocketReactor): completion handling fixes and tests, separation of i/o and completion mutexes * feat(SocketReactor): execute permanent completion handlers on when there are I/O handlers and the expired ones whenever they expire * feat(Socket): expose lastError() * fix(SocketReactor): windows compile * windows fixes, remove Endnpoint * feat(Socket): expose error() * feat(PollSet): Use select() on windows for PollSet #3339 * add ci.yml * fix compile errors * revert(SocketReactor): back to devel branch * feat(SocketProactor): initial version w/ completion handler and executor * chore(SocketProactor): Sockets package * chore(ci): add dir and run script * feat(SocketProactor): add socket error handling #3357 * modify(SocketProactor): wait for completion handlers availability #3357 * feat(PollSet): Make PollSet::poll() interruptible #3359 * modify(SocketProactor): make addSend() public #3357 * modify(SocketProactor): platform non-interrupt sleep without Poco thread #3357 * modify(SocketProactor): allow restart #3357 * fix(SocketProactor): windows fixes and VS build * fix(SocketProactor): race when stop() is called before run() * fix(Socket): Windows SO_REUSEADDR is neither reliable nor safe #3380 * fix(SocketProactor): rvalue refs should not be const * fix(DNS): DNS::hostByAddress not thread-safe #3381 * chore(SocketProactor): remove unnecessary this capture * fix(IPAddress): IPAddress::tryParse does not work for :: #3385 * fix(SoccketProactor): add some try/catch safety nets; broaden the work list mutex coverage to protect all function access * fix(SocketProactor): use Poco::Mutex only * fix(SocketProactor): scheduled work skipped in the absence of socket events * fix(SocketProactor): test * chore (SocketProactor): add some state members * Fix clang linker problem by defining POCO_NO_AUTOMATIC_LIBS (#3177) * Dev/devel 1.12.0 (#3585) * fix(PollSet): #3248 #3249 * bump version to 1.11.0 * updated changelog| * #3299: NetSSL: Allow per-Context InvalidCertificateHandler * #3022: Process::isRunning(PID pid) causes handle leak on Windows * #3022: fix for WinCE * upgrade bundled pdjson to latest master * update build configs - add support for Apple Silicon * #2906, #2904: Support environments without hardware floating point * #3130: fix error handling: report original error before close() * #3107: remove unused variable * #3219: SMTPClientSession: invalid SMTP command if empty recipients list in MailMessage * Poco::trim*() code cleanup - use ptrdiff_t instead of int; additional test cases * #3182 Poco::Process:launch on MacOS BigSur: limit maximum number of file descriptors to close before exec() to 100000 * #3278: Fixing no hardware floating point support - Part II * #3090: Do not initialize value with undefined behavior * #3163: Correct Var::parse null value * #3196: std::forward for Poco::Optional ctor with rvalue * #3068: Documented ENABLE_JWT option * #3041: PostgreSQL and TEXT column type * #3099: Fixed Postgres extraction into Dynamic::Var * #3138: Add support of arch riscv32 * #2825: riscv: Enable double operations when using double float abi * #3166: Fix PostgresSQL BLOB extractor * #3237: An error in the documentation for Poco/JSON/Parser.h * #3193: ServerApplication::registerService() unquoted path security vulnerability * #3266: Order of Util::Application::uninitialize() is not in reverse as documented * #3215: XML parser returns item from different element in a array * #3282: Update constant in setContentType documentation * #3089: HTTPSessionFactory does not support HTTPClientSession::ProxyConfig * #2418: SecureServerSocket doesn't work with IpV6 * fix warnings * #3019: ObjectPool wait on borrow condition fix * #3224: Remove SSL23 support from Poco/Crypto * #3191: Fixing a bug in the NetSSL_Win module (Host name verification failed error) * disallow SSLv3 * #3269: Poco::Net::Context initialization with empty certificateFile * #3307: Poco::Crypto::X509Certificate: obtain certificate fingerprint * #3260: Memory leak in EVPPKey::loadKey used with files & wrong password * #3157: fix(openssl): add missing dependency to OpenSSL components * #3066: CMake warning about MYSQL casing * #3135: Poco::Data::SQLite::Utility::fileToMemory unsuccessful if journal exists * #3217: CMake: warning message with -DPOCO_STATIC confusing * #3274: Fix localtime_r for VxWorks 6.9 and later * #2746, #3169: Fix race condition on TCPServerDispatcher stop * #3092: add more detailed error description when LoadLibrary fails| * #3074: Fix sessions may not return back to the pool * #3309: optimize parsing from stream (no copying of entire JSON to memory); limit maximum depth to avoid stack overflow with malicious documents (fuzzing - #3285); code cleanup * JSON Parser performance improvements * #3310: Upgrade bundled SQLite to 3.35.5 * fix UB/bad cast in TCPServerTest.cpp * add comment regarding potential UB in AnyTest::testCastToReference() * support sanitizers in build configs * bump version * fix 'catching polymorphic type by value' warnings * fix 'catching polymorphic type by value' warnings * fix 'catching polymorphic type by value' warnings * remove failing Android build; add sanitizer builds * update postgres version * fix warning * fix warning * add GitHub workflow * fix ci.yml * fix ci.yml * additional ci builds * fix ci.yml for macos and windows * fix(double-conversion): Upgrade bundled double-conversion #3313 * ci fixes * #3314: NetSSL_OpenSSL: any.pem certificate error: ca md too weak * testReuseSession: remove bad checks for session reuse * investigate failing test * investigate failing test * investigate failing test * investigate failing test * ci * remove travis and appveyor * ci, readme * ci fixes * fix ci * fix ci * fix ci * fix memory leak when ignoring test error/failure * fix ci * don't define UNREACHABLE as poco_bugcheck as it triggers 'control reaches end of non-void function' warning * add Linux cross build, build Data libs on macos * fix ci * add MySQL include/lib search paths for Homebrew * ci fixes * ci fixes * ci fixes * ci fixes * fix indluce paths for brew mysql * #3317: Data::MySQL MySQL headers and library search paths * fix ARM-Linux build config * fix MySQL.make * update FindMySQL.cmake * fix(SocketReactor): fix dataCollection test * chore: remove troubleshooting help leftovers * #3302: MSVC: Poco hides warnings (C4996) for the C++14 attribute [[deprecated]] * fix potential crash in testAsyncNotify: don't delete event object while async notification is still in progress * fix(PollSetTest): change connect to blocking * added ActiveRecord library and compiler * added dependencies file * update copyright dates * ActiveRecord: project files and fixes for MSVC * ci: enable ActiveRecord on Windows * fix(PollSetTest): remove poll timing check (fails on msvc ci) * fix ActiveRecord CMake build and configuration * feat(build): add gen directory (for generated sources) and macchina lib link dirs (if needed) * #3318: Data: Support Poco::UUID for data binding * ODBC tests for UUID, updated ActiveRecord projects * ActiveRecord user guide * update ActiveRecord documentation * documentation fixes * #3321: manually merge ODBC text encoding support * CppParser: merge changes from internal repository * updated Makefile * AbstractObserver::accepts() - add optional name parameter * fix SharedPtr::makeSharedArray() [merge from devel] * remove blank line * #2895, #2935: support OCSP stapling * style * clang support (merge from devel) * #3322: remove useless struct * link libmariadb instead of libmysql if headers indicate MariaDB * fix nullptr passed to memcmp/memcpy reported by ubsan * fix nullptr passed to memcmp/memcpy reported by ubsan * fix PageCompiler cross-compile; fix Content-Security-Policy header * remove Data release notes page * style, remove unused var * update docs * improve BLOB handling, clean-up code * fix(ICMPv4Packet): [asan] Undefined behavior in ICMPv4PacketImpl.cpp #3326 * fix(NumericString): Bug in NumericString with decSep != '.' #3159 * fix(HostEntry): DNS HostEntry returns multiple entries #3303 * fix(PollSet): #3248 #3249 * fix(NetworkInterface): Unterminated string possible in NetworkInterfaceImpl::setPhyParams() #3301 * style/whitespace * fix warnings * add version resources to executables * style * whitespace * update changelog * cpproj: also copy testsuite/include if it's there * branch off 1.11.1 * #3335: XML error when build 1.11.0 * #3353: add POCO_NO_FORK_EXEC CMake option * #3381: DNS::hostByAddress not thread-safe * #3400: fix std::localtime not thread safe * #3221: Crash reported on Windows in X509Certificate verification * #3344: [bug] MacOS bundle destination path is not set * #3360: Add POCO_PGSQL_{INCLUDE,LIB} variables * #3363: Fixed compilation error with MongoDB::Connection and Util::Application * #3377: Correct Poco::Path::configHome() and dataHome() documentation for Windows * #2823: error: implicit conversion from 'int' to 'float' changes value from 2147483647 to 2147483648 * #3425: Fixed suspend/resumeEvents pair in DirectoryWatcher * #2966: SocketReactor loads one core of CPU up to 100% * #3330: Poco::Data::ODBC::ODBCStatementImpl causes crash * use OpenSSL 1.1.1 on macOS * add missing include search path * upgrade bundled PCRE to 8.45 * upgrade bundled SQLite to 3.36.0 * updated changelog * fix brew OpenSSL version * branch off poco-1.11.2 * #3506: Upgrade bundled expat to 2.4.4 * manually merge #3448, part 1 (Crypto) * manually merge #3448, part 1 (NetSSL) * #3515: NetSSL_OpenSSL Testsuite: testInterop() and testProxy() fail due to changed certificate * #3448: fix version check * #3465: NetSSL_Win: bad error handling when decodeMessage() fails * #3458: encryptString() crash on redhat/centos 8 with FIPS enabled using md5 default digest * #3505: JSON::PrintHandler.value(bool) prints incorrect value * #3527: Upgrade bundled expat to 2.4.5 * #3470: bug in JSON ParseHandler.cpp (RFC 7159 should be valid) * #3507: Reference counting for bound configuration in Util::Option is broken * #3518: Expat version check in #defines incorrect * #3338: NamedMutex does not work on Linux distributions where fs.protected_regular=1 * CI: don't build PageCompiler in ARM cross build * detect ARM64 on Windows * updated README.md * ProGen: support generation of VS 2022 project files * ci: add windows 2022 * fix library name * remove unused CppUnit headers * added VS2022 project files * #3530: Upgrade bundled expat to 2.4.6 * #3538: Upgrade bundled expat to 2.4.7 * Add back NIOS2 double conversion detection to fix compile errors The commit https://github.com/pocoproject/poco/commit/558324f672d824300498060aff63356bc6bb8097 removed the nios2 support, which was originally added in https://github.com/pocoproject/poco/commit/e7b91e8125d6910b53f94de5be4bb53f38dc77c1 This commit add it back. Signed-off-by: Julien Olivain * #3466: DefinePlatformSpecific.cmake: handle RelWithDebInfo and MinSizeRel configurations * #3524: remove XML and Util dependencies in Zip/SevenZip * #3483: Adds Windows 11 and Server 2022 to Environment::osDisplayName() * #3495: Array::operator[] should not throw * #3268: Poco redis command set have a bug when you want to set nx ex or expireTime * #3509: fix dst and utcOffset handling for Dublin time zone * #2882: another attempt at fixing it that should also work on other platforms * remove unused method in Timezone_WIN32.cpp * use tm_gmtoff on Linux * Basic support for OpenSSL 3.0.0 (#3448) * updated README.md * Create close-inactive-issues.yml * check return codes of EVP_CIPHER_CTX_new and EVP_CipherInit Especially with OpenSSL 3, it is possible that EVP_CipherInit may fail even when passed a non-null cipher[1]. Without the checking, it will finally get to a segfault. [1] https://github.com/openssl/openssl/issues/16864 * Automatically load default and legacy providers with OpenSSL 3 Without the legacy provider [1], some ciphers are not available. For example, the 'des-ecb' one used by test sutie is missed and the test will fail. [1] OSSL_PROVIDER-LEGACY(7ossl) * Make p12 ca order the same as pem OpenSSL < 3 returns p12 ca order in reversed order. This is fixed in OpenSSL 3. We work around it with old OpenSSL. See: https://github.com/openssl/openssl/issues/16421 https://github.com/openssl/openssl/pull/12641 https://github.com/jeroen/openssl/commit/f5eb85eb0fd432406a24abda6511c449eaee6162 * Implement SSL abort handling on OpenSSL 3 On an unexpected EOF, versions before OpenSSL 3.0 returned SSL_ERROR_SYSCALL, nothing was added to the error stack, and errno was 0. Since OpenSSL 3.0 the returned error is SSL_ERROR_SSL with a meaningful error on the error stack.[1] [1] SSL_GET_ERROR(3ossl) Co-authored-by: Günter Obiltschnig Co-authored-by: Robin Lee Co-authored-by: Aleksandar Fabijanic * fix(Socket): shutdown fixes from pull #3448 * #3500: Sandbox all iFrames in PocoDoc * #3549; replace assert with assertTrue * #3553: Upgrade bundled zlib to 1.2.12 * #3525: Bad management of file in case of OpenSSLException in X509Certificate::readPEM and X509Certificate::writePEM * disable OpenSSL deprecation warnings * chore: cleanup * fix(X509Certificate): add missing string format * #3559: Poco::Data::PostgreSQL - DateTime extraction truncates fractional seconds * feat(EVP): 3.0 support - add EVPCipher - additional EVPPKey constructors - tests - fix and improve openssl-related exceptions Transition towards 3.0 support; deprecating direct EC and RSA interface portions. * fix(openssl): pre 3.0 compile * feat(Envelope): Add envelope to crypto #3561 * fix(Envelope): mac/clang compile * fix(Any): #3297 #3514 * #3562: fixed OpenSSL setup/shutdown * fix exception text * #3563: Remove support for OpenSSL < 1.0 * ci jobs for OpenSSL 1.1 and 3 * updated CHANGELOG * updated .vscode * Refactor/any soo (#3564) * refactor(Any): SOO - encapsulate data holders - add missing gets and ops - eliminate g++ warnings with enable_if's - default enable SOO * refactor(Placeholder): encapsulate SOO memory management and fix leaks; cf. #3297 #3514 * fix(Placeholder): asan errors and add tests cf. #3297 #3514 * fix(SSLManager): Race condition in SSLManager #3558 * remove unused include * updated copyright date * PocoDoc: fix iframe sandboxing * fix(SHA2Engine): cannot use HMACEngine with SHA2Engine #3421 * refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remove it anywhere else (#3566) * refactor(Placeholder): more SOO consolidation and optimization * fix(FPEnvironment): Visual Studio Warning C4244 #3543 * fix(Extractor): move extraction decoding to AbstractExtractor #3396 * Netssl/openssl3 (#3575) * feat(Context): DH init openssl3 port (1/2 hardcoded params) * create poco-1.11.3 branch, bump version * update copyright date * #3567: check legacy provider existence for legacy exception #3567 * fix(Placeholder): comparison for zero value * feat(Context): DH init openssl3 port (2/2 params from file) * test(HTTPSClientSession): try/catch to understand CI failure * chore(cmake): copy the DH parameters file * fix(OpenSSLInitializer): unload provider on uninitialize * chore(HTTPSClientSessionTest): remove try/catch * fix(OpenSSLInitializer): fix provider unloading * feat(CppUnit): make tests exceptions more descriptive * chore(CppUnit): a more descriptive name for callback Co-authored-by: Günter Obiltschnig * fix(Foundation): update VS 2019 platform version * chore(Data): update VS project files (add Transcoder #3396) * fix(Data): Poco::Data::ODBC-dbEncoding property not used for insert/update #3396 * fix(Data): add transcoder to Makefile #3396 * fix(JWT): remove duplicate test functions after merge Co-authored-by: Günter Obiltschnig Co-authored-by: Julien Olivain Co-authored-by: Robin Lee Co-authored-by: Robin Lee * #2755: Fix MySQL's LONGBLOB/LONGTEXT not allocating enough space (#3474) * Unit test for bug #2755. * Removed condition to set buffer length to 0. * Fixes to unit tests for LONGBLOB/TEXT data type. * Adjusted buffer sizes to accommodate LONGBLOBs. Co-authored-by: Hector Toledo Soto * fix(Data): MySQL UUID binding temporary string #3587 * feat(CI): add MySQL tests to CI #3588 * fix(CI): remove mysql client dev (using mariadb) #3588 * fix(CI): another shot at mysql * fix(Net/testsuite): add missing include * fix(DatagramSocket): Socket::available does not always return correct value for UDP #3589 * fix(SocketProactor): few improvements (#3357) * fix(ICMPsocketTest): change appinf (doesn't respond to ping) to github * fix(PollSet): windows fixes * fix(PollSet): windows implementation fixes (multi-fd_set select); minor reactor fixes * Extract JSON type as string (#3491) * Declared JSON as string data # Conflicts: # Data/include/Poco/Data/MetaColumn.h # Data/src/RecordSet.cpp # Data/src/StatementImpl.cpp * Added JSON extractor as string * Added unit test * Update comment Co-authored-by: Joerg-Christian Boehme Co-authored-by: Günter Obiltschnig Co-authored-by: tbarbier Co-authored-by: Linquize Co-authored-by: Jan Kevin Dick Co-authored-by: Neelima Patil Co-authored-by: akete Co-authored-by: YuriAzathoth Co-authored-by: Jonathan Horvath Co-authored-by: Maksim Kita Co-authored-by: Alexander Galanin Co-authored-by: Thomas Sablik Co-authored-by: Nikita Migunov Co-authored-by: Ben Wolsieffer Co-authored-by: micheleselea Co-authored-by: Federico Kircheis Co-authored-by: fenghao119 Co-authored-by: Alex Fabijanic Co-authored-by: linquize Co-authored-by: Julien Olivain Co-authored-by: Robin Lee Co-authored-by: Robin Lee Co-authored-by: hectots Co-authored-by: Hector Toledo Soto Co-authored-by: Hernan Martinez * merge pg binary extraction support * set version number to 1.12.0 * updated VS project files * merge pg binary extraction support * updated VS project files * add Prometheus library * fix Makefile * CppUnit: add generic assertEquals * Cell: fix wrong condition when checking for font styles * upgrade bundled sqlite to 3.38.5; fixed a warning in SQLiteTest.cpp * fix(IPAddress): IPAddress::isLoopback() returns false for IPv4 mapped in IPv6 #3399 * Fixes from develop experimental (on top of 1.11.2) (#3017) * MongoDB::PooledConnection: Prevent unwanted release by disabling copy semantics. Enabled move semantics for C++11. * Construct MongoDB::Cursor from aggragation cursor. * Added function to get OS-specific numerical thread ID and %J pattern to use numerical OS thread id in pattern formatter. Co-authored-by: Tomaz Beltram * fix(SharedLibrary): SharedLibrary::isLoaded() not thread safe #3175 * fix(Task): Task::postNotification possible leak #3240 * fix(Platform): Poco errors with _DEBUG and NDEBUG #3039 * feat(HTTPClientSession): HTTPClientSession source IP address #2271 * feat(samples): add SetSourceIP #2271 * chore(samples): add/fix VS project/solution files #2271 * fix(HTTPClientSession): broken proxy tests #2271 * fix(JSON): Arbitrary indent of 2 applied to JSON string objects Var conversion #3253 * feat(Data): Add JSONRowFormatter #3602 * #3405 #3482 #3485 * Update minimum GCC version information (#3603) Changed in 1.10.0 Release Content modification based on minimum compiler version upgrade (C++14) * cleanup Data transcode test * Add ARM64 to ProGen for vs170 (#3606) * Updated project properties and templates * Added ARM64 templates * Added ARM64 library suffixes * Fix VS2022 TargetMachine property when targeting ARM64 * Add missing changes from zlib update (#3601) * Add --ldflags configure option (#3545) * updated README.md * Create close-inactive-issues.yml * Add --ldflags configure option Add --ldflags configure option to allow the user to provide additional flags to the linker such as -latomic. This will avoid the following build failure with ActiveRecord on sparc v8: /home/peko/autobuild/instance-1/output-1/host/opt/ext-toolchain/bin/../lib/gcc/sparc-buildroot-linux-uclibc/10.3.0/../../../../sparc-buildroot-linux-uclibc/bin/ld: /home/peko/autobuild/instance-1/output-1/build/poco-1.11.1/ActiveRecord/Compiler/obj/Linux/sparc/release_shared/Compiler.o: in function `Poco::RefCountedObject::release() const': Compiler.cpp:(.text._ZNK4Poco16RefCountedObject7releaseEv[_ZNK4Poco16RefCountedObject7releaseEv]+0xc): undefined reference to `__atomic_fetch_sub_4' Fixes: - http://autobuild.buildroot.org/results/b01/b014d6fcb8fdf28984d7ce606db2347b0265bc6a/build-end.log Signed-off-by: Fabrice Fontaine Co-authored-by: Günter Obiltschnig Co-authored-by: Aleksandar Fabijanic * chore(ci): remove close-inactive-issues.yml * Readded named substring support for regexes (#3569) Original merged PR #952 was merged in 2015, but has gone missing. This is adding it back in. * Use transaction_isolation in MySQL 8+ (#3490) * Use transaction_isolation in MySQL 8+ * Trim buffer before comparison * Added LocalConfigurationView to only search inside the viewed scope (#3529) * chore(testsuite): fix testsuite Makefile * fix(Foundation): remove SDK version from VS 2022 project #3605 * fix(SocketReactor): Poco::Net::SocketConnector unregistering #2513 * devel-release-1.12.0 (#3673) * Fix percent-encoded fragment modification in Poco::URI Before this commit using Poco::URI class to parse specific URIs that had percent-encoded fragment identifier resulted in the loss of information concerning the way the fragment identifier was encoded. There could be the cases when the result of Poco::URI object serialization to string did not match the original URI string Poco::URI object was created from. In this commit we change the internal logic of fragment processing in Poco::URI, so that the fragment is stored inside the class in raw form (the same way as query string). The methods getFragment and setFragment work the old way (with percent-decoded fragment values), new methods getRawFragment and setRawFragment are added to get access to the original fragment representation. * Remove SDK version from VS2022 test projects (#3607) * Remaining changes for Windows on ARM64 support (#3608) * Add ARM64 to Foundation * Changed lib, and bin folders of ARM64 builds * Updated buildwin.cmd * Added missing closing tags (#3610) * feat(Platform): LoongArch support #3460 * fix(PollSet): default enable epoll on linux * default disable new state on move * fix(UDPHandler): data race #3613; clean up all Net tsan warnings * ProGen vs170 projects with Win32,x64,ARM64 (#3612) * fix(TCPServer): #1884 #1965 * fix(LogFile): LogFile_STD (LogFileImpl) fails to recover from getting out of space #2084 * Avoid clang 10 -Wimplicit-int-float-conversion warning/error when converting int into float (#2943) Example of warning (error when using -Werror) we get with clang 10: /remote/intdeliv/components/osp/Poco/Foundation/19-0-0-6/include/Poco/Dynamic/VarHolder.h:444:14: error: implicit conversion from 'int' to 'float' changes value from 2147483647 to 2147483648 [-Werror,-Wimplicit-int-float-conversion] if (from > std::numeric_limits::max()) ~ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /remote/intdeliv/components/osp/Poco/Foundation/19-0-0-6/include/Poco/Dynamic/VarHolder.h:332:4: note: in instantiation of function template specialization 'Poco::Dynamic::VarHolder::checkUpperLimitFloat' requested here checkUpperLimitFloat(from); ^ /remote/intdeliv/components/osp/Poco/Foundation/19-0-0-6/include/Poco/Dynamic/VarHolder.h:2175:3: note: in instantiation of function template specialization 'Poco::Dynamic::VarHolder::convertToSmaller' requested here convertToSmaller(_val, val); ^ * chore(ci): run ci on pull requests * #2569: Added TIMESTAMP data type support on MySQL (#3471) * Unit test for TIMESTAMP data type in MySQL. * Added support for TIMESTAMP data type. Co-authored-by: Hector Toledo Soto * MongoDB::Array: int --> size_t in get for consistency with size(), new helper functions to add elements to an array. (#3016) * fix(CppUnit): enable_if disarm numeric notEqualsMessage * fix(CppUnit): CppUnit notEqualsMessage causing compile errors #3615 * Syslog: Include Facility to Syslog Message (#3452) * Fixed indentation * Added Facility to Message in RemoteSyslogListener * Net: make MessageHeader limits configurable (#3404) * Add Message::getAll (#3104) * chore(Message): fix formatting for #3104 * Output to stderr in Poco::WindowsConsoleChannel (#3058) - Fixes #3056 * HTTPDigestCredentials added support for RFC7616 algorithms (#3026) * chore(SHA2Engine): fix formatting for #3026 * Added support for SQLite transaction types using Session property (#3018) * chore(SQLite): fix enum names case for #3018 * fix(HTTPResponse): Add 425 / HTTP_TOO_EARLY to HTTPResponse::HTTPStatus #3592 * fix(SQLite): windows build (global var does not link) #3018 * Added missing SocketProactor class to ProGen source (#3616) * Added missing SocketProactor class to ProGen source * ProGen'd VS2022 Net project * chore(Net): regenerate VS 140,150,160 projects #3614 * Handle MariaDB JSON columns since they are stored as `longtext` (#3621) * Also extract BLOBs when reading longtext columns as std::string * Fix error message in unit test * Added unit test to read longtext columns as std::string * Use `tx_isolation` when connected to MariaDB regardless of version (#3622) * Use `tx_isolation` when connected to MariaDB regardless of version * Rename variable * Handle MariaDB server info in the middle of the string * Updated to PCRE version 8.45 (#3623) * Add missing changes from zlib update * Updated to PCRE version 8.45 Build on Win32 and Linux, RegularExpressionTest was successful * Fix/tsan (#3617) * fix(Foundation): tsan warnings fixes * fix(Thread_POSIX): tsan warnings fixes; add tsan.suppress * fix(Util): tsan fixes * fix(netSSL_OpenSSL): tsan fixes * fix(Data): tsan warnings fixes * feat(ci): add tsan job * feat(ci): add tsan job, another attempt * feat(ci): add tsan job, 3rd attempt * fix(Foundation): tsan warnings fixes * fix(Thread_POSIX): tsan warnings fixes; add tsan.suppress * fix(Util): tsan fixes * fix(netSSL_OpenSSL): tsan fixes * fix(Data): tsan warnings fixes * feat(ci): add tsan job * feat(ci): add tsan job, another attempt * feat(ci): add tsan job, 3rd attempt * fix(ResultMetadata): memory leak #3474 * feat(ci): disable ActiveDispatcher tests for tsan runs * feat(ci): try to fix tsan options file detection (again) * chore(TestLibrary: correct spelling * fix(ci): fix tsan run; add -y to apt; disable samples build for some jobs * fix(ci): add mysql ports * feat(ci): add VS asan * feat(double-conversion): Upgrade double-conversion to v3.2.0 #3624 * chore(asan): disable msvc asan build (dll not found) * chore(double-conversion): move NumericString.h before double-conversion includes to prevent min/max collision; reinstate lost loongarch64 * chore(JSON): sync pdjson with upstream * fix(Statement): Poco::Data::Statement becomes unusable after exception #2287 * added facility to SyslogChannel (#3453) * TCPServerDispatcher.h: missing (#2961) Fixes: b8af168151fe0147fb06557029002ae226dcc549 Fixes: #1965 * Windows embedded OpenSSL: Fixed bogus warning during compilation (External OpenSSL defined but internal headers used - possible mismatch!) (#3627) * fix(double-conversion): nios2 and riscv defines * fix(double-conversion): riscv defines * fix(cmake): TestLibrary debug postfix * fix(cmake): add WebNotifier to samples #3184 * doc(Crypto): Fix error in find_package example #3088 * fix(Event): Event data race #3629 * fix(AsyncChannel): race condition in AsyncChannel close/log #1039 * fix(Zip): Zip 64-bit extensions not set #2590 (tentative) (#3604) * PocoDoc: fix handling of font-style tags if tag is immediately followed by punctuation * Static code analyzer warnings #2688 * MinGW: fatal error: kernelspecs.h: No such file #2691 * Poco::Data::SessionPool change connection timeout #3241 * Makefile: space(s) following target name will break build (during link) #3062 * json format PrintHandler #2678 * indicate compiler that functions will never return (#3639) * fix warning C4717: 'format >': recursive on all control paths, function will cause runtime stack overflow * keep origin format. * fix(format): scope * fix(Crypto): libPocoCrypto.so: undefined reference to pthread_atfork when linking statically with OpenSSL 1.1 #3073 * chore(LocalConfigurationView): fix style #3529 * fix(ConfigurationView): ConfigurationView and JSON is broken for array access #3635 * FifoBuffer.advance method not throw exception when length==0 (#3641) * fifobuffer not throw error when length = 0 * Update FIFOBuffer.h fix indentation Co-authored-by: Aleksandar Fabijanic * fix(URI): Decoding URI query parameters ( ::getQueryParameters) incompatible with Spring 5 #2619 * fix(NTPClient): NTPClient ignores second fractions #2614 * chore(JSON): add test for #2612 * fix(Platform): MinGW also defines __GNUC__. #3195 * Fix some clang 10 -Wsign-compare warnings (#2960) In file included from /data/mwrep/res/osp/Poco/JSON/20-0-0-0/include/Poco/JSON/Object.h:22: In file included from /data/mwrep/res/osp/Poco/JSON/20-0-0-0/include/Poco/JSON/Array.h:23: In file included from /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/Dynamic/Var.h:26: In file included from /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/Dynamic/VarHolder.h:22: In file included from /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/NumberFormatter.h:22: /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/NumericString.h:220:31: error: comparison of integers of different signs: 'unsigned long' and 'char' [-Werror,-Wsign-compare] if ((limitCheck - result) < add) return false; ~~~~~~~~~~~~~~~~~~~ ^ ~~~ /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/NumericString.h:229:31: error: comparison of integers of different signs: 'unsigned long' and 'char' [-Werror,-Wsign-compare] if ((limitCheck - result) < add) return false; ~~~~~~~~~~~~~~~~~~~ ^ ~~~ /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/NumericString.h:240:31: error: comparison of integers of different signs: 'unsigned long' and 'char' [-Werror,-Wsign-compare] if ((limitCheck - result) < add) return false; ~~~~~~~~~~~~~~~~~~~ ^ ~~~ /data/mwrep/res/osp/Poco/Foundation/20-0-0-0/include/Poco/NumericString.h:249:31: error: comparison of integers of different signs: 'unsigned long' and 'char' [-Werror,-Wsign-compare] if ((limitCheck - result) < add) return false; ~~~~~~~~~~~~~~~~~~~ ^ ~~~ 4 errors generated. * chore(README): Add vcpkg installation instructions #2940 * fix(SQLite): SQLite::Connector::open() crashes on db file with non existing directory #2285 * fix(MailMessage): read hangs on missing final multipart boundary #2401 * fix(NumberParser): Rounds very large negative numbers to the incorrect values #3580 * fix(JSON::Stringifier): JSON Serializing NAN #3251 * feat(Timespan): Add std::chrono support #2576 #2623 * fix(strToInt): overflows #3580 * fix(strToInt): thousand separator regression #3580 * fix(MySQL::Extractor): MySQL Extractor #2521 * feat(FTPClientSession): activeDataConnection 1.11.0 cannot set specific data port #3372 * feat(Cipher): No access to padding in Cipher #3374 * feat(TypeHandler): DB into() does not compile for more than 20 members in a tuple #3342 * fix(NumberFormatter): Negative precision in NumberFormatter::format() #2511 * Make ParallelSocketReactor thread namable (#3642) make ParallelSocketReactor thread namable * fix(Redis): Poco::Redis after executing auth command next command always return OK #2457 * chore(NumberParserTest): add test for #2441 * avoid clang tidy warning (#3646) * Revert "avoid clang tidy warning (#3646)" (#3648) This reverts commit b23488d6feab13645ce306fd02fd50635f54b25f. * fix(VarHolder): limits check * As of C++11, std::swap is noexcept. #2386 (#3645) * As of C++11, std::swap is noexcept. #2386 * fix(Any): remove throw on swap * fix(Any): As of C++11, std::swap is noexcept. #2386 * fix(Any): make size const #2386 * fix(SimpleRowFormatter): clang won't compile noexcept #2386 * a couple of arm fixes * fix(Any): As of C++11, std::swap is noexcept. #2386 * fix(AnyTest): local() for POCO_NO_SOO# 2386 * test(RSACipher): RSA encryption without private key #2367 * chore(RSACipherTest): delete ciphers #2367 * add separate accessors and mutators for connect, send and receive tim… (#3476) * add separate accessors and mutators for connect, send and receive timeouts * implement timeout methods outside of class declaration to conform to existing code structure * Update HTTPSession.h Co-authored-by: bfoster Co-authored-by: Aleksandar Fabijanic * Make poll set interruptable (#3644) * Make poll set interruptable * open test for poll set * fix poll set wake up test * fix build error * feat(SecureSocketImpl): how to set the socket of SecureSocketImpl to no-blocking? #2352 * better socket reactor wake up (#3647) * better socket reactor wake up * Remove documentation comment from source file Co-authored-by: Aleksandar Fabijanic * test(MailMesage): MailMessage::read() chokes on Content-disposition #3650 * chore(Net/samples): tcpserver missing from Net/samples/CMakeLists.txt #3651 * fix(CMake): Linking with Foundation on Android gives error #3652 #3653 * #2821: Poco::Buffer: full on creation? - add documentation describing the behavior. * add note regarding receiveFrame with Poco::Buffer * merge changes from 1.11.3 * #3633: Redis: Support Authentication * #3658: Support for chunked transfer encoding trailer * formatHex with lower case (#3657) * feat(Socket): add lastErrorDesc() * fix(Socket): Socket::select EPOLL implementation returns socket in exceptList when empty list is given #3655; mark select as deprecated #1459 * Fix/poll set race (#3630) * fix(PollSet): PollSet data race #3628 * fix(SocketConnector): SocketConnector test #2875 * fix(PollSet): optimize the amount of locked code; fix and simplify wakeUp logic * fix(SocketConnectorTest): fix test memleak (data not flowing, handlers not deleted) #2875 * fix(PollSet): clear() and tests * fix(PollSet): #1459 #3628 #3655 #3661 * fix(PollSet): Integrate windows epoll #2091, #3649 * chore(ProGen): MSVC does not properly recognize std version #3665 * fix(PollSet): eventfd call arg; add wepoll to CMakelists.txt * fix(PollSet): CMakelists.txt * fix(cmake): MSVC does not properly recognize std version #3665 * chore(vscode): add mac config * fix(PollSet): PollSet::add()/update() semantics #3661 * Feat/pcre2 (#3663) * upgrade to pcre2 * use pcre2_*_8 names * fix pcre2 lib name for unbundled build * CMake changes for PCRE2 * add missing macro for unbundled build * add PCRE2_STATIC * updated VS project files for pcre2 Co-authored-by: Günter Obiltschnig * Revert "formatHex with lower case (#3657)" (#3670) This reverts commit b1823b61c0902252d1e15e8a7175f40e31a865b2. * Always set thread names on POSIX platforms (#3384) * chore: gitignore vim .swp files * feat(POSIX): Always set thread names. I'm not sure about the original intent to hide it under a DEBUG macro. Naming the threads in release mode makes it easier to see runtime application and know which thread pool uses how many threads and what their names are. Firefox, Chromium and many other apps do this on Linux. * Remove trailing whitespace (#3668) * doc: update CHANGLEOG Co-authored-by: Daniil Zotkin Co-authored-by: Hernan Martinez Co-authored-by: Romain Geissler @ Amadeus Co-authored-by: hectots Co-authored-by: Hector Toledo Soto Co-authored-by: Matej Kenda Co-authored-by: BeBinder <93721965+BeBinder@users.noreply.github.com> Co-authored-by: Tavi Cacina Co-authored-by: Mathieu Stefani Co-authored-by: Fritz Elfert Co-authored-by: Maksim Kita Co-authored-by: Spaky Co-authored-by: Azat Khuzhin Co-authored-by: Matej Kenda Co-authored-by: Günter Obiltschnig Co-authored-by: Guillermo Frontera Co-authored-by: junwufan Co-authored-by: JackyWoo Co-authored-by: Ben Foster Co-authored-by: bfoster Co-authored-by: Arun Chandrasekaran Co-authored-by: John Vandenberg Co-authored-by: Günter Obiltschnig Co-authored-by: tbarbier Co-authored-by: Linquize Co-authored-by: Jan Kevin Dick Co-authored-by: Neelima Patil Co-authored-by: akete Co-authored-by: YuriAzathoth Co-authored-by: Jonathan Horvath Co-authored-by: Maksim Kita Co-authored-by: Alexander Galanin Co-authored-by: Thomas Sablik Co-authored-by: Nikita Migunov Co-authored-by: Ben Wolsieffer Co-authored-by: micheleselea Co-authored-by: Federico Kircheis Co-authored-by: fenghao119 Co-authored-by: Alex Fabijanic Co-authored-by: linquize Co-authored-by: Robin Lee Co-authored-by: Robin Lee Co-authored-by: Julien Olivain Co-authored-by: hectots Co-authored-by: Hector Toledo Soto Co-authored-by: Hernan Martinez Co-authored-by: Joerg-Christian Boehme Co-authored-by: Matej Kenda Co-authored-by: Tomaz Beltram Co-authored-by: Byungjun Lee <40881444+OneTop4458@users.noreply.github.com> Co-authored-by: Spaky Co-authored-by: Fabrice Fontaine Co-authored-by: cesar Co-authored-by: Kevin Dick Co-authored-by: Daniil Zotkin Co-authored-by: Romain Geissler @ Amadeus Co-authored-by: Matej Kenda Co-authored-by: BeBinder <93721965+BeBinder@users.noreply.github.com> Co-authored-by: Tavi Cacina Co-authored-by: Mathieu Stefani Co-authored-by: Fritz Elfert Co-authored-by: Azat Khuzhin Co-authored-by: Guillermo Frontera Co-authored-by: junwufan Co-authored-by: JackyWoo Co-authored-by: Ben Foster Co-authored-by: bfoster Co-authored-by: Arun Chandrasekaran Co-authored-by: John Vandenberg --- .github/workflows/ci.yml | 74 +- .gitignore | 7 + .vscode/c_cpp_properties.json | 136 +- .vscode/settings.json | 15 +- ActiveRecord/ActiveRecord_vs170.sln | 60 + ActiveRecord/ActiveRecord_vs170.vcxproj | 271 +- ActiveRecord/Compiler/Compiler.progen | 2 +- ActiveRecord/Compiler/Compiler_vs170.sln | 24 + ActiveRecord/Compiler/Compiler_vs170.vcxproj | 294 +- .../testsuite/TestSuite_vs170.vcxproj | 296 +- ApacheConnector/ApacheConnector_vs170.sln | 8 + ApacheConnector/ApacheConnector_vs170.vcxproj | 105 +- ApacheConnector/CMakeLists.txt | 2 +- .../doc/ApacheConnectorUserGuide.page | 32 +- ApacheConnector/include/ApacheConnector.h | 2 +- .../include/ApacheRequestHandlerFactory.h | 2 +- ApacheConnector/include/ApacheServerRequest.h | 12 +- .../include/ApacheServerResponse.h | 20 +- ApacheConnector/include/ApacheStream.h | 8 +- .../samples/FormServer/src/FormServer.cpp | 22 +- .../samples/TimeServer/src/TimeServer.cpp | 4 +- ApacheConnector/src/ApacheApplication.cpp | 2 +- .../src/ApacheRequestHandlerFactory.cpp | 4 +- ApacheConnector/src/ApacheServerRequest.cpp | 8 +- ApacheConnector/src/ApacheServerResponse.cpp | 6 +- ApacheConnector/src/ApacheStream.cpp | 2 +- CHANGELOG | 128 + CMakeLists.txt | 28 +- CppParser/CMakeLists.txt | 2 +- CppParser/CppParser_vs170.sln | 42 + CppParser/CppParser_vs170.vcxproj | 271 +- CppParser/include/Poco/CppParser/Attributes.h | 22 +- .../include/Poco/CppParser/AttributesParser.h | 6 +- CppParser/include/Poco/CppParser/Function.h | 34 +- CppParser/include/Poco/CppParser/NameSpace.h | 32 +- CppParser/include/Poco/CppParser/Parser.h | 2 +- CppParser/include/Poco/CppParser/Struct.h | 32 +- CppParser/include/Poco/CppParser/Utility.h | 4 +- CppParser/include/Poco/CppParser/Variable.h | 6 +- CppParser/src/Attributes.cpp | 8 +- CppParser/src/AttributesParser.cpp | 4 +- CppParser/src/Function.cpp | 8 +- CppParser/src/NameSpace.cpp | 24 +- CppParser/src/Struct.cpp | 4 +- CppParser/src/Tokenizer.cpp | 2 +- CppParser/src/Utility.cpp | 8 +- CppParser/src/Variable.cpp | 6 +- CppParser/testsuite/TestSuite_vs170.vcxproj | 296 +- CppUnit/CMakeLists.txt | 7 +- CppUnit/CppUnit_vs140.vcxproj | 1 - CppUnit/CppUnit_vs150.vcxproj | 1 - CppUnit/CppUnit_vs160.vcxproj | 1 - CppUnit/CppUnit_vs170.sln | 24 + CppUnit/CppUnit_vs170.vcxproj | 267 +- CppUnit/doc/README.html | 8 +- CppUnit/doc/cookbook.htm | 6 +- CppUnit/include/CppUnit/CppUnitException.h | 12 +- CppUnit/include/CppUnit/Orthodox.h | 8 +- CppUnit/include/CppUnit/RepeatedTest.h | 4 +- CppUnit/include/CppUnit/Test.h | 11 +- CppUnit/include/CppUnit/TestCase.h | 30 +- CppUnit/include/CppUnit/TestDecorator.h | 2 +- CppUnit/include/CppUnit/TestFailure.h | 2 +- CppUnit/include/CppUnit/TestResult.h | 32 +- CppUnit/include/CppUnit/TestRunner.h | 20 +- CppUnit/include/CppUnit/TestSetup.h | 10 +- CppUnit/include/CppUnit/TestSuite.h | 6 +- CppUnit/include/CppUnit/TextTestResult.h | 2 +- CppUnit/include/CppUnit/estring.h | 20 +- CppUnit/src/TestCase.cpp | 35 +- CppUnit/src/TestDecorator.cpp | 2 +- CppUnit/src/TestRunner.cpp | 4 +- CppUnit/src/TestSuite.cpp | 6 +- Crypto/CMakeLists.txt | 2 +- Crypto/Crypto_vs170.sln | 42 + Crypto/Crypto_vs170.vcxproj | 273 +- Crypto/Makefile | 10 +- Crypto/include/Poco/Crypto/Cipher.h | 8 +- Crypto/include/Poco/Crypto/CipherFactory.h | 11 +- Crypto/include/Poco/Crypto/Crypto.h | 15 + Crypto/include/Poco/Crypto/DigestEngine.h | 8 +- Crypto/include/Poco/Crypto/ECKey.h | 1 + Crypto/include/Poco/Crypto/ECKeyImpl.h | 6 +- Crypto/include/Poco/Crypto/EVPCipherImpl.h | 76 + Crypto/include/Poco/Crypto/EVPPKey.h | 83 +- Crypto/include/Poco/Crypto/Envelope.h | 174 + Crypto/include/Poco/Crypto/KeyPairImpl.h | 2 +- .../include/Poco/Crypto/OpenSSLInitializer.h | 5 +- Crypto/include/Poco/Crypto/RSADigestEngine.h | 10 +- Crypto/include/Poco/Crypto/RSAKey.h | 3 +- Crypto/include/Poco/Crypto/RSAKeyImpl.h | 10 +- Crypto/include/Poco/Crypto/X509Certificate.h | 2 +- Crypto/samples/genrsakey/src/genrsakey.cpp | 24 +- Crypto/src/Cipher.cpp | 20 +- Crypto/src/CipherFactory.cpp | 14 + Crypto/src/CryptoTransform.cpp | 2 +- Crypto/src/DigestEngine.cpp | 8 +- Crypto/src/EVPCipherImpl.cpp | 310 + Crypto/src/EVPPKey.cpp | 233 +- Crypto/src/Envelope.cpp | 159 + Crypto/src/OpenSSLInitializer.cpp | 16 +- Crypto/src/PKCS12Container.cpp | 8 +- Crypto/src/RSADigestEngine.cpp | 4 +- Crypto/src/X509Certificate.cpp | 2 +- Crypto/testsuite/Makefile | 3 +- Crypto/testsuite/TestSuite_vs170.vcxproj | 296 +- Crypto/testsuite/src/CryptoTestSuite.cpp | 2 + Crypto/testsuite/src/DigestEngineTest.cpp | 2 +- Crypto/testsuite/src/Driver.cpp | 8 +- Crypto/testsuite/src/EVPTest.cpp | 182 + Crypto/testsuite/src/EVPTest.h | 10 + Crypto/testsuite/src/EnvelopeTest.cpp | 147 + Crypto/testsuite/src/EnvelopeTest.h | 41 + Crypto/testsuite/src/PKCS12ContainerTest.h | 5 +- Crypto/testsuite/src/RSATest.cpp | 34 +- Crypto/testsuite/src/WinCEDriver.cpp | 4 +- Crypto/testsuite/src/WinDriver.cpp | 2 +- DLLVersion.rc | 4 +- Data/CMakeLists.txt | 2 +- Data/Data_VS90.vcproj | 16 + Data/Data_vs140.vcxproj | 8 +- Data/Data_vs140.vcxproj.filters | 24 +- Data/Data_vs150.vcxproj | 6 +- Data/Data_vs150.vcxproj.filters | 24 +- Data/Data_vs160.vcxproj | 10 +- Data/Data_vs160.vcxproj.filters | 30 +- Data/Data_vs170.sln | 42 + Data/Data_vs170.vcxproj | 279 +- Data/Data_vs170.vcxproj.filters | 24 +- Data/Makefile | 6 +- Data/MySQL/CMakeLists.txt | 2 +- Data/MySQL/MySQL_vs170.sln | 42 + Data/MySQL/MySQL_vs170.vcxproj | 271 +- .../MySQL/include/Poco/Data/MySQL/Connector.h | 2 +- .../MySQL/include/Poco/Data/MySQL/Extractor.h | 4 + .../Poco/Data/MySQL/MySQLStatementImpl.h | 20 +- .../include/Poco/Data/MySQL/ResultMetadata.h | 10 +- Data/MySQL/src/Extractor.cpp | 47 +- Data/MySQL/src/ResultMetadata.cpp | 73 +- Data/MySQL/src/SessionImpl.cpp | 24 +- Data/MySQL/testsuite/TestSuite_vs170.vcxproj | 296 +- Data/MySQL/testsuite/run-db-setup.sh | 15 + Data/MySQL/testsuite/src/MySQLTest.cpp | 57 + Data/MySQL/testsuite/src/MySQLTest.h | 6 + Data/MySQL/testsuite/src/SQLExecutor.cpp | 104 + Data/MySQL/testsuite/src/SQLExecutor.h | 4 + Data/ODBC/CMakeLists.txt | 2 +- Data/ODBC/Makefile | 2 +- Data/ODBC/ODBC_vs170.sln | 42 + Data/ODBC/ODBC_vs170.vcxproj | 285 +- Data/ODBC/include/Poco/Data/ODBC/Binder.h | 37 +- Data/ODBC/include/Poco/Data/ODBC/Connector.h | 2 +- .../ODBC/include/Poco/Data/ODBC/Diagnostics.h | 58 +- Data/ODBC/include/Poco/Data/ODBC/Error.h | 6 +- Data/ODBC/include/Poco/Data/ODBC/Extractor.h | 12 +- Data/ODBC/include/Poco/Data/ODBC/Handle.h | 10 +- .../include/Poco/Data/ODBC/ODBCMetaColumn.h | 10 +- .../Poco/Data/ODBC/ODBCStatementImpl.h | 14 +- Data/ODBC/include/Poco/Data/ODBC/Parameter.h | 6 +- .../ODBC/include/Poco/Data/ODBC/SessionImpl.h | 16 +- Data/ODBC/include/Poco/Data/ODBC/TypeInfo.h | 8 +- .../include/Poco/Data/ODBC/Unicode_WIN32.h | 4 +- Data/ODBC/src/Binder.cpp | 62 +- Data/ODBC/src/ConnectionHandle.cpp | 19 +- Data/ODBC/src/EnvironmentHandle.cpp | 17 +- Data/ODBC/src/Extractor.cpp | 14 +- Data/ODBC/src/ODBCStatementImpl.cpp | 6 +- Data/ODBC/src/Parameter.cpp | 10 +- Data/ODBC/src/SessionImpl.cpp | 38 +- Data/ODBC/src/TypeInfo.cpp | 46 +- Data/ODBC/src/Unicode_UNIXODBC.cpp | 36 +- Data/ODBC/src/Unicode_WIN32.cpp | 32 +- Data/ODBC/src/Utility.cpp | 12 +- Data/ODBC/testsuite/TestSuite_vs170.vcxproj | 296 +- Data/ODBC/testsuite/src/ODBCAccessTest.cpp | 8 +- Data/ODBC/testsuite/src/ODBCAccessTest.h | 2 +- Data/ODBC/testsuite/src/ODBCDB2Test.cpp | 40 +- Data/ODBC/testsuite/src/ODBCDB2Test.h | 2 +- Data/ODBC/testsuite/src/ODBCMySQLTest.cpp | 24 +- Data/ODBC/testsuite/src/ODBCMySQLTest.h | 6 +- Data/ODBC/testsuite/src/ODBCOracleTest.cpp | 80 +- Data/ODBC/testsuite/src/ODBCOracleTest.h | 6 +- .../ODBC/testsuite/src/ODBCPostgreSQLTest.cpp | 46 +- Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h | 10 +- Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp | 63 +- Data/ODBC/testsuite/src/ODBCSQLServerTest.h | 6 +- Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp | 24 +- Data/ODBC/testsuite/src/ODBCSQLiteTest.h | 2 +- Data/ODBC/testsuite/src/ODBCTest.cpp | 73 +- Data/ODBC/testsuite/src/ODBCTest.h | 113 +- Data/ODBC/testsuite/src/ODBCTestSuite.cpp | 10 +- Data/ODBC/testsuite/src/SQLExecutor.cpp | 561 +- Data/ODBC/testsuite/src/SQLExecutor.h | 162 +- Data/PostgreSQL/CMakeLists.txt | 2 +- Data/PostgreSQL/Makefile | 2 +- Data/PostgreSQL/PostgreSQL_VS90.vcproj | 8 + Data/PostgreSQL/PostgreSQL_vs140.vcxproj | 4 + .../PostgreSQL_vs140.vcxproj.filters | 6 + Data/PostgreSQL/PostgreSQL_vs150.vcxproj | 4 + .../PostgreSQL_vs150.vcxproj.filters | 6 + Data/PostgreSQL/PostgreSQL_vs160.vcxproj | 4 + .../PostgreSQL_vs160.vcxproj.filters | 6 + Data/PostgreSQL/PostgreSQL_vs170.sln | 42 + Data/PostgreSQL/PostgreSQL_vs170.vcxproj | 275 +- .../PostgreSQL_vs170.vcxproj.filters | 6 + .../Poco/Data/PostgreSQL/BinaryExtractor.h | 346 + .../include/Poco/Data/PostgreSQL/Extractor.h | 9 + .../Data/PostgreSQL/PostgreSQLStatementImpl.h | 4 +- .../Poco/Data/PostgreSQL/PostgreSQLTypes.h | 47 +- .../Poco/Data/PostgreSQL/SessionHandle.h | 3 + .../Poco/Data/PostgreSQL/SessionImpl.h | 22 +- .../Poco/Data/PostgreSQL/StatementExecutor.h | 3 +- Data/PostgreSQL/src/BinaryExtractor.cpp | 1071 + Data/PostgreSQL/src/Extractor.cpp | 59 +- .../src/PostgreSQLStatementImpl.cpp | 10 +- Data/PostgreSQL/src/PostgreSQLTypes.cpp | 2 +- Data/PostgreSQL/src/SessionHandle.cpp | 17 + Data/PostgreSQL/src/SessionImpl.cpp | 15 +- Data/PostgreSQL/src/StatementExecutor.cpp | 8 +- .../testsuite/TestSuite_vs170.vcxproj | 296 +- .../testsuite/src/PostgreSQLTest.cpp | 151 +- .../PostgreSQL/testsuite/src/PostgreSQLTest.h | 13 + Data/SQLite/CMakeLists.txt | 2 +- Data/SQLite/SQLite_vs170.sln | 42 + Data/SQLite/SQLite_vs170.vcxproj | 277 +- .../include/Poco/Data/SQLite/Notifier.h | 22 +- .../Poco/Data/SQLite/SQLiteStatementImpl.h | 2 +- .../include/Poco/Data/SQLite/SessionImpl.h | 27 +- .../SQLite/include/Poco/Data/SQLite/Utility.h | 40 +- Data/SQLite/src/Notifier.cpp | 24 +- Data/SQLite/src/SQLiteStatementImpl.cpp | 4 +- Data/SQLite/src/SessionImpl.cpp | 35 +- Data/SQLite/src/Utility.cpp | 2 + Data/SQLite/src/sqlite3.c | 19794 +++++++++------- Data/SQLite/src/sqlite3.h | 539 +- Data/SQLite/testsuite/TestSuite_vs170.vcxproj | 296 +- Data/SQLite/testsuite/src/SQLiteTest.cpp | 83 +- Data/SQLite/testsuite/src/SQLiteTest.h | 3 + Data/SQLite/testsuite/src/WinCEDriver.cpp | 2 +- Data/doc/00300-DataDeveloperManual.page | 162 +- Data/include/Poco/Data/AbstractBinder.h | 18 +- Data/include/Poco/Data/AbstractBinding.h | 2 +- Data/include/Poco/Data/AbstractExtractor.h | 22 +- Data/include/Poco/Data/AbstractSessionImpl.h | 66 +- Data/include/Poco/Data/ArchiveStrategy.h | 16 +- Data/include/Poco/Data/Binding.h | 194 +- Data/include/Poco/Data/Bulk.h | 16 +- Data/include/Poco/Data/BulkBinding.h | 20 +- Data/include/Poco/Data/BulkExtraction.h | 40 +- Data/include/Poco/Data/Column.h | 50 +- Data/include/Poco/Data/Date.h | 4 +- Data/include/Poco/Data/JSONRowFormatter.h | 159 + Data/include/Poco/Data/LOB.h | 6 +- Data/include/Poco/Data/LOBStream.h | 2 +- Data/include/Poco/Data/Limit.h | 4 +- Data/include/Poco/Data/MetaColumn.h | 3 +- Data/include/Poco/Data/PooledSessionHolder.h | 2 +- Data/include/Poco/Data/PooledSessionImpl.h | 10 +- Data/include/Poco/Data/Position.h | 8 +- Data/include/Poco/Data/Preparation.h | 24 +- Data/include/Poco/Data/Range.h | 8 +- Data/include/Poco/Data/RecordSet.h | 28 +- Data/include/Poco/Data/Row.h | 8 +- Data/include/Poco/Data/RowFilter.h | 2 +- Data/include/Poco/Data/RowFormatter.h | 16 +- Data/include/Poco/Data/RowIterator.h | 2 +- Data/include/Poco/Data/SessionFactory.h | 14 +- Data/include/Poco/Data/SessionPool.h | 45 +- Data/include/Poco/Data/SessionPoolContainer.h | 14 +- Data/include/Poco/Data/SimpleRowFormatter.h | 10 +- Data/include/Poco/Data/Statement.h | 14 +- Data/include/Poco/Data/StatementCreator.h | 10 +- Data/include/Poco/Data/StatementImpl.h | 2 +- Data/include/Poco/Data/Time.h | 4 +- Data/include/Poco/Data/Transaction.h | 24 +- Data/include/Poco/Data/Transcoder.h | 97 + Data/include/Poco/Data/TypeHandler.h | 4090 +++- Data/samples/Binding/src/Binding.cpp | 20 +- Data/samples/CMakeLists.txt | 1 + Data/samples/RecordSet/Makefile | 2 +- Data/samples/RecordSet/src/RecordSet.cpp | 8 +- Data/samples/RowFormatter/Makefile | 2 +- .../samples/RowFormatter/src/RowFormatter.cpp | 22 +- Data/samples/Tuple/Makefile | 2 +- Data/samples/Tuple/src/Tuple.cpp | 14 +- Data/samples/TypeHandler/Makefile | 2 +- Data/samples/TypeHandler/src/TypeHandler.cpp | 32 +- Data/samples/WebNotifier/WebNotifier.html | 30 +- Data/src/AbstractBinder.cpp | 19 +- Data/src/AbstractBinding.cpp | 6 +- Data/src/AbstractExtraction.cpp | 4 +- Data/src/AbstractExtractor.cpp | 19 +- Data/src/ArchiveStrategy.cpp | 14 +- Data/src/Date.cpp | 4 +- Data/src/JSONRowFormatter.cpp | 189 + Data/src/MetaColumn.cpp | 2 +- Data/src/RecordSet.cpp | 1 + Data/src/Row.cpp | 22 +- Data/src/RowFilter.cpp | 6 +- Data/src/RowFormatter.cpp | 8 +- Data/src/RowIterator.cpp | 6 +- Data/src/SQLChannel.cpp | 14 +- Data/src/SessionFactory.cpp | 4 +- Data/src/SessionPool.cpp | 11 +- Data/src/SessionPoolContainer.cpp | 12 +- Data/src/SimpleRowFormatter.cpp | 4 +- Data/src/Statement.cpp | 16 +- Data/src/StatementCreator.cpp | 2 +- Data/src/StatementImpl.cpp | 52 +- Data/src/Time.cpp | 10 +- Data/src/Transaction.cpp | 14 +- Data/src/Transcoder.cpp | 76 + Data/testsuite/TestSuite_vs170.vcxproj | 296 +- Data/testsuite/src/DataTest.cpp | 185 +- Data/testsuite/src/DataTest.h | 10 +- Data/testsuite/src/Extractor.cpp | 8 +- Data/testsuite/src/Extractor.h | 10 +- Data/testsuite/src/SessionImpl.cpp | 18 +- Data/testsuite/src/SessionImpl.h | 5 +- Data/testsuite/src/SessionPoolTest.cpp | 35 +- Data/testsuite/src/StatementImpl.cpp | 2 +- Data/testsuite/src/TestStatementImpl.cpp | 9 +- Data/testsuite/src/TestStatementImpl.h | 9 +- Data/testsuite/src/WinCEDriver.cpp | 2 +- Encodings/CMakeLists.txt | 2 +- Encodings/Compiler/Compiler_vs170.sln | 24 + Encodings/Compiler/Compiler_vs170.vcxproj | 296 +- Encodings/Encodings_vs170.sln | 42 + Encodings/Encodings_vs170.vcxproj | 271 +- Encodings/include/Poco/ISO8859_10Encoding.h | 2 +- Encodings/include/Poco/ISO8859_11Encoding.h | 2 +- Encodings/include/Poco/ISO8859_13Encoding.h | 2 +- Encodings/include/Poco/ISO8859_14Encoding.h | 2 +- Encodings/include/Poco/ISO8859_16Encoding.h | 2 +- Encodings/include/Poco/ISO8859_3Encoding.h | 2 +- Encodings/include/Poco/ISO8859_4Encoding.h | 2 +- Encodings/include/Poco/ISO8859_5Encoding.h | 2 +- Encodings/include/Poco/ISO8859_6Encoding.h | 2 +- Encodings/include/Poco/ISO8859_7Encoding.h | 2 +- Encodings/include/Poco/ISO8859_8Encoding.h | 2 +- Encodings/include/Poco/ISO8859_9Encoding.h | 2 +- .../include/Poco/MacCentralEurRomanEncoding.h | 2 +- .../include/Poco/MacChineseSimpEncoding.h | 2 +- .../include/Poco/MacChineseTradEncoding.h | 2 +- Encodings/include/Poco/MacCyrillicEncoding.h | 2 +- Encodings/include/Poco/MacJapaneseEncoding.h | 2 +- Encodings/include/Poco/MacKoreanEncoding.h | 2 +- Encodings/include/Poco/MacRomanEncoding.h | 2 +- Encodings/include/Poco/Windows1253Encoding.h | 2 +- Encodings/include/Poco/Windows1254Encoding.h | 2 +- Encodings/include/Poco/Windows1255Encoding.h | 2 +- Encodings/include/Poco/Windows1256Encoding.h | 2 +- Encodings/include/Poco/Windows1257Encoding.h | 2 +- Encodings/include/Poco/Windows1258Encoding.h | 2 +- Encodings/include/Poco/Windows874Encoding.h | 2 +- Encodings/include/Poco/Windows932Encoding.h | 2 +- Encodings/include/Poco/Windows936Encoding.h | 2 +- Encodings/include/Poco/Windows949Encoding.h | 2 +- Encodings/include/Poco/Windows950Encoding.h | 2 +- Encodings/src/ISO8859_10Encoding.cpp | 98 +- Encodings/src/ISO8859_11Encoding.cpp | 96 +- Encodings/src/ISO8859_13Encoding.cpp | 98 +- Encodings/src/ISO8859_14Encoding.cpp | 98 +- Encodings/src/ISO8859_16Encoding.cpp | 98 +- Encodings/src/ISO8859_3Encoding.cpp | 98 +- Encodings/src/ISO8859_4Encoding.cpp | 98 +- Encodings/src/ISO8859_5Encoding.cpp | 98 +- Encodings/src/ISO8859_6Encoding.cpp | 88 +- Encodings/src/ISO8859_7Encoding.cpp | 98 +- Encodings/src/ISO8859_8Encoding.cpp | 90 +- Encodings/src/ISO8859_9Encoding.cpp | 98 +- Encodings/src/MacCentralEurRomanEncoding.cpp | 90 +- Encodings/src/MacChineseSimpEncoding.cpp | 3802 +-- Encodings/src/MacChineseTradEncoding.cpp | 6786 +++--- Encodings/src/MacCyrillicEncoding.cpp | 90 +- Encodings/src/MacJapaneseEncoding.cpp | 3646 +-- Encodings/src/MacKoreanEncoding.cpp | 4326 ++-- Encodings/src/MacRomanEncoding.cpp | 90 +- Encodings/src/Windows1253Encoding.cpp | 94 +- Encodings/src/Windows1254Encoding.cpp | 98 +- Encodings/src/Windows1255Encoding.cpp | 94 +- Encodings/src/Windows1256Encoding.cpp | 98 +- Encodings/src/Windows1257Encoding.cpp | 96 +- Encodings/src/Windows1258Encoding.cpp | 96 +- Encodings/src/Windows874Encoding.cpp | 92 +- Encodings/testsuite/TestSuite_vs170.vcxproj | 296 +- Foundation/CMakeLists.txt | 67 +- Foundation/Foundation_vs140.vcxproj | 100 +- Foundation/Foundation_vs140.vcxproj.filters | 192 +- Foundation/Foundation_vs150.vcxproj | 100 +- Foundation/Foundation_vs150.vcxproj.filters | 192 +- Foundation/Foundation_vs160.vcxproj | 106 +- Foundation/Foundation_vs160.vcxproj.filters | 192 +- Foundation/Foundation_vs170.sln | 54 + Foundation/Foundation_vs170.vcxproj | 684 +- Foundation/Foundation_vs170.vcxproj.filters | 192 +- Foundation/Makefile | 14 +- Foundation/include/Poco/ASCIIEncoding.h | 2 +- Foundation/include/Poco/AbstractDelegate.h | 12 +- Foundation/include/Poco/AbstractObserver.h | 2 +- .../include/Poco/AbstractPriorityDelegate.h | 4 +- Foundation/include/Poco/AbstractStrategy.h | 6 +- .../include/Poco/AccessExpirationDecorator.h | 2 +- Foundation/include/Poco/AccessExpireCache.h | 12 +- .../include/Poco/AccessExpireLRUCache.h | 4 +- Foundation/include/Poco/ActiveDispatcher.h | 7 +- Foundation/include/Poco/ActiveMethod.h | 12 +- Foundation/include/Poco/ActiveResult.h | 108 +- Foundation/include/Poco/ActiveStarter.h | 2 +- Foundation/include/Poco/Activity.h | 30 +- Foundation/include/Poco/Any.h | 366 +- Foundation/include/Poco/ArchiveStrategy.h | 16 +- Foundation/include/Poco/Array.h | 4 +- Foundation/include/Poco/Ascii.h | 28 +- Foundation/include/Poco/AsyncChannel.h | 2 + Foundation/include/Poco/AutoPtr.h | 4 +- Foundation/include/Poco/AutoReleasePool.h | 14 +- Foundation/include/Poco/Base32Decoder.h | 16 +- Foundation/include/Poco/Base32Encoder.h | 6 +- Foundation/include/Poco/Base64Decoder.h | 8 +- Foundation/include/Poco/Base64Encoder.h | 2 +- Foundation/include/Poco/BasicEvent.h | 6 +- Foundation/include/Poco/Buffer.h | 17 +- Foundation/include/Poco/BufferAllocator.h | 2 +- .../Poco/BufferedBidirectionalStreamBuf.h | 18 +- Foundation/include/Poco/BufferedStreamBuf.h | 16 +- Foundation/include/Poco/Bugcheck.h | 14 +- Foundation/include/Poco/ByteOrder.h | 2 +- Foundation/include/Poco/Channel.h | 12 +- Foundation/include/Poco/Checksum.h | 12 +- Foundation/include/Poco/ClassLibrary.h | 2 +- Foundation/include/Poco/ClassLoader.h | 18 +- Foundation/include/Poco/Clock.h | 34 +- Foundation/include/Poco/Condition.h | 26 +- Foundation/include/Poco/Config.h | 35 +- Foundation/include/Poco/Configurable.h | 6 +- Foundation/include/Poco/ConsoleChannel.h | 24 +- Foundation/include/Poco/CountingStream.h | 26 +- .../include/Poco/DataURIStreamFactory.h | 2 +- Foundation/include/Poco/DateTime.h | 82 +- Foundation/include/Poco/DateTimeFormat.h | 22 +- Foundation/include/Poco/DateTimeFormatter.h | 8 +- Foundation/include/Poco/DateTimeParser.h | 14 +- Foundation/include/Poco/DefaultStrategy.h | 4 +- Foundation/include/Poco/DeflatingStream.h | 18 +- Foundation/include/Poco/DigestEngine.h | 5 +- Foundation/include/Poco/DigestStream.h | 4 +- Foundation/include/Poco/DirectoryIterator.h | 18 +- .../include/Poco/DirectoryIterator_UNIX.h | 6 +- .../include/Poco/DirectoryIterator_WIN32U.h | 6 +- Foundation/include/Poco/DirectoryWatcher.h | 36 +- Foundation/include/Poco/Dynamic/Pair.h | 2 +- Foundation/include/Poco/Dynamic/Struct.h | 2 +- Foundation/include/Poco/Dynamic/Var.h | 80 +- Foundation/include/Poco/Dynamic/VarHolder.h | 85 +- Foundation/include/Poco/Dynamic/VarIterator.h | 10 +- Foundation/include/Poco/Environment_UNIX.h | 6 +- Foundation/include/Poco/Environment_VX.h | 6 +- Foundation/include/Poco/Environment_WIN32U.h | 6 +- Foundation/include/Poco/Environment_WINCE.h | 12 +- Foundation/include/Poco/ErrorHandler.h | 20 +- Foundation/include/Poco/Event.h | 6 +- Foundation/include/Poco/EventArgs.h | 2 +- Foundation/include/Poco/EventChannel.h | 2 +- Foundation/include/Poco/EventLogChannel.h | 16 +- Foundation/include/Poco/Event_POSIX.h | 17 +- Foundation/include/Poco/Event_VX.h | 4 +- Foundation/include/Poco/Event_WIN32.h | 8 +- Foundation/include/Poco/Exception.h | 18 +- Foundation/include/Poco/ExpirationDecorator.h | 2 +- Foundation/include/Poco/Expire.h | 16 +- Foundation/include/Poco/ExpireCache.h | 12 +- Foundation/include/Poco/ExpireLRUCache.h | 4 +- Foundation/include/Poco/ExpireStrategy.h | 4 +- Foundation/include/Poco/FIFOBuffer.h | 89 +- Foundation/include/Poco/FIFOBufferStream.h | 10 +- Foundation/include/Poco/FIFOEvent.h | 6 +- Foundation/include/Poco/FIFOStrategy.h | 4 +- Foundation/include/Poco/FPEnvironment_DEC.h | 10 +- Foundation/include/Poco/FPEnvironment_QNX.h | 10 +- Foundation/include/Poco/FPEnvironment_SUN.h | 10 +- Foundation/include/Poco/FPEnvironment_WIN32.h | 6 +- Foundation/include/Poco/File.h | 6 +- Foundation/include/Poco/FileChannel.h | 26 +- Foundation/include/Poco/FileStream.h | 18 +- Foundation/include/Poco/FileStreamFactory.h | 4 +- Foundation/include/Poco/FileStream_POSIX.h | 2 +- Foundation/include/Poco/File_WIN32U.h | 2 +- Foundation/include/Poco/Format.h | 12 + Foundation/include/Poco/Formatter.h | 10 +- Foundation/include/Poco/FormattingChannel.h | 16 +- Foundation/include/Poco/FunctionDelegate.h | 36 +- .../include/Poco/FunctionPriorityDelegate.h | 20 +- Foundation/include/Poco/Glob.h | 14 +- Foundation/include/Poco/HMACEngine.h | 17 +- Foundation/include/Poco/Hash.h | 111 +- Foundation/include/Poco/HashMap.h | 38 +- Foundation/include/Poco/HashSet.h | 44 +- Foundation/include/Poco/HashStatistic.h | 8 +- Foundation/include/Poco/HashTable.h | 14 +- Foundation/include/Poco/HexBinaryDecoder.h | 14 +- Foundation/include/Poco/HexBinaryEncoder.h | 18 +- Foundation/include/Poco/InflatingStream.h | 34 +- Foundation/include/Poco/Instantiator.h | 12 +- Foundation/include/Poco/KeyValueArgs.h | 8 +- Foundation/include/Poco/LRUCache.h | 6 +- Foundation/include/Poco/LRUStrategy.h | 4 +- Foundation/include/Poco/Latin1Encoding.h | 2 +- Foundation/include/Poco/Latin2Encoding.h | 2 +- Foundation/include/Poco/Latin9Encoding.h | 2 +- Foundation/include/Poco/LineEndingConverter.h | 10 +- Foundation/include/Poco/LinearHashTable.h | 96 +- Foundation/include/Poco/ListMap.h | 38 +- Foundation/include/Poco/LocalDateTime.h | 84 +- Foundation/include/Poco/LogFile_STD.h | 1 + Foundation/include/Poco/LoggingRegistry.h | 4 +- Foundation/include/Poco/MD4Engine.h | 2 +- Foundation/include/Poco/MD5Engine.h | 4 +- Foundation/include/Poco/Manifest.h | 2 +- Foundation/include/Poco/MemoryStream.h | 16 +- Foundation/include/Poco/Message.h | 16 +- Foundation/include/Poco/MetaObject.h | 36 +- Foundation/include/Poco/MetaProgramming.h | 8 +- Foundation/include/Poco/Mutex.h | 30 +- Foundation/include/Poco/Mutex_POSIX.h | 4 +- Foundation/include/Poco/Mutex_VX.h | 2 +- Foundation/include/Poco/Mutex_WIN32.h | 2 +- Foundation/include/Poco/Mutex_WINCE.h | 2 +- Foundation/include/Poco/NObserver.h | 26 +- Foundation/include/Poco/NamedEvent.h | 2 +- Foundation/include/Poco/NamedEvent_Android.h | 2 +- Foundation/include/Poco/NamedEvent_UNIX.h | 4 +- Foundation/include/Poco/NamedEvent_WIN32U.h | 6 +- Foundation/include/Poco/NamedMutex.h | 2 +- Foundation/include/Poco/NamedMutex_UNIX.h | 2 +- Foundation/include/Poco/NamedMutex_WIN32U.h | 2 +- Foundation/include/Poco/NamedTuple.h | 4674 ++-- .../include/Poco/NestedDiagnosticContext.h | 26 +- Foundation/include/Poco/Notification.h | 2 +- Foundation/include/Poco/NotificationCenter.h | 24 +- Foundation/include/Poco/NotificationQueue.h | 24 +- .../include/Poco/NotificationStrategy.h | 8 +- Foundation/include/Poco/NullChannel.h | 2 +- Foundation/include/Poco/NullStream.h | 6 +- Foundation/include/Poco/Nullable.h | 4 +- Foundation/include/Poco/NumberFormatter.h | 12 +- Foundation/include/Poco/NumberParser.h | 24 +- Foundation/include/Poco/NumericString.h | 131 +- Foundation/include/Poco/Observer.h | 24 +- Foundation/include/Poco/Optional.h | 4 +- Foundation/include/Poco/PBKDF2Engine.h | 46 +- Foundation/include/Poco/Path.h | 4 +- Foundation/include/Poco/Path_WIN32U.h | 2 +- Foundation/include/Poco/Path_WINCE.h | 2 +- Foundation/include/Poco/PatternFormatter.h | 11 +- Foundation/include/Poco/Pipe.h | 12 +- Foundation/include/Poco/PipeImpl_POSIX.h | 2 +- Foundation/include/Poco/PipeImpl_WIN32.h | 2 +- Foundation/include/Poco/PipeStream.h | 14 +- Foundation/include/Poco/Platform.h | 6 + Foundation/include/Poco/Platform_VX.h | 4 +- Foundation/include/Poco/Platform_WIN32.h | 17 +- Foundation/include/Poco/PriorityDelegate.h | 16 +- Foundation/include/Poco/PriorityEvent.h | 6 +- Foundation/include/Poco/PriorityExpire.h | 10 +- .../include/Poco/PriorityNotificationQueue.h | 28 +- Foundation/include/Poco/PriorityStrategy.h | 2 +- Foundation/include/Poco/PurgeStrategy.h | 10 +- Foundation/include/Poco/RWLock.h | 8 +- Foundation/include/Poco/RWLock_Android.h | 6 +- Foundation/include/Poco/RWLock_POSIX.h | 6 +- Foundation/include/Poco/RWLock_VX.h | 4 +- Foundation/include/Poco/RWLock_WIN32.h | 2 +- Foundation/include/Poco/RWLock_WINCE.h | 2 +- Foundation/include/Poco/RefCountedObject.h | 4 +- Foundation/include/Poco/RegularExpression.h | 54 +- Foundation/include/Poco/RotateStrategy.h | 18 +- Foundation/include/Poco/Runnable.h | 4 +- Foundation/include/Poco/RunnableAdapter.h | 6 +- Foundation/include/Poco/SHA1Engine.h | 2 +- Foundation/include/Poco/SHA2Engine.h | 88 +- Foundation/include/Poco/ScopedLock.h | 10 +- Foundation/include/Poco/Semaphore.h | 22 +- Foundation/include/Poco/Semaphore_POSIX.h | 8 +- Foundation/include/Poco/Semaphore_VX.h | 4 +- Foundation/include/Poco/Semaphore_WIN32.h | 4 +- Foundation/include/Poco/SharedLibrary.h | 2 +- Foundation/include/Poco/SharedMemory.h | 8 +- Foundation/include/Poco/SharedMemory_DUMMY.h | 2 +- Foundation/include/Poco/SharedMemory_POSIX.h | 2 +- Foundation/include/Poco/SharedPtr.h | 2 +- Foundation/include/Poco/SignalHandler.h | 10 +- Foundation/include/Poco/SimpleFileChannel.h | 18 +- Foundation/include/Poco/SimpleHashTable.h | 12 +- Foundation/include/Poco/SingletonHolder.h | 8 +- Foundation/include/Poco/SplitterChannel.h | 8 +- Foundation/include/Poco/Stopwatch.h | 10 +- Foundation/include/Poco/StrategyCollection.h | 2 +- Foundation/include/Poco/StreamChannel.h | 4 +- Foundation/include/Poco/StreamConverter.h | 4 +- Foundation/include/Poco/StreamTokenizer.h | 10 +- Foundation/include/Poco/StringTokenizer.h | 12 +- Foundation/include/Poco/SynchronizedObject.h | 12 +- Foundation/include/Poco/SyslogChannel.h | 16 +- Foundation/include/Poco/Task.h | 24 +- Foundation/include/Poco/TaskManager.h | 4 +- Foundation/include/Poco/TaskNotification.h | 8 +- Foundation/include/Poco/TeeStream.h | 6 +- Foundation/include/Poco/TextBufferIterator.h | 24 +- Foundation/include/Poco/TextConverter.h | 4 +- Foundation/include/Poco/TextIterator.h | 26 +- Foundation/include/Poco/Thread.h | 11 +- Foundation/include/Poco/ThreadLocal.h | 24 +- Foundation/include/Poco/ThreadTarget.h | 14 +- Foundation/include/Poco/Thread_POSIX.h | 8 +- Foundation/include/Poco/Thread_VX.h | 5 +- Foundation/include/Poco/Thread_WIN32.h | 9 +- Foundation/include/Poco/Thread_WINCE.h | 7 +- .../include/Poco/TimedNotificationQueue.h | 14 +- Foundation/include/Poco/Timer.h | 22 +- Foundation/include/Poco/Timespan.h | 70 +- Foundation/include/Poco/Timestamp.h | 44 +- Foundation/include/Poco/Token.h | 16 +- Foundation/include/Poco/Tuple.h | 38 +- Foundation/include/Poco/TypeList.h | 28 +- Foundation/include/Poco/URI.h | 35 +- Foundation/include/Poco/URIStreamFactory.h | 12 +- Foundation/include/Poco/URIStreamOpener.h | 8 +- Foundation/include/Poco/UTF16Encoding.h | 18 +- Foundation/include/Poco/UTF32Encoding.h | 18 +- Foundation/include/Poco/UTF8Encoding.h | 4 +- Foundation/include/Poco/UTF8String.h | 2 +- Foundation/include/Poco/UTFString.h | 24 +- Foundation/include/Poco/UUID.h | 28 +- Foundation/include/Poco/UnbufferedStreamBuf.h | 12 +- Foundation/include/Poco/Unicode.h | 26 +- Foundation/include/Poco/UnicodeConverter.h | 4 +- .../include/Poco/UniqueAccessExpireCache.h | 14 +- .../include/Poco/UniqueAccessExpireLRUCache.h | 10 +- .../include/Poco/UniqueAccessExpireStrategy.h | 10 +- Foundation/include/Poco/UniqueExpireCache.h | 14 +- .../include/Poco/UniqueExpireLRUCache.h | 8 +- .../include/Poco/UniqueExpireStrategy.h | 8 +- Foundation/include/Poco/ValidArgs.h | 8 +- Foundation/include/Poco/Version.h | 2 +- Foundation/include/Poco/Void.h | 6 +- Foundation/include/Poco/Windows1250Encoding.h | 2 +- Foundation/include/Poco/Windows1251Encoding.h | 2 +- Foundation/include/Poco/Windows1252Encoding.h | 2 +- .../include/Poco/WindowsConsoleChannel.h | 16 +- Foundation/include/Poco/ordered_hash.h | 700 +- Foundation/include/Poco/ordered_map.h | 615 +- Foundation/include/Poco/ordered_set.h | 424 +- Foundation/include/Poco/zconf.h | 2 +- Foundation/include/Poco/zlib.h | 221 +- .../samples/ActiveMethod/src/ActiveMethod.cpp | 10 +- Foundation/samples/Activity/src/Activity.cpp | 6 +- .../BinaryReaderWriter.progen | 1 + .../src/BinaryReaderWriter.cpp | 10 +- Foundation/samples/DateTime/DateTime.progen | 1 + Foundation/samples/DateTime/src/DateTime.cpp | 2 +- .../LineEndingConverter.progen | 1 + .../samples/LogRotation/LogRotation.progen | 1 + Foundation/samples/Logger/Logger.progen | 1 + Foundation/samples/Logger/src/Logger.cpp | 16 +- .../NotificationQueue.progen | 1 + .../src/NotificationQueue.cpp | 18 +- .../StringTokenizer/StringTokenizer.progen | 1 + Foundation/samples/Timer/Timer.progen | 1 + Foundation/samples/Timer/src/Timer.cpp | 12 +- Foundation/samples/URI/URI.progen | 1 + Foundation/samples/URI/src/URI.cpp | 8 +- .../samples/base64decode/base64decode.progen | 1 + .../samples/base64decode/src/base64decode.cpp | 10 +- .../samples/base64encode/base64encode.progen | 1 + .../samples/base64encode/src/base64encode.cpp | 10 +- Foundation/samples/deflate/deflate.progen | 1 + Foundation/samples/deflate/src/deflate.cpp | 10 +- Foundation/samples/dir/dir.progen | 1 + Foundation/samples/dir/src/dir.cpp | 4 +- Foundation/samples/grep/grep.progen | 1 + Foundation/samples/grep/src/grep.cpp | 8 +- Foundation/samples/hmacmd5/hmacmd5.progen | 1 + Foundation/samples/hmacmd5/src/hmacmd5.cpp | 12 +- Foundation/samples/inflate/inflate.progen | 1 + Foundation/samples/inflate/src/inflate.cpp | 10 +- Foundation/samples/md5/md5.progen | 1 + Foundation/samples/md5/src/md5.cpp | 8 +- Foundation/samples/uuidgen/src/uuidgen.cpp | 8 +- Foundation/samples/uuidgen/uuidgen.progen | 1 + Foundation/src/ASCIIEncoding.cpp | 34 +- Foundation/src/AbstractObserver.cpp | 2 +- Foundation/src/ActiveDispatcher.cpp | 6 +- Foundation/src/ArchiveStrategy.cpp | 8 +- Foundation/src/Ascii.cpp | 2 +- Foundation/src/AsyncChannel.cpp | 19 +- Foundation/src/AtomicCounter.cpp | 4 +- Foundation/src/Base32Decoder.cpp | 10 +- Foundation/src/Base32Encoder.cpp | 2 +- Foundation/src/Bugcheck.cpp | 2 +- Foundation/src/Clock.cpp | 16 +- Foundation/src/Condition.cpp | 4 +- Foundation/src/ConsoleChannel.cpp | 14 +- Foundation/src/CountingStream.cpp | 38 +- Foundation/src/DateTime.cpp | 16 +- Foundation/src/DateTimeFormatter.cpp | 8 +- Foundation/src/DateTimeParser.cpp | 26 +- Foundation/src/DigestEngine.cpp | 12 +- Foundation/src/DigestStream.cpp | 44 +- Foundation/src/DirectoryIterator_WIN32U.cpp | 2 +- Foundation/src/DirectoryWatcher.cpp | 4 +- Foundation/src/Environment_WINCE.cpp | 10 +- Foundation/src/Error.cpp | 12 +- Foundation/src/ErrorHandler.cpp | 4 +- Foundation/src/EventLogChannel.cpp | 18 +- Foundation/src/Event_POSIX.cpp | 5 +- Foundation/src/Event_WIN32.cpp | 2 +- Foundation/src/Exception.cpp | 6 +- Foundation/src/File.cpp | 2 +- Foundation/src/FileChannel.cpp | 16 +- Foundation/src/FileStreamFactory.cpp | 4 +- Foundation/src/FileStream_POSIX.cpp | 12 +- Foundation/src/FileStream_WIN32.cpp | 14 +- Foundation/src/File_VX.cpp | 2 +- Foundation/src/File_WINCE.cpp | 2 +- Foundation/src/Format.cpp | 20 +- Foundation/src/FormattingChannel.cpp | 12 +- Foundation/src/Glob.cpp | 6 +- Foundation/src/HashStatistic.cpp | 8 +- Foundation/src/HexBinaryDecoder.cpp | 2 +- Foundation/src/HexBinaryEncoder.cpp | 6 +- Foundation/src/JSONString.cpp | 5 +- Foundation/src/Latin1Encoding.cpp | 34 +- Foundation/src/Latin2Encoding.cpp | 22 +- Foundation/src/Latin9Encoding.cpp | 34 +- Foundation/src/LineEndingConverter.cpp | 28 +- Foundation/src/LogFile_STD.cpp | 18 +- Foundation/src/LogFile_WIN32U.cpp | 2 +- Foundation/src/Logger.cpp | 2 +- Foundation/src/LoggingRegistry.cpp | 4 +- Foundation/src/MD4Engine.cpp | 6 +- Foundation/src/MD5Engine.cpp | 10 +- Foundation/src/MemoryPool.cpp | 10 +- Foundation/src/MemoryStream.cpp | 8 +- Foundation/src/Message.cpp | 18 + Foundation/src/Mutex_WINCE.cpp | 4 +- Foundation/src/NamedEvent_WIN32U.cpp | 2 +- Foundation/src/NamedMutex_WIN32U.cpp | 2 +- Foundation/src/NestedDiagnosticContext.cpp | 8 +- Foundation/src/NotificationQueue.cpp | 8 +- Foundation/src/NullStream.cpp | 2 +- Foundation/src/NumberParser.cpp | 8 +- Foundation/src/NumericString.cpp | 8 +- Foundation/src/Path.cpp | 2 +- Foundation/src/Path_WINCE.cpp | 2 +- Foundation/src/PatternFormatter.cpp | 7 +- Foundation/src/Pipe.cpp | 2 +- Foundation/src/PipeImpl_WIN32.cpp | 2 +- Foundation/src/PipeStream.cpp | 2 +- Foundation/src/PriorityNotificationQueue.cpp | 6 +- Foundation/src/RWLock.cpp | 2 +- Foundation/src/RWLock_WIN32.cpp | 2 +- Foundation/src/RWLock_WINCE.cpp | 42 +- Foundation/src/Random.cpp | 30 +- Foundation/src/RandomStream.cpp | 4 +- Foundation/src/RegularExpression.cpp | 201 +- Foundation/src/RotateStrategy.cpp | 2 +- Foundation/src/SHA1Engine.cpp | 4 +- Foundation/src/SHA2Engine.cpp | 60 +- Foundation/src/Semaphore_WIN32.cpp | 2 +- Foundation/src/SharedLibrary.cpp | 2 +- Foundation/src/SharedLibrary_HPUX.cpp | 1 + Foundation/src/SharedLibrary_UNIX.cpp | 1 + Foundation/src/SharedLibrary_VX.cpp | 1 + Foundation/src/SharedLibrary_WIN32U.cpp | 1 + Foundation/src/SharedMemory_WIN32.cpp | 2 +- Foundation/src/SignalHandler.cpp | 2 +- Foundation/src/SimpleFileChannel.cpp | 10 +- Foundation/src/SortedDirectoryIterator.cpp | 2 +- Foundation/src/SplitterChannel.cpp | 2 +- Foundation/src/StreamChannel.cpp | 2 +- Foundation/src/StreamConverter.cpp | 10 +- Foundation/src/StreamTokenizer.cpp | 6 +- Foundation/src/String.cpp | 8 +- Foundation/src/StringTokenizer.cpp | 6 +- Foundation/src/SynchronizedObject.cpp | 2 +- Foundation/src/SyslogChannel.cpp | 17 +- Foundation/src/Task.cpp | 8 +- Foundation/src/TaskManager.cpp | 8 +- Foundation/src/TaskNotification.cpp | 10 +- Foundation/src/TeeStream.cpp | 6 +- Foundation/src/TemporaryFile.cpp | 10 +- Foundation/src/TextBufferIterator.cpp | 26 +- Foundation/src/TextConverter.cpp | 2 +- Foundation/src/TextEncoding.cpp | 16 +- Foundation/src/TextIterator.cpp | 26 +- Foundation/src/ThreadLocal.cpp | 2 +- Foundation/src/ThreadPool.cpp | 42 +- Foundation/src/Thread_POSIX.cpp | 47 +- Foundation/src/Thread_VX.cpp | 8 +- Foundation/src/Thread_WIN32.cpp | 12 +- Foundation/src/Thread_WINCE.cpp | 8 +- Foundation/src/TimedNotificationQueue.cpp | 6 +- Foundation/src/Timer.cpp | 8 +- Foundation/src/Timespan.cpp | 6 +- Foundation/src/Timestamp.cpp | 2 +- Foundation/src/Token.cpp | 2 +- Foundation/src/URI.cpp | 33 +- Foundation/src/URIStreamFactory.cpp | 2 +- Foundation/src/URIStreamOpener.cpp | 8 +- Foundation/src/UUID.cpp | 26 +- Foundation/src/Unicode.cpp | 6 +- Foundation/src/UnicodeConverter.cpp | 2 +- Foundation/src/Var.cpp | 41 +- Foundation/src/VarIterator.cpp | 4 +- Foundation/src/Windows1250Encoding.cpp | 18 +- Foundation/src/Windows1251Encoding.cpp | 16 +- Foundation/src/Windows1252Encoding.cpp | 34 +- Foundation/src/WindowsConsoleChannel.cpp | 14 +- Foundation/src/bignum-dtoa.cc | 46 +- Foundation/src/bignum.cc | 583 +- Foundation/src/bignum.h | 64 +- Foundation/src/cached-powers.cc | 204 +- Foundation/src/cached-powers.h | 26 +- Foundation/src/diy-fp.cc | 57 - Foundation/src/diy-fp.h | 59 +- Foundation/src/double-conversion.h | 546 +- Foundation/src/double-to-string.cc | 440 + Foundation/src/double-to-string.h | 445 + Foundation/src/fast-dtoa.cc | 58 +- Foundation/src/fixed-dtoa.cc | 24 +- Foundation/src/ieee.h | 79 +- Foundation/src/pcre.h | 677 - Foundation/src/pcre2.h | 993 + Foundation/src/pcre2_auto_possess.c | 1361 ++ .../{pcre_chartables.c => pcre2_chartables.c} | 90 +- Foundation/src/pcre2_compile.c | 10621 +++++++++ Foundation/src/pcre2_config.c | 250 + Foundation/src/pcre2_config.h | 458 + Foundation/src/pcre2_context.c | 485 + Foundation/src/pcre2_convert.c | 1179 + .../{pcre_dfa_exec.c => pcre2_dfa_match.c} | 2105 +- Foundation/src/pcre2_error.c | 338 + Foundation/src/pcre2_extuni.c | 144 + Foundation/src/pcre2_find_bracket.c | 216 + Foundation/src/pcre2_internal.h | 2048 ++ Foundation/src/pcre2_intmodedep.h | 934 + ...pcre_jit_compile.c => pcre2_jit_compile.c} | 8696 ++++--- Foundation/src/pcre2_jit_match.c | 186 + Foundation/src/pcre2_jit_misc.c | 232 + .../{pcre_maketables.c => pcre2_maketables.c} | 118 +- Foundation/src/pcre2_match.c | 7534 ++++++ Foundation/src/pcre2_match_data.c | 163 + .../src/{pcre_newline.c => pcre2_newline.c} | 153 +- .../src/{pcre_ord2utf8.c => pcre2_ord2utf.c} | 75 +- Foundation/src/pcre2_pattern_info.c | 429 + Foundation/src/pcre2_script_run.c | 341 + Foundation/src/pcre2_serialize.c | 282 + Foundation/src/pcre2_string_utils.c | 234 + Foundation/src/pcre2_study.c | 1822 ++ Foundation/src/pcre2_substitute.c | 1003 + Foundation/src/pcre2_substring.c | 544 + Foundation/src/pcre2_tables.c | 232 + Foundation/src/pcre2_ucd.c | 5394 +++++ Foundation/src/pcre2_ucp.h | 394 + Foundation/src/pcre2_ucptables.c | 1524 ++ .../{pcre_valid_utf8.c => pcre2_valid_utf.c} | 276 +- .../src/{pcre_xclass.c => pcre2_xclass.c} | 69 +- Foundation/src/pcre_byte_order.c | 315 - Foundation/src/pcre_compile.c | 9812 -------- Foundation/src/pcre_config.c | 187 - Foundation/src/pcre_config.h | 413 - Foundation/src/pcre_exec.c | 7174 ------ Foundation/src/pcre_fullinfo.c | 242 - Foundation/src/pcre_get.c | 666 - Foundation/src/pcre_globals.c | 83 - Foundation/src/pcre_internal.h | 2827 --- Foundation/src/pcre_refcount.c | 90 - Foundation/src/pcre_string_utils.c | 207 - Foundation/src/pcre_study.c | 1683 -- Foundation/src/pcre_tables.c | 723 - Foundation/src/pcre_ucd.c | 3641 --- Foundation/src/pcre_version.c | 94 - ...uble-conversion.cc => string-to-double.cc} | 519 +- Foundation/src/string-to-double.h | 238 + Foundation/src/strtod.cc | 136 +- Foundation/src/strtod.h | 19 + Foundation/src/utils.h | 161 +- Foundation/testsuite/CMakeLists.txt | 2 +- Foundation/testsuite/TestApp_vs140.vcxproj | 1 - Foundation/testsuite/TestApp_vs150.vcxproj | 1 - Foundation/testsuite/TestApp_vs160.vcxproj | 14 +- Foundation/testsuite/TestApp_vs170.vcxproj | 278 +- .../testsuite/TestLibrary_vs140.vcxproj | 1 - .../testsuite/TestLibrary_vs150.vcxproj | 1 - .../testsuite/TestLibrary_vs160.vcxproj | 6 +- .../testsuite/TestLibrary_vs170.vcxproj | 99 +- Foundation/testsuite/TestSuite_vs140.vcxproj | 1 - Foundation/testsuite/TestSuite_vs150.vcxproj | 1 - Foundation/testsuite/TestSuite_vs160.vcxproj | 8 +- Foundation/testsuite/TestSuite_vs170.vcxproj | 283 +- .../testsuite/src/ActiveDispatcherTest.cpp | 39 +- .../testsuite/src/ActiveDispatcherTest.h | 1 + Foundation/testsuite/src/ActiveMethodTest.cpp | 10 +- Foundation/testsuite/src/ActivityTest.cpp | 12 +- Foundation/testsuite/src/AnyTest.cpp | 216 +- Foundation/testsuite/src/AnyTest.h | 28 +- Foundation/testsuite/src/ArrayTest.cpp | 4 +- .../testsuite/src/AutoReleasePoolTest.cpp | 14 +- Foundation/testsuite/src/BasicEventTest.h | 4 +- .../testsuite/src/BinaryReaderWriterTest.cpp | 20 +- Foundation/testsuite/src/ByteOrderTest.cpp | 12 +- Foundation/testsuite/src/ChannelTest.cpp | 35 +- Foundation/testsuite/src/ClassLoaderTest.cpp | 26 +- Foundation/testsuite/src/ClockTest.cpp | 6 +- Foundation/testsuite/src/ConditionTest.cpp | 46 +- .../testsuite/src/DateTimeFormatterTest.cpp | 2 +- .../testsuite/src/DateTimeFormatterTest.h | 2 +- .../testsuite/src/DateTimeParserTest.cpp | 10 +- Foundation/testsuite/src/DateTimeTest.cpp | 210 +- Foundation/testsuite/src/DigestStreamTest.cpp | 2 +- .../testsuite/src/DirectoryIteratorsTest.h | 4 +- .../testsuite/src/DirectoryWatcherTest.cpp | 32 +- .../testsuite/src/DirectoryWatcherTest.h | 2 + Foundation/testsuite/src/ExpireCacheTest.cpp | 2 +- .../testsuite/src/ExpireLRUCacheTest.cpp | 2 +- .../testsuite/src/FIFOBufferStreamTest.cpp | 8 +- Foundation/testsuite/src/FIFOEventTest.h | 2 +- Foundation/testsuite/src/FPETest.cpp | 12 +- Foundation/testsuite/src/FileChannelTest.h | 2 +- Foundation/testsuite/src/FileTest.h | 2 +- .../testsuite/src/FilesystemTestSuite.cpp | 2 +- Foundation/testsuite/src/FormatTest.cpp | 54 +- Foundation/testsuite/src/GlobTest.cpp | 84 +- Foundation/testsuite/src/HMACEngineTest.cpp | 338 +- Foundation/testsuite/src/HMACEngineTest.h | 6 +- Foundation/testsuite/src/HashMapTest.cpp | 36 +- Foundation/testsuite/src/HashSetTest.cpp | 26 +- .../testsuite/src/LinearHashTableTest.cpp | 58 +- .../testsuite/src/LinearHashTableTest.h | 2 +- Foundation/testsuite/src/ListMapTest.cpp | 38 +- Foundation/testsuite/src/LoggerTest.cpp | 24 +- .../testsuite/src/LoggingRegistryTest.cpp | 26 +- Foundation/testsuite/src/MD4EngineTest.cpp | 2 +- Foundation/testsuite/src/ManifestTest.cpp | 8 +- Foundation/testsuite/src/MemoryPoolTest.cpp | 10 +- Foundation/testsuite/src/MemoryStreamTest.cpp | 10 +- Foundation/testsuite/src/NamedMutexTest.h | 2 +- Foundation/testsuite/src/NamedTuplesTest.cpp | 1290 +- .../testsuite/src/NotificationCenterTest.cpp | 8 +- .../testsuite/src/NotificationCenterTest.h | 2 +- .../testsuite/src/NotificationQueueTest.cpp | 6 +- .../testsuite/src/NumberFormatterTest.cpp | 22 +- Foundation/testsuite/src/NumberParserTest.cpp | 38 +- Foundation/testsuite/src/PBKDF2EngineTest.cpp | 12 +- .../testsuite/src/PatternFormatterTest.cpp | 8 +- Foundation/testsuite/src/PriorityEventTest.h | 2 +- .../src/PriorityNotificationQueueTest.cpp | 8 +- Foundation/testsuite/src/ProcessTest.cpp | 2 +- Foundation/testsuite/src/RWLockTest.cpp | 12 +- Foundation/testsuite/src/RandomStreamTest.cpp | 4 +- Foundation/testsuite/src/RandomTest.cpp | 10 +- Foundation/testsuite/src/RandomTest.h | 2 +- .../testsuite/src/RegularExpressionTest.cpp | 12 + .../testsuite/src/RegularExpressionTest.h | 1 + Foundation/testsuite/src/SHA2EngineTest.cpp | 56 +- Foundation/testsuite/src/SHA2EngineTest.h | 2 + Foundation/testsuite/src/SemaphoreTest.cpp | 14 +- .../testsuite/src/SharedLibraryTest.cpp | 6 +- Foundation/testsuite/src/SharedMemoryTest.cpp | 2 +- Foundation/testsuite/src/StopwatchTest.cpp | 8 +- .../testsuite/src/StreamConverterTest.cpp | 28 +- .../testsuite/src/StreamTokenizerTest.cpp | 28 +- Foundation/testsuite/src/StringTest.cpp | 381 +- Foundation/testsuite/src/StringTest.h | 23 +- .../testsuite/src/StringTokenizerTest.cpp | 8 +- Foundation/testsuite/src/TaskManagerTest.cpp | 88 +- Foundation/testsuite/src/TaskTest.cpp | 6 +- Foundation/testsuite/src/TestChannel.h | 6 +- Foundation/testsuite/src/TestLibrary.cpp | 14 +- .../testsuite/src/TextBufferIteratorTest.cpp | 38 +- .../testsuite/src/TextConverterTest.cpp | 32 +- Foundation/testsuite/src/TextEncodingTest.cpp | 6 +- Foundation/testsuite/src/TextIteratorTest.cpp | 38 +- Foundation/testsuite/src/ThreadLocalTest.cpp | 6 +- Foundation/testsuite/src/ThreadPoolTest.cpp | 14 +- Foundation/testsuite/src/ThreadTest.cpp | 6 +- .../src/TimedNotificationQueueTest.cpp | 40 +- Foundation/testsuite/src/TimerTest.cpp | 2 +- Foundation/testsuite/src/TimespanTest.cpp | 16 +- Foundation/testsuite/src/TimestampTest.cpp | 10 +- Foundation/testsuite/src/TuplesTest.cpp | 78 +- Foundation/testsuite/src/TypeListTest.cpp | 2 +- .../testsuite/src/URIStreamOpenerTest.cpp | 26 +- Foundation/testsuite/src/URITest.cpp | 48 + Foundation/testsuite/src/URITest.h | 1 + .../testsuite/src/UUIDGeneratorTest.cpp | 2 +- Foundation/testsuite/src/UUIDGeneratorTest.h | 2 +- Foundation/testsuite/src/UUIDTest.cpp | 18 +- .../testsuite/src/UnicodeConverterTest.cpp | 2 +- .../testsuite/src/UniqueExpireCacheTest.cpp | 4 +- .../testsuite/src/UniqueExpireCacheTest.h | 2 +- .../src/UniqueExpireLRUCacheTest.cpp | 2 +- .../testsuite/src/UniqueExpireLRUCacheTest.h | 2 +- Foundation/testsuite/src/VarTest.cpp | 24 +- Foundation/testsuite/src/VarTest.h | 1 + Foundation/testsuite/src/WinCEDriver.cpp | 2 +- Foundation/testsuite/src/ZLibTest.cpp | 12 +- Foundation/wcelibcex-1.0/LICENSE.txt | 4 +- Foundation/wcelibcex-1.0/README.txt | 2 +- Foundation/wcelibcex-1.0/src/errno.h | 6 +- Foundation/wcelibcex-1.0/src/fcntl.h | 6 +- Foundation/wcelibcex-1.0/src/wce_abort.c | 10 +- Foundation/wcelibcex-1.0/src/wce_access.c | 16 +- Foundation/wcelibcex-1.0/src/wce_asctime.c | 18 +- Foundation/wcelibcex-1.0/src/wce_bsearch.c | 8 +- Foundation/wcelibcex-1.0/src/wce_clock.c | 18 +- Foundation/wcelibcex-1.0/src/wce_ctime.c | 12 +- Foundation/wcelibcex-1.0/src/wce_direct.h | 6 +- .../src/wce_directorymanagement.c | 14 +- Foundation/wcelibcex-1.0/src/wce_errno.c | 6 +- Foundation/wcelibcex-1.0/src/wce_errno.h | 6 +- Foundation/wcelibcex-1.0/src/wce_fcntl.h | 8 +- Foundation/wcelibcex-1.0/src/wce_findfile.c | 40 +- Foundation/wcelibcex-1.0/src/wce_getenv.c | 8 +- Foundation/wcelibcex-1.0/src/wce_getopt.c | 4 +- .../wcelibcex-1.0/src/wce_gettimeofday.c | 4 +- Foundation/wcelibcex-1.0/src/wce_io.h | 6 +- Foundation/wcelibcex-1.0/src/wce_lfind.c | 2 +- Foundation/wcelibcex-1.0/src/wce_localtime.c | 20 +- Foundation/wcelibcex-1.0/src/wce_mkdir.c | 20 +- Foundation/wcelibcex-1.0/src/wce_mktime.c | 18 +- Foundation/wcelibcex-1.0/src/wce_path.c | 16 +- Foundation/wcelibcex-1.0/src/wce_rename.c | 18 +- Foundation/wcelibcex-1.0/src/wce_rewind.c | 12 +- Foundation/wcelibcex-1.0/src/wce_rmdir.c | 16 +- Foundation/wcelibcex-1.0/src/wce_setlocale.c | 8 +- Foundation/wcelibcex-1.0/src/wce_stat.c | 6 +- Foundation/wcelibcex-1.0/src/wce_stat.h | 14 +- Foundation/wcelibcex-1.0/src/wce_stdio.h | 8 +- Foundation/wcelibcex-1.0/src/wce_stdlib.h | 14 +- Foundation/wcelibcex-1.0/src/wce_strerror.c | 8 +- Foundation/wcelibcex-1.0/src/wce_string.h | 6 +- Foundation/wcelibcex-1.0/src/wce_time.c | 16 +- Foundation/wcelibcex-1.0/src/wce_time.h | 12 +- Foundation/wcelibcex-1.0/src/wce_timesys.c | 20 +- Foundation/wcelibcex-1.0/src/wce_timesys.h | 6 +- Foundation/wcelibcex-1.0/src/wce_types.h | 6 +- Foundation/wcelibcex-1.0/src/wce_unistd.h | 10 +- Foundation/wcelibcex-1.0/src/wce_unlink.c | 16 +- Foundation/wcelibcex-1.0/src/wce_winbase.c | 6 +- Foundation/wcelibcex-1.0/src/wce_winbase.h | 6 +- JSON/CMakeLists.txt | 2 +- JSON/JSON.progen | 1 + JSON/JSON_vs170.sln | 42 + JSON/JSON_vs170.vcxproj | 283 +- JSON/include/Poco/JSON/Array.h | 4 +- JSON/include/Poco/JSON/Handler.h | 2 +- JSON/include/Poco/JSON/Object.h | 4 +- JSON/include/Poco/JSON/ParseHandler.h | 2 +- JSON/include/Poco/JSON/PrintHandler.h | 2 +- JSON/include/Poco/JSON/Query.h | 24 +- JSON/include/Poco/JSON/Template.h | 10 +- JSON/include/Poco/JSON/TemplateCache.h | 2 +- JSON/samples/Benchmark/Benchmark.progen | 1 + JSON/src/Query.cpp | 12 +- JSON/src/Stringifier.cpp | 2 + JSON/src/Template.cpp | 12 +- JSON/src/TemplateCache.cpp | 4 +- JSON/src/pdjson.c | 2 +- JSON/src/pdjson.h | 18 +- JSON/testsuite/TestSuite.progen | 1 + JSON/testsuite/TestSuite_vs170.vcxproj | 296 +- JSON/testsuite/src/JSONTest.cpp | 126 + JSON/testsuite/src/JSONTest.h | 2 + JSON/testsuite/src/WinCEDriver.cpp | 2 +- JWT/CMakeLists.txt | 2 +- JWT/JWT.progen | 1 + JWT/JWT_vs170.sln | 42 + JWT/JWT_vs170.vcxproj | 271 +- JWT/testsuite/TestSuite.progen | 1 + JWT/testsuite/TestSuite_vs170.vcxproj | 296 +- Makefile | 24 +- MongoDB/CMakeLists.txt | 2 +- MongoDB/MongoDB.progen | 1 + MongoDB/MongoDB_vs170.sln | 42 + MongoDB/MongoDB_vs170.vcxproj | 271 +- MongoDB/include/Poco/MongoDB/Array.h | 34 +- MongoDB/include/Poco/MongoDB/BSONWriter.h | 2 +- MongoDB/include/Poco/MongoDB/Cursor.h | 4 +- MongoDB/include/Poco/MongoDB/Database.h | 16 +- MongoDB/include/Poco/MongoDB/DeleteRequest.h | 12 +- MongoDB/include/Poco/MongoDB/GetMoreRequest.h | 10 +- MongoDB/include/Poco/MongoDB/InsertRequest.h | 16 +- .../include/Poco/MongoDB/KillCursorsRequest.h | 8 +- MongoDB/include/Poco/MongoDB/Message.h | 2 +- .../Poco/MongoDB/PoolableConnectionFactory.h | 17 + MongoDB/include/Poco/MongoDB/QueryRequest.h | 52 +- .../include/Poco/MongoDB/ResponseMessage.h | 3 + MongoDB/include/Poco/MongoDB/UpdateRequest.h | 10 +- MongoDB/samples/SQLToMongo/SQLToMongo.progen | 1 + MongoDB/src/Array.cpp | 4 +- MongoDB/src/Cursor.cpp | 6 + MongoDB/src/Database.cpp | 52 +- MongoDB/src/DeleteRequest.cpp | 4 +- MongoDB/src/Element.cpp | 2 +- MongoDB/src/GetMoreRequest.cpp | 2 +- MongoDB/src/InsertRequest.cpp | 2 +- MongoDB/src/KillCursorsRequest.cpp | 2 +- MongoDB/src/Message.cpp | 2 +- MongoDB/src/MessageHeader.cpp | 8 +- MongoDB/src/ObjectId.cpp | 2 +- MongoDB/src/QueryRequest.cpp | 6 +- MongoDB/src/RegularExpression.cpp | 4 +- MongoDB/src/ReplicaSet.cpp | 6 +- MongoDB/src/ResponseMessage.cpp | 20 +- MongoDB/src/UpdateRequest.cpp | 2 +- MongoDB/testsuite/TestSuite.progen | 1 + MongoDB/testsuite/TestSuite_vs170.vcxproj | 296 +- MongoDB/testsuite/src/MongoDBTest.cpp | 37 + MongoDB/testsuite/src/MongoDBTest.h | 1 + MongoDB/testsuite/src/WinCEDriver.cpp | 2 +- Net/CMakeLists.txt | 6 +- Net/Makefile | 2 +- Net/Net.progen | 1 + Net/Net_vs140.vcxproj | 8 +- Net/Net_vs140.vcxproj.filters | 114 +- Net/Net_vs150.vcxproj | 796 +- Net/Net_vs150.vcxproj.filters | 120 +- Net/Net_vs160.vcxproj | 800 +- Net/Net_vs160.vcxproj.filters | 120 +- Net/Net_vs170.sln | 42 + Net/Net_vs170.vcxproj | 796 +- Net/Net_vs170.vcxproj.filters | 120 +- Net/Net_vs90.vcproj | 18 +- .../Poco/Net/AbstractHTTPRequestHandler.h | 8 +- Net/include/Poco/Net/DatagramSocket.h | 71 +- Net/include/Poco/Net/DatagramSocketImpl.h | 4 +- Net/include/Poco/Net/DialogSocket.h | 22 +- Net/include/Poco/Net/FTPClientSession.h | 10 +- Net/include/Poco/Net/FilePartSource.h | 6 +- Net/include/Poco/Net/HTTPChunkedStream.h | 16 +- Net/include/Poco/Net/HTTPClientSession.h | 59 +- Net/include/Poco/Net/HTTPDigestCredentials.h | 17 +- Net/include/Poco/Net/HTTPFixedLengthStream.h | 8 +- Net/include/Poco/Net/HTTPHeaderStream.h | 6 +- Net/include/Poco/Net/HTTPIOStream.h | 14 +- Net/include/Poco/Net/HTTPRequestHandler.h | 4 +- .../Poco/Net/HTTPRequestHandlerFactory.h | 8 +- Net/include/Poco/Net/HTTPResponse.h | 2 + Net/include/Poco/Net/HTTPServerConnection.h | 2 +- .../Poco/Net/HTTPServerConnectionFactory.h | 2 +- Net/include/Poco/Net/HTTPServerRequest.h | 8 +- Net/include/Poco/Net/HTTPServerRequestImpl.h | 18 +- Net/include/Poco/Net/HTTPServerResponse.h | 20 +- Net/include/Poco/Net/HTTPServerResponseImpl.h | 24 +- Net/include/Poco/Net/HTTPServerSession.h | 10 +- Net/include/Poco/Net/HTTPSession.h | 143 +- Net/include/Poco/Net/HTTPStream.h | 6 +- Net/include/Poco/Net/HTTPStreamFactory.h | 14 +- Net/include/Poco/Net/HostEntry.h | 10 +- Net/include/Poco/Net/ICMPClient.h | 10 +- Net/include/Poco/Net/ICMPEventArgs.h | 4 +- Net/include/Poco/Net/ICMPPacket.h | 6 +- Net/include/Poco/Net/ICMPSocket.h | 4 +- Net/include/Poco/Net/ICMPSocketImpl.h | 2 +- Net/include/Poco/Net/IPAddress.h | 123 +- Net/include/Poco/Net/IPAddressImpl.h | 4 +- Net/include/Poco/Net/MailRecipient.h | 22 +- Net/include/Poco/Net/MailStream.h | 10 +- Net/include/Poco/Net/MediaType.h | 40 +- Net/include/Poco/Net/MessageHeader.h | 51 +- Net/include/Poco/Net/MultiSocketPoller.h | 2 +- Net/include/Poco/Net/MulticastSocket.h | 4 +- Net/include/Poco/Net/MultipartReader.h | 12 +- Net/include/Poco/Net/MultipartWriter.h | 8 +- Net/include/Poco/Net/NTPClient.h | 4 +- Net/include/Poco/Net/NTPEventArgs.h | 4 +- Net/include/Poco/Net/NTPPacket.h | 2 +- Net/include/Poco/Net/NameValueCollection.h | 28 +- Net/include/Poco/Net/Net.h | 20 + Net/include/Poco/Net/NetworkInterface.h | 38 +- Net/include/Poco/Net/NullPartHandler.h | 4 +- Net/include/Poco/Net/OAuth10Credentials.h | 46 +- Net/include/Poco/Net/OAuth20Credentials.h | 14 +- Net/include/Poco/Net/POP3ClientSession.h | 10 +- Net/include/Poco/Net/ParallelSocketAcceptor.h | 33 +- Net/include/Poco/Net/ParallelSocketReactor.h | 16 +- Net/include/Poco/Net/PartHandler.h | 6 +- Net/include/Poco/Net/PollSet.h | 40 +- Net/include/Poco/Net/QuotedPrintableDecoder.h | 12 +- Net/include/Poco/Net/QuotedPrintableEncoder.h | 2 +- Net/include/Poco/Net/RawSocket.h | 51 +- Net/include/Poco/Net/RawSocketImpl.h | 6 +- Net/include/Poco/Net/RemoteSyslogChannel.h | 3 + Net/include/Poco/Net/RemoteSyslogListener.h | 5 +- Net/include/Poco/Net/SMTPChannel.h | 16 +- Net/include/Poco/Net/ServerSocket.h | 12 +- Net/include/Poco/Net/SingleSocketPoller.h | 2 +- Net/include/Poco/Net/Socket.h | 266 +- Net/include/Poco/Net/SocketAcceptor.h | 14 +- Net/include/Poco/Net/SocketAddress.h | 6 + Net/include/Poco/Net/SocketConnector.h | 46 +- Net/include/Poco/Net/SocketDefs.h | 15 +- Net/include/Poco/Net/SocketImpl.h | 24 + Net/include/Poco/Net/SocketNotification.h | 12 +- Net/include/Poco/Net/SocketNotifier.h | 18 +- Net/include/Poco/Net/SocketProactor.h | 502 + Net/include/Poco/Net/SocketReactor.h | 22 +- Net/include/Poco/Net/SocketStream.h | 14 +- Net/include/Poco/Net/StreamSocket.h | 62 + Net/include/Poco/Net/StreamSocketImpl.h | 4 +- Net/include/Poco/Net/StringPartSource.h | 6 +- Net/include/Poco/Net/TCPServer.h | 23 +- Net/include/Poco/Net/TCPServerConnection.h | 4 +- .../Poco/Net/TCPServerConnectionFactory.h | 6 +- Net/include/Poco/Net/TCPServerDispatcher.h | 61 +- Net/include/Poco/Net/TCPServerParams.h | 18 +- Net/include/Poco/Net/UDPClient.h | 2 +- Net/include/Poco/Net/UDPHandler.h | 62 +- Net/include/Poco/Net/UDPServer.h | 4 +- Net/include/Poco/Net/WebSocket.h | 48 +- Net/include/Poco/Net/WebSocketImpl.h | 2 +- Net/samples/CMakeLists.txt | 2 + Net/samples/EchoServer/EchoServer.progen | 1 + Net/samples/EchoServer/src/EchoServer.cpp | 28 +- .../HTTPFormServer/HTTPFormServer.progen | 1 + .../HTTPFormServer/src/HTTPFormServer.cpp | 32 +- Net/samples/HTTPLoadTest/HTTPLoadTest.progen | 1 + Net/samples/HTTPLoadTest/src/HTTPLoadTest.cpp | 52 +- .../HTTPTimeServer/HTTPTimeServer.progen | 1 + .../HTTPTimeServer/src/HTTPTimeServer.cpp | 20 +- Net/samples/Mail/Mail.progen | 1 + Net/samples/Mail/src/Mail.cpp | 6 +- Net/samples/Mail/src/PocoLogo.hpp | 262 +- Net/samples/Ping/Ping.progen | 1 + Net/samples/Ping/src/Ping.cpp | 34 +- Net/samples/SMTPLogger/SMTPLogger.progen | 1 + Net/samples/SMTPLogger/src/SMTPLogger.cpp | 2 +- Net/samples/TimeServer/TimeServer.progen | 1 + Net/samples/TimeServer/src/TimeServer.cpp | 18 +- .../WebSocketServer/WebSocketServer.progen | 1 + .../WebSocketServer/src/WebSocketServer.cpp | 16 +- Net/samples/dict/dict.progen | 1 + Net/samples/dict/src/dict.cpp | 8 +- Net/samples/download/download.progen | 1 + Net/samples/httpget/httpget.progen | 1 + Net/samples/ifconfig/ifconfig.progen | 1 + Net/samples/tcpserver/tcpserver.progen | 1 + Net/src/DatagramSocket.cpp | 62 +- Net/src/FTPClientSession.cpp | 14 +- Net/src/FTPStreamFactory.cpp | 26 +- Net/src/HTTPChunkedStream.cpp | 52 +- Net/src/HTTPClientSession.cpp | 79 +- Net/src/HTTPDigestCredentials.cpp | 131 +- Net/src/HTTPResponse.cpp | 3 + Net/src/HTTPServerConnection.cpp | 2 + Net/src/HTTPServerParams.cpp | 12 +- Net/src/HTTPServerRequestImpl.cpp | 6 +- Net/src/HTTPServerResponseImpl.cpp | 10 +- Net/src/HTTPServerSession.cpp | 2 +- Net/src/HTTPSession.cpp | 13 +- Net/src/HTTPStreamFactory.cpp | 24 +- Net/src/HostEntry.cpp | 6 +- Net/src/ICMPEventArgs.cpp | 24 +- Net/src/ICMPPacketImpl.cpp | 4 +- Net/src/ICMPSocket.cpp | 6 +- Net/src/ICMPSocketImpl.cpp | 15 +- Net/src/IPAddress.cpp | 116 +- Net/src/IPAddressImpl.cpp | 25 +- Net/src/MailMessage.cpp | 54 +- Net/src/MailRecipient.cpp | 14 +- Net/src/MailStream.cpp | 14 +- Net/src/MediaType.cpp | 2 +- Net/src/MessageHeader.cpp | 75 +- Net/src/MulticastSocket.cpp | 22 +- Net/src/MultipartReader.cpp | 7 +- Net/src/NTPClient.cpp | 2 +- Net/src/NTPEventArgs.cpp | 4 +- Net/src/NTPPacket.cpp | 9 +- Net/src/NameValueCollection.cpp | 18 +- Net/src/NetworkInterface.cpp | 2 +- Net/src/OAuth10Credentials.cpp | 30 +- Net/src/OAuth20Credentials.cpp | 2 +- Net/src/POP3ClientSession.cpp | 16 +- Net/src/PartSource.cpp | 2 +- Net/src/PollSet.cpp | 409 +- Net/src/QuotedPrintableDecoder.cpp | 6 +- Net/src/QuotedPrintableEncoder.cpp | 6 +- Net/src/RawSocket.cpp | 48 +- Net/src/RawSocketImpl.cpp | 4 +- Net/src/RemoteSyslogChannel.cpp | 69 +- Net/src/RemoteSyslogListener.cpp | 7 +- Net/src/SMTPChannel.cpp | 58 +- Net/src/ServerSocket.cpp | 4 +- Net/src/Socket.cpp | 213 +- Net/src/SocketAddress.cpp | 13 + Net/src/SocketImpl.cpp | 83 +- Net/src/SocketNotification.cpp | 14 +- Net/src/SocketProactor.cpp | 808 + Net/src/SocketReactor.cpp | 17 +- Net/src/SocketStream.cpp | 4 +- Net/src/StreamSocket.cpp | 51 +- Net/src/StreamSocketImpl.cpp | 2 +- Net/src/StringPartSource.cpp | 2 +- Net/src/TCPServer.cpp | 14 +- Net/src/TCPServerDispatcher.cpp | 57 +- Net/src/WebSocket.cpp | 52 + Net/src/wepoll.c | 2253 ++ Net/src/wepoll.h | 114 + Net/testsuite/Makefile | 3 +- Net/testsuite/TestSuite.progen | 1 + Net/testsuite/TestSuite_vs150.vcxproj | 532 +- Net/testsuite/TestSuite_vs150.vcxproj.filters | 124 +- Net/testsuite/TestSuite_vs160.vcxproj | 536 +- Net/testsuite/TestSuite_vs160.vcxproj.filters | 124 +- Net/testsuite/TestSuite_vs170.vcxproj | 532 +- Net/testsuite/TestSuite_vs170.vcxproj.filters | 124 +- Net/testsuite/TestSuite_vs90.vcproj | 18 +- Net/testsuite/src/DNSTest.cpp | 8 +- Net/testsuite/src/DatagramSocketTest.cpp | 218 +- Net/testsuite/src/DatagramSocketTest.h | 7 + Net/testsuite/src/DialogServer.cpp | 8 +- Net/testsuite/src/DialogServer.h | 20 +- Net/testsuite/src/DialogSocketTest.cpp | 10 +- Net/testsuite/src/EchoServer.h | 5 +- Net/testsuite/src/FTPClientSessionTest.cpp | 56 +- Net/testsuite/src/FTPClientSessionTest.h | 2 +- Net/testsuite/src/HTTPClientSessionTest.cpp | 32 +- Net/testsuite/src/HTTPClientSessionTest.h | 1 + Net/testsuite/src/HTTPCredentialsTest.cpp | 79 + Net/testsuite/src/HTTPCredentialsTest.h | 3 + Net/testsuite/src/HTTPRequestTest.cpp | 10 +- Net/testsuite/src/HTTPRequestTest.h | 2 +- Net/testsuite/src/HTTPServerTest.cpp | 88 +- Net/testsuite/src/HTTPServerTest.h | 1 + Net/testsuite/src/HTTPTestServer.cpp | 33 +- Net/testsuite/src/HTTPTestServer.h | 8 +- Net/testsuite/src/ICMPClientTest.cpp | 16 +- Net/testsuite/src/ICMPSocketTest.cpp | 4 +- Net/testsuite/src/IPAddressTest.cpp | 97 +- Net/testsuite/src/MailMessageTest.cpp | 160 +- Net/testsuite/src/MailMessageTest.h | 2 + Net/testsuite/src/MailStreamTest.cpp | 8 +- Net/testsuite/src/MessageHeaderTest.cpp | 66 +- Net/testsuite/src/MessageHeaderTest.h | 2 + Net/testsuite/src/MulticastEchoServer.cpp | 6 +- Net/testsuite/src/MulticastEchoServer.h | 14 +- Net/testsuite/src/MultipartWriterTest.cpp | 4 +- Net/testsuite/src/NTPClientTest.cpp | 6 +- Net/testsuite/src/NameValueCollectionTest.cpp | 30 +- Net/testsuite/src/OAuth10CredentialsTest.cpp | 82 +- Net/testsuite/src/OAuth20CredentialsTest.cpp | 4 +- Net/testsuite/src/PollSetTest.cpp | 269 +- Net/testsuite/src/PollSetTest.h | 5 + Net/testsuite/src/QuotedPrintableTest.cpp | 2 +- Net/testsuite/src/QuotedPrintableTest.h | 2 +- Net/testsuite/src/RawSocketTest.cpp | 33 +- Net/testsuite/src/RawSocketTest.h | 1 + Net/testsuite/src/ReactorTestSuite.cpp | 2 + Net/testsuite/src/SMTPClientSessionTest.cpp | 2 +- Net/testsuite/src/SMTPClientSessionTest.h | 2 +- Net/testsuite/src/SocketAddressTest.cpp | 26 +- Net/testsuite/src/SocketConnectorTest.cpp | 170 + Net/testsuite/src/SocketConnectorTest.h | 36 + Net/testsuite/src/SocketProactorTest.cpp | 355 + Net/testsuite/src/SocketProactorTest.h | 49 + Net/testsuite/src/SocketReactorTest.cpp | 62 +- Net/testsuite/src/SocketReactorTest.h | 1 + Net/testsuite/src/SocketStreamTest.cpp | 4 +- Net/testsuite/src/SocketTest.cpp | 72 +- Net/testsuite/src/SocketTest.h | 1 + Net/testsuite/src/SocketsTestSuite.cpp | 2 + Net/testsuite/src/SyslogTest.cpp | 42 +- Net/testsuite/src/SyslogTest.h | 1 + Net/testsuite/src/TCPServerTest.cpp | 22 +- Net/testsuite/src/UDPEchoServer.h | 8 +- Net/testsuite/src/UDPServerTest.cpp | 5 +- Net/testsuite/src/WebSocketTest.cpp | 22 +- Net/testsuite/src/WinCEDriver.cpp | 2 +- NetSSL_OpenSSL/CMakeLists.txt | 2 +- NetSSL_OpenSSL/NetSSL_OpenSSL.progen | 1 + NetSSL_OpenSSL/NetSSL_OpenSSL_vs170.sln | 42 + NetSSL_OpenSSL/NetSSL_OpenSSL_vs170.vcxproj | 273 +- NetSSL_OpenSSL/doc/howtobuild.txt | 2 +- .../Poco/Net/CertificateHandlerFactory.h | 4 +- .../Poco/Net/ConsoleCertificateHandler.h | 2 +- NetSSL_OpenSSL/include/Poco/Net/Context.h | 19 + .../include/Poco/Net/FTPSClientSession.h | 10 + .../include/Poco/Net/HTTPSClientSession.h | 16 +- .../include/Poco/Net/HTTPSStreamFactory.h | 12 +- .../include/Poco/Net/KeyFileHandler.h | 2 +- NetSSL_OpenSSL/include/Poco/Net/NetSSL.h | 6 +- .../include/Poco/Net/PrivateKeyFactory.h | 4 +- .../Poco/Net/PrivateKeyPassphraseHandler.h | 6 +- .../Poco/Net/RejectCertificateHandler.h | 2 +- .../include/Poco/Net/SecureServerSocket.h | 2 +- .../include/Poco/Net/SecureSocketImpl.h | 10 + .../include/Poco/Net/SecureStreamSocket.h | 42 +- .../include/Poco/Net/SecureStreamSocketImpl.h | 50 +- .../include/Poco/Net/X509Certificate.h | 14 +- .../HTTPSTimeServer/HTTPSTimeServer.progen | 1 + .../HTTPSTimeServer/src/HTTPSTimeServer.cpp | 20 +- NetSSL_OpenSSL/samples/Mail/Mail.progen | 1 + NetSSL_OpenSSL/samples/Mail/src/Mail.cpp | 10 +- NetSSL_OpenSSL/samples/Mail/src/PocoLogo.hpp | 262 +- NetSSL_OpenSSL/samples/Makefile | 1 + .../samples/SetSourceIP/CMakeLists.txt | 5 + NetSSL_OpenSSL/samples/SetSourceIP/Makefile | 26 + .../samples/SetSourceIP/SetSourceIP.progen | 17 + .../SetSourceIP/SetSourceIP_vs140.vcxproj | 610 + .../SetSourceIP_vs140.vcxproj.filters | 18 + .../SetSourceIP/SetSourceIP_vs150.vcxproj | 610 + .../SetSourceIP_vs150.vcxproj.filters | 18 + .../SetSourceIP/SetSourceIP_vs160.vcxproj | 610 + .../SetSourceIP_vs160.vcxproj.filters | 18 + .../SetSourceIP/SetSourceIP_vs170.vcxproj | 610 + .../SetSourceIP_vs170.vcxproj.filters | 18 + .../SetSourceIP/SetSourceIP_vs90.vcproj | 447 + .../SetSourceIP/SetSourceIP_x64_vs140.vcxproj | 314 + .../SetSourceIP_x64_vs140.vcxproj.filters | 21 + .../SetSourceIP/SetSourceIP_x64_vs150.vcxproj | 314 + .../SetSourceIP_x64_vs150.vcxproj.filters | 21 + .../samples/SetSourceIP/SetSourceIp.readme | 274 + .../samples/SetSourceIP/src/SetSourceIP.cpp | 203 + .../TwitterClient/TwitterClient.progen | 1 + .../samples/TwitterClient/src/TweetApp.cpp | 20 +- .../samples/TwitterClient/src/Twitter.cpp | 16 +- .../samples/TwitterClient/src/Twitter.h | 14 +- .../samples/download/doc/readme.txt | 4 +- .../samples/download/download.progen | 1 + NetSSL_OpenSSL/samples/samples.progen | 1 + NetSSL_OpenSSL/samples/samples_vs140.sln | 38 + NetSSL_OpenSSL/samples/samples_vs150.sln | 38 + NetSSL_OpenSSL/samples/samples_vs160.sln | 38 + NetSSL_OpenSSL/samples/samples_vs170.sln | 38 + .../src/CertificateHandlerFactoryMgr.cpp | 6 +- NetSSL_OpenSSL/src/Context.cpp | 147 +- NetSSL_OpenSSL/src/FTPSClientSession.cpp | 8 + NetSSL_OpenSSL/src/HTTPSStreamFactory.cpp | 20 +- NetSSL_OpenSSL/src/KeyFileHandler.cpp | 2 +- NetSSL_OpenSSL/src/PrivateKeyFactoryMgr.cpp | 6 +- NetSSL_OpenSSL/src/SSLManager.cpp | 2 + NetSSL_OpenSSL/src/SecureServerSocket.cpp | 12 +- NetSSL_OpenSSL/src/SecureSocketImpl.cpp | 59 +- NetSSL_OpenSSL/src/SecureStreamSocket.cpp | 30 +- NetSSL_OpenSSL/src/SecureStreamSocketImpl.cpp | 14 +- NetSSL_OpenSSL/src/Session.cpp | 2 +- NetSSL_OpenSSL/src/Utility.cpp | 12 +- NetSSL_OpenSSL/testsuite/CMakeLists.txt | 1 + NetSSL_OpenSSL/testsuite/TestSuite.progen | 1 + .../testsuite/TestSuite_vs170.vcxproj | 296 +- NetSSL_OpenSSL/testsuite/dhparams.pem | 8 + NetSSL_OpenSSL/testsuite/src/DialogServer.cpp | 2 +- NetSSL_OpenSSL/testsuite/src/DialogServer.h | 16 +- NetSSL_OpenSSL/testsuite/src/Driver.cpp | 7 +- .../testsuite/src/HTTPSClientSessionTest.cpp | 3 +- .../testsuite/src/HTTPSTestServer.cpp | 16 +- .../testsuite/src/HTTPSTestServer.h | 8 +- NetSSL_OpenSSL/testsuite/src/WinCEDriver.cpp | 6 +- NetSSL_OpenSSL/testsuite/src/WinDriver.cpp | 4 +- NetSSL_OpenSSL/testsuite/testrunner.xml | 1 + NetSSL_Win/CMakeLists.txt | 2 +- NetSSL_Win/NetSSL_Win.progen | 1 + NetSSL_Win/NetSSL_Win_vs170.sln | 42 + NetSSL_Win/NetSSL_Win_vs170.vcxproj | 273 +- NetSSL_Win/doc/README.txt | 16 +- .../Poco/Net/AcceptCertificateHandler.h | 2 +- .../include/Poco/Net/AutoSecBufferDesc.h | 4 +- .../Poco/Net/CertificateHandlerFactory.h | 4 +- .../Poco/Net/CertificateHandlerFactoryMgr.h | 6 +- .../Poco/Net/ConsoleCertificateHandler.h | 2 +- NetSSL_Win/include/Poco/Net/Context.h | 56 +- .../include/Poco/Net/HTTPSClientSession.h | 16 +- .../include/Poco/Net/HTTPSStreamFactory.h | 12 +- .../Poco/Net/InvalidCertificateHandler.h | 8 +- NetSSL_Win/include/Poco/Net/KeyFileHandler.h | 2 +- NetSSL_Win/include/Poco/Net/NetSSL.h | 2 +- .../include/Poco/Net/PrivateKeyFactory.h | 4 +- .../include/Poco/Net/PrivateKeyFactoryMgr.h | 6 +- .../Poco/Net/PrivateKeyPassphraseHandler.h | 6 +- .../Poco/Net/RejectCertificateHandler.h | 2 +- NetSSL_Win/include/Poco/Net/SSLManager.h | 30 +- .../include/Poco/Net/SecureServerSocket.h | 2 +- .../include/Poco/Net/SecureStreamSocket.h | 42 +- .../include/Poco/Net/SecureStreamSocketImpl.h | 50 +- NetSSL_Win/include/Poco/Net/Session.h | 6 +- NetSSL_Win/include/Poco/Net/X509Certificate.h | 34 +- .../HTTPSTimeServer/HTTPSTimeServer.progen | 1 + .../HTTPSTimeServer/src/HTTPSTimeServer.cpp | 20 +- NetSSL_Win/samples/Mail/Mail.progen | 1 + NetSSL_Win/samples/Mail/src/Mail.cpp | 10 +- NetSSL_Win/samples/Mail/src/PocoLogo.hpp | 262 +- NetSSL_Win/samples/download/download.progen | 1 + .../src/CertificateHandlerFactoryMgr.cpp | 6 +- NetSSL_Win/src/HTTPSClientSession.cpp | 2 +- NetSSL_Win/src/HTTPSStreamFactory.cpp | 16 +- NetSSL_Win/src/KeyFileHandler.cpp | 2 +- NetSSL_Win/src/PrivateKeyFactoryMgr.cpp | 6 +- NetSSL_Win/src/SSLManager.cpp | 10 +- NetSSL_Win/src/SecureServerSocket.cpp | 12 +- NetSSL_Win/src/SecureStreamSocket.cpp | 30 +- NetSSL_Win/src/SecureStreamSocketImpl.cpp | 14 +- NetSSL_Win/src/Session.cpp | 2 +- NetSSL_Win/src/X509Certificate.cpp | 2 +- NetSSL_Win/testsuite/TestSuite.progen | 1 + NetSSL_Win/testsuite/TestSuite_vs170.vcxproj | 296 +- NetSSL_Win/testsuite/src/Driver.cpp | 4 +- .../testsuite/src/HTTPSClientSessionTest.cpp | 20 +- NetSSL_Win/testsuite/src/HTTPSServerTest.cpp | 26 +- NetSSL_Win/testsuite/src/HTTPSTestServer.cpp | 16 +- NetSSL_Win/testsuite/src/HTTPSTestServer.h | 6 +- NetSSL_Win/testsuite/src/TCPServerTest.cpp | 40 +- NetSSL_Win/testsuite/src/WinCEDriver.cpp | 6 +- NetSSL_Win/testsuite/src/WinDriver.cpp | 4 +- PDF/CMakeLists.txt | 2 +- PDF/PDF.progen | 1 + PDF/PDF_vs170.sln | 42 + PDF/PDF_vs170.vcxproj | 271 +- PDF/include/Poco/PDF/Destination.h | 4 +- PDF/include/Poco/PDF/Document.h | 38 +- PDF/include/Poco/PDF/Encoder.h | 8 +- PDF/include/Poco/PDF/Font.h | 4 +- PDF/include/Poco/PDF/Page.h | 74 +- PDF/include/Poco/PDF/Resource.h | 8 +- PDF/include/Poco/PDF/hpdf.h | 22 +- PDF/include/Poco/PDF/hpdf_3dmeasure.h | 2 +- PDF/include/Poco/PDF/hpdf_exdata.h | 2 +- PDF/include/Poco/PDF/hpdf_ext_gstate.h | 2 +- PDF/include/Poco/PDF/hpdf_pages.h | 2 +- PDF/include/Poco/PDF/hpdf_pdfa.h | 2 +- PDF/include/Poco/PDF/hpdf_types.h | 4 +- PDF/include/Poco/PDF/png.h | 6 +- PDF/include/Poco/PDF/pngconf.h | 26 +- PDF/samples/Image/Image.progen | 1 + PDF/samples/Template/Template.progen | 1 + PDF/samples/Text/Text.progen | 1 + PDF/src/AttributedString.cpp | 6 +- PDF/src/Cell.cpp | 10 +- PDF/src/Destination.cpp | 2 +- PDF/src/Document.cpp | 22 +- PDF/src/Encoder.cpp | 2 +- PDF/src/Font.cpp | 2 +- PDF/src/Image.cpp | 2 +- PDF/src/LinkAnnotation.cpp | 2 +- PDF/src/Outline.cpp | 2 +- PDF/src/PDFException.cpp | 38 +- PDF/src/Page.cpp | 24 +- PDF/src/TextAnnotation.cpp | 2 +- PDF/src/XMLTemplate.cpp | 2 +- PDF/src/hpdf_3dmeasure.c | 12 +- PDF/src/hpdf_annotation.c | 42 +- PDF/src/hpdf_encoder_utf.c | 2 +- PDF/src/hpdf_exdata.c | 2 +- PDF/src/hpdf_ext_gstate.c | 24 +- PDF/src/hpdf_image_ccitt.c | 28 +- PDF/src/hpdf_image_png.c | 4 +- PDF/src/hpdf_page_operator.c | 6 +- PDF/src/hpdf_pages.c | 16 +- PDF/src/hpdf_pdfa.c | 16 +- PDF/src/hpdf_streams.c | 6 +- PDF/src/hpdf_u3d.c | 20 +- PDF/src/pngget.c | 2 +- PDF/src/pngpread.c | 2 +- PDF/src/pngrtran.c | 4 +- PDF/src/pngrutil.c | 2 +- PDF/src/pngset.c | 4 +- PDF/src/pngtest.c | 2 +- PDF/src/t4.h | 16 +- PDF/testsuite/TestSuite.progen | 1 + PDF/testsuite/TestSuite_vs170.vcxproj | 296 +- PageCompiler/File2Page/File2Page.progen | 1 + PageCompiler/File2Page/File2Page_vs170.sln | 24 + .../File2Page/File2Page_vs170.vcxproj | 296 +- PageCompiler/File2Page/src/File2Page.cpp | 28 +- PageCompiler/PageCompiler.progen | 1 + PageCompiler/PageCompiler_vs170.sln | 24 + PageCompiler/PageCompiler_vs170.vcxproj | 296 +- PageCompiler/cpspc.properties | 2 +- .../HTTPTimeServer/HTTPTimeServer.progen | 1 + .../HTTPTimeServer/src/HTTPTimeServerApp.cpp | 10 +- PageCompiler/src/CodeWriter.h | 6 +- PageCompiler/src/Page.cpp | 2 +- PageCompiler/src/Page.h | 8 +- PageCompiler/src/PageReader.h | 4 +- PocoDoc/PocoDoc.progen | 1 + PocoDoc/PocoDoc_vs170.sln | 24 + PocoDoc/PocoDoc_vs170.vcxproj | 296 +- PocoDoc/cfg/mkdoc-poco.xml | 2 +- PocoDoc/cfg/mkdocumentation.xml | 2 +- PocoDoc/pages/samplePage.page | 2 +- PocoDoc/resources/css/styles.css | 228 +- PocoDoc/resources/js/CollapsibleLists.js | 14 +- .../js/iframeResizer.contentWindow.js | 2 +- PocoDoc/src/DocWriter.cpp | 5 +- PocoDoc/src/DocWriter.h | 32 +- PocoDoc/src/PocoDoc.cpp | 5 + ProGen/ProGen.progen | 1 + ProGen/ProGen_vs170.sln | 24 + ProGen/ProGen_vs170.vcxproj | 296 +- ProGen/progen.bat | 2 +- ProGen/progen.properties | 8 +- ProGen/rebuildall32.bat | 2 +- ProGen/src/ProGen.cpp | 101 +- ProGen/src/VSXMLWriter.cpp | 4 +- ProGen/src/VSXMLWriter.h | 2 +- .../executable/debug_shared-ARM64.template | 86 + .../executable/debug_static_md-ARM64.template | 86 + .../executable/debug_static_mt-ARM64.template | 86 + .../vs170/Win32/executable/project.properties | 5 +- .../vs170/Win32/executable/project.template | 3 + .../executable/release_shared-ARM64.template | 89 + .../release_static_md-ARM64.template | 89 + .../release_static_mt-ARM64.template | 89 + .../Win32/library/debug_shared-ARM64.template | 87 + .../library/debug_static_md-ARM64.template | 73 + .../library/debug_static_mt-ARM64.template | 73 + .../vs170/Win32/library/project.properties | 7 +- .../vs170/Win32/library/project.template | 3 + .../library/release_shared-ARM64.template | 92 + .../library/release_static_md-ARM64.template | 75 + .../library/release_static_mt-ARM64.template | 75 + .../Win32/plugin/debug_shared-ARM64.template | 86 + .../vs170/Win32/plugin/project.properties | 5 +- .../vs170/Win32/plugin/project.template | 3 + .../plugin/release_shared-ARM64.template | 91 + .../testsuite/debug_shared-ARM64.template | 86 + .../testsuite/debug_static_md-ARM64.template | 86 + .../testsuite/debug_static_mt-ARM64.template | 86 + .../vs170/Win32/testsuite/project.properties | 5 +- .../vs170/Win32/testsuite/project.template | 3 + .../testsuite/release_shared-ARM64.template | 89 + .../release_static_md-ARM64.template | 89 + .../release_static_mt-ARM64.template | 89 + Prometheus/CMakeLists.txt | 39 + Prometheus/Makefile | 28 + Prometheus/Prometheus.progen | 17 + Prometheus/Prometheus_vs140.sln | 102 + Prometheus/Prometheus_vs140.vcxproj | 619 + Prometheus/Prometheus_vs140.vcxproj.filters | 117 + Prometheus/Prometheus_vs150.sln | 102 + Prometheus/Prometheus_vs150.vcxproj | 619 + Prometheus/Prometheus_vs150.vcxproj.filters | 117 + Prometheus/Prometheus_vs160.sln | 102 + Prometheus/Prometheus_vs160.vcxproj | 619 + Prometheus/Prometheus_vs160.vcxproj.filters | 117 + Prometheus/Prometheus_vs170.sln | 144 + Prometheus/Prometheus_vs170.vcxproj | 886 + Prometheus/Prometheus_vs170.vcxproj.filters | 117 + Prometheus/Prometheus_vs90.sln | 60 + Prometheus/Prometheus_vs90.vcproj | 676 + Prometheus/cmake/PocoPrometheusConfig.cmake | 4 + Prometheus/dependencies | 2 + .../include/Poco/Prometheus/AtomicFloat.h | 105 + .../include/Poco/Prometheus/CallbackMetric.h | 151 + .../include/Poco/Prometheus/Collector.h | 114 + Prometheus/include/Poco/Prometheus/Counter.h | 191 + Prometheus/include/Poco/Prometheus/Exporter.h | 76 + Prometheus/include/Poco/Prometheus/Gauge.h | 273 + .../include/Poco/Prometheus/Histogram.h | 236 + .../include/Poco/Prometheus/IntCounter.h | 153 + Prometheus/include/Poco/Prometheus/IntGauge.h | 186 + .../include/Poco/Prometheus/LabeledMetric.h | 95 + .../Poco/Prometheus/LabeledMetricImpl.h | 193 + Prometheus/include/Poco/Prometheus/Metric.h | 116 + .../Poco/Prometheus/MetricsRequestHandler.h | 54 + .../include/Poco/Prometheus/MetricsServer.h | 80 + .../Poco/Prometheus/ProcessCollector.h | 83 + .../include/Poco/Prometheus/Prometheus.h | 62 + Prometheus/include/Poco/Prometheus/Registry.h | 101 + .../include/Poco/Prometheus/TextExporter.h | 73 + .../Poco/Prometheus/ThreadPoolCollector.h | 79 + Prometheus/samples/CMakeLists.txt | 1 + Prometheus/samples/Makefile | 10 + .../samples/MetricsSample/CMakeLists.txt | 2 + Prometheus/samples/MetricsSample/Makefile | 15 + .../MetricsSample/MetricsSample.progen | 11 + .../MetricsSample/MetricsSample_vs140.vcxproj | 607 + .../MetricsSample_vs140.vcxproj.filters | 13 + .../MetricsSample/MetricsSample_vs150.vcxproj | 607 + .../MetricsSample_vs150.vcxproj.filters | 13 + .../MetricsSample/MetricsSample_vs160.vcxproj | 607 + .../MetricsSample_vs160.vcxproj.filters | 13 + .../MetricsSample/MetricsSample_vs170.vcxproj | 607 + .../MetricsSample_vs170.vcxproj.filters | 13 + .../MetricsSample/MetricsSample_vs90.vcproj | 445 + .../MetricsSample/src/MetricsSample.cpp | 95 + Prometheus/samples/dependencies | 5 + Prometheus/samples/samples_vs140.sln | 61 + Prometheus/samples/samples_vs150.sln | 61 + Prometheus/samples/samples_vs160.sln | 61 + Prometheus/samples/samples_vs170.sln | 61 + Prometheus/src/Collector.cpp | 37 + Prometheus/src/Counter.cpp | 82 + Prometheus/src/Gauge.cpp | 82 + Prometheus/src/Histogram.cpp | 151 + Prometheus/src/IntCounter.cpp | 33 + Prometheus/src/IntGauge.cpp | 33 + Prometheus/src/LabeledMetric.cpp | 52 + Prometheus/src/MetricsRequestHandler.cpp | 69 + Prometheus/src/MetricsServer.cpp | 118 + Prometheus/src/ProcessCollector.cpp | 102 + Prometheus/src/Registry.cpp | 105 + Prometheus/src/TextExporter.cpp | 185 + Prometheus/src/ThreadPoolCollector.cpp | 120 + Prometheus/testsuite/CMakeLists.txt | 31 + Prometheus/testsuite/Makefile | 23 + Prometheus/testsuite/TestSuite.progen | 10 + Prometheus/testsuite/TestSuite_vs140.vcxproj | 637 + .../testsuite/TestSuite_vs140.vcxproj.filters | 60 + Prometheus/testsuite/TestSuite_vs150.vcxproj | 637 + .../testsuite/TestSuite_vs150.vcxproj.filters | 60 + Prometheus/testsuite/TestSuite_vs160.vcxproj | 637 + .../testsuite/TestSuite_vs160.vcxproj.filters | 60 + Prometheus/testsuite/TestSuite_vs170.vcxproj | 929 + .../testsuite/TestSuite_vs170.vcxproj.filters | 60 + Prometheus/testsuite/TestSuite_vs90.vcproj | 630 + .../testsuite/src/CallbackMetricTest.cpp | 79 + Prometheus/testsuite/src/CallbackMetricTest.h | 35 + Prometheus/testsuite/src/CounterTest.cpp | 240 + Prometheus/testsuite/src/CounterTest.h | 39 + Prometheus/testsuite/src/Driver.cpp | 17 + Prometheus/testsuite/src/GaugeTest.cpp | 204 + Prometheus/testsuite/src/GaugeTest.h | 38 + Prometheus/testsuite/src/HistogramTest.cpp | 178 + Prometheus/testsuite/src/HistogramTest.h | 38 + Prometheus/testsuite/src/IntCounterTest.cpp | 90 + Prometheus/testsuite/src/IntCounterTest.h | 36 + Prometheus/testsuite/src/IntGaugeTest.cpp | 96 + Prometheus/testsuite/src/IntGaugeTest.h | 36 + .../testsuite/src/PrometheusTestSuite.cpp | 32 + .../testsuite/src/PrometheusTestSuite.h | 27 + Prometheus/testsuite/src/WinCEDriver.cpp | 30 + Prometheus/testsuite/src/WinDriver.cpp | 28 + README | 21 +- README.md | 17 +- Redis/CMakeLists.txt | 2 +- Redis/Redis.progen | 1 + Redis/Redis_vs170.sln | 42 + Redis/Redis_vs170.vcxproj | 271 +- Redis/include/Poco/Redis/Command.h | 6 + Redis/src/Array.cpp | 2 +- Redis/src/AsyncReader.cpp | 2 +- Redis/src/Command.cpp | 18 + Redis/testsuite/TestSuite.progen | 1 + Redis/testsuite/TestSuite_vs170.vcxproj | 296 +- Redis/testsuite/src/RedisTest.cpp | 2 +- Redis/testsuite/src/WinCEDriver.cpp | 2 +- SevenZip/CMakeLists.txt | 2 +- SevenZip/SevenZip.progen | 1 + SevenZip/SevenZip_vs170.sln | 24 + SevenZip/SevenZip_vs170.vcxproj | 277 +- SevenZip/include/Poco/SevenZip/Archive.h | 26 +- SevenZip/include/Poco/SevenZip/ArchiveEntry.h | 30 +- SevenZip/samples/un7zip/src/un7zip.cpp | 42 +- SevenZip/samples/un7zip/un7zip.progen | 1 + SevenZip/src/7z.h | 6 +- SevenZip/src/7zCrc.c | 4 +- SevenZip/src/7zFile.c | 20 +- SevenZip/src/7zIn.c | 24 +- SevenZip/src/Alloc.c | 4 +- SevenZip/src/ArchiveEntry.cpp | 6 +- SevenZip/src/Bra.c | 10 +- SevenZip/src/Bra.h | 8 +- SevenZip/src/BraIA64.c | 10 +- SevenZip/src/CpuArch.c | 2 +- SevenZip/src/LzFind.c | 4 +- SevenZip/src/LzFindMt.c | 16 +- SevenZip/src/LzFindMt.h | 4 +- SevenZip/src/Lzma2Dec.c | 14 +- SevenZip/src/Lzma2Enc.c | 18 +- SevenZip/src/Lzma86Enc.c | 6 +- SevenZip/src/LzmaDec.c | 12 +- SevenZip/src/LzmaDec.h | 4 +- SevenZip/src/LzmaEnc.c | 40 +- SevenZip/src/LzmaLib.h | 4 +- SevenZip/src/MtCoder.c | 4 +- SevenZip/src/MtCoder.h | 4 +- SevenZip/src/Ppmd.h | 2 +- SevenZip/src/Ppmd7.c | 36 +- SevenZip/src/Ppmd7.h | 2 +- SevenZip/src/Ppmd7Dec.c | 4 +- SevenZip/src/Ppmd7Enc.c | 6 +- SevenZip/src/Sha256.c | 2 +- SevenZip/src/Xz.h | 2 +- SevenZip/src/XzDec.c | 24 +- SevenZip/src/XzEnc.c | 10 +- SevenZip/src/XzIn.c | 6 +- Util/CMakeLists.txt | 2 +- Util/Makefile | 2 +- Util/Util.progen | 1 + Util/Util_vs140.vcxproj | 4 + Util/Util_vs140.vcxproj.filters | 6 + Util/Util_vs150.vcxproj | 4 + Util/Util_vs150.vcxproj.filters | 6 + Util/Util_vs160.vcxproj | 4 + Util/Util_vs160.vcxproj.filters | 6 + Util/Util_vs170.sln | 42 + Util/Util_vs170.vcxproj | 275 +- Util/Util_vs170.vcxproj.filters | 6 + Util/Util_vs90.vcproj | 8 + .../include/Poco/Util/AbstractConfiguration.h | 63 +- Util/include/Poco/Util/ConfigurationMapper.h | 6 +- Util/include/Poco/Util/ConfigurationView.h | 8 +- .../Poco/Util/FilesystemConfiguration.h | 4 +- Util/include/Poco/Util/HelpFormatter.h | 34 +- Util/include/Poco/Util/IniFileConfiguration.h | 12 +- Util/include/Poco/Util/JSONConfiguration.h | 6 +- Util/include/Poco/Util/LayeredConfiguration.h | 16 +- .../Poco/Util/LocalConfigurationView.h | 71 + Util/include/Poco/Util/LoggingConfigurator.h | 16 +- Util/include/Poco/Util/LoggingSubsystem.h | 2 +- Util/include/Poco/Util/MapConfiguration.h | 2 +- Util/include/Poco/Util/Option.h | 2 +- Util/include/Poco/Util/OptionCallback.h | 16 +- Util/include/Poco/Util/OptionProcessor.h | 8 +- Util/include/Poco/Util/OptionSet.h | 10 +- .../Poco/Util/PropertyFileConfiguration.h | 14 +- Util/include/Poco/Util/RegExpValidator.h | 2 +- Util/include/Poco/Util/ServerApplication.h | 24 +- Util/include/Poco/Util/SystemConfiguration.h | 10 +- Util/include/Poco/Util/TimerTask.h | 17 +- Util/include/Poco/Util/TimerTaskAdapter.h | 12 +- Util/include/Poco/Util/Units.h | 120 +- .../Poco/Util/WinRegistryConfiguration.h | 2 +- Util/include/Poco/Util/WinService.h | 20 +- Util/include/Poco/Util/XMLConfiguration.h | 16 +- Util/samples/SampleApp/SampleApp.progen | 1 + Util/samples/SampleApp/src/SampleApp.cpp | 24 +- Util/samples/SampleServer/SampleServer.progen | 1 + .../samples/SampleServer/src/SampleServer.cpp | 10 +- Util/samples/Units/Makefile | 2 +- Util/samples/Units/Units.progen | 1 + Util/samples/Units/src/Units.cpp | 36 +- Util/samples/pkill/pkill.progen | 1 + Util/samples/pkill/src/pkill.cpp | 14 +- Util/src/AbstractConfiguration.cpp | 43 +- Util/src/ConfigurationMapper.cpp | 2 +- Util/src/ConfigurationView.cpp | 2 +- Util/src/FilesystemConfiguration.cpp | 2 +- Util/src/HelpFormatter.cpp | 8 +- Util/src/IniFileConfiguration.cpp | 6 +- Util/src/JSONConfiguration.cpp | 50 +- Util/src/LayeredConfiguration.cpp | 4 +- Util/src/LocalConfigurationView.cpp | 70 + Util/src/LoggingConfigurator.cpp | 8 +- Util/src/LoggingSubsystem.cpp | 2 +- Util/src/Option.cpp | 2 +- Util/src/OptionProcessor.cpp | 2 +- Util/src/OptionSet.cpp | 2 +- Util/src/PropertyFileConfiguration.cpp | 8 +- Util/src/Timer.cpp | 2 +- Util/src/WinService.cpp | 22 +- Util/src/XMLConfiguration.cpp | 14 +- Util/testsuite/Makefile | 2 +- Util/testsuite/TestSuite.progen | 1 + Util/testsuite/TestSuite_vs140.vcxproj | 4 + .../testsuite/TestSuite_vs140.vcxproj.filters | 6 + Util/testsuite/TestSuite_vs150.vcxproj | 4 + .../testsuite/TestSuite_vs150.vcxproj.filters | 6 + Util/testsuite/TestSuite_vs160.vcxproj | 4 + .../testsuite/TestSuite_vs160.vcxproj.filters | 6 + Util/testsuite/TestSuite_vs170.vcxproj | 300 +- .../testsuite/TestSuite_vs170.vcxproj.filters | 6 + Util/testsuite/TestSuite_vs90.vcproj | 4 + .../src/AbstractConfigurationTest.cpp | 36 +- .../testsuite/src/AbstractConfigurationTest.h | 4 +- .../testsuite/src/ConfigurationMapperTest.cpp | 14 +- Util/testsuite/src/ConfigurationTestSuite.cpp | 2 + Util/testsuite/src/ConfigurationViewTest.cpp | 14 +- .../src/FilesystemConfigurationTest.cpp | 6 +- Util/testsuite/src/HelpFormatterTest.cpp | 12 +- .../src/IniFileConfigurationTest.cpp | 14 +- Util/testsuite/src/JSONConfigurationTest.cpp | 21 + Util/testsuite/src/JSONConfigurationTest.h | 1 + .../src/LayeredConfigurationTest.cpp | 36 +- .../src/LocalConfigurationViewTest.cpp | 114 + .../src/LocalConfigurationViewTest.h | 34 + .../testsuite/src/LoggingConfiguratorTest.cpp | 20 +- Util/testsuite/src/MapConfigurationTest.cpp | 4 +- Util/testsuite/src/OptionProcessorTest.cpp | 54 +- Util/testsuite/src/OptionSetTest.cpp | 8 +- Util/testsuite/src/OptionTest.cpp | 48 +- .../src/PropertyFileConfigurationTest.cpp | 16 +- .../testsuite/src/SystemConfigurationTest.cpp | 8 +- Util/testsuite/src/TimerTest.cpp | 2 +- Util/testsuite/src/ValidatorTest.cpp | 6 +- Util/testsuite/src/WinCEDriver.cpp | 2 +- Util/testsuite/src/WinConfigurationTest.cpp | 8 +- Util/testsuite/src/WinRegistryTest.cpp | 10 +- Util/testsuite/src/WinServiceTest.cpp | 20 +- Util/testsuite/src/XMLConfigurationTest.cpp | 34 +- VERSION | 2 +- XML/CMakeLists.txt | 2 +- XML/XML.progen | 1 + XML/XML_vs170.sln | 42 + XML/XML_vs170.vcxproj | 289 +- XML/include/Poco/DOM/Attr.h | 12 +- XML/include/Poco/DOM/AttrMap.h | 2 +- XML/include/Poco/DOM/CDATASection.h | 8 +- XML/include/Poco/DOM/CharacterData.h | 8 +- XML/include/Poco/DOM/ChildNodesList.h | 4 +- XML/include/Poco/DOM/Comment.h | 2 +- XML/include/Poco/DOM/DOMBuilder.h | 6 +- XML/include/Poco/DOM/DOMException.h | 18 +- XML/include/Poco/DOM/DOMImplementation.h | 14 +- XML/include/Poco/DOM/DOMObject.h | 4 +- XML/include/Poco/DOM/DOMParser.h | 10 +- XML/include/Poco/DOM/DOMSerializer.h | 8 +- XML/include/Poco/DOM/DOMWriter.h | 6 +- XML/include/Poco/DOM/DTDMap.h | 6 +- XML/include/Poco/DOM/Document.h | 40 +- XML/include/Poco/DOM/DocumentFragment.h | 10 +- XML/include/Poco/DOM/DocumentType.h | 10 +- XML/include/Poco/DOM/Element.h | 24 +- XML/include/Poco/DOM/ElementsByTagNameList.h | 4 +- XML/include/Poco/DOM/Entity.h | 14 +- XML/include/Poco/DOM/EntityReference.h | 6 +- XML/include/Poco/DOM/Event.h | 52 +- XML/include/Poco/DOM/EventDispatcher.h | 18 +- XML/include/Poco/DOM/EventException.h | 8 +- XML/include/Poco/DOM/EventListener.h | 4 +- XML/include/Poco/DOM/EventTarget.h | 30 +- XML/include/Poco/DOM/MutationEvent.h | 28 +- XML/include/Poco/DOM/NamedNodeMap.h | 8 +- XML/include/Poco/DOM/Node.h | 40 +- XML/include/Poco/DOM/NodeAppender.h | 4 +- XML/include/Poco/DOM/NodeFilter.h | 16 +- XML/include/Poco/DOM/NodeIterator.h | 18 +- XML/include/Poco/DOM/NodeList.h | 6 +- XML/include/Poco/DOM/Notation.h | 10 +- XML/include/Poco/DOM/ProcessingInstruction.h | 6 +- XML/include/Poco/DOM/Text.h | 4 +- XML/include/Poco/DOM/TreeWalker.h | 18 +- XML/include/Poco/SAX/Attributes.h | 36 +- XML/include/Poco/SAX/AttributesImpl.h | 12 +- XML/include/Poco/SAX/ContentHandler.h | 62 +- XML/include/Poco/SAX/DTDHandler.h | 52 +- XML/include/Poco/SAX/DeclHandler.h | 52 +- XML/include/Poco/SAX/DefaultHandler.h | 22 +- XML/include/Poco/SAX/EntityResolver.h | 52 +- XML/include/Poco/SAX/EntityResolverImpl.h | 16 +- XML/include/Poco/SAX/ErrorHandler.h | 62 +- XML/include/Poco/SAX/InputSource.h | 78 +- XML/include/Poco/SAX/LexicalHandler.h | 92 +- XML/include/Poco/SAX/Locator.h | 74 +- XML/include/Poco/SAX/LocatorImpl.h | 20 +- XML/include/Poco/SAX/NamespaceSupport.h | 56 +- XML/include/Poco/SAX/SAXException.h | 62 +- XML/include/Poco/SAX/WhitespaceFilter.h | 2 +- XML/include/Poco/SAX/XMLFilter.h | 22 +- XML/include/Poco/SAX/XMLFilterImpl.h | 22 +- XML/include/Poco/SAX/XMLReader.h | 124 +- XML/include/Poco/XML/Name.h | 32 +- XML/include/Poco/XML/NamePool.h | 8 +- XML/include/Poco/XML/NamespaceStrategy.h | 12 +- XML/include/Poco/XML/QName.h | 2 +- XML/include/Poco/XML/XML.h | 6 +- XML/include/Poco/XML/XMLString.h | 6 +- XML/include/Poco/XML/XMLWriter.h | 38 +- XML/samples/DOMParser/DOMParser.progen | 1 + XML/samples/DOMParser/src/DOMParser.cpp | 6 +- XML/samples/DOMWriter/DOMWriter.progen | 1 + XML/samples/DOMWriter/src/DOMWriter.cpp | 6 +- XML/samples/PrettyPrint/PrettyPrint.progen | 1 + XML/samples/PrettyPrint/src/PrettyPrint.cpp | 2 +- XML/samples/SAXParser/SAXParser.progen | 1 + XML/samples/SAXParser/src/SAXParser.cpp | 50 +- XML/src/AbstractNode.cpp | 4 +- XML/src/Attr.cpp | 2 +- XML/src/AttrMap.cpp | 6 +- XML/src/AttributesImpl.cpp | 4 +- XML/src/CDATASection.cpp | 4 +- XML/src/CharacterData.cpp | 4 +- XML/src/Comment.cpp | 4 +- XML/src/DOMException.cpp | 6 +- XML/src/DOMImplementation.cpp | 2 +- XML/src/DOMObject.cpp | 2 +- XML/src/DOMSerializer.cpp | 14 +- XML/src/DOMWriter.cpp | 4 +- XML/src/Document.cpp | 14 +- XML/src/DocumentFragment.cpp | 4 +- XML/src/DocumentType.cpp | 4 +- XML/src/Element.cpp | 4 +- XML/src/ElementsByTagNameList.cpp | 4 +- XML/src/Entity.cpp | 4 +- XML/src/EntityReference.cpp | 4 +- XML/src/EntityResolverImpl.cpp | 2 +- XML/src/EventDispatcher.cpp | 8 +- XML/src/MutationEvent.cpp | 8 +- XML/src/Name.cpp | 6 +- XML/src/NamePool.cpp | 18 +- XML/src/NamespaceStrategy.cpp | 4 +- XML/src/NamespaceSupport.cpp | 10 +- XML/src/NodeAppender.cpp | 4 +- XML/src/NodeIterator.cpp | 32 +- XML/src/Notation.cpp | 4 +- XML/src/ProcessingInstruction.cpp | 4 +- XML/src/QName.cpp | 4 +- XML/src/SAXException.cpp | 4 +- XML/src/Text.cpp | 4 +- XML/src/TreeWalker.cpp | 34 +- XML/src/WhitespaceFilter.cpp | 6 +- XML/src/XMLFilterImpl.cpp | 4 +- XML/src/XMLString.cpp | 4 +- XML/src/XMLWriter.cpp | 32 +- XML/src/xmltok.c | 2 +- XML/testsuite/TestSuite.progen | 1 + XML/testsuite/TestSuite_vs170.vcxproj | 296 +- XML/testsuite/src/AttributesImplTest.cpp | 36 +- XML/testsuite/src/ChildNodesTest.cpp | 6 +- XML/testsuite/src/DocumentTest.cpp | 42 +- XML/testsuite/src/DocumentTypeTest.cpp | 12 +- XML/testsuite/src/ElementTest.h | 2 +- XML/testsuite/src/EventTest.cpp | 100 +- XML/testsuite/src/NamePoolTest.cpp | 8 +- XML/testsuite/src/NameTest.cpp | 12 +- XML/testsuite/src/NameTest.h | 2 +- XML/testsuite/src/NamespaceSupportTest.cpp | 30 +- XML/testsuite/src/NodeAppenderTest.cpp | 36 +- XML/testsuite/src/NodeIteratorTest.cpp | 32 +- XML/testsuite/src/NodeTest.cpp | 62 +- XML/testsuite/src/ParserWriterTest.cpp | 8 +- XML/testsuite/src/SAXParserTest.cpp | 20 +- XML/testsuite/src/TreeWalkerTest.cpp | 58 +- XML/testsuite/src/WinCEDriver.cpp | 2 +- Zip/CMakeLists.txt | 2 +- Zip/Zip.progen | 1 + Zip/Zip_vs170.sln | 42 + Zip/Zip_vs170.vcxproj | 279 +- Zip/include/Poco/Zip/AutoDetectStream.h | 10 +- Zip/include/Poco/Zip/Compress.h | 4 +- Zip/include/Poco/Zip/Decompress.h | 2 +- Zip/include/Poco/Zip/PartialStream.h | 8 +- Zip/include/Poco/Zip/ZipArchive.h | 2 +- Zip/include/Poco/Zip/ZipArchiveInfo.h | 8 +- Zip/include/Poco/Zip/ZipFileInfo.h | 11 +- Zip/include/Poco/Zip/ZipManipulator.h | 4 +- Zip/include/Poco/Zip/ZipStream.h | 2 +- Zip/include/Poco/Zip/ZipUtil.h | 2 +- Zip/samples/unzip/src/unzip.cpp | 16 +- Zip/samples/unzip/unzip.progen | 1 + Zip/samples/zip/src/zip.cpp | 16 +- Zip/samples/zip/zip.progen | 1 + Zip/src/AutoDetectStream.cpp | 8 +- Zip/src/Compress.cpp | 14 +- Zip/src/ZipArchiveInfo.cpp | 2 +- Zip/src/ZipLocalFileHeader.cpp | 3 +- Zip/src/ZipManipulator.cpp | 4 +- Zip/src/ZipUtil.cpp | 10 +- Zip/testsuite/TestSuite.progen | 1 + Zip/testsuite/TestSuite_vs170.vcxproj | 296 +- Zip/testsuite/src/PartialStreamTest.cpp | 10 +- Zip/testsuite/src/WinCEDriver.cpp | 2 +- Zip/testsuite/src/ZipTest.h | 2 +- Zip/testsuite/testfile.txt | 82 +- Zip/testsuite/testfile2.txt | 82 +- Zip/testsuite/testfile3.txt | 82 +- build/config/AIX | 4 +- build/config/ARM-Linux | 2 +- build/config/Android | 10 +- build/config/AppleTV | 20 +- build/config/AppleTVSimulator | 2 +- build/config/CEGCCARM | 10 +- build/config/CygLinux | 4 +- build/config/Cygwin | 34 +- build/config/FreeBSD-Linux-compat | 4 +- build/config/HP-UX | 4 +- build/config/Linux-SolarisStudio | 4 +- build/config/Linux-clang | 2 +- build/config/MinGW | 2 +- build/config/MinGW-CrossEnv | 2 +- build/config/NIOS2-Linux | 2 +- build/config/OSF1 | 20 +- build/config/QNX | 6 +- build/config/SmartOS-gcc | 2 +- build/config/SunOS-GCC | 4 +- build/config/SunOS-SunForte | 2 +- build/config/SunOS-SunStudio | 2 +- build/config/SunOS-SunStudio11 | 2 +- build/config/SunOS-stdcxx-x86_64 | 2 +- build/config/WatchOS | 20 +- build/config/WatchSimulator | 2 +- build/config/iPhone-clang | 2 +- build/config/iPhone-clang-libc++ | 2 +- build/config/iPhoneSimulator | 2 +- build/config/iPhoneSimulator-clang | 2 +- build/config/iPhoneSimulator-clang-libc++ | 2 +- build/rules/dylib | 4 + build/rules/exec | 4 + build/rules/global | 8 +- build/rules/lib | 4 + build/rules/sample | 2 +- build/script/makedepend.aCC | 2 +- build/script/makeldpath | 2 +- build/script/vxprogen | 6 +- build_vs170.cmd | 2 + buildwin.cmd | 18 +- buildwin.ps1 | 700 +- ci/runtests.sh | 4 + cmake/FindODBC.cmake | 6 +- cmake/FindPCRE.cmake | 107 - cmake/FindPCRE2.cmake | 107 + cmake/PocoMacros.cmake | 2 +- cmake/UseEmbeddedOpenSSL.cmake | 4 +- components | 1 + configure | 17 + doc/00200-GettingStarted.page | 2 +- doc/99100-ReleaseNotes.page | 134 + doc/99200-WinCEPlatformNotes.page | 28 +- doc/99250-VxWorksPlatformNotes.page | 28 +- doc/99300-AndroidPlatformNotes.page | 30 +- libversion | 2 +- packaging/README.md | 6 +- packaging/README.txt | 2 +- packaging/Windows/NuGet/Poco.shared.nuspec | 4 +- packaging/Windows/NuGet/Poco.static.nuspec | 4 +- packaging/Windows/NuGet/Poco.static.targets | 2 +- packaging/Windows/NuGet/bap.cmd | 4 +- packaging/Windows/NuGet/pack.cmd | 6 +- release/script/mkrel | 2 +- release/spec/all.release | 1 + tsan.suppress | 25 + 2123 files changed, 146150 insertions(+), 72786 deletions(-) create mode 100644 Crypto/include/Poco/Crypto/EVPCipherImpl.h create mode 100644 Crypto/include/Poco/Crypto/Envelope.h create mode 100644 Crypto/src/EVPCipherImpl.cpp create mode 100644 Crypto/src/Envelope.cpp create mode 100644 Crypto/testsuite/src/EnvelopeTest.cpp create mode 100644 Crypto/testsuite/src/EnvelopeTest.h create mode 100755 Data/MySQL/testsuite/run-db-setup.sh create mode 100644 Data/PostgreSQL/include/Poco/Data/PostgreSQL/BinaryExtractor.h create mode 100644 Data/PostgreSQL/src/BinaryExtractor.cpp mode change 100644 => 100755 Data/SQLite/testsuite/src/SQLiteTest.cpp mode change 100644 => 100755 Data/SQLite/testsuite/src/SQLiteTest.h create mode 100644 Data/include/Poco/Data/JSONRowFormatter.h create mode 100644 Data/include/Poco/Data/Transcoder.h create mode 100644 Data/src/JSONRowFormatter.cpp create mode 100644 Data/src/Transcoder.cpp mode change 100644 => 100755 Foundation/include/Poco/AbstractObserver.h mode change 100644 => 100755 Foundation/include/Poco/NObserver.h mode change 100644 => 100755 Foundation/include/Poco/Observer.h delete mode 100644 Foundation/src/diy-fp.cc create mode 100644 Foundation/src/double-to-string.cc create mode 100644 Foundation/src/double-to-string.h delete mode 100644 Foundation/src/pcre.h create mode 100644 Foundation/src/pcre2.h create mode 100644 Foundation/src/pcre2_auto_possess.c rename Foundation/src/{pcre_chartables.c => pcre2_chartables.c} (67%) create mode 100644 Foundation/src/pcre2_compile.c create mode 100644 Foundation/src/pcre2_config.c create mode 100644 Foundation/src/pcre2_config.h create mode 100644 Foundation/src/pcre2_context.c create mode 100644 Foundation/src/pcre2_convert.c rename Foundation/src/{pcre_dfa_exec.c => pcre2_dfa_match.c} (64%) create mode 100644 Foundation/src/pcre2_error.c create mode 100644 Foundation/src/pcre2_extuni.c create mode 100644 Foundation/src/pcre2_find_bracket.c create mode 100644 Foundation/src/pcre2_internal.h create mode 100644 Foundation/src/pcre2_intmodedep.h rename Foundation/src/{pcre_jit_compile.c => pcre2_jit_compile.c} (57%) create mode 100644 Foundation/src/pcre2_jit_match.c create mode 100644 Foundation/src/pcre2_jit_misc.c rename Foundation/src/{pcre_maketables.c => pcre2_maketables.c} (56%) create mode 100644 Foundation/src/pcre2_match.c create mode 100644 Foundation/src/pcre2_match_data.c rename Foundation/src/{pcre_newline.c => pcre2_newline.c} (64%) rename Foundation/src/{pcre_ord2utf8.c => pcre2_ord2utf.c} (65%) create mode 100644 Foundation/src/pcre2_pattern_info.c create mode 100644 Foundation/src/pcre2_script_run.c create mode 100644 Foundation/src/pcre2_serialize.c create mode 100644 Foundation/src/pcre2_string_utils.c create mode 100644 Foundation/src/pcre2_study.c create mode 100644 Foundation/src/pcre2_substitute.c create mode 100644 Foundation/src/pcre2_substring.c create mode 100644 Foundation/src/pcre2_tables.c create mode 100644 Foundation/src/pcre2_ucd.c create mode 100644 Foundation/src/pcre2_ucp.h create mode 100644 Foundation/src/pcre2_ucptables.c rename Foundation/src/{pcre_valid_utf8.c => pcre2_valid_utf.c} (51%) rename Foundation/src/{pcre_xclass.c => pcre2_xclass.c} (81%) delete mode 100644 Foundation/src/pcre_byte_order.c delete mode 100644 Foundation/src/pcre_compile.c delete mode 100644 Foundation/src/pcre_config.c delete mode 100644 Foundation/src/pcre_config.h delete mode 100644 Foundation/src/pcre_exec.c delete mode 100644 Foundation/src/pcre_fullinfo.c delete mode 100644 Foundation/src/pcre_get.c delete mode 100644 Foundation/src/pcre_globals.c delete mode 100644 Foundation/src/pcre_internal.h delete mode 100644 Foundation/src/pcre_refcount.c delete mode 100644 Foundation/src/pcre_string_utils.c delete mode 100644 Foundation/src/pcre_study.c delete mode 100644 Foundation/src/pcre_tables.c delete mode 100644 Foundation/src/pcre_ucd.c delete mode 100644 Foundation/src/pcre_version.c rename Foundation/src/{double-conversion.cc => string-to-double.cc} (62%) create mode 100644 Foundation/src/string-to-double.h create mode 100644 Net/include/Poco/Net/SocketProactor.h create mode 100644 Net/src/SocketProactor.cpp create mode 100644 Net/src/wepoll.c create mode 100644 Net/src/wepoll.h create mode 100644 Net/testsuite/src/SocketConnectorTest.cpp create mode 100644 Net/testsuite/src/SocketConnectorTest.h create mode 100644 Net/testsuite/src/SocketProactorTest.cpp create mode 100644 Net/testsuite/src/SocketProactorTest.h create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/CMakeLists.txt create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/Makefile create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP.progen create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs140.vcxproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs140.vcxproj.filters create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs150.vcxproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs150.vcxproj.filters create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs160.vcxproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs160.vcxproj.filters create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs170.vcxproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs170.vcxproj.filters create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_vs90.vcproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_x64_vs140.vcxproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_x64_vs140.vcxproj.filters create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_x64_vs150.vcxproj create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIP_x64_vs150.vcxproj.filters create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/SetSourceIp.readme create mode 100644 NetSSL_OpenSSL/samples/SetSourceIP/src/SetSourceIP.cpp create mode 100644 NetSSL_OpenSSL/testsuite/dhparams.pem create mode 100644 ProGen/templates/vs170/Win32/executable/debug_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/executable/debug_static_md-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/executable/debug_static_mt-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/executable/release_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/executable/release_static_md-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/executable/release_static_mt-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/library/debug_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/library/debug_static_md-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/library/debug_static_mt-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/library/release_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/library/release_static_md-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/library/release_static_mt-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/plugin/debug_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/plugin/release_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/testsuite/debug_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/testsuite/debug_static_md-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/testsuite/debug_static_mt-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/testsuite/release_shared-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/testsuite/release_static_md-ARM64.template create mode 100644 ProGen/templates/vs170/Win32/testsuite/release_static_mt-ARM64.template create mode 100644 Prometheus/CMakeLists.txt create mode 100644 Prometheus/Makefile create mode 100644 Prometheus/Prometheus.progen create mode 100644 Prometheus/Prometheus_vs140.sln create mode 100644 Prometheus/Prometheus_vs140.vcxproj create mode 100644 Prometheus/Prometheus_vs140.vcxproj.filters create mode 100644 Prometheus/Prometheus_vs150.sln create mode 100644 Prometheus/Prometheus_vs150.vcxproj create mode 100644 Prometheus/Prometheus_vs150.vcxproj.filters create mode 100644 Prometheus/Prometheus_vs160.sln create mode 100644 Prometheus/Prometheus_vs160.vcxproj create mode 100644 Prometheus/Prometheus_vs160.vcxproj.filters create mode 100644 Prometheus/Prometheus_vs170.sln create mode 100644 Prometheus/Prometheus_vs170.vcxproj create mode 100644 Prometheus/Prometheus_vs170.vcxproj.filters create mode 100644 Prometheus/Prometheus_vs90.sln create mode 100644 Prometheus/Prometheus_vs90.vcproj create mode 100644 Prometheus/cmake/PocoPrometheusConfig.cmake create mode 100644 Prometheus/dependencies create mode 100644 Prometheus/include/Poco/Prometheus/AtomicFloat.h create mode 100644 Prometheus/include/Poco/Prometheus/CallbackMetric.h create mode 100644 Prometheus/include/Poco/Prometheus/Collector.h create mode 100644 Prometheus/include/Poco/Prometheus/Counter.h create mode 100644 Prometheus/include/Poco/Prometheus/Exporter.h create mode 100644 Prometheus/include/Poco/Prometheus/Gauge.h create mode 100644 Prometheus/include/Poco/Prometheus/Histogram.h create mode 100644 Prometheus/include/Poco/Prometheus/IntCounter.h create mode 100644 Prometheus/include/Poco/Prometheus/IntGauge.h create mode 100644 Prometheus/include/Poco/Prometheus/LabeledMetric.h create mode 100644 Prometheus/include/Poco/Prometheus/LabeledMetricImpl.h create mode 100644 Prometheus/include/Poco/Prometheus/Metric.h create mode 100644 Prometheus/include/Poco/Prometheus/MetricsRequestHandler.h create mode 100644 Prometheus/include/Poco/Prometheus/MetricsServer.h create mode 100644 Prometheus/include/Poco/Prometheus/ProcessCollector.h create mode 100644 Prometheus/include/Poco/Prometheus/Prometheus.h create mode 100644 Prometheus/include/Poco/Prometheus/Registry.h create mode 100644 Prometheus/include/Poco/Prometheus/TextExporter.h create mode 100644 Prometheus/include/Poco/Prometheus/ThreadPoolCollector.h create mode 100644 Prometheus/samples/CMakeLists.txt create mode 100644 Prometheus/samples/Makefile create mode 100644 Prometheus/samples/MetricsSample/CMakeLists.txt create mode 100644 Prometheus/samples/MetricsSample/Makefile create mode 100644 Prometheus/samples/MetricsSample/MetricsSample.progen create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs140.vcxproj create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs140.vcxproj.filters create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs150.vcxproj create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs150.vcxproj.filters create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs160.vcxproj create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs160.vcxproj.filters create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs170.vcxproj create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs170.vcxproj.filters create mode 100644 Prometheus/samples/MetricsSample/MetricsSample_vs90.vcproj create mode 100644 Prometheus/samples/MetricsSample/src/MetricsSample.cpp create mode 100644 Prometheus/samples/dependencies create mode 100644 Prometheus/samples/samples_vs140.sln create mode 100644 Prometheus/samples/samples_vs150.sln create mode 100644 Prometheus/samples/samples_vs160.sln create mode 100644 Prometheus/samples/samples_vs170.sln create mode 100644 Prometheus/src/Collector.cpp create mode 100644 Prometheus/src/Counter.cpp create mode 100644 Prometheus/src/Gauge.cpp create mode 100644 Prometheus/src/Histogram.cpp create mode 100644 Prometheus/src/IntCounter.cpp create mode 100644 Prometheus/src/IntGauge.cpp create mode 100644 Prometheus/src/LabeledMetric.cpp create mode 100644 Prometheus/src/MetricsRequestHandler.cpp create mode 100644 Prometheus/src/MetricsServer.cpp create mode 100644 Prometheus/src/ProcessCollector.cpp create mode 100644 Prometheus/src/Registry.cpp create mode 100644 Prometheus/src/TextExporter.cpp create mode 100644 Prometheus/src/ThreadPoolCollector.cpp create mode 100644 Prometheus/testsuite/CMakeLists.txt create mode 100644 Prometheus/testsuite/Makefile create mode 100644 Prometheus/testsuite/TestSuite.progen create mode 100644 Prometheus/testsuite/TestSuite_vs140.vcxproj create mode 100644 Prometheus/testsuite/TestSuite_vs140.vcxproj.filters create mode 100644 Prometheus/testsuite/TestSuite_vs150.vcxproj create mode 100644 Prometheus/testsuite/TestSuite_vs150.vcxproj.filters create mode 100644 Prometheus/testsuite/TestSuite_vs160.vcxproj create mode 100644 Prometheus/testsuite/TestSuite_vs160.vcxproj.filters create mode 100644 Prometheus/testsuite/TestSuite_vs170.vcxproj create mode 100644 Prometheus/testsuite/TestSuite_vs170.vcxproj.filters create mode 100644 Prometheus/testsuite/TestSuite_vs90.vcproj create mode 100644 Prometheus/testsuite/src/CallbackMetricTest.cpp create mode 100644 Prometheus/testsuite/src/CallbackMetricTest.h create mode 100644 Prometheus/testsuite/src/CounterTest.cpp create mode 100644 Prometheus/testsuite/src/CounterTest.h create mode 100644 Prometheus/testsuite/src/Driver.cpp create mode 100644 Prometheus/testsuite/src/GaugeTest.cpp create mode 100644 Prometheus/testsuite/src/GaugeTest.h create mode 100644 Prometheus/testsuite/src/HistogramTest.cpp create mode 100644 Prometheus/testsuite/src/HistogramTest.h create mode 100644 Prometheus/testsuite/src/IntCounterTest.cpp create mode 100644 Prometheus/testsuite/src/IntCounterTest.h create mode 100644 Prometheus/testsuite/src/IntGaugeTest.cpp create mode 100644 Prometheus/testsuite/src/IntGaugeTest.h create mode 100644 Prometheus/testsuite/src/PrometheusTestSuite.cpp create mode 100644 Prometheus/testsuite/src/PrometheusTestSuite.h create mode 100644 Prometheus/testsuite/src/WinCEDriver.cpp create mode 100644 Prometheus/testsuite/src/WinDriver.cpp create mode 100644 Util/include/Poco/Util/LocalConfigurationView.h create mode 100644 Util/src/LocalConfigurationView.cpp create mode 100644 Util/testsuite/src/LocalConfigurationViewTest.cpp create mode 100644 Util/testsuite/src/LocalConfigurationViewTest.h create mode 100644 build_vs170.cmd delete mode 100644 cmake/FindPCRE.cmake create mode 100644 cmake/FindPCRE2.cmake create mode 100644 tsan.suppress diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e8e73a280..5af0030b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,23 +1,54 @@ name: poco-ci -on: [push] +on: [push, pull_request] jobs: linux-gcc-make: runs-on: ubuntu-20.04 + services: + mysql: + image: mysql:latest + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_USER: pocotest + MYSQL_PASSWORD: pocotest + MYSQL_DATABASE: pocotest + ports: + - 3306:3306 steps: - uses: actions/checkout@v2 - - run: sudo apt update && sudo apt install libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev redis-server libmysqlclient-dev - run: ./configure --everything --omit=PDF && make all -s -j4 && sudo make install - run: >- sudo -s - EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB" + EXCLUDE_TESTS="Data/ODBC Data/PostgreSQL MongoDB" ./ci/runtests.sh linux-gcc-make-asan: runs-on: ubuntu-20.04 + services: + mysql: + image: mysql:latest + env: + MYSQL_ALLOW_EMPTY_PASSWORD: yes + MYSQL_USER: pocotest + MYSQL_PASSWORD: pocotest + MYSQL_DATABASE: pocotest + ports: + - 3306:3306 steps: - uses: actions/checkout@v2 - - run: sudo apt update && sudo apt install libssl-dev unixodbc-dev libmysqlclient-dev redis-server - - run: ./configure --everything --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install + - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install + - run: >- + sudo -s + EXCLUDE_TESTS="Data/ODBC Data/PostgreSQL MongoDB" + ./ci/runtests.sh + + linux-gcc-make-asan-no-soo: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: ./configure --everything --no-samples --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install - run: >- sudo -s EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB" @@ -27,18 +58,28 @@ jobs: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - run: sudo apt update && sudo apt install libssl-dev unixodbc-dev libmysqlclient-dev redis-server - - run: ./configure --everything --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install + - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: ./configure --everything --no-samples --omit=PDF && make all -s -j4 SANITIZEFLAGS=-fsanitize=undefined && sudo make install - run: >- sudo -s EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB" ./ci/runtests.sh + linux-gcc-make-tsan: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + - run: sudo apt -y update && sudo apt -y install libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: ./configure --everything --no-samples --omit=CppParser,Encodings,Data/MySQL,Data/ODBC,Data/PostgreSQL,MongoDB,PageCompiler,PDF,PocoDoc,ProGen,Redis,SevenZip && make all -s -j4 SANITIZEFLAGS=-fsanitize=thread && sudo make install + - run: >- + sudo -s + ./ci/runtests.sh TSAN + linux-gcc-cmake: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - - run: sudo apt update && sudo apt install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server + - run: sudo apt -y update && sudo apt -y install cmake ninja-build libssl-dev unixodbc-dev libmysqlclient-dev redis-server - run: cmake -H. -Bcmake-build -GNinja -DENABLE_PDF=OFF -DENABLE_TESTS=ON && cmake --build cmake-build --target all - run: >- cd cmake-build && @@ -51,8 +92,8 @@ jobs: steps: - uses: actions/checkout@v2 - run: >- - sudo apt-get update && - sudo apt-get install crossbuild-essential-armhf + sudo apt-get -y update && + sudo apt-get -y install crossbuild-essential-armhf - run: >- ./configure --config=ARM-Linux --everything --omit=PDF,Crypto,NetSSL_OpenSSL,JWT,Data/MySQL,Data/ODBC,Data/PostgreSQL,PageCompiler,PageCompiler/File2Page && make all -s -j4 ARCHFLAGS="-mcpu=cortex-a8 -mfloat-abi=hard -mfpu=neon" TOOL=arm-linux-gnueabihf @@ -118,3 +159,16 @@ jobs: - run: >- cd cmake-build; ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Release + +# missing asan dll path +# windows-2022-msvc-cmake-2022-asan: +# runs-on: windows-2022 +# env: +# CPPUNIT_IGNORE: class CppUnit::TestCaller.testFind,class CppUnit::TestCaller.testSendToReceiveFrom,class CppUnit::TestCaller.testPing,class CppUnit::TestCaller.testBigPing,class CppUnit::TestCaller.testMTU,class CppUnit::TestCaller.testProxy,class CppUnit::TestCaller.testProxy +# steps: +# - uses: actions/checkout@v2 +# - run: cmake -S. -Bcmake-build -DPOCO_SANITIZE_ASAN=ON -DENABLE_NETSSL_WIN=ON -DENABLE_NETSSL=OFF -DENABLE_CRYPTO=OFF -DENABLE_JWT=OFF -DENABLE_DATA=ON -DENABLE_DATA_ODBC=ON -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_TESTS=ON +# - run: cmake --build cmake-build --config Debug +# - run: >- +# cd cmake-build; +# ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(Redis)|(MongoDB)" -C Debug diff --git a/.gitignore b/.gitignore index a326021e3..b334caf22 100644 --- a/.gitignore +++ b/.gitignore @@ -144,3 +144,10 @@ cmake-build/ *.bak stage/ releases/ + +# vim # +####### +*.orig +*.swp +*.vim +tags diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index bb03adf50..9ba835918 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -1,64 +1,76 @@ { - "env": { - "POCO_BASE": "${workspaceFolder}", - "pocoIncludePath": [ - "${POCO_BASE}/CppUnit/include", - "${POCO_BASE}/Foundation/include", - "${POCO_BASE}/Encodings/include", - "${POCO_BASE}/XML/include", - "${POCO_BASE}/JSON/include", - "${POCO_BASE}/Util/include", - "${POCO_BASE}/Net/include", - "${POCO_BASE}/Crypto/include", - "${POCO_BASE}/NetSSL_OpenSSL/include", - "${POCO_BASE}/Data/include", - "${POCO_BASE}/Data/SQLite/include", - "${POCO_BASE}/Data/ODBC/include", - "${POCO_BASE}/Data/MySQL/include", - "${POCO_BASE}/Data/PostgreSQL/include", - "${POCO_BASE}/ActiveRecord/include", - "${POCO_BASE}/Zip/include", - "${POCO_BASE}/CppParser/include", - "${POCO_BASE}/JWT/include", - "${POCO_BASE}/Redis/include", - "${POCO_BASE}/MongoDB/include", - "${POCO_BASE}/ApacheConnector/include" - ] - }, - "configurations": [ - { - "name": "Mac", - "intelliSenseMode": "clang-x64", - "includePath": ["${pocoIncludePath}", "/usr/local/opt/openssl@3/include"], - "macFrameworkPath": ["/System/Library/Frameworks"], - "defines": [], - "forcedInclude": [], - "compilerPath": "/usr/bin/clang", - "cStandard": "c11", - "cppStandard": "c++14", - "compileCommands": "", - "browse": { - "path": ["${workspaceFolder}"], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } + "env": { + "POCO_BASE": "${workspaceFolder}", + "pocoIncludePath": [ + "${POCO_BASE}/CppUnit/include", + "${POCO_BASE}/Foundation/include", + "${POCO_BASE}/Encodings/include", + "${POCO_BASE}/XML/include", + "${POCO_BASE}/JSON/include", + "${POCO_BASE}/Util/include", + "${POCO_BASE}/Net/include", + "${POCO_BASE}/Crypto/include", + "${POCO_BASE}/NetSSL_OpenSSL/include", + "${POCO_BASE}/Data/include", + "${POCO_BASE}/Data/SQLite/include", + "${POCO_BASE}/Data/ODBC/include", + "${POCO_BASE}/Data/MySQL/include", + "${POCO_BASE}/Data/PostgreSQL/include", + "${POCO_BASE}/ActiveRecord/include", + "${POCO_BASE}/Zip/include", + "${POCO_BASE}/CppParser/include", + "${POCO_BASE}/JWT/include", + "${POCO_BASE}/Redis/include", + "${POCO_BASE}/MongoDB/include", + "${POCO_BASE}/ApacheConnector/include" + ] }, - { - "name": "Linux", - "intelliSenseMode": "gcc-x64", - "includePath": ["${pocoIncludePath}"], - "defines": [], - "forcedInclude": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c11", - "cppStandard": "c++14", - "compileCommands": "", - "browse": { - "path": ["${workspaceFolder}"], - "limitSymbolsToIncludedHeaders": true, - "databaseFilename": "" - } - } - ], - "version": 4 -} + "configurations": [ + { + "name": "Mac", + "intelliSenseMode": "clang-x64", + "includePath": [ + "${pocoIncludePath}", + "/usr/local/opt/openssl@3/include" + ], + "macFrameworkPath": [ + "/System/Library/Frameworks" + ], + "defines": [], + "forcedInclude": [], + "compilerPath": "/usr/bin/clang", + "cStandard": "c11", + "cppStandard": "c++14", + "compileCommands": "", + "browse": { + "path": [ + "${workspaceFolder}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "configurationProvider": "ms-vscode.makefile-tools" + }, + { + "name": "Linux", + "intelliSenseMode": "gcc-x64", + "includePath": [ + "${pocoIncludePath}" + ], + "defines": [], + "forcedInclude": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++14", + "compileCommands": "", + "browse": { + "path": [ + "${workspaceFolder}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index f4358367c..bc8e0af14 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -81,12 +81,23 @@ "unordered_set": "cpp", "utility": "cpp", "vector": "cpp", - "__bits": "cpp" + "*.tcc": "cpp", + "compare": "cpp", + "concepts": "cpp", + "memory_resource": "cpp", + "random": "cpp", + "ranges": "cpp", + "cfenv": "cpp", + "__bits": "cpp", + "variant": "cpp", + "condition_variable": "cpp", + "valarray": "cpp" }, "files.exclude": { "**/.dep": true, "**/bin": true, "**/obj": true }, - "git.ignoreLimitWarning": true + "git.ignoreLimitWarning": true, + "cmake.configureOnOpen": false } diff --git a/ActiveRecord/ActiveRecord_vs170.sln b/ActiveRecord/ActiveRecord_vs170.sln index b712dd3a6..c87e3d4da 100644 --- a/ActiveRecord/ActiveRecord_vs170.sln +++ b/ActiveRecord/ActiveRecord_vs170.sln @@ -15,6 +15,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Compiler", "Compiler\Compil EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 debug_shared|Win32 = debug_shared|Win32 release_shared|Win32 = release_shared|Win32 debug_static_mt|Win32 = debug_static_mt|Win32 @@ -29,6 +35,24 @@ Global release_static_md|x64 = release_static_md|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_shared|Win32.Build.0 = debug_shared|Win32 {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 @@ -65,6 +89,24 @@ Global {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_md|x64.ActiveCfg = release_static_md|x64 {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_md|x64.Build.0 = release_static_md|x64 {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E}.release_static_md|x64.Deploy.0 = release_static_md|x64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_shared|Win32.Build.0 = debug_shared|Win32 {16B8C4E7-6F29-4910-9350-848730F9EF77}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 @@ -101,6 +143,24 @@ Global {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_md|x64.ActiveCfg = release_static_md|x64 {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_md|x64.Build.0 = release_static_md|x64 {16B8C4E7-6F29-4910-9350-848730F9EF77}.release_static_md|x64.Deploy.0 = release_static_md|x64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|Win32.Build.0 = debug_shared|Win32 {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 diff --git a/ActiveRecord/ActiveRecord_vs170.vcxproj b/ActiveRecord/ActiveRecord_vs170.vcxproj index d73a8f41c..d0af33fa4 100644 --- a/ActiveRecord/ActiveRecord_vs170.vcxproj +++ b/ActiveRecord/ActiveRecord_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 ActiveRecord {CCC0A578-E065-4CBA-BB8D-F02BB2C24E7E} ActiveRecord @@ -87,6 +112,36 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + StaticLibrary MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + PocoActiveRecordA64d + PocoActiveRecordmdd + PocoActiveRecordmtd + PocoActiveRecordA64 + PocoActiveRecordmd + PocoActiveRecordmt PocoActiveRecordd PocoActiveRecordmdd PocoActiveRecordmtd @@ -171,6 +250,32 @@ PocoActiveRecordmd PocoActiveRecordmt + + ..\binA64\ + objA64\ActiveRecord\$(Configuration)\ + true + + + ..\binA64\ + objA64\ActiveRecord\$(Configuration)\ + false + + + ..\libA64\ + objA64\ActiveRecord\$(Configuration)\ + + + ..\libA64\ + objA64\ActiveRecord\$(Configuration)\ + + + ..\libA64\ + objA64\ActiveRecord\$(Configuration)\ + + + ..\libA64\ + objA64\ActiveRecord\$(Configuration)\ + ..\bin\ obj\ActiveRecord\$(Configuration)\ @@ -223,6 +328,164 @@ ..\lib64\ obj64\ActiveRecord\$(Configuration)\ + + + Disabled + .\include;..\Foundation\include; ..\Data\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;ActiveRecordLib_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + ..\binA64\PocoActiveRecordA64d.dll + true + true + ..\binA64\PocoActiveRecordA64d.pdb + ..\libA64;%(AdditionalLibraryDirectories) + Console + ..\libA64\PocoActiveRecordd.lib + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include; ..\Data\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;ActiveRecordLib_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + ..\binA64\PocoActiveRecordA64.dll + true + false + ..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\libA64\PocoActiveRecord.lib + MachineARM64 + + + + + Disabled + .\include;..\Foundation\include; ..\Data\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + ..\libA64\PocoActiveRecordmtd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\PocoActiveRecordmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include; ..\Data\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + ..\libA64\PocoActiveRecordmt.lib + + + + + Disabled + .\include;..\Foundation\include; ..\Data\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + ..\libA64\PocoActiveRecordmdd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\PocoActiveRecordmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include; ..\Data\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + ..\libA64\PocoActiveRecordmd.lib + + Disabled @@ -564,12 +827,16 @@ + true true true + true true true + true true true + true true true diff --git a/ActiveRecord/Compiler/Compiler.progen b/ActiveRecord/Compiler/Compiler.progen index 14d6ad151..624f293a6 100644 --- a/ActiveRecord/Compiler/Compiler.progen +++ b/ActiveRecord/Compiler/Compiler.progen @@ -12,5 +12,5 @@ vc.project.compiler.defines = vc.project.compiler.defines.shared = vc.project.compiler.defines.debug_shared = ${vc.project.compiler.defines.shared} vc.project.compiler.defines.release_shared = ${vc.project.compiler.defines.shared} -vc.project.linker.dependencies = +vc.project.linker.dependencies = vc.solution.create = true diff --git a/ActiveRecord/Compiler/Compiler_vs170.sln b/ActiveRecord/Compiler/Compiler_vs170.sln index 615fbaa35..820d34cc9 100644 --- a/ActiveRecord/Compiler/Compiler_vs170.sln +++ b/ActiveRecord/Compiler/Compiler_vs170.sln @@ -4,6 +4,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Compiler", "Compiler_vs170. EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 debug_shared|Win32 = debug_shared|Win32 release_shared|Win32 = release_shared|Win32 debug_static_mt|Win32 = debug_static_mt|Win32 @@ -18,6 +24,24 @@ Global release_static_md|x64 = release_static_md|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {84DD1CB5-4735-478A-B48E-5E4858F0E831}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|Win32.Build.0 = debug_shared|Win32 {84DD1CB5-4735-478A-B48E-5E4858F0E831}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 diff --git a/ActiveRecord/Compiler/Compiler_vs170.vcxproj b/ActiveRecord/Compiler/Compiler_vs170.vcxproj index 755b43ae1..02a5053ac 100644 --- a/ActiveRecord/Compiler/Compiler_vs170.vcxproj +++ b/ActiveRecord/Compiler/Compiler_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 Compiler {84DD1CB5-4735-478A-B48E-5E4858F0E831} Compiler @@ -87,6 +112,36 @@ MultiByte v143 + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + Application MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + arcd + arcd + arcd + arc + arc + arc arcd arcd arcd @@ -171,6 +250,36 @@ arc arc + + binA64\ + objA64\Compiler\$(Configuration)\ + true + + + binA64\ + objA64\Compiler\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\Compiler\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\Compiler\$(Configuration)\ + false + + + binA64\static_md\ + objA64\Compiler\$(Configuration)\ + true + + + binA64\static_md\ + objA64\Compiler\$(Configuration)\ + false + bin\ obj\Compiler\$(Configuration)\ @@ -231,6 +340,187 @@ obj64\Compiler\$(Configuration)\ false + + + Disabled + .\include;..\..\Foundation\include;..\..\XML\include;..\..\Util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + binA64\arcd.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\arcd.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\Foundation\include;..\..\XML\include;..\..\Util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + binA64\arc.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\Foundation\include;..\..\XML\include;..\..\Util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_mt\arcd.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_mt\arcd.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\Foundation\include;..\..\XML\include;..\..\Util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_mt\arc.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + .\include;..\..\Foundation\include;..\..\XML\include;..\..\Util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_md\arcd.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_md\arcd.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\..\Foundation\include;..\..\XML\include;..\..\Util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0500;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_md\arc.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + Disabled diff --git a/ActiveRecord/testsuite/TestSuite_vs170.vcxproj b/ActiveRecord/testsuite/TestSuite_vs170.vcxproj index b78371221..12f536372 100644 --- a/ActiveRecord/testsuite/TestSuite_vs170.vcxproj +++ b/ActiveRecord/testsuite/TestSuite_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 TestSuite {16B8C4E7-6F29-4910-9350-848730F9EF77} TestSuite @@ -87,6 +112,36 @@ MultiByte v143 + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + Application MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + TestSuited + TestSuited + TestSuited + TestSuite + TestSuite + TestSuite TestSuited TestSuited TestSuited @@ -171,6 +250,36 @@ TestSuite TestSuite + + binA64\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\ + objA64\TestSuite\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\TestSuite\$(Configuration)\ + false + + + binA64\static_md\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\static_md\ + objA64\TestSuite\$(Configuration)\ + false + bin\ obj\TestSuite\$(Configuration)\ @@ -231,6 +340,189 @@ obj64\TestSuite\$(Configuration)\ false + + + Disabled + ..\include;..\..\CppUnit\include;..\..\Foundation\include;..\..\Data\include;..\..\Data\SQLite\include;..\..\ActiveRecord\include;.\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitd.lib;%(AdditionalDependencies) + binA64\TestSuited.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\CppUnit\include;..\..\Foundation\include;..\..\Data\include;..\..\Data\SQLite\include;..\..\ActiveRecord\include;.\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + CppUnit.lib;%(AdditionalDependencies) + binA64\TestSuite.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + ..\include;..\..\CppUnit\include;..\..\Foundation\include;..\..\Data\include;..\..\Data\SQLite\include;..\..\ActiveRecord\include;.\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitmtd.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_mt\TestSuited.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_mt\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\CppUnit\include;..\..\Foundation\include;..\..\Data\include;..\..\Data\SQLite\include;..\..\ActiveRecord\include;.\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + CppUnitmt.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_mt\TestSuite.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + ..\include;..\..\CppUnit\include;..\..\Foundation\include;..\..\Data\include;..\..\Data\SQLite\include;..\..\ActiveRecord\include;.\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitmdd.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_md\TestSuited.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_md\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\CppUnit\include;..\..\Foundation\include;..\..\Data\include;..\..\Data\SQLite\include;..\..\ActiveRecord\include;.\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + CppUnitmd.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies) + binA64\static_md\TestSuite.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + Disabled diff --git a/ApacheConnector/ApacheConnector_vs170.sln b/ApacheConnector/ApacheConnector_vs170.sln index 67e7f47c8..86cdecee5 100644 --- a/ApacheConnector/ApacheConnector_vs170.sln +++ b/ApacheConnector/ApacheConnector_vs170.sln @@ -4,12 +4,20 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApacheConnector", "ApacheCo EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 debug_shared|Win32 = debug_shared|Win32 release_shared|Win32 = release_shared|Win32 debug_shared|x64 = debug_shared|x64 release_shared|x64 = release_shared|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {9866EE28-0612-4746-BD35-3B15B0AF7267}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 {9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Build.0 = debug_shared|Win32 {9866EE28-0612-4746-BD35-3B15B0AF7267}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 diff --git a/ApacheConnector/ApacheConnector_vs170.vcxproj b/ApacheConnector/ApacheConnector_vs170.vcxproj index 7409023c3..53d920ca1 100644 --- a/ApacheConnector/ApacheConnector_vs170.vcxproj +++ b/ApacheConnector/ApacheConnector_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + release_shared + ARM64 + release_shared Win32 @@ -19,6 +27,7 @@ + 17.0 ApacheConnector {9866EE28-0612-4746-BD35-3B15B0AF7267} ApacheConnector @@ -35,6 +44,16 @@ MultiByte v143 + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + DynamicLibrary MultiByte @@ -53,6 +72,12 @@ + + + + + + @@ -61,12 +86,24 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + mod_pocoA64d + mod_pocoA64 mod_pocod mod_poco mod_poco64d mod_poco64 + + ..\binA64\ + objA64\ApacheConnector\$(Configuration)\ + true + + + ..\binA64\ + objA64\ApacheConnector\$(Configuration)\ + false + ..\bin\ obj\ApacheConnector\$(Configuration)\ @@ -87,6 +124,70 @@ obj64\ApacheConnector\$(Configuration)\ false + + + Disabled + .\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies) + ..\binA64\mod_pocoA64d.dll + true + true + ..\binA64\mod_pocoA64d.pdb + ..\libA64;%(AdditionalLibraryDirectories) + Console + ..\libA64\mod_pocod.lib + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;..\Net\include;..\Util\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;ApacheHandlers_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + libapr-1.lib;libaprutil-1.lib;libhttpd.lib;%(AdditionalDependencies) + ..\binA64\mod_pocoA64.dll + true + false + ..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\libA64\mod_poco.lib + MachineARM64 + + Disabled diff --git a/ApacheConnector/CMakeLists.txt b/ApacheConnector/CMakeLists.txt index 86d7210a5..544904fe2 100644 --- a/ApacheConnector/CMakeLists.txt +++ b/ApacheConnector/CMakeLists.txt @@ -14,7 +14,7 @@ set_target_properties(mod_poco target_include_directories(mod_poco PUBLIC $ - $ + $ PRIVATE ${APACHE2_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/src diff --git a/ApacheConnector/doc/ApacheConnectorUserGuide.page b/ApacheConnector/doc/ApacheConnectorUserGuide.page index b045dc54e..7c3162221 100644 --- a/ApacheConnector/doc/ApacheConnectorUserGuide.page +++ b/ApacheConnector/doc/ApacheConnectorUserGuide.page @@ -16,7 +16,7 @@ file (usually <[httpd.conf]>): LoadModule poco_module modules/mod_pocod.so ---- - + !!!Configuring ApacheConnector ApacheConnector must be able to find shared libraries containing request handler, as well as optional configuration files. ApacheConnector provides an Poco::Util::Application class @@ -30,7 +30,7 @@ is used in the Apache configuration file: AddPocoRequestHandler ... ---- - + The first argument specifies the name of the request handler factory class. The second argument contains the path of the shared library containing the request handler. The third (and optionally following) argument(s) specify the URI paths handled by the @@ -38,7 +38,7 @@ request handler. For example: AddPocoRequestHandler TimeRequestHandlerFactory p:/Poco/ApacheConnector/samples/TimeServer/bin/TimeServerd.dll /time ---- - + loads the TimeRequestHandlerFactory from TimeServerd.dll. Whenever a request for a URI starting with "/time" is sent by a client, this request will be handled by the TimeRequestHandler. @@ -76,8 +76,8 @@ Following is a sample for a request handler implementation. The complete sample #include "Poco/DateTimeFormatter.h" #include "Poco/DateTimeFormat.h" #include "Poco/ClassLibrary.h" - - + + using Poco::Net::HTTPRequestHandler; using Poco::Net::HTTPRequestHandlerFactory; using Poco::Net::HTTPServerRequest; @@ -85,24 +85,24 @@ Following is a sample for a request handler implementation. The complete sample using Poco::Timestamp; using Poco::DateTimeFormatter; using Poco::DateTimeFormat; - - + + class TimeRequestHandler: public HTTPRequestHandler /// Return a HTML document with the current date and time. { public: - TimeRequestHandler() + TimeRequestHandler() { } - + void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { Timestamp now; std::string dt(DateTimeFormatter::format(now, DateTimeFormat::SORTABLE_FORMAT)); - + response.setChunkedTransferEncoding(true); response.setContentType("text/html"); - + std::ostream& ostr = response.send(); ostr << "TimeServer powered by POCO ApacheConnector"; ostr << ""; @@ -111,22 +111,22 @@ Following is a sample for a request handler implementation. The complete sample ostr << "

"; } }; - - + + class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory { public: TimeRequestHandlerFactory() { } - + HTTPRequestHandler* createRequestHandler(const HTTPServerRequest& request) { return new TimeRequestHandler; } }; - - + + POCO_BEGIN_MANIFEST(HTTPRequestHandlerFactory) POCO_EXPORT_CLASS(TimeRequestHandlerFactory) POCO_END_MANIFEST diff --git a/ApacheConnector/include/ApacheConnector.h b/ApacheConnector/include/ApacheConnector.h index 55a6cf3f3..1de4130ff 100644 --- a/ApacheConnector/include/ApacheConnector.h +++ b/ApacheConnector/include/ApacheConnector.h @@ -25,7 +25,7 @@ class ApacheRequestRec public: ApacheRequestRec(request_rec* _pRec); /// Creates the ApacheRequestRec; - + bool haveRequestBody(); /// Returns true if the request contains a body. diff --git a/ApacheConnector/include/ApacheRequestHandlerFactory.h b/ApacheConnector/include/ApacheRequestHandlerFactory.h index 7e071aab5..f24e86879 100644 --- a/ApacheConnector/include/ApacheRequestHandlerFactory.h +++ b/ApacheConnector/include/ApacheRequestHandlerFactory.h @@ -45,7 +45,7 @@ public: private: typedef std::map RequestHandlerFactories; - + RequestHandlerFactories _requestHandlers; Poco::ClassLoader _loader; Poco::FastMutex _mutex; diff --git a/ApacheConnector/include/ApacheServerRequest.h b/ApacheConnector/include/ApacheServerRequest.h index 825d6b734..6dd9b5c60 100644 --- a/ApacheConnector/include/ApacheServerRequest.h +++ b/ApacheConnector/include/ApacheServerRequest.h @@ -25,10 +25,10 @@ class ApacheServerRequest: public Poco::Net::HTTPServerRequest { public: ApacheServerRequest( - ApacheRequestRec* pApacheRequest, - const char* serverName, - int serverPort, - const char* clientName, + ApacheRequestRec* pApacheRequest, + const char* serverName, + int serverPort, + const char* clientName, int clientPort); /// Creates a new ApacheServerRequest. @@ -73,7 +73,7 @@ private: ApacheInputStream* _pStream; Poco::Net::SocketAddress _serverAddress; Poco::Net::SocketAddress _clientAddress; - + friend class ApacheServerResponse; }; @@ -84,7 +84,7 @@ private: inline std::istream& ApacheServerRequest::stream() { poco_check_ptr (_pStream); - + return *_pStream; } diff --git a/ApacheConnector/include/ApacheServerResponse.h b/ApacheConnector/include/ApacheServerResponse.h index 5b110dea1..ea03caec8 100644 --- a/ApacheConnector/include/ApacheServerResponse.h +++ b/ApacheConnector/include/ApacheServerResponse.h @@ -42,7 +42,7 @@ public: void sendContinue(); /// Sends a 100 Continue response to the /// client. - + void sendErrorResponse(int status); /// Sends an error response with the given /// status back to the client. @@ -55,20 +55,20 @@ public: /// The returned stream is valid until the response /// object is destroyed. /// - /// Must not be called after sendFile(), sendBuffer() + /// Must not be called after sendFile(), sendBuffer() /// or redirect() has been called. - + void sendFile(const std::string& path, const std::string& mediaType); /// Sends the response header to the client, followed /// by the content of the given file. /// - /// Must not be called after send(), sendBuffer() + /// Must not be called after send(), sendBuffer() /// or redirect() has been called. /// /// Throws a FileNotFoundException if the file /// cannot be found, or an OpenFileException if /// the file cannot be opened. - + void sendBuffer(const void* pBuffer, std::size_t length); /// Sends the response header to the client, followed /// by the contents of the given buffer. @@ -77,12 +77,12 @@ public: /// to length and chunked transfer encoding is disabled. /// /// If both the HTTP message header and body (from the - /// given buffer) fit into one single network packet, the + /// given buffer) fit into one single network packet, the /// complete response can be sent in one network packet. /// - /// Must not be called after send(), sendFile() + /// Must not be called after send(), sendFile() /// or redirect() has been called. - + void redirect(const std::string& uri, Poco::Net::HTTPResponse::HTTPStatus status); /// Sets the status code, which must be one of /// HTTP_MOVED_PERMANENTLY (301), HTTP_FOUND (302), @@ -92,12 +92,12 @@ public: /// the HTTP specification, must be absolute. /// /// Must not be called after send() has been called. - + void requireAuthentication(const std::string& realm); /// Sets the status code to 401 (Unauthorized) /// and sets the "WWW-Authenticate" header field /// according to the given realm. - + bool sent() const; /// Returns true if the response (header) has been sent. diff --git a/ApacheConnector/include/ApacheStream.h b/ApacheConnector/include/ApacheStream.h index f79cfc7e0..22b355e8d 100644 --- a/ApacheConnector/include/ApacheStream.h +++ b/ApacheConnector/include/ApacheStream.h @@ -33,7 +33,7 @@ protected: int writeToDevice(const char* buffer, std::streamsize length); private: - enum + enum { STREAM_BUFFER_SIZE = 1024 }; @@ -53,15 +53,15 @@ class ApacheIOS: public virtual std::ios public: ApacheIOS(ApacheRequestRec* pApacheRequest, bool haveData = false); /// Creates the ApacheIOS with the given socket. - + ~ApacheIOS(); /// Destroys the ApacheIOS. /// /// Flushes the buffer, but does not close the socket. - + ApacheStreamBuf* rdbuf(); /// Returns a pointer to the internal ApacheStreamBuf. - + void close(); /// Flushes the stream. diff --git a/ApacheConnector/samples/FormServer/src/FormServer.cpp b/ApacheConnector/samples/FormServer/src/FormServer.cpp index 278b71700..c5df459c7 100644 --- a/ApacheConnector/samples/FormServer/src/FormServer.cpp +++ b/ApacheConnector/samples/FormServer/src/FormServer.cpp @@ -40,7 +40,7 @@ public: _length(0) { } - + void handlePart(const MessageHeader& header, std::istream& stream) { _type = header.get("Content-Type", "(unspecified)"); @@ -52,18 +52,18 @@ public: _name = params.get("name", "(unnamed)"); _fileName = params.get("filename", "(unnamed)"); } - + CountingInputStream istr(stream); NullOutputStream ostr; StreamCopier::copyStream(istr, ostr); _length = istr.chars(); } - + int length() const { return _length; } - + const std::string& name() const { return _name; @@ -73,12 +73,12 @@ public: { return _fileName; } - + const std::string& contentType() const { return _type; } - + private: int _length; std::string _type; @@ -91,10 +91,10 @@ class FormRequestHandler: public HTTPRequestHandler /// Return a HTML document with the current date and time. { public: - FormRequestHandler() + FormRequestHandler() { } - + void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { MyPartHandler partHandler; @@ -104,7 +104,7 @@ public: response.setContentType("text/html"); std::ostream& ostr = response.send(); - + ostr << "\n" "\n" @@ -127,7 +127,7 @@ public: " \n" "\n" "\n"; - + ostr << "

Request

\n"; ostr << "Method: " << request.getMethod() << "
\n"; ostr << "URI: " << request.getURI() << "
\n"; @@ -150,7 +150,7 @@ public: } ostr << "

"; } - + if (!partHandler.name().empty()) { ostr << "

Upload

\n"; diff --git a/ApacheConnector/samples/TimeServer/src/TimeServer.cpp b/ApacheConnector/samples/TimeServer/src/TimeServer.cpp index d12642df5..f577981f4 100644 --- a/ApacheConnector/samples/TimeServer/src/TimeServer.cpp +++ b/ApacheConnector/samples/TimeServer/src/TimeServer.cpp @@ -32,10 +32,10 @@ class TimeRequestHandler: public HTTPRequestHandler /// Return a HTML document with the current date and time. { public: - TimeRequestHandler() + TimeRequestHandler() { } - + void handleRequest(HTTPServerRequest& request, HTTPServerResponse& response) { Timestamp now; diff --git a/ApacheConnector/src/ApacheApplication.cpp b/ApacheConnector/src/ApacheApplication.cpp index c67810ceb..114356e6c 100644 --- a/ApacheConnector/src/ApacheApplication.cpp +++ b/ApacheConnector/src/ApacheApplication.cpp @@ -35,7 +35,7 @@ ApacheApplication::~ApacheApplication() void ApacheApplication::setup() { FastMutex::ScopedLock lock(_mutex); - + if (!_ready) { std::vector cmdLine; diff --git a/ApacheConnector/src/ApacheRequestHandlerFactory.cpp b/ApacheConnector/src/ApacheRequestHandlerFactory.cpp index d1ac5d78d..cd1fdb1b4 100644 --- a/ApacheConnector/src/ApacheRequestHandlerFactory.cpp +++ b/ApacheConnector/src/ApacheRequestHandlerFactory.cpp @@ -34,7 +34,7 @@ ApacheRequestHandlerFactory::~ApacheRequestHandlerFactory() Poco::Net::HTTPRequestHandler* ApacheRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) { FastMutex::ScopedLock lock(_mutex); - + // only if the given uri is found in _uris we are // handling this request. RequestHandlerFactories::iterator it = _requestHandlers.begin(); @@ -75,7 +75,7 @@ void ApacheRequestHandlerFactory::handleURIs(const std::string& uris) void ApacheRequestHandlerFactory::addRequestHandlerFactory(const std::string& dllPath, const std::string& factoryName, const std::string& uri) -{ +{ try { _loader.loadLibrary(dllPath); diff --git a/ApacheConnector/src/ApacheServerRequest.cpp b/ApacheConnector/src/ApacheServerRequest.cpp index 0699c79ba..d36382b32 100644 --- a/ApacheConnector/src/ApacheServerRequest.cpp +++ b/ApacheConnector/src/ApacheServerRequest.cpp @@ -16,10 +16,10 @@ ApacheServerRequest::ApacheServerRequest( - ApacheRequestRec* pApacheRequest, - const char* serverName, - int serverPort, - const char* clientName, + ApacheRequestRec* pApacheRequest, + const char* serverName, + int serverPort, + const char* clientName, int clientPort): _pApacheRequest(pApacheRequest), _pResponse(0), diff --git a/ApacheConnector/src/ApacheServerResponse.cpp b/ApacheConnector/src/ApacheServerResponse.cpp index a8e866054..73f1e95fa 100644 --- a/ApacheConnector/src/ApacheServerResponse.cpp +++ b/ApacheConnector/src/ApacheServerResponse.cpp @@ -52,7 +52,7 @@ void ApacheServerResponse::initApacheOutputStream() std::vector cookies; getCookies(cookies); - + std::size_t cnt = cookies.size(); for (int c = 0; c < cnt; c++) { @@ -77,7 +77,7 @@ void ApacheServerResponse::sendContinue() std::ostream& ApacheServerResponse::send() { poco_assert (!_pStream); - + initApacheOutputStream(); return *_pStream; @@ -124,7 +124,7 @@ void ApacheServerResponse::redirect(const std::string& uri, HTTPStatus status) void ApacheServerResponse::sendErrorResponse(int status) -{ +{ initApacheOutputStream(); _pApacheRequest->sendErrorResponse(status); diff --git a/ApacheConnector/src/ApacheStream.cpp b/ApacheConnector/src/ApacheStream.cpp index aeaacc6a1..5f92f7c7d 100644 --- a/ApacheConnector/src/ApacheStream.cpp +++ b/ApacheConnector/src/ApacheStream.cpp @@ -21,7 +21,7 @@ using Poco::BufferedStreamBuf; // -ApacheStreamBuf::ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData): +ApacheStreamBuf::ApacheStreamBuf(ApacheRequestRec* pApacheRequest, bool haveData): BufferedStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out), _pApacheRequest(pApacheRequest), _haveData(haveData) diff --git a/CHANGELOG b/CHANGELOG index dd04b8d0c..cf7325842 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,133 @@ This is the changelog file for the POCO C++ Libraries. +Release 1.12.0 (2022-07-08) +=========================== + +- This release introduces Prometheus library +- Upgraded bundled PCRE to PCRE2 10.40 +- Small object optimization for Any and Dynamic::Var (compile-time option, enabled by default) +- All swap operations are noexcept now +- PollSet::add() is mode-cumulative now +- UDPServer now requires explicit starting +- Move semantics for sockets and SocketAddress (compile-time option, disabled by default) + +- GH #709: Poco::Dynamic::Var memory leak +- GH #1039 Race condition in AsyncChannel close/log +- GH #1459 Fix Socket::select() epoll and poll implementations +- GH #1687 SQLite Notifier has no table information +- GH #1884 TCPServerDispatcher::run() issue +- GH #2084 LogFile_STD (LogFileImpl) fails to recover from getting out of space +- GH #2085 Crash due to race condition in TCPServerDispatcher +- GH #2091 Integrate windows poll +- GH #2222 Warning when compiling my that's use VarHolder +- GH #2270 HTTPClientSession not supporting binding source address for proxy connect +- GH #2271 HTTPClientSession source IP address +- GH #2285 SQLite::Connector::open() crashes on db file with non existing directory +- GH #2287 Poco::Data::Statement becomes unusable after exception +- GH #2352 Allow setting the socket of SecureSocketImpl to no-blocking +- GH #2386 As of C++11, std::swap is noexcept +- GH #2401 Net::MailMessage::read hangs on missing final multipart boundary +- GH #2457 Poco::Redis after executing "auth" command next command always return "OK" +- GH #2465 Operating system specific thread ID is not available any more in Logger/Formatter +- GH #2470 Can't use Poco::MongoDB::Cursor on aggregation cursor +- GH #2511 Negative precision in NumberFormatter::format() +- GH #2513 Poco::Net::SocketConnector unregistering +- GH #2516 SHA3Engine hard to use with HMACEngine duplicate enhancement +- GH #2521 MySQL Extractor null value extraction +- GH #2538 Poco::Data::Session::connector() returns empty string for MySQL session +- GH #2569 MySQL timestamp +- GH #2576 Add std::chrono support to Timespan +- GH #2590 Zip 64-bit extensions not set +- GH #2614 NTPClient ignores second fractions enhancement +- GH #2619 Decoding URI query parameters incompatible with Spring 5 +- GH #2638 Upgrade Windows SDK Used for Building Poco +- GH #2688 Static code analyzer warnings +- GH #2691 MinGW: fatal error: kernelspecs.h: No such file +- GH #2706 [windows bug] pollset WSAPoll with non blocking socket will not report error +- GH #2755 MySQL LONGTEXT +- GH #2821 Poco::Buffer: full on creation +- GH #2849 setPadding does nothing when OpenSSL 1.1.x is used +- GH #2864 SessionImpl begin +- GH #2940 Add vcpkg installation instructions +- GH #2943 Avoid clang 10 -Wimplicit-int-float-conversion warning/error when converting int into float +- GH #2959 Fix percent-encoded fragment modification in Poco::URI +- GH #2980 Memory leaks in Poco::Any +- GH #2986 Once exhausted, Poco::ObjectPool does not lend out returned objects +- GH #3016 MongoDB::Array interface improvements +- GH #3026 HTTPDigestCredentials added support for RFC7616 algorithms +- GH #3039 Poco errors with _DEBUG and NDEBUG +- GH #3052 Fix constness of URI::getPathSegments +- GH #3088 Fix error in find_package example +- GH #3056 Inconsistent behavior ConsoleChannel vs. WindowsConsoleChannel +- GH #3062 Makefile: space(s) following target name will break build (during link) +- GH #3073 libPocoCrypto.so: undefined reference to `pthread_atfork' when linking statically with OpenSSL 1.1 +- GH #3104 Publicly expose Poco::Message parameters +- GH #3105 CMake: use GNUInstallDirs +- GH #3175 SharedLibrary::isLoaded() not thread safe +- GH #3195 MinGW also defines __GNUC__ +- GH #3240 Task::postNotification possible leak +- GH #3241 Poco::Data::SessionPool change connection timeout +- GH #3251 JSON Serializing NAN +- GH #3253 Arbitrary indent of 2 applied to JSON string objects Var conversion +- GH #3261 Upgrade to PCRE2 latest version +- GH #3283 DatagramSocket does not allow IPV6_V6ONLY +- GH #3296 Add move semantics to Net (sockets and addresses) +- GH #3297 Poco Foundation Fails to Compile With POCO_ENABLE_SOO Defined +- GH #3323 Extend format patterns %T and %I to support native threads +- GH #3342 DB into() does not compile for more than 20 members in a tuple +- GH #3357 Add socket proactor +- GH #3359 Make PollSet::poll() interruptible +- GH #3371 SocketReactor::getNotifier() does not use socket.impl() +- GH #3372 FTPClientSession::activeDataConnection 1.11.0 cannot set specific data port +- GH #3374 No access to padding in Cipher +- GH #3375 PollSet::SocketModeMap poll(const Poco::Timespan& timeout) hasSignaledFDs issue slow down connections +- GH #3378 PollSet function setMode 1.11.0 cause while(1) on windows +- GH #3380 Windows SO_REUSEADDR is neither reliable nor safe +- GH #3384 Always set thread names on POSIX platforms +- GH #3385 IPAddress::tryParse does not work for "::" +- GH #3396 Poco::Data::ODBC - dbEncoding property not used for insert/update +- GH #3399 IPAddress::isLoopback() returns false for IPv4 mapped in IPv6 +- GH #3404 Net: make MessageHeader limits configurable +- GH #3415 OpenSSL 3.0 support +- GH #3417 Calling SocketReactor's run() method in a program's main thread yields a lot of null pointer exceptions +- GH #3421 Cannot use HMACEngine with SHA2Engine +- GH #3452 Syslog: Include Facility to Syslog Message +- GH #3453 added facility to SyslogChannel +- GH #3460 LoongArch support +- GH #3481 JSON DataType support for MySQL +- GH #3482 Visual Studio 2022 (v170) missing from buildwin.cmd +- GH #3486 Windows on ARM64 support +- GH #3516 Fix OpenSSL 3.0 deprecated warnings +- GH #3529 Added LocalConfigurationView to only search inside the viewed scope +- GH #3543 Visual Studio Warning C4244 +- GH #3558 Race condition in SSLManager +- GH #3561 Add envelope to crypto +- GH #3569 Readded named substring support for regexes +- GH #3580 Rounds very large negative numbers to the incorrect values +- GH #3592 Add 425 / HTTP_TOO_EARLY to HTTPResponse::HTTPStatus +- GH #3598 Socket::available does not always return correct value for UDP +- GH #3602 Add Data::JSONRowFormatter +- GH #3603 Update minimum GCC version information +- GH #3611 VS2022 Arm64 projects missing or do not load +- GH #3613 UDPHandler data race +- GH #3620 MariaDB still uses tx_isolation for transaction isolation unlike MySQL 8+ which uses transaction_isolation +- GH #3624 Upgrade double-conversion to v3.2.0 +- GH #3628 PollSet data race +- GH #3629 Event data race +- GH #3633 Redis: Support Authentication +- GH #3635 ConfigurationView and JSON is broken for array access +- GH #3639 Bugcheck: indicate compiler that functions will never return +- GH #3640 fix warning C4717: 'format': recursive on all control paths, function will cause runtime stack overflow +- GH #3641 FifoBuffer.advance method not throw exception when length==0 +- GH #3642 Make ParallelSocketReactor thread namable +- GH #3651 TCPserver missing from Net/samples/CMakeLists.txt +- GH #3652 Linking with Foundation on Android gives error +- GH #3655 Socket::select EPOLL implementation returns socket in exceptList when empty list is given +- GH #3658 Support for chunked transfer encoding trailer +- GH #3661 PollSet::add()/update() semantics +- GH #3665 MSVC does not properly recognize std version + + Release 1.11.3 (2022-06-12) =========================== diff --git a/CMakeLists.txt b/CMakeLists.txt index 4338befe5..c5520915c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,9 @@ if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "RelWithDebInfo") endif() +# Enable standard installation directories +include(GNUInstallDirs) + # Include some common macros to simpilfy the Poco CMake files include(PocoMacros) @@ -75,6 +78,11 @@ if(MSVC) if((NOT POCO_DISABLE_INTERNAL_OPENSSL) AND (ENABLE_NETSSL OR ENABLE_CRYPTO OR (ENABLE_DATA_MYSQL AND MINGW))) include(UseEmbeddedOpenSSL) endif() + + if(POCO_SANITIZE_ASAN) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fsanitize=address") + endif() + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus") endif() option(ENABLE_NETSSL_WIN "Enable NetSSL Windows" OFF) @@ -164,6 +172,7 @@ option(ENABLE_JSON "Enable JSON" ON) option(ENABLE_MONGODB "Enable MongoDB" ON) option(ENABLE_DATA_SQLITE "Enable Data SQlite" ON) option(ENABLE_REDIS "Enable Redis" ON) +option(ENABLE_PROMETHEUS "Enable Prometheus" ON) option(ENABLE_PDF "Enable PDF" OFF) option(ENABLE_UTIL "Enable Util" ON) option(ENABLE_NET "Enable Net" ON) @@ -197,9 +206,9 @@ else() endif() if(POCO_UNBUNDLED) - message(STATUS "Using external sqlite, zlib, pcre, expat, ...") + message(STATUS "Using external sqlite, zlib, pcre2, expat, ...") else() - message(STATUS "Using internal sqlite, zlib, pcre, expat, ...") + message(STATUS "Using internal sqlite, zlib, pcre2, expat, ...") endif() # Disable fork exec @@ -234,7 +243,7 @@ if(ENABLE_PAGECOMPILER) set(ENABLE_UTIL ON CACHE BOOL "Enable Util" FORCE) endif() -if(ENABLE_MONGODB OR ENABLE_REDIS) +if(ENABLE_MONGODB OR ENABLE_REDIS OR ENABLE_PROMETHEUS) set(ENABLE_NET ON CACHE BOOL "Enable Net" FORCE) endif() @@ -337,6 +346,11 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/Redis AND ENABLE_REDIS) list(APPEND Poco_COMPONENTS "Redis") endif() +if(EXISTS ${PROJECT_SOURCE_DIR}/Prometheus AND ENABLE_PROMETHEUS) + add_subdirectory(Prometheus) + list(APPEND Poco_COMPONENTS "Prometheus") +endif() + if(EXISTS ${PROJECT_SOURCE_DIR}/PDF AND ENABLE_PDF) add_subdirectory(PDF) list(APPEND Poco_COMPONENTS "PDF") @@ -436,7 +450,9 @@ add_custom_target(uninstall ############################################################# # Enable packaging -include(InstallRequiredSystemLibraries) +if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + include(InstallRequiredSystemLibraries) +endif() set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Poco Libraries") set(CPACK_PACKAGE_VENDOR "Applied Informatics Software Engineering GmbH") @@ -462,7 +478,7 @@ write_basic_package_version_file( if(WIN32) set(PocoConfigPackageLocation "cmake") else() - set(PocoConfigPackageLocation "lib${LIB_SUFFIX}/cmake/${PROJECT_NAME}") + set(PocoConfigPackageLocation "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") endif() configure_file(cmake/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}/${PROJECT_NAME}Config.cmake" @ONLY) @@ -477,7 +493,7 @@ install( ) if(POCO_UNBUNDLED) - install(FILES cmake/FindPCRE.cmake + install(FILES cmake/FindPCRE2.cmake DESTINATION "${PocoConfigPackageLocation}") install(FILES cmake/V39/FindEXPAT.cmake DESTINATION "${PocoConfigPackageLocation}/V39") diff --git a/CppParser/CMakeLists.txt b/CppParser/CMakeLists.txt index 7e41461e5..86ceca0c1 100644 --- a/CppParser/CMakeLists.txt +++ b/CppParser/CMakeLists.txt @@ -25,7 +25,7 @@ target_link_libraries(CppParser PUBLIC Poco::Foundation) target_include_directories(CppParser PUBLIC $ - $ + $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) diff --git a/CppParser/CppParser_vs170.sln b/CppParser/CppParser_vs170.sln index 728a152b3..ace73f8ad 100644 --- a/CppParser/CppParser_vs170.sln +++ b/CppParser/CppParser_vs170.sln @@ -9,6 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\Test EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 debug_shared|Win32 = debug_shared|Win32 release_shared|Win32 = release_shared|Win32 debug_static_mt|Win32 = debug_static_mt|Win32 @@ -23,6 +29,24 @@ Global release_static_md|x64 = release_static_md|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_shared|Win32.Build.0 = debug_shared|Win32 {C77B9D92-EC91-11DA-A4CE-005056C00008}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 @@ -59,6 +83,24 @@ Global {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_md|x64.ActiveCfg = release_static_md|x64 {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_md|x64.Build.0 = release_static_md|x64 {C77B9D92-EC91-11DA-A4CE-005056C00008}.release_static_md|x64.Deploy.0 = release_static_md|x64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {C79112BD-EC91-11DA-A4CE-005056C00008}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_shared|Win32.Build.0 = debug_shared|Win32 {C79112BD-EC91-11DA-A4CE-005056C00008}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 diff --git a/CppParser/CppParser_vs170.vcxproj b/CppParser/CppParser_vs170.vcxproj index f5556a8d5..9dfabac9b 100644 --- a/CppParser/CppParser_vs170.vcxproj +++ b/CppParser/CppParser_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 CppParser {C77B9D92-EC91-11DA-A4CE-005056C00008} CppParser @@ -87,6 +112,36 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + StaticLibrary MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + PocoCppParserA64d + PocoCppParsermdd + PocoCppParsermtd + PocoCppParserA64 + PocoCppParsermd + PocoCppParsermt PocoCppParserd PocoCppParsermdd PocoCppParsermtd @@ -171,6 +250,32 @@ PocoCppParsermd PocoCppParsermt + + ..\binA64\ + objA64\CppParser\$(Configuration)\ + true + + + ..\binA64\ + objA64\CppParser\$(Configuration)\ + false + + + ..\libA64\ + objA64\CppParser\$(Configuration)\ + + + ..\libA64\ + objA64\CppParser\$(Configuration)\ + + + ..\libA64\ + objA64\CppParser\$(Configuration)\ + + + ..\libA64\ + objA64\CppParser\$(Configuration)\ + ..\bin\ obj\CppParser\$(Configuration)\ @@ -223,6 +328,164 @@ ..\lib64\ obj64\CppParser\$(Configuration)\ + + + Disabled + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;CppParser_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + ..\binA64\PocoCppParserA64d.dll + true + true + ..\binA64\PocoCppParserA64d.pdb + ..\libA64;%(AdditionalLibraryDirectories) + Console + ..\libA64\PocoCppParserd.lib + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;CppParser_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + ..\binA64\PocoCppParserA64.dll + true + false + ..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\libA64\PocoCppParser.lib + MachineARM64 + + + + + Disabled + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + ..\libA64\PocoCppParsermtd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\PocoCppParsermtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + ..\libA64\PocoCppParsermt.lib + + + + + Disabled + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + ..\libA64\PocoCppParsermdd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\PocoCppParsermdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + ..\libA64\PocoCppParsermd.lib + + Disabled @@ -615,12 +878,16 @@ + true true true + true true true + true true true + true true true diff --git a/CppParser/include/Poco/CppParser/Attributes.h b/CppParser/include/Poco/CppParser/Attributes.h index 2f90db269..3c1519b2d 100644 --- a/CppParser/include/Poco/CppParser/Attributes.h +++ b/CppParser/include/Poco/CppParser/Attributes.h @@ -34,7 +34,7 @@ class CppParser_API Attributes public: typedef std::map AttrMap; typedef AttrMap::const_iterator Iterator; - + Attributes(); /// Creates the Attributes object. @@ -46,15 +46,15 @@ public: Attributes& operator = (const Attributes& attrs); /// Assignment operator. - + bool has(const std::string& name) const; /// Returns true if an attribute with the given name exists. - + std::string getString(const std::string& name) const; /// Returns the attribute's value as a string. /// /// Throws a Poco::NotFoundException if the attribute does not exist. - + std::string getString(const std::string& name, const std::string& defaultValue) const; /// Returns the attribute's value as a string, if it exists. /// Returns the defaultValue if the attribute does not exist. @@ -64,7 +64,7 @@ public: /// /// Throws a Poco::NotFoundException if the attribute does not exist. /// Throws a Poco::SyntaxException if the stored value is not an integer. - + int getInt(const std::string& name, int defaultValue) const; /// Returns the attribute's value as an integer, if it exists. /// Returns the defaultValue if the attribute does not exist. @@ -74,7 +74,7 @@ public: bool getBool(const std::string& name) const; /// Returns the attribute's value as a boolean. /// The returned value is 'true', iff the stored value is not "false". - /// + /// /// Throws a Poco::NotFoundException if the attribute does not exist. bool getBool(const std::string& name, bool defaultValue) const; @@ -83,17 +83,17 @@ public: void set(const std::string& name, const std::string& value); /// Sets the value of an attribute. - + void remove(const std::string& name); /// Removes the attribute with the given name. /// Does nothing if the attribute does not exist. - + const std::string& operator [] (const std::string& name) const; - std::string& operator [] (const std::string& name); - + std::string& operator [] (const std::string& name); + Iterator begin() const; Iterator end() const; - + void clear(); /// Clears all attributes. diff --git a/CppParser/include/Poco/CppParser/AttributesParser.h b/CppParser/include/Poco/CppParser/AttributesParser.h index 8dcd62537..2cbeee8e8 100644 --- a/CppParser/include/Poco/CppParser/AttributesParser.h +++ b/CppParser/include/Poco/CppParser/AttributesParser.h @@ -34,13 +34,13 @@ class CppParser_API AttributesParser /// structs/classes, functions, types, etc. can be annotated /// with attributes. /// - /// Attributes always come immediately before the symbol that + /// Attributes always come immediately before the symbol that /// is being annotated, and are written inside special comments /// with the syntax: /// //@ [,...] /// where is /// [=] - /// is a valid C++ identifier, or two identifiers separated by + /// is a valid C++ identifier, or two identifiers separated by /// a period (struct accessor notation). /// is a string, integer, identifier, bool literal, or a complex value /// in the form @@ -67,7 +67,7 @@ protected: static bool isOperator(const Poco::Token* pToken, int kind); static bool isLiteral(const Poco::Token* pToken); static bool isEOF(const Poco::Token* pToken); - + private: Attributes& _attrs; Tokenizer _tokenizer; diff --git a/CppParser/include/Poco/CppParser/Function.h b/CppParser/include/Poco/CppParser/Function.h index b59c273c7..4f4853201 100644 --- a/CppParser/include/Poco/CppParser/Function.h +++ b/CppParser/include/Poco/CppParser/Function.h @@ -48,7 +48,7 @@ public: FN_DEFAULT = 512, /// The function is default. FN_DELETE = 1024 /// The function has been deleted. }; - + typedef std::vector Parameters; typedef Parameters::const_iterator Iterator; @@ -68,51 +68,51 @@ public: Iterator end() const; /// Returns an iterator for iterating over the Function's Parameter's. - + void makeInline(); /// Sets the FN_INLINE flag. - + void makeConst(); /// Sets the FN_CONST flag. - + void makePureVirtual(); /// Sets the FN_PURE_VIRTUAL flag. - + void makeFinal(); /// Sets the FN_FINAL flag. - + void makeOverride(); /// Sets the FN_OVERRIDE flag. - + void makeNoexcept(); /// Sets the FN_NOEXCEPT flag. void makeDefault(); /// Sets the FN_DEFAULT flag. - + void makeDelete(); /// Sets the FN_DELETE flag. - + int flags() const; /// Returns the function's flags. - + bool isConstructor() const; /// Returns true iff the function is a constructor. - + bool isDestructor() const; /// Returns true iff the function is a destructor. bool isMethod() const; /// Returns true iff the function is a method (it's part of /// a Struct and it's neither a constructor nor a destructor). - + bool isFunction() const; /// Returns true iff the function is not a member of a class /// (a freestanding function). bool isConst() const; /// Returns true iff the method is const. - + bool isDefault() const; /// Returns true iff the method has a default implementation. @@ -121,20 +121,20 @@ public: int countParameters() const; /// Returns the number of parameters. - + std::string signature() const; /// Returns the signature of the function. - + bool isVirtual() const; /// Returns true if the method is virtual. Also examines base /// classes to check for a virtual function with the same /// signature. - + Function* getOverridden() const; /// If the function is virtual and overrides a function in a /// base class, the base class function is returned. /// Otherwise, null is returned. - + Symbol::Kind kind() const; std::string toString() const; diff --git a/CppParser/include/Poco/CppParser/NameSpace.h b/CppParser/include/Poco/CppParser/NameSpace.h index bd3417b92..02d7f5450 100644 --- a/CppParser/include/Poco/CppParser/NameSpace.h +++ b/CppParser/include/Poco/CppParser/NameSpace.h @@ -37,7 +37,7 @@ public: typedef SymbolTable::const_iterator Iterator; typedef std::map AliasMap; typedef std::vector NameSpaceVec; - + NameSpace(); /// Creates the NameSpace. @@ -46,56 +46,56 @@ public: ~NameSpace(); /// Destroys the NameSpace. - + void addSymbol(Symbol* pSymbol); /// Adds a symbol to the namespace. - + void importSymbol(const std::string& fullName); /// Imports a symbol from another namespace (using ). - + void importNameSpace(const std::string& nameSpace); /// Imports a namespace (using namespace ). - + Iterator begin() const; /// Returns an iterator for iterating over the NameSpace's Symbol's. Iterator end() const; /// Returns an iterator for iterating over the NameSpace's Symbol's. - + Symbol* lookup(const std::string& name) const; /// Looks up the given name in the symbol table /// and returns the corresponding symbol, or null /// if no symbol can be found. The name can include /// a namespace. - + static NameSpace* root(); /// Returns the root namespace. Never delete this one! - + void nameSpaces(SymbolTable& table) const; /// Fills the symbol table with all namespaces. - + void typeDefs(SymbolTable& table) const; /// Fills the symbol table with all type definitions. - + void typeAliases(SymbolTable& table) const; /// Fills the symbol table with all type alias (using) definitions. void enums(SymbolTable& table) const; /// Fills the symbol table with all enums. - + void classes(SymbolTable& table) const; /// Fills the symbol table with all classes and structs. - + void functions(SymbolTable& table) const; /// Fills the symbol table with all functions. - + void variables(SymbolTable& table) const; /// Fills the symbol table with all variables. - + const AliasMap& importedSymbols() const; /// Returns a const reference to a SymbolTable containing all /// imported symbols. - + const NameSpaceVec& importedNameSpaces() const; /// Returns a vector containing all imported namespaces. @@ -128,7 +128,7 @@ inline const NameSpace::AliasMap& NameSpace::importedSymbols() const return _importedSymbols; } - + inline const NameSpace::NameSpaceVec& NameSpace::importedNameSpaces() const { return _importedNameSpaces; diff --git a/CppParser/include/Poco/CppParser/Parser.h b/CppParser/include/Poco/CppParser/Parser.h index 6c7e4a4d1..060551b8c 100644 --- a/CppParser/include/Poco/CppParser/Parser.h +++ b/CppParser/include/Poco/CppParser/Parser.h @@ -82,7 +82,7 @@ protected: const Poco::Token* parseClassMembers(const Poco::Token* pNext, Struct* pClass); const Poco::Token* parseAccess(const Poco::Token* pNext); const Poco::Token* parseIdentifier(const Poco::Token* pNext, std::string& id); - + void addSymbol(Symbol* pSymbol, int lineNumber, bool addGST = true); void pushNameSpace(NameSpace* pNameSpace, int lineNumber, bool addGST = true); void popNameSpace(); diff --git a/CppParser/include/Poco/CppParser/Struct.h b/CppParser/include/Poco/CppParser/Struct.h index 12c25cbf4..2c3a5c7cd 100644 --- a/CppParser/include/Poco/CppParser/Struct.h +++ b/CppParser/include/Poco/CppParser/Struct.h @@ -42,7 +42,7 @@ public: FN_TEMPLATE_SPECIALIZATION = 4, FN_FINAL = 8 }; - + struct Base { Symbol::Access access; @@ -50,7 +50,7 @@ public: std::string name; Struct* pClass; }; - + typedef std::vector BaseClasses; typedef BaseClasses::const_iterator BaseIterator; typedef std::vector StructVec; @@ -67,13 +67,13 @@ public: void addBase(const std::string&, Symbol::Access access, bool isVirtual); /// Adds a base class. - + BaseIterator baseBegin() const; /// Returns an iterator for iterating over all base classes. - + BaseIterator baseEnd() const; /// Returns an iterator for iterating over all base classes. - + void fixupBases(); /// Adds pointers for all base classes. @@ -88,13 +88,13 @@ public: const std::string& declaration() const; /// Returns the declaration. - + int flags() const; /// Returns the struct's flags. void makeInline(); /// Changes the class to a inline class, i.e. definition and implementation are hidden in a cpp file. - + void makeFinal(); /// Makes the class final. @@ -106,39 +106,39 @@ public: void constructors(Functions& functions) const; /// Returns all constructors, sorted by their parameter count. - + Function* destructor() const; /// Returns the destructor, or NULL if no /// destructor is defined. void methods(Symbol::Access access, Functions& functions) const; /// Returns all functions with the given access. - + void inheritedMethods(FunctionSet& functions) const; /// Returns all inherited methods. - + void bases(std::set& bases) const; /// Returns all base classes. - + void derived(StructSet& derived) const; - /// Returns all derived classes. - + /// Returns all derived classes. + Function* findFunction(const std::string& signature) const; /// Finds a function with the given signature. - + bool hasVirtualDestructor() const; /// Returns true if the class CppParser_API or one if its base classes /// has a virtual destructor. bool isClass() const; /// Returns true iff the struct was declared as class. - + bool isDerived() const; /// Returns true iff the struct or class is derived from another struct or class. Symbol::Kind kind() const; std::string toString() const; - + private: std::string _decl; BaseClasses _bases; diff --git a/CppParser/include/Poco/CppParser/Utility.h b/CppParser/include/Poco/CppParser/Utility.h index 3ded488e0..8fa9267b8 100644 --- a/CppParser/include/Poco/CppParser/Utility.h +++ b/CppParser/include/Poco/CppParser/Utility.h @@ -37,9 +37,9 @@ public: public: std::string beginNameSpaceDecl; // contains either $(NS)_BEGIN or the namespace x { decl std::string endNameSpaceDecl; // contains either $(NS)_END or the closing brackets } - std::vector classDecls; // contains strings of the form "class X;" + std::vector classDecls; // contains strings of the form "class X;" }; - + static void parse(const std::string& file, NameSpace::SymbolTable& st, const std::string& exec, const std::string& options, const std::string& path); /// Preprocesses and parses the file. The resulting symboltable has base class references already fixed, diff --git a/CppParser/include/Poco/CppParser/Variable.h b/CppParser/include/Poco/CppParser/Variable.h index d167eda59..92f67752d 100644 --- a/CppParser/include/Poco/CppParser/Variable.h +++ b/CppParser/include/Poco/CppParser/Variable.h @@ -37,13 +37,13 @@ public: VAR_VOLATILE = 4, /// The variable is volatile. VAR_CONST = 8 /// The variable is const. }; - + Variable(const std::string& decl, NameSpace* pNameSpace); /// Creates the Variable. ~Variable(); /// Destroys the Variable. - + int flags() const; /// Returns the variable's flags. @@ -57,7 +57,7 @@ public: /// /// Example: a type const std::string& -> std::string, a type const std::string* returns std::string - + private: int _flags; bool _isPointer; diff --git a/CppParser/src/Attributes.cpp b/CppParser/src/Attributes.cpp index 21d14e808..5507d20cf 100644 --- a/CppParser/src/Attributes.cpp +++ b/CppParser/src/Attributes.cpp @@ -48,13 +48,13 @@ Attributes& Attributes::operator = (const Attributes& attrs) return *this; } - + bool Attributes::has(const std::string& name) const { return _map.find(name) != _map.end(); } - + std::string Attributes::getString(const std::string& name) const { AttrMap::const_iterator it = _map.find(name); @@ -64,7 +64,7 @@ std::string Attributes::getString(const std::string& name) const throw Poco::NotFoundException(name); } - + std::string Attributes::getString(const std::string& name, const std::string& defaultValue) const { AttrMap::const_iterator it = _map.find(name); @@ -84,7 +84,7 @@ int Attributes::getInt(const std::string& name) const throw Poco::NotFoundException(name); } - + int Attributes::getInt(const std::string& name, int defaultValue) const { AttrMap::const_iterator it = _map.find(name); diff --git a/CppParser/src/AttributesParser.cpp b/CppParser/src/AttributesParser.cpp index 441c988b8..ef8eb3dc1 100644 --- a/CppParser/src/AttributesParser.cpp +++ b/CppParser/src/AttributesParser.cpp @@ -88,7 +88,7 @@ const Token* AttributesParser::parseAttribute(const Token* pNext) const Token* AttributesParser::parseComplexAttribute(const Token* pNext, const std::string& id) { poco_assert_dbg (isOperator(pNext, OperatorToken::OP_OPENBRACE)); - + pNext = next(); std::string oldId(_id); if (!_id.empty()) @@ -103,7 +103,7 @@ const Token* AttributesParser::parseComplexAttribute(const Token* pNext, const s pNext = next(); else throw SyntaxException("bad attribute declaration"); - + return pNext; } diff --git a/CppParser/src/Function.cpp b/CppParser/src/Function.cpp index b518d8940..e41db8004 100644 --- a/CppParser/src/Function.cpp +++ b/CppParser/src/Function.cpp @@ -111,13 +111,13 @@ void Function::makeFinal() _flags |= FN_FINAL; } - + void Function::makeOverride() { _flags |= FN_OVERRIDE; } - + void Function::makeNoexcept() { _flags |= FN_NOEXCEPT; @@ -141,7 +141,7 @@ bool Function::isConstructor() const return name() == nameSpace()->name(); } - + bool Function::isDestructor() const { return name()[0] == '~'; @@ -201,7 +201,7 @@ std::string Function::signature() const return signature; } - + bool Function::isVirtual() const { if (_flags & FN_VIRTUAL) diff --git a/CppParser/src/NameSpace.cpp b/CppParser/src/NameSpace.cpp index 7551bc17f..9bd683030 100644 --- a/CppParser/src/NameSpace.cpp +++ b/CppParser/src/NameSpace.cpp @@ -49,7 +49,7 @@ NameSpace::~NameSpace() void NameSpace::addSymbol(Symbol* pSymbol) { poco_check_ptr (pSymbol); - + _symbols.insert(SymbolTable::value_type(pSymbol->name(), pSymbol)); } @@ -65,7 +65,7 @@ void NameSpace::importSymbol(const std::string& fullName) } } - + void NameSpace::importNameSpace(const std::string& nameSpace) { _importedNameSpaces.push_back(nameSpace); @@ -94,7 +94,7 @@ Symbol* NameSpace::lookup(const std::string& name) const Symbol* NameSpace::lookup(const std::string& name, std::set& alreadyVisited) const { Symbol* pSymbol = 0; - + if (name.empty()) return pSymbol; @@ -103,12 +103,12 @@ Symbol* NameSpace::lookup(const std::string& name, std::set& a std::string head; std::string tail; splitName(name, head, tail); - + alreadyVisited.insert(this); bool currentNSInserted = true; - - if (head.empty()) + + if (head.empty()) { alreadyVisited.insert(this); return root()->lookup(tail, alreadyVisited); @@ -161,13 +161,13 @@ void NameSpace::nameSpaces(SymbolTable& table) const extract(Symbol::SYM_NAMESPACE, table); } - + void NameSpace::typeDefs(SymbolTable& table) const { extract(Symbol::SYM_TYPEDEF, table); } - + void NameSpace::typeAliases(SymbolTable& table) const { extract(Symbol::SYM_TYPEALIAS, table); @@ -179,19 +179,19 @@ void NameSpace::enums(SymbolTable& table) const extract(Symbol::SYM_ENUM, table); } - + void NameSpace::classes(SymbolTable& table) const { extract(Symbol::SYM_STRUCT, table); } - + void NameSpace::functions(SymbolTable& table) const { extract(Symbol::SYM_FUNCTION, table); } - + void NameSpace::variables(SymbolTable& table) const { extract(Symbol::SYM_VARIABLE, table); @@ -226,7 +226,7 @@ void NameSpace::splitName(const std::string& name, std::string& head, std::strin head.assign(name, 0, pos); pos += 2; poco_assert (pos < name.length()); - tail.assign(name, pos, name.length() - pos); + tail.assign(name, pos, name.length() - pos); } else head = name; } diff --git a/CppParser/src/Struct.cpp b/CppParser/src/Struct.cpp index 02db88321..fa2ed6db4 100644 --- a/CppParser/src/Struct.cpp +++ b/CppParser/src/Struct.cpp @@ -62,7 +62,7 @@ void Struct::addBase(const std::string& name, Symbol::Access access, bool isVirt _bases.push_back(base); } - + Struct::BaseIterator Struct::baseBegin() const { return _bases.begin(); @@ -78,7 +78,7 @@ Struct::BaseIterator Struct::baseEnd() const void Struct::addDerived(Struct* pClass) { poco_check_ptr (pClass); - + _derived.push_back(pClass); } diff --git a/CppParser/src/Tokenizer.cpp b/CppParser/src/Tokenizer.cpp index d557e2a86..a51258584 100644 --- a/CppParser/src/Tokenizer.cpp +++ b/CppParser/src/Tokenizer.cpp @@ -25,7 +25,7 @@ namespace CppParser { Tokenizer::Tokenizer(std::istream& istr): - StreamTokenizer(istr) + StreamTokenizer(istr) { addToken(new OperatorToken); addToken(new IdentifierToken); diff --git a/CppParser/src/Utility.cpp b/CppParser/src/Utility.cpp index 2eb93a266..c6017a01b 100644 --- a/CppParser/src/Utility.cpp +++ b/CppParser/src/Utility.cpp @@ -195,14 +195,14 @@ std::string Utility::preprocessFile(const std::string& file, const std::string& newPath += path; Environment::set("PATH", path); } - - ProcessHandle proc = Process::launch(exec, args); + + ProcessHandle proc = Process::launch(exec, args); int rc = Process::wait(proc); if (rc != 0) { throw Poco::RuntimeException("Failed to process file"); } - + return pp.getFileName(); } @@ -293,7 +293,7 @@ std::string replace(const std::string& input, const std::string& oldToken, const start = pos + oldToken.length(); } while (pos != std::string::npos); - + return result; } diff --git a/CppParser/src/Variable.cpp b/CppParser/src/Variable.cpp index 01459f0e5..5062e8033 100644 --- a/CppParser/src/Variable.cpp +++ b/CppParser/src/Variable.cpp @@ -39,10 +39,10 @@ Variable::Variable(const std::string& decl, NameSpace* pNameSpace): std::size_t pos = decl.rfind(name()); std::string tmp = decl.substr(0, pos); tmp = Poco::trim(tmp); - + pos = tmp.rfind("*"); _isPointer = (pos == (tmp.size()-1)); - + Poco::replaceInPlace(tmp, "static ", ""); Poco::replaceInPlace(tmp, "mutable ", ""); Poco::replaceInPlace(tmp, "volatile ", ""); @@ -53,7 +53,7 @@ Variable::Variable(const std::string& decl, NameSpace* pNameSpace): tmp = tmp.substr(6); if (tmp.find("const\t") == 0) tmp = tmp.substr(6); - + std::size_t rightCut = tmp.size(); while (rightCut > 0 && (tmp[rightCut-1] == '&' || tmp[rightCut-1] == '*' || tmp[rightCut-1] == '\t' || tmp[rightCut-1] == ' ')) --rightCut; diff --git a/CppParser/testsuite/TestSuite_vs170.vcxproj b/CppParser/testsuite/TestSuite_vs170.vcxproj index b63f29c0e..8ddceef30 100644 --- a/CppParser/testsuite/TestSuite_vs170.vcxproj +++ b/CppParser/testsuite/TestSuite_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 TestSuite {C79112BD-EC91-11DA-A4CE-005056C00008} TestSuite @@ -87,6 +112,36 @@ MultiByte v143 + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + Application MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + TestSuited + TestSuited + TestSuited + TestSuite + TestSuite + TestSuite TestSuited TestSuited TestSuited @@ -171,6 +250,36 @@ TestSuite TestSuite + + binA64\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\ + objA64\TestSuite\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\TestSuite\$(Configuration)\ + false + + + binA64\static_md\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\static_md\ + objA64\TestSuite\$(Configuration)\ + false + bin\ obj\TestSuite\$(Configuration)\ @@ -231,6 +340,189 @@ obj64\TestSuite\$(Configuration)\ false + + + Disabled + ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitd.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\TestSuited.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + CppUnit.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\TestSuite.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitmtd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\TestSuited.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_mt\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + CppUnitmt.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\TestSuite.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitmdd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\TestSuited.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_md\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + CppUnitmd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\TestSuite.exe + ..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + Disabled diff --git a/CppUnit/CMakeLists.txt b/CppUnit/CMakeLists.txt index c367bd2bb..78b89d442 100644 --- a/CppUnit/CMakeLists.txt +++ b/CppUnit/CMakeLists.txt @@ -18,10 +18,15 @@ target_link_libraries(CppUnit PUBLIC Poco::Foundation) target_include_directories(CppUnit PUBLIC $ - $ + $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src ) +if(WIN32) + if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + target_compile_definitions(CppUnit PUBLIC POCO_NO_AUTOMATIC_LIBS) + endif() +endif() if(NOT BUILD_SHARED_LIBS) target_compile_definitions(CppUnit diff --git a/CppUnit/CppUnit_vs140.vcxproj b/CppUnit/CppUnit_vs140.vcxproj index dd1dc6737..9e23021a8 100644 --- a/CppUnit/CppUnit_vs140.vcxproj +++ b/CppUnit/CppUnit_vs140.vcxproj @@ -55,7 +55,6 @@ {138BB448-808A-4FE5-A66D-78D1F8770F59} CppUnit Win32Proj - 8.1 diff --git a/CppUnit/CppUnit_vs150.vcxproj b/CppUnit/CppUnit_vs150.vcxproj index 79e00b808..3e6611653 100644 --- a/CppUnit/CppUnit_vs150.vcxproj +++ b/CppUnit/CppUnit_vs150.vcxproj @@ -55,7 +55,6 @@ {138BB448-808A-4FE5-A66D-78D1F8770F59} CppUnit Win32Proj - 8.1 diff --git a/CppUnit/CppUnit_vs160.vcxproj b/CppUnit/CppUnit_vs160.vcxproj index de55fcfcf..7eeafbc10 100644 --- a/CppUnit/CppUnit_vs160.vcxproj +++ b/CppUnit/CppUnit_vs160.vcxproj @@ -55,7 +55,6 @@ {138BB448-808A-4FE5-A66D-78D1F8770F59} CppUnit Win32Proj - 10.0 diff --git a/CppUnit/CppUnit_vs170.sln b/CppUnit/CppUnit_vs170.sln index 6ca2d6861..e9a5caf63 100644 --- a/CppUnit/CppUnit_vs170.sln +++ b/CppUnit/CppUnit_vs170.sln @@ -4,6 +4,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppUnit", "CppUnit_vs170.vc EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 + release_shared|ARM64 = release_shared|ARM64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 + release_static_mt|ARM64 = release_static_mt|ARM64 + debug_static_md|ARM64 = debug_static_md|ARM64 + release_static_md|ARM64 = release_static_md|ARM64 debug_shared|Win32 = debug_shared|Win32 release_shared|Win32 = release_shared|Win32 debug_static_mt|Win32 = debug_static_mt|Win32 @@ -18,6 +24,24 @@ Global release_static_md|x64 = release_static_md|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_shared|ARM64.Build.0 = release_shared|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_shared|ARM64.Deploy.0 = release_shared|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 + {138BB448-808A-4FE5-A66D-78D1F8770F59}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64 {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_shared|Win32.Build.0 = debug_shared|Win32 {138BB448-808A-4FE5-A66D-78D1F8770F59}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 diff --git a/CppUnit/CppUnit_vs170.vcxproj b/CppUnit/CppUnit_vs170.vcxproj index 13dc51ca5..5d8927b1a 100644 --- a/CppUnit/CppUnit_vs170.vcxproj +++ b/CppUnit/CppUnit_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 CppUnit {138BB448-808A-4FE5-A66D-78D1F8770F59} CppUnit @@ -87,6 +112,36 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + StaticLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + + + DynamicLibrary + MultiByte + v143 + StaticLibrary MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + CppUnitA64d + CppUnitmdd + CppUnitmtd + CppUnitA64 + CppUnitmd + CppUnitmt CppUnitd CppUnitmdd CppUnitmtd @@ -171,6 +250,32 @@ CppUnitmd CppUnitmt + + ..\binA64\ + objA64\CppUnit\$(Configuration)\ + true + + + ..\binA64\ + objA64\CppUnit\$(Configuration)\ + false + + + ..\libA64\ + objA64\CppUnit\$(Configuration)\ + + + ..\libA64\ + objA64\CppUnit\$(Configuration)\ + + + ..\libA64\ + objA64\CppUnit\$(Configuration)\ + + + ..\libA64\ + objA64\CppUnit\$(Configuration)\ + ..\bin\ obj\CppUnit\$(Configuration)\ @@ -223,6 +328,164 @@ ..\lib64\ obj64\CppUnit\$(Configuration)\ + + + Disabled + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;POCO_NO_AUTOMATIC_LIBS;CppUnit_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + ..\binA64\CppUnitA64d.dll + true + true + ..\binA64\CppUnitA64d.pdb + ..\libA64;%(AdditionalLibraryDirectories) + Console + ..\libA64\CppUnitd.lib + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;POCO_NO_AUTOMATIC_LIBS;CppUnit_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + ..\binA64\CppUnitA64.dll + true + false + ..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\libA64\CppUnit.lib + MachineARM64 + + + + + Disabled + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;POCO_NO_AUTOMATIC_LIBS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + ..\libA64\CppUnitmtd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\CppUnitmtd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;POCO_NO_AUTOMATIC_LIBS;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + ..\libA64\CppUnitmt.lib + + + + + Disabled + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;POCO_NO_AUTOMATIC_LIBS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + ..\libA64\CppUnitmdd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\CppUnitmdd.lib + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;..\Foundation\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;POCO_NO_AUTOMATIC_LIBS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + ..\libA64\CppUnitmd.lib + + Disabled diff --git a/CppUnit/doc/README.html b/CppUnit/doc/README.html index 5f8a1418a..788619cd3 100644 --- a/CppUnit/doc/README.html +++ b/CppUnit/doc/README.html @@ -15,14 +15,14 @@

CppUnit is a simple unit test framework for C++. It is a port from JUnit, a testing framework for Java, developed by Kent Beck and Erich Gamma.

Contents

README.html                     this file
-    
+   
     test                        the source code
         framework               the testing framework
-		extensions	some framework extension classes 
-        textui                  a command line interface to run tests 
+		extensions	some framework extension classes
+        textui                  a command line interface to run tests
     ms                          code for a Microsoft specific TestRunner
     samples                     some example test cases and extensions to the framework
-        multicaster             a sample illustrating a publish/subscribe 
+        multicaster             a sample illustrating a publish/subscribe
 				multicaster under test
     doc                         documentation

Installation

diff --git a/CppUnit/doc/cookbook.htm b/CppUnit/doc/cookbook.htm index 08224883b..2cf027258 100644 --- a/CppUnit/doc/cookbook.htm +++ b/CppUnit/doc/cookbook.htm @@ -17,7 +17,7 @@

Subclass the TestCase class. Override the method "runTest ()". When you want to check a value, call "assert (bool)" and pass in an expression that is true if the test succeeds.

For example, to test the equality comparison for a Complex number class, write:

	class ComplexNumberTest : public TestCase { 
-	public: 
+	public:
                     ComplexNumberTest (string name) : TestCase (name) {}
         void        runTest () {
                         assert (Complex (10, 1) == Complex (10, 1));
@@ -59,7 +59,7 @@
 	void		setUp ()  {
 			    m_10_1 = new Complex (10, 1);
 			    m_1_1  = new Complex (1, 1);
-			    m_11_2  = new Complex (11, 2);  
+			    m_11_2  = new Complex (11, 2);
                         }
 	void		tearDown ()  {
 			    delete m_10_1, delete m_1_1, delete m_11_2;
@@ -83,7 +83,7 @@
 	void		setUp ()  {
 			    m_10_1 = new Complex (10, 1);
 			    m_1_1  = new Complex (1, 1);
-			    m_11_2 = new Complex (11, 2);  
+			    m_11_2 = new Complex (11, 2);
                         }
 	void		tearDown ()  {
 			    delete m_10_1, delete m_1_1, delete m_11_2;
diff --git a/CppUnit/include/CppUnit/CppUnitException.h b/CppUnit/include/CppUnit/CppUnitException.h
index 68eb9739c..7bbc891d1 100644
--- a/CppUnit/include/CppUnit/CppUnitException.h
+++ b/CppUnit/include/CppUnit/CppUnitException.h
@@ -20,8 +20,8 @@ class CppUnit_API CppUnitException: public std::exception
 	/// descriptive strings through its what() method
 {
 public:
-	CppUnitException(const std::string& message = "", 
-	                 long lineNumber = CPPUNIT_UNKNOWNLINENUMBER, 
+	CppUnitException(const std::string& message = "",
+	                 long lineNumber = CPPUNIT_UNKNOWNLINENUMBER,
 	                 const std::string& fileName = CPPUNIT_UNKNOWNFILENAME);
 	CppUnitException(const std::string& message,
 	                 long lineNumber,
@@ -110,26 +110,26 @@ inline const char* CppUnitException::what() const throw ()
 
 inline long CppUnitException::lineNumber() const
 {
-	return _lineNumber; 
+	return _lineNumber;
 }
 
 
 inline long CppUnitException::data1LineNumber() const
 {
-	return _data1lineNumber; 
+	return _data1lineNumber;
 }
 
 
 inline long CppUnitException::data2LineNumber() const
 {
-	return _data2lineNumber; 
+	return _data2lineNumber;
 }
 
 
 // The file in which the error occurred
 inline const std::string& CppUnitException::fileName() const
 {
-	return _fileName; 
+	return _fileName;
 }
 
 
diff --git a/CppUnit/include/CppUnit/Orthodox.h b/CppUnit/include/CppUnit/Orthodox.h
index 5e9f41c37..ac08c0100 100644
--- a/CppUnit/include/CppUnit/Orthodox.h
+++ b/CppUnit/include/CppUnit/Orthodox.h
@@ -45,11 +45,11 @@ namespace CppUnit {
  *
  * see TestSuite
  */
-template  
+template 
 class Orthodox: public TestCase
 {
 public:
-	Orthodox(): TestCase("Orthodox") 
+	Orthodox(): TestCase("Orthodox")
 	{
 	}
 
@@ -60,7 +60,7 @@ protected:
 
 
 // Run an orthodoxy test
-template  
+template 
 void Orthodox::runTest()
 {
     // make sure we have a default constructor
@@ -90,7 +90,7 @@ void Orthodox::runTest()
 
 
 // Exercise a call
-template  
+template 
 ClassUnderTest Orthodox::call(ClassUnderTest object)
 {
     return object;
diff --git a/CppUnit/include/CppUnit/RepeatedTest.h b/CppUnit/include/CppUnit/RepeatedTest.h
index dd471c0c1..21499f780 100644
--- a/CppUnit/include/CppUnit/RepeatedTest.h
+++ b/CppUnit/include/CppUnit/RepeatedTest.h
@@ -29,7 +29,7 @@ class CppUnit_API RepeatedTest: public TestDecorator
 	REFERENCEOBJECT (RepeatedTest)
 
 public:
-	RepeatedTest(Test* test, int timesRepeat): TestDecorator (test), _timesRepeat (timesRepeat) 
+	RepeatedTest(Test* test, int timesRepeat): TestDecorator (test), _timesRepeat (timesRepeat)
 	{
 	}
 
@@ -59,7 +59,7 @@ inline std::string RepeatedTest::toString()
 // Runs a repeated test
 inline void RepeatedTest::run(TestResult *result)
 {
-	for (int n = 0; n < _timesRepeat; n++) 
+	for (int n = 0; n < _timesRepeat; n++)
 	{
 		if (result->shouldStop())
 			break;
diff --git a/CppUnit/include/CppUnit/Test.h b/CppUnit/include/CppUnit/Test.h
index 1c69ab122..aeabfe099 100644
--- a/CppUnit/include/CppUnit/Test.h
+++ b/CppUnit/include/CppUnit/Test.h
@@ -10,6 +10,7 @@
 #include "CppUnit/CppUnit.h"
 #include 
 #include 
+#include 
 
 
 namespace CppUnit {
@@ -33,8 +34,10 @@ public:
 	};
 
 public:
+	using Callback = std::function;
+
 	virtual ~Test() = 0;
-	virtual void run(TestResult* result) = 0;
+	virtual void run(TestResult* result, const Callback& callback = nullptr) = 0;
 	virtual int countTestCases() const = 0;
 	virtual std::string toString() const = 0;
 	virtual Test::Type getType() const = 0;
@@ -43,7 +46,7 @@ public:
 	const std::vector& setup() const;
 
 private:
-	std::vector	_setup;
+	std::vector _setup;
 };
 
 
@@ -53,7 +56,7 @@ inline Test::~Test()
 
 
 // Runs a test and collects its result in a TestResult instance.
-inline void Test::run(TestResult *result)
+inline void Test::run(TestResult *result, const Callback& callback)
 {
 }
 
@@ -61,7 +64,7 @@ inline void Test::run(TestResult *result)
 // Counts the number of test cases that will be run by this test.
 inline int Test::countTestCases() const
 {
-	return 0; 
+	return 0;
 }
 
 
diff --git a/CppUnit/include/CppUnit/TestCase.h b/CppUnit/include/CppUnit/TestCase.h
index 109d1ecaa..bd18de301 100644
--- a/CppUnit/include/CppUnit/TestCase.h
+++ b/CppUnit/include/CppUnit/TestCase.h
@@ -90,7 +90,7 @@ public:
 	TestCase(const std::string& Name, Test::Type testType = Test::Normal);
 	~TestCase();
 
-	virtual void run(TestResult* result);
+	virtual void run(TestResult* result, const Test::Callback& callback = nullptr);
 	virtual TestResult* run();
 	virtual int countTestCases() const;
 	virtual std::string toString() const;
@@ -124,10 +124,17 @@ protected:
                                    long data2LineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER,
 	                               const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME);
 
-	void assertEquals(long expected,
-	                  long actual,
+	template ::value, T1>::type,
+		typename = typename std::enable_if::value, T2>::type>
+	void assertEquals(T1 expected,
+	                  T2 actual,
 	                  long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER,
-	                  const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME);
+	                  const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME)
+	{
+		if (expected != actual)
+			assertImplementation(false, notEqualsMessage(expected, actual), lineNumber, fileName);
+	}
 
 	void assertEquals(double expected,
 	                  double actual,
@@ -140,13 +147,24 @@ protected:
 	                  long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER,
 	                  const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME);
 
+	void assertEquals(const char* expected,
+	                  const std::string& actual,
+	                  long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER,
+	                  const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME);
+
 	void assertEquals(const void* expected,
 	                  const void* actual,
 	                  long lineNumber = CppUnitException::CPPUNIT_UNKNOWNLINENUMBER,
 	                  const std::string& fileName = CppUnitException::CPPUNIT_UNKNOWNFILENAME);
 
-	std::string notEqualsMessage(long expected, long actual);
-	std::string notEqualsMessage(double expected, double actual);
+	template ::value, T1>::type,
+		typename = typename std::enable_if::value, T2>::type>
+	std::string notEqualsMessage(T1 expected, T2 actual)
+	{
+		return "expected: " + std::to_string(expected) + " but was: " + std::to_string(actual);
+	}
+
 	std::string notEqualsMessage(const void* expected, const void* actual);
 	std::string notEqualsMessage(const std::string& expected, const std::string& actual);
 
diff --git a/CppUnit/include/CppUnit/TestDecorator.h b/CppUnit/include/CppUnit/TestDecorator.h
index 85b5f3de9..7ade2d431 100644
--- a/CppUnit/include/CppUnit/TestDecorator.h
+++ b/CppUnit/include/CppUnit/TestDecorator.h
@@ -35,7 +35,7 @@ public:
 
 	int countTestCases() const;
 
-	void run(TestResult* result);
+	void run(TestResult* result, const Test::Callback& callback);
 
 	std::string toString() const;
 
diff --git a/CppUnit/include/CppUnit/TestFailure.h b/CppUnit/include/CppUnit/TestFailure.h
index b443f5970..b2ff60aae 100644
--- a/CppUnit/include/CppUnit/TestFailure.h
+++ b/CppUnit/include/CppUnit/TestFailure.h
@@ -57,7 +57,7 @@ inline TestFailure::TestFailure(Test* failedTest, CppUnitException* thrownExcept
 
 // Deletes the owned exception.
 inline TestFailure::~TestFailure()
-{ 
+{
 	delete _thrownException;
 }
 
diff --git a/CppUnit/include/CppUnit/TestResult.h b/CppUnit/include/CppUnit/TestResult.h
index a09aa9e88..6539e0bae 100644
--- a/CppUnit/include/CppUnit/TestResult.h
+++ b/CppUnit/include/CppUnit/TestResult.h
@@ -67,7 +67,7 @@ public:
 		SynchronizationObject()
 		{
 		}
-		
+
 		virtual ~SynchronizationObject()
 		{
 		}
@@ -75,7 +75,7 @@ public:
 		virtual void lock()
 		{
 		}
-		
+
 		virtual void unlock()
 		{
 		}
@@ -112,7 +112,7 @@ protected:
 // Construct a TestResult
 inline TestResult::TestResult(): _syncObject(new SynchronizationObject())
 {
-	_runTests = 0; 
+	_runTests = 0;
 	_stop = false;
 }
 
@@ -121,7 +121,7 @@ inline TestResult::TestResult(): _syncObject(new SynchronizationObject())
 // caused the error
 inline void TestResult::addError(Test* test, CppUnitException* e)
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	_errors.push_back(new TestFailure(test, e));
 }
 
@@ -130,7 +130,7 @@ inline void TestResult::addError(Test* test, CppUnitException* e)
 // caused the failure.
 inline void TestResult::addFailure(Test* test, CppUnitException* e)
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	_failures.push_back(new TestFailure(test, e));
 }
 
@@ -138,7 +138,7 @@ inline void TestResult::addFailure(Test* test, CppUnitException* e)
 // Informs the result that a test will be started.
 inline void TestResult::startTest(Test* test)
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	_runTests++;
 }
 
@@ -153,7 +153,7 @@ inline void TestResult::endTest(Test* test)
 // Gets the number of run tests.
 inline int TestResult::runTests()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	return _runTests;
 }
 
@@ -161,7 +161,7 @@ inline int TestResult::runTests()
 // Gets the number of detected errors.
 inline int TestResult::testErrors()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	return (int) _errors.size();
 }
 
@@ -169,7 +169,7 @@ inline int TestResult::testErrors()
 // Gets the number of detected failures.
 inline int TestResult::testFailures()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	return (int) _failures.size();
 }
 
@@ -177,15 +177,15 @@ inline int TestResult::testFailures()
 // Returns whether the entire test was successful or not.
 inline bool TestResult::wasSuccessful()
 {
-	ExclusiveZone zone(_syncObject); 
-	return _failures.size() == 0 && _errors.size () == 0; 
+	ExclusiveZone zone(_syncObject);
+	return _failures.size() == 0 && _errors.size () == 0;
 }
 
 
 // Returns a std::vector of the errors.
 inline std::vector& TestResult::errors()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	return _errors;
 }
 
@@ -193,7 +193,7 @@ inline std::vector& TestResult::errors()
 // Returns a std::vector of the failures.
 inline std::vector& TestResult::failures()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	return _failures;
 }
 
@@ -201,7 +201,7 @@ inline std::vector& TestResult::failures()
 // Returns whether testing should be stopped
 inline bool TestResult::shouldStop()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	return _stop;
 }
 
@@ -209,7 +209,7 @@ inline bool TestResult::shouldStop()
 // Stop testing
 inline void TestResult::stop()
 {
-	ExclusiveZone zone(_syncObject); 
+	ExclusiveZone zone(_syncObject);
 	_stop = true;
 }
 
@@ -218,7 +218,7 @@ inline void TestResult::stop()
 // TestResult assumes ownership of the object
 inline void TestResult::setSynchronizationObject(SynchronizationObject* syncObject)
 {
-	delete _syncObject; 
+	delete _syncObject;
 	_syncObject = syncObject;
 }
 
diff --git a/CppUnit/include/CppUnit/TestRunner.h b/CppUnit/include/CppUnit/TestRunner.h
index fa8ea0912..6157bc749 100644
--- a/CppUnit/include/CppUnit/TestRunner.h
+++ b/CppUnit/include/CppUnit/TestRunner.h
@@ -8,20 +8,19 @@
 
 
 #include "CppUnit/CppUnit.h"
+#include "CppUnit/Test.h"
 #include 
 #include 
 #include 
 #if defined(POCO_VXWORKS)
 #include 
 #endif
+#include "Poco/Exception.h"
 
 
 namespace CppUnit {
 
 
-class Test;
-
-
 /*
  * A command line based tool to run tests.
  * TestRunner expects as its only argument the name of a TestCase class.
@@ -46,7 +45,7 @@ public:
 	TestRunner(std::ostream& ostr);
 	~TestRunner();
 
-	bool run(const std::vector& args);
+	bool run(const std::vector& args, const Test::Callback& callback = nullptr);
 	void addTest(const std::string& name, Test* test);
 
 protected:
@@ -85,6 +84,16 @@ private:
 		return runner.run(args) ? 0 : 1; \
 	}
 #else
+#define CppUnitPocoExceptionText(exc) \
+	CppUnit::Test::Callback exc = [] (const std::exception& ex) \
+	{ \
+		std::string text; \
+		const Poco::Exception* pEx = dynamic_cast(&ex); \
+		if (pEx) text = pEx->displayText(); \
+		else text = ex.what(); \
+		return text; \
+	}
+
 #define CppUnitMain(testCase) \
 	int main(int ac, char **av)							\
 	{													\
@@ -93,7 +102,8 @@ private:
 			args.push_back(std::string(av[i]));			\
 		CppUnit::TestRunner runner;						\
 		runner.addTest(#testCase, testCase::suite());	\
-		return runner.run(args) ? 0 : 1;				\
+		CppUnitPocoExceptionText(exc);					\
+		return runner.run(args, exc) ? 0 : 1;			\
 	}
 #endif
 
diff --git a/CppUnit/include/CppUnit/TestSetup.h b/CppUnit/include/CppUnit/TestSetup.h
index 323d6cf5b..040b7685a 100644
--- a/CppUnit/include/CppUnit/TestSetup.h
+++ b/CppUnit/include/CppUnit/TestSetup.h
@@ -24,17 +24,17 @@ class CppUnit_API TestSetup: public TestDecorator
 	REFERENCEOBJECT (TestSetup)
 
 public:
-	TestSetup(Test* test): TestDecorator(test) 
+	TestSetup(Test* test): TestDecorator(test)
 	{
 	}
-	
+
 	void run(TestResult* result);
 
 protected:
-	void setUp() 
+	void setUp()
 	{
 	}
-	
+
 	void tearDown()
 	{
 	}
@@ -44,7 +44,7 @@ protected:
 inline void TestSetup::run(TestResult* result)
 {
 	setUp();
-	TestDecorator::run(result); 
+	TestDecorator::run(result);
 	tearDown();
 }
 
diff --git a/CppUnit/include/CppUnit/TestSuite.h b/CppUnit/include/CppUnit/TestSuite.h
index 7d3da3d61..9aa6a55d9 100644
--- a/CppUnit/include/CppUnit/TestSuite.h
+++ b/CppUnit/include/CppUnit/TestSuite.h
@@ -41,14 +41,14 @@ public:
 	TestSuite(const std::string& name = "");
 	~TestSuite();
 
-	void run(TestResult* result);
+	void run(TestResult* result, const Test::Callback& callback = nullptr);
 	int countTestCases() const;
 	void addTest(Test* test);
 	std::string toString() const;
 	Test::Type getType() const;
 
 	virtual void deleteContents();
-	
+
 	const std::vector tests() const;
 
 private:
@@ -80,7 +80,7 @@ inline void TestSuite::addTest(Test* test)
 // Returns a std::string representation of the test suite.
 inline std::string TestSuite::toString() const
 {
-	return "suite " + _name; 
+	return "suite " + _name;
 }
 
 // Returns the type of the test, see Test::Type
diff --git a/CppUnit/include/CppUnit/TextTestResult.h b/CppUnit/include/CppUnit/TextTestResult.h
index d7421f16f..867679965 100644
--- a/CppUnit/include/CppUnit/TextTestResult.h
+++ b/CppUnit/include/CppUnit/TextTestResult.h
@@ -31,7 +31,7 @@ public:
 	virtual void printErrors(std::ostream& stream);
 	virtual void printFailures(std::ostream& stream);
 	virtual void printHeader(std::ostream& stream);
-	
+
 protected:
 	std::string shortName(const std::string& testName);
 	void setup();
diff --git a/CppUnit/include/CppUnit/estring.h b/CppUnit/include/CppUnit/estring.h
index 8adf030b3..b323db9ed 100644
--- a/CppUnit/include/CppUnit/estring.h
+++ b/CppUnit/include/CppUnit/estring.h
@@ -32,26 +32,26 @@ inline std::string estring(std::string& expandedString)
 // Create a std::string from an int
 inline std::string estring(int number)
 {
-	char buffer[50]; 
-	std::snprintf(buffer, sizeof(buffer), "%d", number); 
-	return std::string (buffer); 
+	char buffer[50];
+	std::snprintf(buffer, sizeof(buffer), "%d", number);
+	return std::string (buffer);
 }
 
 
 // Create a string from a long
 inline std::string estring(long number)
 {
-	char buffer[50]; 
-	std::snprintf(buffer, sizeof(buffer), "%ld", number); 
-	return std::string (buffer); 
+	char buffer[50];
+	std::snprintf(buffer, sizeof(buffer), "%ld", number);
+	return std::string (buffer);
 }
 
 
 // Create a std::string from a double
 inline std::string estring(double number)
 {
-	char buffer[50]; 
-	std::snprintf(buffer, sizeof(buffer), "%lf", number); 
+	char buffer[50];
+	std::snprintf(buffer, sizeof(buffer), "%lf", number);
 	return std::string(buffer);
 }
 
@@ -59,8 +59,8 @@ inline std::string estring(double number)
 // Create a std::string from a double
 inline std::string estring(const void* ptr)
 {
-	char buffer[50]; 
-	std::snprintf(buffer, sizeof(buffer), "%p", ptr); 
+	char buffer[50];
+	std::snprintf(buffer, sizeof(buffer), "%p", ptr);
 	return std::string(buffer);
 }
 
diff --git a/CppUnit/src/TestCase.cpp b/CppUnit/src/TestCase.cpp
index 6863080c4..7aa9136d1 100644
--- a/CppUnit/src/TestCase.cpp
+++ b/CppUnit/src/TestCase.cpp
@@ -47,14 +47,6 @@ void TestCase::loop2assertImplementation(bool condition, const std::string& cond
 }
 
 
-// Check for a failed equality assertion
-void TestCase::assertEquals(long expected, long actual, long lineNumber, const std::string& fileName)
-{
-	if (expected != actual)
-		assertImplementation(false, notEqualsMessage(expected, actual), lineNumber, fileName);
-}
-
-
 // Check for a failed equality assertion
 void TestCase::assertEquals(double expected, double actual, double delta, long lineNumber, const std::string& fileName)
 {
@@ -79,6 +71,14 @@ void TestCase::assertEquals(const std::string& expected, const std::string& actu
 }
 
 
+// Check for a failed equality assertion
+void TestCase::assertEquals(const char* expected, const std::string& actual, long lineNumber, const std::string& fileName)
+{
+	if (std::string(expected) != actual)
+		assertImplementation(false, notEqualsMessage(std::string(expected), actual), lineNumber, fileName);
+}
+
+
 void TestCase::assertNotNull(const void* pointer, const std::string& pointerExpression, long lineNumber, const std::string& fileName)
 {
 	if (pointer == NULL)
@@ -106,7 +106,7 @@ void TestCase::warn(const std::string& message, long lineNumber, const std::stri
 
 
 // Run the test and catch any exceptions that are triggered by it
-void TestCase::run(TestResult *result)
+void TestCase::run(TestResult *result, const Test::Callback& callback)
 {
 	result->startTest(this);
 
@@ -123,8 +123,7 @@ void TestCase::run(TestResult *result)
 	catch (std::exception& e)
 	{
 		std::string msg(typeid(e).name());
-		msg.append(": ");
-		msg.append(e.what());
+		msg.append(":\n").append(callback(e));
 		result->addError(this, new CppUnitException(msg));
 	}
 	catch (...)
@@ -153,20 +152,6 @@ void TestCase::runTest()
 }
 
 
-// Build a message about a failed equality check
-std::string TestCase::notEqualsMessage(long expected, long actual)
-{
-	return "expected: " + estring(expected) + " but was: " + estring(actual);
-}
-
-
-// Build a message about a failed equality check
-std::string TestCase::notEqualsMessage(double expected, double actual)
-{
-	return "expected: " + estring(expected) + " but was: " + estring(actual);
-}
-
-
 // Build a message about a failed equality check
 std::string TestCase::notEqualsMessage(const void* expected, const void* actual)
 {
diff --git a/CppUnit/src/TestDecorator.cpp b/CppUnit/src/TestDecorator.cpp
index 634af35b6..10da39bdc 100644
--- a/CppUnit/src/TestDecorator.cpp
+++ b/CppUnit/src/TestDecorator.cpp
@@ -26,7 +26,7 @@ int TestDecorator::countTestCases() const
 }
 
 
-void TestDecorator::run(TestResult* result)
+void TestDecorator::run(TestResult* result, const Test::Callback& callback = nullptr)
 {
 	_test->run(result);
 }
diff --git a/CppUnit/src/TestRunner.cpp b/CppUnit/src/TestRunner.cpp
index c6814da4e..31c54ec95 100644
--- a/CppUnit/src/TestRunner.cpp
+++ b/CppUnit/src/TestRunner.cpp
@@ -41,7 +41,7 @@ void TestRunner::printBanner()
 }
 
 
-bool TestRunner::run(const std::vector& args)
+bool TestRunner::run(const std::vector& args, const Test::Callback& callback)
 {
 	std::string testCase;
 	int numberOfTests = 0;
@@ -139,7 +139,7 @@ bool TestRunner::run(const std::vector& args)
 		if (setup.size() > 0)
 			testToRun->addSetup(setup);
 
-		testToRun->run(&result);
+		testToRun->run(&result, callback);
 		numberOfTests++;
 	}
 	_ostr << result << std::endl;
diff --git a/CppUnit/src/TestSuite.cpp b/CppUnit/src/TestSuite.cpp
index b89c47b4b..00d336d06 100644
--- a/CppUnit/src/TestSuite.cpp
+++ b/CppUnit/src/TestSuite.cpp
@@ -19,9 +19,9 @@ void TestSuite::deleteContents()
 
 
 // Runs the tests and collects their result in a TestResult.
-void TestSuite::run(TestResult *result)
+void TestSuite::run(TestResult *result, const Test::Callback& callback)
 {
-	for (std::vector::iterator it = _tests.begin(); it != _tests.end(); ++it) 
+	for (std::vector::iterator it = _tests.begin(); it != _tests.end(); ++it)
 	{
 		if (result->shouldStop ())
 			break;
@@ -29,7 +29,7 @@ void TestSuite::run(TestResult *result)
 		Test *test = *it;
 		if (!setup().empty())
 			test->addSetup(setup());
-		test->run(result);
+		test->run(result, callback);
 	}
 }
 
diff --git a/Crypto/CMakeLists.txt b/Crypto/CMakeLists.txt
index 9204a91cb..0a3b620df 100644
--- a/Crypto/CMakeLists.txt
+++ b/Crypto/CMakeLists.txt
@@ -25,7 +25,7 @@ target_link_libraries(Crypto PUBLIC Poco::Foundation OpenSSL::SSL OpenSSL::Crypt
 target_include_directories(Crypto
 	PUBLIC
 		$
-		$
+		$
 	PRIVATE
 		${CMAKE_CURRENT_SOURCE_DIR}/src
 )
diff --git a/Crypto/Crypto_vs170.sln b/Crypto/Crypto_vs170.sln
index 4ac53237f..a73ee33fd 100644
--- a/Crypto/Crypto_vs170.sln
+++ b/Crypto/Crypto_vs170.sln
@@ -9,6 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\Test
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		debug_shared|ARM64 = debug_shared|ARM64
+		release_shared|ARM64 = release_shared|ARM64
+		debug_static_mt|ARM64 = debug_static_mt|ARM64
+		release_static_mt|ARM64 = release_static_mt|ARM64
+		debug_static_md|ARM64 = debug_static_md|ARM64
+		release_static_md|ARM64 = release_static_md|ARM64
 		debug_shared|Win32 = debug_shared|Win32
 		release_shared|Win32 = release_shared|Win32
 		debug_static_mt|Win32 = debug_static_mt|Win32
@@ -23,6 +29,24 @@ Global
 		release_static_md|x64 = release_static_md|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
@@ -59,6 +83,24 @@ Global
 		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_md|x64.ActiveCfg = release_static_md|x64
 		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_md|x64.Build.0 = release_static_md|x64
 		{EEEE7259-32E9-4D56-B023-C733940AB2A0}.release_static_md|x64.Deploy.0 = release_static_md|x64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
diff --git a/Crypto/Crypto_vs170.vcxproj b/Crypto/Crypto_vs170.vcxproj
index 55aeb08cf..aa7b65bff 100644
--- a/Crypto/Crypto_vs170.vcxproj
+++ b/Crypto/Crypto_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     Crypto
     {EEEE7259-32E9-4D56-B023-C733940AB2A0}
     Crypto
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
   
     StaticLibrary
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    PocoCryptoA64d
+    PocoCryptomdd
+    PocoCryptomtd
+    PocoCryptoA64
+    PocoCryptomd
+    PocoCryptomt
     PocoCryptod
     PocoCryptomdd
     PocoCryptomtd
@@ -171,6 +250,32 @@
     PocoCryptomd
     PocoCryptomt
   
+  
+    ..\binA64\
+    objA64\Crypto\$(Configuration)\
+    true
+  
+  
+    ..\binA64\
+    objA64\Crypto\$(Configuration)\
+    false
+  
+  
+    ..\libA64\
+    objA64\Crypto\$(Configuration)\
+  
+  
+    ..\libA64\
+    objA64\Crypto\$(Configuration)\
+  
+  
+    ..\libA64\
+    objA64\Crypto\$(Configuration)\
+  
+  
+    ..\libA64\
+    objA64\Crypto\$(Configuration)\
+  
   
     ..\bin\
     obj\Crypto\$(Configuration)\
@@ -223,6 +328,166 @@
     ..\lib64\
     obj64\Crypto\$(Configuration)\
   
+  
+    
+      Disabled
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;_USRDLL;Crypto_EXPORTS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      ..\binA64\PocoCryptoA64d.dll
+      true
+      true
+      ..\binA64\PocoCryptoA64d.pdb
+      ..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      ..\libA64\PocoCryptod.lib
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;_USRDLL;Crypto_EXPORTS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      ..\binA64\PocoCryptoA64.dll
+      true
+      false
+      ..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      true
+      true
+      ..\libA64\PocoCrypto.lib
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      ..\libA64\PocoCryptomtd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\libA64\PocoCryptomtd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\libA64\PocoCryptomt.lib
+    
+  
+  
+    
+      Disabled
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      ..\libA64\PocoCryptomdd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\libA64\PocoCryptomdd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\libA64\PocoCryptomd.lib
+    
+  
   
     
       Disabled
@@ -640,12 +905,16 @@
   
   
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
     
diff --git a/Crypto/Makefile b/Crypto/Makefile
index 3e654d1b1..732eb031c 100644
--- a/Crypto/Makefile
+++ b/Crypto/Makefile
@@ -6,11 +6,15 @@
 
 include $(POCO_BASE)/build/rules/global
 
-SYSLIBS += -lssl -lcrypto
+# see https://github.com/pocoproject/poco/issues/3073
+GLOBAL_SYSLIBS := $(SYSLIBS)
+SYSLIBS = -lssl -lcrypto
+SYSLIBS += $(GLOBAL_SYSLIBS)
 
 objects = Cipher CipherFactory CipherImpl CipherKey CipherKeyImpl \
-	CryptoException CryptoStream CryptoTransform ECDSADigestEngine \
-	ECKey ECKeyImpl EVPPKey KeyPair KeyPairImpl PKCS12Container \
+	CryptoException CryptoStream CryptoTransform \
+	ECDSADigestEngine ECKey ECKeyImpl Envelope \
+	EVPCipherImpl EVPPKey KeyPair KeyPairImpl PKCS12Container \
 	RSACipherImpl RSAKey RSAKeyImpl RSADigestEngine DigestEngine \
 	X509Certificate OpenSSLInitializer
 
diff --git a/Crypto/include/Poco/Crypto/Cipher.h b/Crypto/include/Poco/Crypto/Cipher.h
index b6ecf1172..c0a6188fc 100644
--- a/Crypto/include/Poco/Crypto/Cipher.h
+++ b/Crypto/include/Poco/Crypto/Cipher.h
@@ -107,16 +107,16 @@ public:
 	virtual CryptoTransform::Ptr createDecryptor() = 0;
 		/// Creates a decryptor object to be used with a CryptoStream.
 
-	virtual std::string encryptString(const std::string& str, Encoding encoding = ENC_NONE);
+	virtual std::string encryptString(const std::string& str, Encoding encoding = ENC_NONE, bool padding = true);
 		/// Directly encrypt a string and encode it using the given encoding.
 
-	virtual std::string decryptString(const std::string& str, Encoding encoding = ENC_NONE);
+	virtual std::string decryptString(const std::string& str, Encoding encoding = ENC_NONE, bool padding = true);
 		/// Directly decrypt a string that is encoded with the given encoding.
 
-	virtual void encrypt(std::istream& source, std::ostream& sink, Encoding encoding = ENC_NONE);
+	virtual void encrypt(std::istream& source, std::ostream& sink, Encoding encoding = ENC_NONE, bool padding = true);
 		/// Directly encrypts an input stream and encodes it using the given encoding.
 
-	virtual void decrypt(std::istream& source, std::ostream& sink, Encoding encoding = ENC_NONE);
+	virtual void decrypt(std::istream& source, std::ostream& sink, Encoding encoding = ENC_NONE, bool padding = true);
 		/// Directly decrypt an input stream that is encoded with the given encoding.
 
 protected:
diff --git a/Crypto/include/Poco/Crypto/CipherFactory.h b/Crypto/include/Poco/Crypto/CipherFactory.h
index 36aa964a1..5202e3f70 100644
--- a/Crypto/include/Poco/Crypto/CipherFactory.h
+++ b/Crypto/include/Poco/Crypto/CipherFactory.h
@@ -28,6 +28,7 @@ namespace Crypto {
 class Cipher;
 class CipherKey;
 class RSAKey;
+class EVPPKey;
 
 
 class Crypto_API CipherFactory
@@ -42,8 +43,8 @@ public:
 		/// Destroys the CipherFactory.
 
 	Cipher* createCipher(const CipherKey& key);
-		/// Creates a Cipher object for the given Cipher name. Valid cipher 
-		/// names depend on the OpenSSL version the library is linked with;  
+		/// Creates a Cipher object for the given Cipher name. Valid cipher
+		/// names depend on the OpenSSL version the library is linked with;
 		/// see the output of
 		///
 		///     openssl enc --help
@@ -59,7 +60,11 @@ public:
 	Cipher* createCipher(const RSAKey& key, RSAPaddingMode paddingMode = RSA_PADDING_PKCS1);
 		/// Creates a RSACipher using the given RSA key and padding mode
 		/// for public key encryption/private key decryption.
-	
+
+	Cipher* createCipher(const EVPPKey& key);
+		/// Creates an EVPCipher using the given EVP key
+		/// for public key encryption/private key decryption.
+
 	static CipherFactory& defaultFactory();
 		/// Returns the default CipherFactory.
 
diff --git a/Crypto/include/Poco/Crypto/Crypto.h b/Crypto/include/Poco/Crypto/Crypto.h
index f44a4f88d..7b857cf31 100644
--- a/Crypto/include/Poco/Crypto/Crypto.h
+++ b/Crypto/include/Poco/Crypto/Crypto.h
@@ -35,6 +35,7 @@
 
 #include "Poco/Foundation.h"
 #include 
+#include 
 
 
 #ifndef OPENSSL_VERSION_PREREQ
@@ -178,6 +179,20 @@ namespace Poco {
 namespace Crypto {
 
 
+inline std::string& getError(std::string& msg)
+	/// Appends OpenSSL error(s) to msg and
+	/// returns the augmented error description.
+{
+	unsigned long err;
+	while ((err = ERR_get_error()))
+	{
+		if (!msg.empty()) msg.append(1, '\n');
+		msg.append(ERR_error_string(err, 0));
+	}
+	return msg;
+}
+
+
 void Crypto_API initializeCrypto();
 	/// Initialize the Crypto library, as well as the underlying OpenSSL
 	/// libraries, by calling OpenSSLInitializer::initialize().
diff --git a/Crypto/include/Poco/Crypto/DigestEngine.h b/Crypto/include/Poco/Crypto/DigestEngine.h
index 8244a6ea8..1c30e769d 100644
--- a/Crypto/include/Poco/Crypto/DigestEngine.h
+++ b/Crypto/include/Poco/Crypto/DigestEngine.h
@@ -39,13 +39,13 @@ public:
 		/// See the OpenSSL documentation for a list of supported digest algorithms.
 		///
 		/// Throws a Poco::NotFoundException if no algorithm with the given name exists.
-		
+
 	~DigestEngine();
 		/// Destroys the DigestEngine.
-	
+
 	const std::string& algorithm() const;
 		/// Returns the name of the digest algorithm.
-	
+
 	int nid() const;
 		/// Returns the NID (OpenSSL object identifier) of the digest algorithm.
 
@@ -56,7 +56,7 @@ public:
 
 protected:
 	void updateImpl(const void* data, std::size_t length);
-	
+
 private:
 	std::string _name;
 	EVP_MD_CTX* _pContext;
diff --git a/Crypto/include/Poco/Crypto/ECKey.h b/Crypto/include/Poco/Crypto/ECKey.h
index e2abb928f..950b86928 100644
--- a/Crypto/include/Poco/Crypto/ECKey.h
+++ b/Crypto/include/Poco/Crypto/ECKey.h
@@ -32,6 +32,7 @@ class X509Certificate;
 class PKCS12Container;
 
 
+//@ deprecated
 class Crypto_API ECKey: public KeyPair
 	/// This class stores an EC key pair, consisting
 	/// of private and public key. Storage of the private
diff --git a/Crypto/include/Poco/Crypto/ECKeyImpl.h b/Crypto/include/Poco/Crypto/ECKeyImpl.h
index 1795e9584..f9c1b1d42 100644
--- a/Crypto/include/Poco/Crypto/ECKeyImpl.h
+++ b/Crypto/include/Poco/Crypto/ECKeyImpl.h
@@ -62,8 +62,8 @@ public:
 
 	ECKeyImpl(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase);
 		/// Creates the ECKey, by reading public and private key from the given files and
-		/// using the given passphrase for the private key. Can only by used for signing if 
-		/// a private key is available. 
+		/// using the given passphrase for the private key. Can only by used for signing if
+		/// a private key is available.
 
 	ECKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase);
 		/// Creates the ECKey. Can only by used for signing if pPrivKey
@@ -91,7 +91,7 @@ public:
 	void save(const std::string& publicKeyFile,
 		const std::string& privateKeyFile = "",
 		const std::string& privateKeyPassphrase = "") const;
-		/// Exports the public and private keys to the given files. 
+		/// Exports the public and private keys to the given files.
 		///
 		/// If an empty filename is specified, the corresponding key
 		/// is not exported.
diff --git a/Crypto/include/Poco/Crypto/EVPCipherImpl.h b/Crypto/include/Poco/Crypto/EVPCipherImpl.h
new file mode 100644
index 000000000..b85d7eaaa
--- /dev/null
+++ b/Crypto/include/Poco/Crypto/EVPCipherImpl.h
@@ -0,0 +1,76 @@
+//
+// EVPCipherImpl.h
+//
+// Library: Crypto
+// Package: EVP
+// Module:  EVPCipherImpl
+//
+// Definition of the EVPCipherImpl class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#ifndef Crypto_EVPCipherImpl_INCLUDED
+#define Crypto_EVPCipherImpl_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/Cipher.h"
+#include "Poco/Crypto/EVPPKey.h"
+#include "Poco/Crypto/OpenSSLInitializer.h"
+#include 
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class EVPCipherImpl: public Cipher
+	/// An implementation of the Cipher class for
+	/// asymmetric (public-private key) encryption
+	/// based on the OpenSSL crypto library.
+	///
+	/// Encryption is using the public key, decryption
+	/// requires the private key.
+{
+public:
+	EVPCipherImpl(const EVPPKey& key);
+		/// Creates a new EVPCipherImpl object for the given EVPPKey
+		/// and using the given padding mode.
+
+	virtual ~EVPCipherImpl();
+		/// Destroys the EVPCipherImpl.
+
+	const std::string& name() const;
+		/// Returns the name of the Cipher.
+
+	CryptoTransform::Ptr createEncryptor();
+		/// Creates an encryptor object.
+
+	CryptoTransform::Ptr createDecryptor();
+		/// Creates a decryptor object.
+
+private:
+	EVPPKey _key;
+	OpenSSLInitializer _openSSLInitializer;
+};
+
+
+//
+// Inlines
+//
+
+inline const std::string& EVPCipherImpl::name() const
+{
+	return _key.name();
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_EVPCipherImpl_INCLUDED
diff --git a/Crypto/include/Poco/Crypto/EVPPKey.h b/Crypto/include/Poco/Crypto/EVPPKey.h
index 7cf44d867..1bc0356f9 100644
--- a/Crypto/include/Poco/Crypto/EVPPKey.h
+++ b/Crypto/include/Poco/Crypto/EVPPKey.h
@@ -22,20 +22,25 @@
 #include "Poco/Crypto/Crypto.h"
 #include "Poco/Crypto/CryptoException.h"
 #include "Poco/StreamCopier.h"
+#include "Poco/Format.h"
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
 
 
 namespace Poco {
 namespace Crypto {
 
-
+//@deprecated
 class ECKey;
+//@deprecated
 class RSAKey;
+class PKCS12Container;
+class X509Certificate;
 
 
 class Crypto_API EVPPKey
@@ -55,10 +60,36 @@ public:
 		/// Only EC keys can be wrapped by an EVPPKey
 		/// created using this constructor.
 
+	EVPPKey(const X509Certificate& cert);
+		/// Constructs EVPPKey from the given certificate.
+
+	EVPPKey(const PKCS12Container& cert);
+		/// Constructs EVPPKey from the given container.
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+	EVPPKey(int type, int param);
+		/// Creates the EVPPKey.
+		/// Creates a new public/private keypair using the given parameters.
+		/// Can be used to sign data and verify signatures.
+		///
+		/// Suported types:
+		///   - EVP_PKEY_RSA
+		///   - EVP_PKEY_EC
+		///
+		/// Parameters:
+		///   - for EVP_PKEY_RSA: key length in bits
+		///   - for EVP_PKEY_EC: curve NID
+		///
+		/// This constructor is not available for OpenSSL version < 1.0.0
+
+#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
+
 	explicit EVPPKey(EVP_PKEY* pEVPPKey);
 		/// Constructs EVPPKey from EVP_PKEY pointer.
 		/// The content behind the supplied pointer is internally duplicated.
 
+	//@ deprecated
 	template
 	explicit EVPPKey(K* pKey): _pEVPPKey(EVP_PKEY_new())
 		/// Constructs EVPPKey from a "native" OpenSSL (RSA or EC_KEY),
@@ -124,6 +155,9 @@ public:
 	int type() const;
 		/// Retuns the EVPPKey type NID.
 
+	const std::string& name() const;
+		/// Retuns the EVPPKey name.
+
 	bool isSupported(int type) const;
 		/// Returns true if OpenSSL type is supported
 
@@ -135,19 +169,25 @@ public:
 
 	static EVP_PKEY* duplicate(const EVP_PKEY* pFromKey, EVP_PKEY** pToKey);
 		/// Duplicates pFromKey into *pToKey and returns
-		// the pointer to duplicated EVP_PKEY.
+		/// the pointer to duplicated EVP_PKEY.
 
 private:
 	EVPPKey();
 
 	static int type(const EVP_PKEY* pEVPPKey);
+	void checkType();
 	void newECKey(const char* group);
 	void duplicate(EVP_PKEY* pEVPPKey);
 
+	//@ deprecated
 	void setKey(ECKey* pKey);
+	//@ deprecated
 	void setKey(RSAKey* pKey);
+	//@ deprecated
 	void setKey(EC_KEY* pKey);
+	//@ deprecated
 	void setKey(RSA* pKey);
+
 	static int passCB(char* buf, int size, int, void* pass);
 
 	typedef EVP_PKEY* (*PEM_read_FILE_Key_fn)(FILE*, EVP_PKEY**, pem_password_cb*, void*);
@@ -180,7 +220,7 @@ private:
 #if defined(_MSC_VER)
 #pragma warning(push)
 #pragma warning(disable:4996) // deprecation warnings
-#endif				
+#endif
 				pFile = fopen(keyFile.c_str(), "r");
 #if defined(_MSC_VER)
 #pragma warning(pop)
@@ -211,8 +251,10 @@ private:
 				}
 				else
 				{
+					std::string msg = Poco::format("EVPPKey::loadKey('%s')\n", keyFile);
+					getError(msg);
 					if (getFunc) EVP_PKEY_free(pKey);
-					throw IOException("ECKeyImpl, cannot open file", keyFile);
+					throw IOException(msg);
 				}
 			}
 			else goto error;
@@ -220,8 +262,10 @@ private:
 		return false;
 
 	error:
+		std::string msg = Poco::format("EVPPKey::loadKey('%s')\n", keyFile);
+		getError(msg);
 		if (pFile) fclose(pFile);
-		throw OpenSSLException("EVPKey::loadKey(string)");
+		throw OpenSSLException(msg);
 	}
 
 	template 
@@ -277,13 +321,18 @@ private:
 		return false;
 
 	error:
+		std::string msg = "EVPPKey::loadKey(istream)\n";
+		getError(msg);
 		if (pBIO) BIO_free(pBIO);
-		throw OpenSSLException("EVPKey::loadKey(stream)");
+		throw OpenSSLException(msg);
 	}
 
-	EVP_PKEY* _pEVPPKey;
+	EVP_PKEY* _pEVPPKey = 0;
+	static const std::map KNOWN_TYPES;
 
+	//@deprecated
 	friend class ECKeyImpl;
+	//@deprecated
 	friend class RSAKeyImpl;
 };
 
@@ -297,7 +346,11 @@ inline bool EVPPKey::operator == (const EVPPKey& other) const
 {
 	poco_check_ptr (other._pEVPPKey);
 	poco_check_ptr (_pEVPPKey);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	return (1 == EVP_PKEY_eq(_pEVPPKey, other._pEVPPKey));
+#else
 	return (1 == EVP_PKEY_cmp(_pEVPPKey, other._pEVPPKey));
+#endif
 }
 
 
@@ -311,7 +364,7 @@ inline int EVPPKey::type(const EVP_PKEY* pEVPPKey)
 {
 	if (!pEVPPKey) return NID_undef;
 
-	return EVP_PKEY_type(EVP_PKEY_id(pEVPPKey));
+	return EVP_PKEY_type(EVP_PKEY_base_id(pEVPPKey));
 }
 
 
@@ -339,20 +392,6 @@ inline EVPPKey::operator EVP_PKEY*()
 }
 
 
-inline void EVPPKey::setKey(EC_KEY* pKey)
-{
-	if (!EVP_PKEY_set1_EC_KEY(_pEVPPKey, pKey))
-		throw OpenSSLException();
-}
-
-
-inline void EVPPKey::setKey(RSA* pKey)
-{
-	if (!EVP_PKEY_set1_RSA(_pEVPPKey, pKey))
-		throw OpenSSLException();
-}
-
-
 } } // namespace Poco::Crypto
 
 
diff --git a/Crypto/include/Poco/Crypto/Envelope.h b/Crypto/include/Poco/Crypto/Envelope.h
new file mode 100644
index 000000000..0fe3c3ad2
--- /dev/null
+++ b/Crypto/include/Poco/Crypto/Envelope.h
@@ -0,0 +1,174 @@
+//
+// Envelope.h
+//
+// Library: Crypto
+// Package: Envelope
+// Module:  Envelope
+//
+// Definition of the Envelope class.
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#ifndef Crypto_Envelope_INCLUDED
+#define Crypto_Envelope_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "Poco/Crypto/EVPPKey.h"
+#include 
+#include 
+
+
+namespace Poco {
+namespace Crypto {
+
+
+class Crypto_API Envelope
+	/// Envelope encrypts/decrypts data using a symmetric key.
+	///
+	/// Encryption and decryption with asymmetric keys is computationally expensive.
+	/// To alleviate that, Envelope encrypts data using a symmetric session key;
+	/// the key is then itself asymmetrically encrypted using a public key.
+	/// It is also possible to encrypt the session key with multiple public keys,
+	/// so that the message can be sent to multiple recipients.
+	///
+	/// Each recipient decrypts the session with their private key; the session
+	/// key for the message decryption is the same for each recipient.
+{
+public:
+	using Byte = unsigned char;
+	using ByteVec = std::vector;
+	using EVPPKeyVec = std::vector;
+	using EVP_PKEYVec = std::vector;
+	using EncKeyVec = std::vector;
+
+	Envelope() = delete;
+
+	Envelope(const EVPPKey& key, int cipherNID);
+		/// Creates a new Envelope object.
+		/// Initialization vector is automatically
+		/// generated.
+
+	Envelope(const EVPPKeyVec& keys, int cipherNID);
+		/// Creates a new Envelope object.
+		/// Initialization vector is automatically
+		/// generated.
+
+	~Envelope();
+		/// Destroys the Envelope.
+
+	const ByteVec& iv() const;
+		/// Returns the initialization vector.
+
+	void addKey(const EVPPKey& key);
+		/// Adds the key to the list of private keys.
+
+	const EncKeyVec& keys() const;
+		/// Returns encrypted symmetric keys.
+
+	int cipherNID() const;
+		/// Reurns the cipher NID.
+
+	const ByteVec& seal(const std::string& plainText);
+		/// Encrypts the given text and returns the encrypted text.
+
+	const ByteVec& seal(const ByteVec& plainData);
+		/// Encrypts the given data and returns the encrypted data.
+
+	const ByteVec& getContent() const;
+		/// Returns the encrypted content.
+	
+	void setContent(const ByteVec& enc);
+		/// Sets the encrypted content.
+
+	ByteVec open(const EVPPKey& privKey, const ByteVec& encKeys, const ByteVec& iv = ByteVec());
+		/// Decrypts the stored encrypted data and returns it.
+
+	std::string openAsString(const EVPPKey& privKey, const ByteVec& encKeys, const ByteVec& iv = ByteVec());
+		/// Decrypts the stored encrypted data and returns it.
+
+	static std::string toString(const ByteVec& data);
+		/// Converts and returns string from ByteVec.
+
+private:
+	Envelope(int cipherNID);
+	Envelope(int cipherNID, const ByteVec& iv);
+
+	int ivSize() const;
+	int blockSize() const;
+	void handleErrors(std::string&& msg);
+
+	const EVP_CIPHER* _pCipher;
+	EVP_CIPHER_CTX*   _pCtx;
+	EVP_CIPHER_CTX*   _pDecCtx;
+	ByteVec           _iv;
+	EVP_PKEYVec       _pubKeys;
+	EncKeyVec         _encKeys;
+	std::vector  _encKeysSizes;
+	ByteVec           _encContent;
+};
+
+
+inline int Envelope::ivSize() const
+{
+	return EVP_CIPHER_iv_length(_pCipher);
+}
+
+
+inline const Envelope::ByteVec& Envelope::iv() const
+{
+	return _iv;
+}
+
+
+inline int Envelope::blockSize() const
+{
+	return EVP_CIPHER_block_size(_pCipher);
+}
+
+
+inline const Envelope::EncKeyVec& Envelope::keys() const
+{
+	return _encKeys;
+}
+
+
+inline std::string Envelope::toString(const ByteVec& data)
+{
+	return std::string(data.begin(), data.end());
+}
+
+
+inline std::string Envelope::openAsString(const EVPPKey& privKey, const ByteVec& encKey, const ByteVec& iv)
+{
+	return toString(open(privKey, encKey, iv));
+}
+
+
+const Envelope::ByteVec& Envelope::getContent() const
+{
+	return _encContent;
+}
+	
+
+void Envelope::setContent(const ByteVec& enc)
+{
+	_encContent = enc;
+}
+
+
+inline int Envelope::cipherNID() const
+{
+	return EVP_CIPHER_nid(_pCipher);
+}
+
+
+} } // namespace Poco::Crypto
+
+
+#endif // Crypto_Envelope_INCLUDED
diff --git a/Crypto/include/Poco/Crypto/KeyPairImpl.h b/Crypto/include/Poco/Crypto/KeyPairImpl.h
index 6999a46d8..50718ce37 100644
--- a/Crypto/include/Poco/Crypto/KeyPairImpl.h
+++ b/Crypto/include/Poco/Crypto/KeyPairImpl.h
@@ -56,7 +56,7 @@ public:
 	virtual void save(const std::string& publicKeyFile,
 		const std::string& privateKeyFile = "",
 		const std::string& privateKeyPassphrase = "") const = 0;
-		/// Exports the public and private keys to the given files. 
+		/// Exports the public and private keys to the given files.
 		///
 		/// If an empty filename is specified, the corresponding key
 		/// is not exported.
diff --git a/Crypto/include/Poco/Crypto/OpenSSLInitializer.h b/Crypto/include/Poco/Crypto/OpenSSLInitializer.h
index 4bba5455f..25e4c477a 100644
--- a/Crypto/include/Poco/Crypto/OpenSSLInitializer.h
+++ b/Crypto/include/Poco/Crypto/OpenSSLInitializer.h
@@ -24,6 +24,7 @@
 #include 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
 #include 
+#include 
 #endif
 #if defined(OPENSSL_FIPS) && OPENSSL_VERSION_NUMBER < 0x010001000L
 #include 
@@ -91,8 +92,8 @@ private:
 #endif
 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-	static OSSL_PROVIDER* _defaultProvider;
-	static OSSL_PROVIDER* _legacyProvider;
+	static std::atomic _defaultProvider;
+	static std::atomic _legacyProvider;
 #endif
 };
 
diff --git a/Crypto/include/Poco/Crypto/RSADigestEngine.h b/Crypto/include/Poco/Crypto/RSADigestEngine.h
index 7c4d38605..e0c451d24 100644
--- a/Crypto/include/Poco/Crypto/RSADigestEngine.h
+++ b/Crypto/include/Poco/Crypto/RSADigestEngine.h
@@ -39,7 +39,7 @@ class Crypto_API RSADigestEngine: public Poco::DigestEngine
 	/// signed. Then, the hash value is encrypted, using
 	/// the RSA private key.
 	///
-	/// To verify a signature, pass it to the verify() 
+	/// To verify a signature, pass it to the verify()
 	/// member function. It will decrypt the signature
 	/// using the RSA public key and compare the resulting
 	/// hash with the actual hash of the data.
@@ -50,7 +50,7 @@ public:
 		DIGEST_MD5,
 		DIGEST_SHA1
 	};
-	
+
 	//@ deprecated
 	RSADigestEngine(const RSAKey& key, DigestType digestType = DIGEST_SHA1);
 		/// Creates the RSADigestEngine with the given RSA key,
@@ -74,11 +74,11 @@ public:
 	void reset();
 		/// Resets the engine so that a new
 		/// digest can be computed.
-		
+
 	const DigestEngine::Digest& digest();
-		/// Finishes the computation of the digest 
+		/// Finishes the computation of the digest
 		/// (the first time it's called) and
-		/// returns the message digest. 
+		/// returns the message digest.
 		///
 		/// Can be called multiple times.
 
diff --git a/Crypto/include/Poco/Crypto/RSAKey.h b/Crypto/include/Poco/Crypto/RSAKey.h
index 51c97432f..767d5cd3d 100644
--- a/Crypto/include/Poco/Crypto/RSAKey.h
+++ b/Crypto/include/Poco/Crypto/RSAKey.h
@@ -31,6 +31,7 @@ class X509Certificate;
 class PKCS12Container;
 
 
+//@ deprecated
 class Crypto_API RSAKey: public KeyPair
 	/// This class stores an RSA key pair, consisting
 	/// of private and public key. Storage of the private
@@ -56,7 +57,7 @@ public:
 	};
 
 	RSAKey(const EVPPKey& key);
-		/// Constructs ECKeyImpl by extracting the EC key.
+		/// Constructs RSAKey by extracting the RSA key.
 
 	RSAKey(const X509Certificate& cert);
 		/// Extracts the RSA public key from the given certificate.
diff --git a/Crypto/include/Poco/Crypto/RSAKeyImpl.h b/Crypto/include/Poco/Crypto/RSAKeyImpl.h
index f89c3bf22..f0397381c 100644
--- a/Crypto/include/Poco/Crypto/RSAKeyImpl.h
+++ b/Crypto/include/Poco/Crypto/RSAKeyImpl.h
@@ -51,13 +51,13 @@ public:
 	using ByteVec = std::vector;
 
 	RSAKeyImpl(const EVPPKey& key);
-		/// Constructs ECKeyImpl by extracting the EC key.
+		/// Constructs RSAKeyImpl by extracting the RSA key.
 
 	RSAKeyImpl(const X509Certificate& cert);
 		/// Extracts the RSA public key from the given certificate.
 
 	RSAKeyImpl(const PKCS12Container& cert);
-		/// Extracts the EC private key from the given certificate.
+		/// Extracts the RSA private key from the given certificate.
 
 	RSAKeyImpl(int keyLength, unsigned long exponent);
 		/// Creates the RSAKey. Creates a new public/private keypair using the given parameters.
@@ -65,8 +65,8 @@ public:
 
 	RSAKeyImpl(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase);
 		/// Creates the RSAKey, by reading public and private key from the given files and
-		/// using the given passphrase for the private key. Can only by used for signing if 
-		/// a private key is available. 
+		/// using the given passphrase for the private key. Can only by used for signing if
+		/// a private key is available.
 
 	RSAKeyImpl(std::istream* pPublicKeyStream, std::istream* pPrivateKeyStream, const std::string& privateKeyPassphrase);
 		/// Creates the RSAKey. Can only by used for signing if pPrivKey
@@ -97,7 +97,7 @@ public:
 	void save(const std::string& publicKeyFile,
 		const std::string& privateKeyFile = "",
 		const std::string& privateKeyPassphrase = "") const;
-		/// Exports the public and private keys to the given files. 
+		/// Exports the public and private keys to the given files.
 		///
 		/// If an empty filename is specified, the corresponding key
 		/// is not exported.
diff --git a/Crypto/include/Poco/Crypto/X509Certificate.h b/Crypto/include/Poco/Crypto/X509Certificate.h
index a3ea8e164..8284dd71d 100644
--- a/Crypto/include/Poco/Crypto/X509Certificate.h
+++ b/Crypto/include/Poco/Crypto/X509Certificate.h
@@ -84,7 +84,7 @@ public:
 	X509Certificate& operator = (X509Certificate&& cert) noexcept;
 		/// Move assignment.
 
-	void swap(X509Certificate& cert);
+	void swap(X509Certificate& cert) noexcept;
 		/// Exchanges the certificate with another one.
 
 	~X509Certificate();
diff --git a/Crypto/samples/genrsakey/src/genrsakey.cpp b/Crypto/samples/genrsakey/src/genrsakey.cpp
index 75ce37544..f284c6281 100644
--- a/Crypto/samples/genrsakey/src/genrsakey.cpp
+++ b/Crypto/samples/genrsakey/src/genrsakey.cpp
@@ -52,29 +52,29 @@ public:
 	{
 		Poco::Crypto::initializeCrypto();
 	}
-	
+
 	~RSAApp()
 	{
 		Poco::Crypto::uninitializeCrypto();
 	}
 
-protected:	
+protected:
 	void initialize(Application& self)
 	{
 		loadConfiguration(); // load default configuration files, if present
 		Application::initialize(self);
 	}
-	
+
 	void uninitialize()
 	{
 		Application::uninitialize();
 	}
-	
+
 	void reinitialize(Application& self)
 	{
 		Application::reinitialize(self);
 	}
-	
+
 	void defineOptions(OptionSet& options)
 	{
 		Application::defineOptions(options);
@@ -97,7 +97,7 @@ protected:
 				.repeatable(false)
 				.argument("512|1024|2048|4096")
 				.callback(OptionCallback(this, &RSAApp::handleKeyLength)));
-				
+
 		options.addOption(
 			Option("exponent", "e", "defines the exponent of the key")
 				.required(false)
@@ -119,14 +119,14 @@ protected:
 				.argument("pwd")
 				.callback(OptionCallback(this, &RSAApp::handlePassword)));
 	}
-	
+
 	void handleHelp(const std::string& name, const std::string& value)
 	{
 		_helpRequested = true;
 		displayHelp();
 		stopOptionsProcessing();
 	}
-	
+
 	void handleKeyLength(const std::string& name, const std::string& value)
 	{
 		int keyLen = Poco::NumberParser::parse(value);
@@ -150,12 +150,12 @@ protected:
 			throw Poco::Util::IncompatibleOptionsException("Empty file prefix forbidden");
 		_name = value;
 	}
-	
+
 	void handlePassword(const std::string& name, const std::string& value)
 	{
 		_pwd = value;
 	}
-		
+
 	void displayHelp()
 	{
 		HelpFormatter helpFormatter(options());
@@ -176,14 +176,14 @@ protected:
 			logger().information("Generating key: DONE");
 			std::string pubFile(_name + ".pub");
 			std::string privFile(_name + ".priv");
-			
+
 			logger().information("Saving key to " + pubFile + " and " + privFile);
 			key.save(pubFile, privFile, _pwd);
 			logger().information("Key saved");
 		}
 		return Application::EXIT_OK;
 	}
-	
+
 private:
 	bool _helpRequested;
 	RSAKey::KeyLength _length;
diff --git a/Crypto/src/Cipher.cpp b/Crypto/src/Cipher.cpp
index 8b4d57964..2e9326f44 100644
--- a/Crypto/src/Cipher.cpp
+++ b/Crypto/src/Cipher.cpp
@@ -39,30 +39,32 @@ Cipher::~Cipher()
 }
 
 
-std::string Cipher::encryptString(const std::string& str, Encoding encoding)
+std::string Cipher::encryptString(const std::string& str, Encoding encoding, bool padding)
 {
 	std::istringstream source(str);
 	std::ostringstream sink;
 
-	encrypt(source, sink, encoding);
+	encrypt(source, sink, encoding, padding);
 
 	return sink.str();
 }
 
 
-std::string Cipher::decryptString(const std::string& str, Encoding encoding)
+std::string Cipher::decryptString(const std::string& str, Encoding encoding, bool padding)
 {
 	std::istringstream source(str);
 	std::ostringstream sink;
 
-	decrypt(source, sink, encoding);
+	decrypt(source, sink, encoding, padding);
 	return sink.str();
 }
 
 
-void Cipher::encrypt(std::istream& source, std::ostream& sink, Encoding encoding)
+void Cipher::encrypt(std::istream& source, std::ostream& sink, Encoding encoding, bool padding)
 {
-	CryptoInputStream encryptor(source, createEncryptor());
+	CryptoTransform::Ptr p = createEncryptor();
+	if (!padding) p->setPadding(0);
+	CryptoInputStream encryptor(source, p);
 
 	switch (encoding)
 	{
@@ -102,9 +104,11 @@ void Cipher::encrypt(std::istream& source, std::ostream& sink, Encoding encoding
 }
 
 
-void Cipher::decrypt(std::istream& source, std::ostream& sink, Encoding encoding)
+void Cipher::decrypt(std::istream& source, std::ostream& sink, Encoding encoding, bool padding)
 {
-	CryptoOutputStream decryptor(sink, createDecryptor());
+	CryptoTransform::Ptr p = createDecryptor();
+	if (!padding) p->setPadding(0);
+	CryptoOutputStream decryptor(sink, p);
 
 	switch (encoding)
 	{
diff --git a/Crypto/src/CipherFactory.cpp b/Crypto/src/CipherFactory.cpp
index 28ba37486..9e59dc267 100644
--- a/Crypto/src/CipherFactory.cpp
+++ b/Crypto/src/CipherFactory.cpp
@@ -18,10 +18,14 @@
 #include "Poco/Crypto/RSAKey.h"
 #include "Poco/Crypto/CipherImpl.h"
 #include "Poco/Crypto/RSACipherImpl.h"
+#include "Poco/Crypto/EVPCipherImpl.h"
 #include "Poco/Exception.h"
 #include "Poco/SingletonHolder.h"
 #include 
 #include 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include 
+#endif
 
 
 namespace Poco {
@@ -30,6 +34,10 @@ namespace Crypto {
 
 CipherFactory::CipherFactory()
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	OSSL_PROVIDER_load(NULL, "default");
+	OSSL_PROVIDER_load(NULL, "legacy");
+#endif
 }
 
 
@@ -62,4 +70,10 @@ Cipher* CipherFactory::createCipher(const RSAKey& key, RSAPaddingMode paddingMod
 }
 
 
+Cipher* CipherFactory::createCipher(const EVPPKey& key)
+{
+	return new EVPCipherImpl(key);
+}
+
+
 } } // namespace Poco::Crypto
diff --git a/Crypto/src/CryptoTransform.cpp b/Crypto/src/CryptoTransform.cpp
index e4e58fd6e..6ecba2ec8 100644
--- a/Crypto/src/CryptoTransform.cpp
+++ b/Crypto/src/CryptoTransform.cpp
@@ -28,7 +28,7 @@ CryptoTransform::~CryptoTransform()
 {
 }
 
-  
+
 int CryptoTransform::setPadding(int padding)
 {
 	return 1;
diff --git a/Crypto/src/DigestEngine.cpp b/Crypto/src/DigestEngine.cpp
index bac2d44e0..db5cf6069 100644
--- a/Crypto/src/DigestEngine.cpp
+++ b/Crypto/src/DigestEngine.cpp
@@ -26,10 +26,10 @@ DigestEngine::DigestEngine(const std::string& name):
 {
 	const EVP_MD* md = EVP_get_digestbyname(_name.c_str());
 	if (!md) throw Poco::NotFoundException(_name);
-	EVP_DigestInit_ex(_pContext, md, NULL);	
+	EVP_DigestInit_ex(_pContext, md, NULL);
 }
 
-	
+
 DigestEngine::~DigestEngine()
 {
 	EVP_MD_CTX_destroy(_pContext);
@@ -37,7 +37,11 @@ DigestEngine::~DigestEngine()
 
 int DigestEngine::nid() const
 {
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	return EVP_MD_nid(EVP_MD_CTX_get0_md(_pContext));
+#else
 	return EVP_MD_nid(EVP_MD_CTX_md(_pContext));
+#endif
 }
 
 std::size_t DigestEngine::digestLength() const
diff --git a/Crypto/src/EVPCipherImpl.cpp b/Crypto/src/EVPCipherImpl.cpp
new file mode 100644
index 000000000..b282f4bb2
--- /dev/null
+++ b/Crypto/src/EVPCipherImpl.cpp
@@ -0,0 +1,310 @@
+//
+// EVPCipherImpl.cpp
+//
+// Library: Crypto
+// Package: EVP
+// Module:  EVPCipherImpl
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#include "Poco/Crypto/EVPCipherImpl.h"
+#include "Poco/Crypto/CryptoTransform.h"
+#include "Poco/Exception.h"
+#include "Poco/Logger.h"
+#include 
+#include 
+#include 
+
+
+namespace Poco {
+namespace Crypto {
+
+
+namespace
+{
+	void throwError(std::string&& msg)
+	{
+		unsigned long err;
+		while ((err = ERR_get_error()))
+		{
+			if (!msg.empty()) msg.append("; ");
+			msg.append(ERR_error_string(err, 0));
+		}
+
+		throw Poco::IOException(msg);
+	}
+
+	class EVPPKeyContext
+	{
+	public:
+		EVPPKeyContext() = delete;
+		EVPPKeyContext(const EVP_PKEY* pEVP) : _pCtx(EVP_PKEY_CTX_new(const_cast(pEVP), NULL))
+		{
+			if (!_pCtx)
+			{
+				std::string fmt = "EVPPKeyContext():%s()";
+				throwError(Poco::format(fmt, std::string("EVP_PKEY_CTX_new")));
+			}
+		}
+
+		~EVPPKeyContext()
+		{
+			EVP_PKEY_CTX_free(_pCtx);
+		}
+
+		operator EVP_PKEY_CTX*()
+		{
+			return _pCtx;
+		}
+
+	private:
+		EVP_PKEY_CTX* _pCtx = nullptr;
+	};
+
+	class EVPEncryptImpl: public CryptoTransform
+	{
+	public:
+		EVPEncryptImpl(const EVP_PKEY* pEVP):
+			_pEVP(pEVP),
+			_pCtx(_pEVP),
+			_pos(0),
+			_pBuf(0)
+		{
+			std::string fmt = "EVPEncryptImpl():%s()";
+			poco_check_ptr(_pEVP);
+
+			if (!_pCtx)
+				throwError(Poco::format(fmt, std::string("EVP_PKEY_CTX_new")));
+
+			if (EVP_PKEY_encrypt_init(_pCtx) <= 0)
+        		throwError(Poco::format(fmt, std::string("EVP_PKEY_encrypt_init")));
+
+			_blockSize = EVP_PKEY_size(_pEVP);
+			if (!_blockSize)
+				throwError(Poco::format(fmt, std::string("EVP_PKEY_size")));
+			_pBuf = new unsigned char[_blockSize];
+		}
+
+		~EVPEncryptImpl()
+		{
+			delete [] _pBuf;
+		}
+
+		std::size_t blockSize() const
+		{
+			return _blockSize;
+		}
+
+		std::string getTag(std::size_t)
+		{
+			return "";
+		}
+
+		void setTag(const std::string&)
+		{
+		}
+
+		std::streamsize transform(const unsigned char* input, std::streamsize inputLength,
+			unsigned char* output, std::streamsize outputLength)
+		{
+			std::string fmt = "EVPEncryptImpl::transform():%s()";
+			std::streamsize maxSize = static_cast(maxDataSize(input, inputLength));
+			std::streamsize evpSize = static_cast(_blockSize);
+			poco_assert_dbg(_pos <= maxSize);
+			poco_assert (outputLength >= evpSize);
+			int rc = 0;
+			while (inputLength > 0)
+			{
+				poco_assert_dbg (maxSize >= _pos);
+				std::streamsize missing = maxSize - _pos;
+				if (missing == 0)
+				{
+					poco_assert (outputLength >= evpSize);
+					std::size_t outLen;
+					if (EVP_PKEY_encrypt(_pCtx, NULL, &outLen, _pBuf, static_cast(maxSize)) <= 0)
+						throwError(Poco::format(fmt, std::string("EVP_PKEY_encrypt(NULL)")));
+					if (EVP_PKEY_encrypt(_pCtx, output, &outLen, _pBuf, static_cast(maxSize)) <= 0)
+						throwError(Poco::format(fmt, std::string("EVP_PKEY_encrypt")));
+					rc += outLen;
+					output += outLen;
+					outputLength -= outLen;
+					_pos = 0;
+
+				}
+				else
+				{
+					if (missing > inputLength) missing = inputLength;
+					std::memcpy(_pBuf + _pos, input, static_cast(missing));
+					input += missing;
+					_pos += missing;
+					inputLength -= missing;
+				}
+			}
+			return rc;
+		}
+
+		std::streamsize finalize(unsigned char*	output, std::streamsize length)
+		{
+			poco_assert (length >= blockSize());
+			poco_assert (_pos <= maxDataSize(output, length));
+			std::string fmt = "EVPEncryptImpl::finalize():%s()";
+			std::size_t outLen = 0;
+			if (_pos > 0)
+			{
+				if (EVP_PKEY_encrypt(_pCtx, NULL, &outLen, _pBuf, static_cast(_pos)) <= 0)
+					throwError(Poco::format(fmt, std::string("EVP_PKEY_encrypt")));
+				if (EVP_PKEY_encrypt(_pCtx, output, &outLen, _pBuf, static_cast(_pos)) <= 0)
+					throwError(Poco::format(fmt, std::string("EVP_PKEY_encrypt")));
+			}
+			return static_cast(outLen);
+		}
+
+	private:
+		std::size_t maxDataSize(const unsigned char* pIO, std::streamsize length)
+		{
+			std::string fmt = "EVPEncryptImpl::maxDataSize():%s()";
+			std::size_t outLength = 0;
+			if (EVP_PKEY_encrypt(_pCtx, NULL, &outLength, pIO, length) <= 0)
+				throwError(Poco::format(fmt, std::string("EVP_PKEY_encrypt")));
+			return outLength;
+		}
+
+		const EVP_PKEY* _pEVP;
+		EVPPKeyContext  _pCtx;
+		int             _blockSize;
+		std::streamsize _pos;
+		unsigned char*  _pBuf;
+	};
+
+
+	class EVPDecryptImpl: public CryptoTransform
+	{
+	public:
+		EVPDecryptImpl(const EVP_PKEY* pEVP):
+			_pEVP(pEVP),
+			_pCtx(_pEVP),
+			_pos(0),
+			_pBuf(0)
+		{
+			std::string fmt = "EVPDecryptImpl():%s()";
+			poco_check_ptr(_pEVP);
+
+			if (EVP_PKEY_decrypt_init(_pCtx) <= 0)
+        		throwError(Poco::format(fmt, std::string("EVP_PKEY_decrypt_init")));
+
+			_blockSize = EVP_PKEY_size(_pEVP);
+			if (!_blockSize)
+				throwError(Poco::format(fmt, std::string("EVP_PKEY_size")));
+			_pBuf = new unsigned char[_blockSize];
+		}
+
+		~EVPDecryptImpl()
+		{
+			delete [] _pBuf;
+		}
+
+		std::size_t blockSize() const
+		{
+			return _blockSize;
+		}
+
+		std::string getTag(std::size_t)
+		{
+			return "";
+		}
+
+		void setTag(const std::string&)
+		{
+		}
+
+		std::streamsize transform(const unsigned char* input, std::streamsize inputLength,
+			unsigned char* output, std::streamsize outputLength)
+		{
+			std::string fmt = "EVPDecryptImpl::transform():%s()";
+			std::streamsize evpSize = static_cast(_blockSize);
+			poco_assert_dbg(_pos <= evpSize);
+			poco_assert (outputLength >= evpSize);
+			int rc = 0;
+			while (inputLength > 0)
+			{
+				poco_assert_dbg (evpSize >= _pos);
+				std::streamsize missing = evpSize - _pos;
+				if (missing == 0)
+				{
+					std::size_t outLen = 0;
+					if (EVP_PKEY_decrypt(_pCtx, NULL, &outLen, _pBuf, static_cast(_pos)) <= 0)
+						throwError(Poco::format(fmt, std::string("EVP_PKEY_decrypt(NULL)")));
+					if (EVP_PKEY_decrypt(_pCtx, output, &outLen, _pBuf, static_cast(_pos)) <= 0)
+						throwError(Poco::format(fmt, std::string("EVP_PKEY_decrypt")));
+					rc += outLen;
+					output += outLen;
+					outputLength -= outLen;
+					_pos = 0;
+				}
+				else
+				{
+					if (missing > inputLength) missing = inputLength;
+					std::memcpy(_pBuf + _pos, input, static_cast(missing));
+					input += missing;
+					_pos += missing;
+					inputLength -= missing;
+				}
+			}
+			return rc;
+		}
+
+		std::streamsize finalize(unsigned char* output, std::streamsize length)
+		{
+			poco_assert (length >= _blockSize);
+			std::string fmt = "EVPDecryptImpl::finalize():%s()";
+			std::size_t outLen = 0;
+			if (EVP_PKEY_decrypt(_pCtx, NULL, &outLen, _pBuf, static_cast(_pos)) <= 0)
+					throwError(Poco::format(fmt, std::string("EVP_PKEY_decrypt(NULL)")));
+			poco_assert (length >= outLen);
+			if (_pos > 0)
+			{
+				if (EVP_PKEY_decrypt(_pCtx, output, &outLen, _pBuf, static_cast(_pos)) <= 0)
+					throwError(Poco::format(fmt, std::string("EVP_PKEY_decrypt")));
+			}
+			return outLen;
+		}
+
+	private:
+		const EVP_PKEY* _pEVP;
+		EVPPKeyContext  _pCtx;
+		int             _blockSize;
+		std::streamsize _pos;
+		unsigned char*  _pBuf;
+	};
+}
+
+
+EVPCipherImpl::EVPCipherImpl(const EVPPKey& key):
+	_key(key)
+{
+}
+
+
+EVPCipherImpl::~EVPCipherImpl()
+{
+}
+
+
+CryptoTransform::Ptr EVPCipherImpl::createEncryptor()
+{
+	return new EVPEncryptImpl(_key);
+}
+
+
+CryptoTransform::Ptr EVPCipherImpl::createDecryptor()
+{
+	return new EVPDecryptImpl(_key);
+}
+
+
+} } // namespace Poco::Crypto
diff --git a/Crypto/src/EVPPKey.cpp b/Crypto/src/EVPPKey.cpp
index 832add751..2964bf0d2 100644
--- a/Crypto/src/EVPPKey.cpp
+++ b/Crypto/src/EVPPKey.cpp
@@ -14,19 +14,33 @@
 
 
 #include "Poco/Crypto/EVPPKey.h"
+#include "Poco/Crypto/PKCS12Container.h"
+#include "Poco/Crypto/X509Certificate.h"
 #include "Poco/Crypto/ECKey.h"
 #include "Poco/Crypto/RSAKey.h"
 #include "Poco/NumberFormatter.h"
+#include 
 
 
 namespace Poco {
 namespace Crypto {
 
 
+const std::map EVPPKey::KNOWN_TYPES =
+	{
+		{ EVP_PKEY_RSA, "rsa" },
+		// not implemented
+		//{ EVP_PKEY_DSA, "dsa" },
+		//{ EVP_PKEY_DH, "dh" },
+		{ EVP_PKEY_EC, "ec" }
+	};
+
+
 EVPPKey::EVPPKey(const std::string& ecCurveName): _pEVPPKey(0)
 {
 	newECKey(ecCurveName.c_str());
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 }
 
 
@@ -34,13 +48,93 @@ EVPPKey::EVPPKey(const char* ecCurveName): _pEVPPKey(0)
 {
 	newECKey(ecCurveName);
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 }
 
 
+EVPPKey::EVPPKey(const X509Certificate& cert):
+	_pEVPPKey(X509_get_pubkey(const_cast(cert.certificate())))
+{
+	poco_check_ptr(_pEVPPKey);
+	checkType();
+}
+
+
+EVPPKey::EVPPKey(const PKCS12Container& cont): EVPPKey(cont.getKey())
+{
+	poco_check_ptr(_pEVPPKey);
+	checkType();
+}
+
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+EVPPKey::EVPPKey(int type, int param): _pEVPPKey(0)
+{
+	EVP_PKEY_CTX *pCtx = EVP_PKEY_CTX_new_id(type, NULL);
+	if (NULL == pCtx)
+	{
+		std::string msg = Poco::format(
+			"EVPPKey(%d, %d):EVP_PKEY_CTX_new_id()\n", type, param);
+		throw OpenSSLException(getError(msg));
+	}
+	int ret = EVP_PKEY_keygen_init(pCtx);
+	if (ret != 1)
+	{
+		std::string msg = Poco::format(
+			"EVPPKey(%d, %d):EVP_PKEY_keygen_init()\n", type, param);
+		throw OpenSSLException(getError(msg));
+	}
+
+	if (EVP_PKEY_RSA == type)
+	{
+		ret = EVP_PKEY_CTX_set_rsa_keygen_bits(pCtx, param);
+		if (ret != 1)
+		{
+			std::string msg = Poco::format(
+				"EVPPKey(%d, %d):EVP_PKEY_CTX_set_rsa_keygen_bits()\n", type, param);
+			throw OpenSSLException(getError(msg));
+		}
+	}
+	else if (EVP_PKEY_EC == type)
+	{
+		ret = EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pCtx, param);
+		if (ret != 1)
+		{
+			std::string msg = Poco::format(
+				"EVPPKey(%d, %d):EVP_PKEY_CTX_set_ec_paramgen_curve_nid()\n", type, param);
+			throw OpenSSLException(getError(msg));
+		}
+	}
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	ret = EVP_PKEY_generate(pCtx, &_pEVPPKey);
+	if (ret != 1)
+	{
+		std::string msg = Poco::format(
+			"EVPPKey(%d, %d):EVP_PKEY_generate()\n", type, param);
+		throw OpenSSLException(getError(msg));
+	}
+#else
+	ret = EVP_PKEY_keygen(pCtx, &_pEVPPKey);
+	if (ret != 1)
+	{
+		std::string msg = Poco::format(
+			"EVPPKey(%d, %d):EVP_PKEY_keygen()\n", type, param);
+		throw OpenSSLException(getError(msg));
+	}
+#endif
+	EVP_PKEY_CTX_free(pCtx);
+	checkType();
+}
+
+#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+
 EVPPKey::EVPPKey(EVP_PKEY* pEVPPKey): _pEVPPKey(0)
 {
 	duplicate(pEVPPKey, &_pEVPPKey);
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 }
 
 
@@ -57,9 +151,11 @@ EVPPKey::EVPPKey(const std::string& publicKeyFile,
 	// no private key, this must be public key only, otherwise throw
 	if (!loadKey(&_pEVPPKey, PEM_read_PUBKEY, (EVP_PKEY_get_Key_fn)0, publicKeyFile))
 	{
-		throw OpenSSLException("ECKeyImpl(const string&, const string&, const string&");
+		std::string msg = "EVPPKey(const string&, const string&, const string&)\n";
+		throw OpenSSLException(getError(msg));
 	}
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 }
 
 
@@ -76,9 +172,11 @@ EVPPKey::EVPPKey(std::istream* pPublicKeyStream,
 	// no private key, this must be public key only, otherwise throw
 	if (!loadKey(&_pEVPPKey, PEM_read_bio_PUBKEY, (EVP_PKEY_get_Key_fn)0, pPublicKeyStream))
 	{
-		throw OpenSSLException("ECKeyImpl(istream*, istream*, const string&");
+		std::string msg = "EVPPKey(istream* ,istream* const string&)\n";
+		throw OpenSSLException(getError(msg));
 	}
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 }
 
 
@@ -86,6 +184,7 @@ EVPPKey::EVPPKey(const EVPPKey& other)
 {
 	duplicate(other._pEVPPKey, &_pEVPPKey);
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 }
 
 
@@ -93,6 +192,7 @@ EVPPKey::EVPPKey(EVPPKey&& other) noexcept:
 	_pEVPPKey(other._pEVPPKey)
 {
 	other._pEVPPKey = nullptr;
+	checkType();
 }
 
 
@@ -100,6 +200,7 @@ EVPPKey& EVPPKey::operator = (const EVPPKey& other)
 {
 	duplicate(other._pEVPPKey, &_pEVPPKey);
 	poco_check_ptr(_pEVPPKey);
+	checkType();
 	return *this;
 }
 
@@ -108,6 +209,7 @@ EVPPKey& EVPPKey::operator = (EVPPKey&& other) noexcept
 {
 	_pEVPPKey = other._pEVPPKey;
 	other._pEVPPKey = nullptr;
+	checkType();
 	return *this;
 }
 
@@ -118,19 +220,68 @@ EVPPKey::~EVPPKey()
 }
 
 
+const std::string& EVPPKey::name() const
+{
+	int t = type(_pEVPPKey);
+	auto it = KNOWN_TYPES.find(t);
+	if (it == KNOWN_TYPES.end())
+		throw Poco::NotImplementedException(Poco::format("EVPPKey::type(%d)", t));
+	return it->second;
+}
+
+
+void EVPPKey::checkType()
+{
+	if (_pEVPPKey)
+	{
+		int t = type(_pEVPPKey);
+		if (KNOWN_TYPES.find(t) == KNOWN_TYPES.end())
+			throw Poco::NotImplementedException(Poco::format("EVPPKey::type(%d)", t));
+	}
+}
+
+
+void EVPPKey::setKey(EC_KEY* pKey)
+{
+	if (!EVP_PKEY_set1_EC_KEY(_pEVPPKey, pKey))
+	{
+		std::string msg = "EVPPKey::setKey('EC')\n";
+		throw OpenSSLException(getError(msg));
+	}
+}
+
+
+void EVPPKey::setKey(RSA* pKey)
+{
+	if (!EVP_PKEY_set1_RSA(_pEVPPKey, pKey))
+	{
+		std::string msg = "EVPPKey::setKey('RSA')\n";
+		throw OpenSSLException(getError(msg));
+	}
+}
+
+
 void EVPPKey::save(const std::string& publicKeyFile, const std::string& privateKeyFile, const std::string& privateKeyPassphrase) const
 {
 	if (!publicKeyFile.empty() && (publicKeyFile != privateKeyFile))
 	{
 		BIO* bio = BIO_new(BIO_s_file());
-		if (!bio) throw Poco::IOException("Cannot create BIO for writing public key file", publicKeyFile);
+		if (!bio)
+		{
+			std::string msg = Poco::format(
+				"EVPPKey::save(%s) Cannot create BIO for writing public key file\n", publicKeyFile);
+			throw Poco::IOException(getError(msg));
+		}
 		try
 		{
 			if (BIO_write_filename(bio, const_cast(publicKeyFile.c_str())))
 			{
 				if (!PEM_write_bio_PUBKEY(bio, _pEVPPKey))
 				{
-					throw Poco::WriteFileException("Failed to write public key to file", publicKeyFile);
+					std::string msg = Poco::format("EVPPKey::save('%s', '%s', '%s')\n",
+						publicKeyFile, privateKeyFile, privateKeyPassphrase);
+					msg.append(Poco::format("Failed to write public key '%s' to file", publicKeyFile));
+					throw Poco::WriteFileException(getError(msg));
 				}
 			}
 			else throw Poco::CreateFileException("Cannot create public key file");
@@ -146,7 +297,12 @@ void EVPPKey::save(const std::string& publicKeyFile, const std::string& privateK
 	if (!privateKeyFile.empty())
 	{
 		BIO* bio = BIO_new(BIO_s_file());
-		if (!bio) throw Poco::IOException("Cannot create BIO for writing private key file", privateKeyFile);
+		if (!bio)
+		{
+			std::string msg = Poco::format(
+				"EVPPKey::save(%s): Cannot create BIO for writing private key file\n", privateKeyFile);
+			throw Poco::IOException(getError(msg));
+		}
 		try
 		{
 			if (BIO_write_filename(bio, const_cast(privateKeyFile.c_str())))
@@ -163,9 +319,18 @@ void EVPPKey::save(const std::string& publicKeyFile, const std::string& privateK
 						static_cast(privateKeyPassphrase.length()), 0, 0);
 				}
 				if (!rc)
-					throw Poco::FileException("Failed to write private key to file", privateKeyFile);
+				{
+					std::string msg = Poco::format(
+						"EVPPKey::save(%s):PEM_write_bio_PrivateKey()\n", privateKeyFile);
+					throw Poco::FileException(getError(msg));
+				}
+			}
+			else
+			{
+				std::string msg = Poco::format(
+					"EVPPKey::save(%s):BIO_write_filename()\n", privateKeyFile);
+				throw Poco::CreateFileException(getError(msg));
 			}
-			else throw Poco::CreateFileException("Cannot create private key file", privateKeyFile);
 		}
 		catch (...)
 		{
@@ -182,11 +347,18 @@ void EVPPKey::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStre
 	if (pPublicKeyStream && (pPublicKeyStream != pPrivateKeyStream))
 	{
 		BIO* bio = BIO_new(BIO_s_mem());
-		if (!bio) throw Poco::IOException("Cannot create BIO for writing public key");
+		if (!bio)
+		{
+			std::string msg = "EVPPKey::save(ostream*, ostream*, const string&)\n";
+			msg.append("Cannot create BIO for writing public key");
+			throw Poco::IOException(getError(msg));
+		}
 		if (!PEM_write_bio_PUBKEY(bio, _pEVPPKey))
 		{
+			std::string msg = "EVPPKey::save(ostream*, ostream*, const string&)\n";
+			msg.append("Failed to write public key to stream");
 			BIO_free(bio);
-			throw Poco::WriteFileException("Failed to write public key to stream");
+			throw Poco::WriteFileException(getError(msg));
 		}
 		char* pData;
 		long size = BIO_get_mem_data(bio, &pData);
@@ -197,7 +369,12 @@ void EVPPKey::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStre
 	if (pPrivateKeyStream)
 	{
 		BIO* bio = BIO_new(BIO_s_mem());
-		if (!bio) throw Poco::IOException("Cannot create BIO for writing public key");
+		if (!bio)
+		{
+			std::string msg = "EVPPKey::save(ostream*, ostream*, const string&)\n";
+			msg.append("Cannot create BIO for writing private key");
+			throw Poco::IOException(getError(msg));
+		}
 		int rc = 0;
 		if (privateKeyPassphrase.empty())
 			rc = PEM_write_bio_PrivateKey(bio, _pEVPPKey, 0, 0, 0, 0, 0);
@@ -207,8 +384,10 @@ void EVPPKey::save(std::ostream* pPublicKeyStream, std::ostream* pPrivateKeyStre
 				static_cast(privateKeyPassphrase.length()), 0, 0);
 		if (!rc)
 		{
+			std::string msg = "EVPPKey::save(ostream*, ostream*, const string&)\n";
+			msg.append("Failed to write private key to stream");
 			BIO_free(bio);
-			throw Poco::FileException("Failed to write private key to stream");
+			throw Poco::FileException(getError(msg));
 		}
 		char* pData;
 		long size = BIO_get_mem_data(bio, &pData);
@@ -224,8 +403,11 @@ EVP_PKEY* EVPPKey::duplicate(const EVP_PKEY* pFromKey, EVP_PKEY** pToKey)
 		"provided key pointer is null.");
 
 	*pToKey = EVP_PKEY_new();
-	if (!*pToKey) throw NullPointerException("EVPPKey::duplicate(): "
-		"EVP_PKEY_new() returned null.");
+	if (!*pToKey)
+	{
+		std::string msg = "EVPPKey::duplicate():EVP_PKEY_new()\n";
+		throw NullPointerException(getError(msg));
+	}
 
 	int keyType = type(pFromKey);
 	switch (keyType)
@@ -238,7 +420,11 @@ EVP_PKEY* EVPPKey::duplicate(const EVP_PKEY* pFromKey, EVP_PKEY** pToKey)
 				EVP_PKEY_set1_RSA(*pToKey, pRSA);
 				RSA_free(pRSA);
 			}
-			else throw OpenSSLException("EVPPKey::duplicate(): EVP_PKEY_get1_RSA()");
+			else
+			{
+				std::string msg = "EVPPKey::duplicate():EVP_PKEY_get1_RSA()\n";
+				throw OpenSSLException(getError(msg));
+			}
 			break;
 		}
 		case EVP_PKEY_EC:
@@ -250,14 +436,24 @@ EVP_PKEY* EVPPKey::duplicate(const EVP_PKEY* pFromKey, EVP_PKEY** pToKey)
 				EC_KEY_free(pEC);
 				int cmp = EVP_PKEY_cmp_parameters(*pToKey, pFromKey);
 				if (cmp < 0)
-					throw OpenSSLException("EVPPKey::duplicate(): EVP_PKEY_cmp_parameters()");
+				{
+					std::string msg = "EVPPKey::duplicate():EVP_PKEY_cmp_parameters()\n";
+					throw OpenSSLException(getError(msg));
+				}
 				if (0 == cmp)
 				{
 					if(!EVP_PKEY_copy_parameters(*pToKey, pFromKey))
-						throw OpenSSLException("EVPPKey::duplicate(): EVP_PKEY_copy_parameters()");
+					{
+						std::string msg = "EVPPKey::duplicate():EVP_PKEY_copy_parameters()\n";
+						throw OpenSSLException(getError(msg));
+					}
 				}
 			}
-			else throw OpenSSLException();
+			else
+			{
+				std::string msg = "EVPPKey::duplicate():EVP_PKEY_get1_EC_KEY()\n";
+				throw OpenSSLException(getError(msg));
+			}
 			break;
 		}
 		default:
@@ -281,7 +477,8 @@ void EVPPKey::newECKey(const char* ecCurveName)
 	EC_KEY_free(pEC);
 	return;
 err:
-	throw OpenSSLException("EVPPKey:newECKey()");
+	std::string msg = "EVPPKey::newECKey()\n";
+	throw OpenSSLException(getError(msg));
 }
 
 
diff --git a/Crypto/src/Envelope.cpp b/Crypto/src/Envelope.cpp
new file mode 100644
index 000000000..983edf371
--- /dev/null
+++ b/Crypto/src/Envelope.cpp
@@ -0,0 +1,159 @@
+//
+// Envelope.cpp
+//
+// Library: Crypto
+// Package: Envelope
+// Module:  Envelope
+//
+// Copyright (c) 2008, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#include "Poco/Crypto/Envelope.h"
+
+
+namespace Poco {
+namespace Crypto {
+
+
+Envelope::Envelope(int cipherNID): _pCipher(EVP_get_cipherbynid(cipherNID)),
+	_pCtx(EVP_CIPHER_CTX_new())
+{
+	poco_check_ptr(_pCipher);
+	poco_check_ptr(_pCtx);
+	if (1 != EVP_CIPHER_CTX_init(_pCtx))
+		handleErrors(std::string("Envelope():EVP_CIPHER_CTX_init()"));
+	_iv.resize(ivSize(), 0);
+}
+
+
+Envelope::Envelope(const EVPPKey& key, int cipherNID):
+	Envelope(cipherNID)
+{
+	addKey(key);
+}
+
+
+Envelope::Envelope(const EVPPKeyVec& keys, int cipherNID):
+	Envelope(cipherNID)
+{
+	for (const auto& k : keys) addKey(k);
+}
+
+
+Envelope::~Envelope()
+{
+	for (auto& pK : _pubKeys)
+		EVP_PKEY_free(pK);
+	EVP_CIPHER_CTX_free(_pCtx);
+}
+
+
+void Envelope::addKey(const EVPPKey& key)
+{
+	EVP_PKEY* pKey;
+	_pubKeys.push_back(EVPPKey::duplicate((const EVP_PKEY*)key, &pKey));
+	_encKeys.emplace_back(EVP_PKEY_size(_pubKeys.back()));
+}
+
+
+const Envelope::ByteVec& Envelope::seal(const ByteVec& plainData)
+{
+	std::vector pEncKeys(_encKeys.size(), 0);
+	std::vector encKeysSizes(_encKeys.size(), 0);
+	int i = 0;
+	for (const auto& k : _encKeys)
+		pEncKeys[i++] = new Byte[k.size()];
+
+	int noOfKeys = static_cast(_pubKeys.size());
+	if (_encKeys.size() != EVP_SealInit(_pCtx, _pCipher, &pEncKeys[0], &encKeysSizes[0], &_iv[0], &_pubKeys[0], noOfKeys))
+	{
+		i = 0;
+		for (; i < _encKeys.size(); ++i) delete [] pEncKeys[i];
+		handleErrors(std::string("Envelope::seal():EVP_SealInit()"));
+	}
+	i = 0;
+	for (auto& k : _encKeys)
+	{
+		if (encKeysSizes[i] != k.size())
+			k.resize(encKeysSizes[i]);
+		std::memcpy(&k[0], pEncKeys[i], encKeysSizes[i]);
+		++i;
+	}
+
+	i = 0;
+	for (; i < _encKeys.size(); ++i) delete [] pEncKeys[i];
+
+	int cipherTextLen = 0, len = 0;
+	int plainDataSize = static_cast(plainData.size());
+    _encContent.resize(plainDataSize + blockSize());
+	if (1 != EVP_SealUpdate(_pCtx, &_encContent[0], &len, &plainData[0], plainDataSize))
+		handleErrors(std::string("Envelope::seal():EVP_SealUpdate()"));
+	
+	cipherTextLen = len;
+	poco_assert (cipherTextLen < _encContent.size());
+
+	if(1 != EVP_SealFinal(_pCtx, &_encContent[len], &len))
+		handleErrors(std::string("Envelope::seal():EVP_SealFinal()"));
+	cipherTextLen += len;
+	poco_assert (cipherTextLen <= _encContent.size());
+	_encContent.resize(cipherTextLen);
+
+	return _encContent;
+}
+
+
+const Envelope::ByteVec& Envelope::seal(const std::string& plainText)
+{
+	return seal(ByteVec(plainText.begin(), plainText.end()));
+}
+
+
+Envelope::ByteVec Envelope::open(const EVPPKey& privKey, const ByteVec& encKey, const ByteVec& iv)
+{
+	if (iv.size() > 0) _iv = iv;
+	int encContentLen = static_cast(_encContent.size());
+	int blockSz = blockSize();
+	int mod = encContentLen % blockSz;
+	if (mod || (encContentLen < blockSz))
+	{
+		throw Poco::InvalidArgumentException(
+			Poco::format("Envelope::open(): bad encrypted buffer size: %z (must be N x %d)",
+				_encContent.size(), blockSz));
+	}
+
+	int encKeyLen = static_cast(encKey.size());
+	EVP_PKEY* pKey = const_cast((const EVP_PKEY*)privKey);
+	if (1 != EVP_OpenInit(_pCtx, _pCipher, &encKey[0], encKeyLen, &_iv[0], pKey))
+		handleErrors(std::string("Envelope::open():EVP_OpenInit()"));
+
+	ByteVec plainData(_encContent.size()+blockSz, 0);
+	int len = 0;
+	if(1 != EVP_OpenUpdate(_pCtx, &plainData[0], &len, &_encContent[0], encContentLen))
+		handleErrors(std::string("Envelope::open():EVP_OpenUpdate()"));
+	int totalLen = len;
+	
+	if(1 != EVP_OpenFinal(_pCtx, &plainData[len], &len))
+		handleErrors(std::string("Envelope::open():EVP_OpenFinal()"));
+	totalLen += len;
+	plainData.resize(totalLen);
+	return plainData;
+}
+
+
+void Envelope::handleErrors(std::string&& msg)
+{
+	unsigned long err;
+	while ((err = ERR_get_error()))
+	{
+		if (!msg.empty()) msg.append("\n");
+		msg.append(ERR_error_string(err, 0));
+	}
+	throw CryptoException(msg);
+}
+
+
+} } // namespace Poco::Crypto
diff --git a/Crypto/src/OpenSSLInitializer.cpp b/Crypto/src/OpenSSLInitializer.cpp
index 1d2c92551..4678d2229 100644
--- a/Crypto/src/OpenSSLInitializer.cpp
+++ b/Crypto/src/OpenSSLInitializer.cpp
@@ -66,8 +66,8 @@ Poco::FastMutex* OpenSSLInitializer::_mutexes(0);
 #endif
 
 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-OSSL_PROVIDER* OpenSSLInitializer::_defaultProvider(0);
-OSSL_PROVIDER* OpenSSLInitializer::_legacyProvider(0);
+std::atomic OpenSSLInitializer::_defaultProvider(0);
+std::atomic OpenSSLInitializer::_legacyProvider(0);
 #endif
 
 
@@ -157,6 +157,18 @@ void OpenSSLInitializer::uninitialize()
 #endif
 		delete [] _mutexes;
 #endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+		OSSL_PROVIDER* provider = nullptr;
+		if ((provider = _defaultProvider.exchange(nullptr)))
+		{
+			OSSL_PROVIDER_unload(provider);
+		}
+		if ((provider = _legacyProvider.exchange(nullptr)))
+		{
+			OSSL_PROVIDER_unload(provider);
+		}
+#endif
 	}
 }
 
diff --git a/Crypto/src/PKCS12Container.cpp b/Crypto/src/PKCS12Container.cpp
index b15252b9b..04ff8b973 100644
--- a/Crypto/src/PKCS12Container.cpp
+++ b/Crypto/src/PKCS12Container.cpp
@@ -175,10 +175,10 @@ void PKCS12Container::load(PKCS12* pPKCS12, const std::string& password)
 					X509* pX509 = sk_X509_value(pCA, i);
 #else
 					// Cert order is reversed on OpenSSL < 3.
- 					// https://github.com/openssl/openssl/issues/16421
- 					// https://github.com/openssl/openssl/pull/12641
- 					// https://github.com/jeroen/openssl/commit/f5eb85eb0fd432406a24abda6511c449eaee6162
-					X509* pX509 = sk_X509_value(pCA, certCount - i - 1);
+					// https://github.com/openssl/openssl/issues/16421
+					// https://github.com/openssl/openssl/pull/12641
+					// https://github.com/jeroen/openssl/commit/f5eb85eb0fd432406a24abda6511c449eaee6162
+					X509* pX509 = sk_X509_value(pCA, (certCount - i - 1));
 #endif
 					if (pX509)
 					{
diff --git a/Crypto/src/RSADigestEngine.cpp b/Crypto/src/RSADigestEngine.cpp
index 948aa25ac..9786eec3f 100644
--- a/Crypto/src/RSADigestEngine.cpp
+++ b/Crypto/src/RSADigestEngine.cpp
@@ -51,7 +51,7 @@ void RSADigestEngine::reset()
 	_signature.clear();
 }
 
-	
+
 const DigestEngine::Digest& RSADigestEngine::digest()
 {
 	if (_digest.empty())
@@ -77,7 +77,7 @@ const DigestEngine::Digest& RSADigestEngine::signature()
     return _signature;
 }
 
-	
+
 bool RSADigestEngine::verify(const DigestEngine::Digest& sig)
 {
 	digest();
diff --git a/Crypto/src/X509Certificate.cpp b/Crypto/src/X509Certificate.cpp
index ed5beeba6..d3f3e5377 100644
--- a/Crypto/src/X509Certificate.cpp
+++ b/Crypto/src/X509Certificate.cpp
@@ -121,7 +121,7 @@ X509Certificate& X509Certificate::operator = (X509Certificate&& cert) noexcept
 }
 
 
-void X509Certificate::swap(X509Certificate& cert)
+void X509Certificate::swap(X509Certificate& cert) noexcept
 {
 	using std::swap;
 	swap(cert._issuerName, _issuerName);
diff --git a/Crypto/testsuite/Makefile b/Crypto/testsuite/Makefile
index df050ecf7..034d999e5 100644
--- a/Crypto/testsuite/Makefile
+++ b/Crypto/testsuite/Makefile
@@ -19,7 +19,8 @@ endif
 
 objects = CryptoTestSuite Driver \
 	CryptoTest DigestEngineTest ECTest \
-	EVPTest RSATest PKCS12ContainerTest
+	EVPTest RSATest PKCS12ContainerTest \
+	EnvelopeTest
 
 target         = testrunner
 target_version = 1
diff --git a/Crypto/testsuite/TestSuite_vs170.vcxproj b/Crypto/testsuite/TestSuite_vs170.vcxproj
index 77708cf45..8c416e4e5 100644
--- a/Crypto/testsuite/TestSuite_vs170.vcxproj
+++ b/Crypto/testsuite/TestSuite_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     TestSuite
     {C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}
     TestSuite
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
   
     Application
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    TestSuited
+    TestSuited
+    TestSuited
+    TestSuite
+    TestSuite
+    TestSuite
     TestSuited
     TestSuited
     TestSuited
@@ -171,6 +250,36 @@
     TestSuite
     TestSuite
   
+  
+    binA64\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
+  
+    binA64\static_mt\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\static_mt\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
+  
+    binA64\static_md\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\static_md\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
   
     bin\
     obj\TestSuite\$(Configuration)\
@@ -231,6 +340,189 @@
     obj64\TestSuite\$(Configuration)\
     false
   
+  
+    
+      Disabled
+      ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitd.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\TestSuited.exe
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnit.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\TestSuite.exe
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitmtd.lib;iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;Crypt32.lib;%(AdditionalDependencies)
+      binA64\static_mt\TestSuited.exe
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\static_mt\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnitmt.lib;iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;Crypt32.lib;%(AdditionalDependencies)
+      binA64\static_mt\TestSuite.exe
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitmdd.lib;iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_md\TestSuited.exe
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\static_md\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\CppUnit\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnitmd.lib;iphlpapi.lib;winmm.lib;ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_md\TestSuite.exe
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
   
     
       Disabled
diff --git a/Crypto/testsuite/src/CryptoTestSuite.cpp b/Crypto/testsuite/src/CryptoTestSuite.cpp
index 03efca93d..0e3a16636 100644
--- a/Crypto/testsuite/src/CryptoTestSuite.cpp
+++ b/Crypto/testsuite/src/CryptoTestSuite.cpp
@@ -21,6 +21,7 @@
 #include "EVPTest.h"
 #include "DigestEngineTest.h"
 #include "PKCS12ContainerTest.h"
+#include "EnvelopeTest.h"
 
 
 CppUnit::Test* CryptoTestSuite::suite()
@@ -33,5 +34,6 @@ CppUnit::Test* CryptoTestSuite::suite()
 	pSuite->addTest(EVPTest::suite());
 	pSuite->addTest(DigestEngineTest::suite());
 	pSuite->addTest(PKCS12ContainerTest::suite());
+	pSuite->addTest(EnvelopeTest::suite());
 	return pSuite;
 }
diff --git a/Crypto/testsuite/src/DigestEngineTest.cpp b/Crypto/testsuite/src/DigestEngineTest.cpp
index bedba5b97..7e1ccd819 100644
--- a/Crypto/testsuite/src/DigestEngineTest.cpp
+++ b/Crypto/testsuite/src/DigestEngineTest.cpp
@@ -47,7 +47,7 @@ void DigestEngineTest::testMD5()
 
 	engine.update("abcdefghijklmnopqrstuvwxyz");
 	assertTrue (DigestEngine::digestToHex(engine.digest()) == "c3fcd3d76192e4007dfb496cca67e13b");
-	
+
 	engine.update("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
 	engine.update("abcdefghijklmnopqrstuvwxyz0123456789");
 	assertTrue (DigestEngine::digestToHex(engine.digest()) == "d174ab98d277d9f5a5611c2c9f419d9f");
diff --git a/Crypto/testsuite/src/Driver.cpp b/Crypto/testsuite/src/Driver.cpp
index 5e1a899cf..a4c76e977 100644
--- a/Crypto/testsuite/src/Driver.cpp
+++ b/Crypto/testsuite/src/Driver.cpp
@@ -13,6 +13,7 @@
 #include "CppUnit/TestRunner.h"
 #include "CryptoTestSuite.h"
 #include "Poco/Crypto/Crypto.h"
+#include "Poco/Exception.h"
 
 
 class CryptoInitializer
@@ -22,7 +23,7 @@ public:
 	{
 		Poco::Crypto::initializeCrypto();
 	}
-	
+
 	~CryptoInitializer()
 	{
 		Poco::Crypto::uninitializeCrypto();
@@ -33,11 +34,12 @@ public:
 int main(int ac, char **av)
 {
 	CryptoInitializer ci;
-	
+
 	std::vector args;
 	for (int i = 0; i < ac; ++i)
 		args.push_back(std::string(av[i]));
 	CppUnit::TestRunner runner;
 	runner.addTest("CryptoTestSuite", CryptoTestSuite::suite());
-	return runner.run(args) ? 0 : 1;
+	CppUnitPocoExceptionText (exc);
+	return runner.run(args, exc) ? 0 : 1;
 }
diff --git a/Crypto/testsuite/src/EVPTest.cpp b/Crypto/testsuite/src/EVPTest.cpp
index f5921b35c..bebf963da 100644
--- a/Crypto/testsuite/src/EVPTest.cpp
+++ b/Crypto/testsuite/src/EVPTest.cpp
@@ -9,9 +9,13 @@
 
 
 #include "EVPTest.h"
+#include "PKCS12ContainerTest.h"
 #include "Poco/Crypto/RSAKey.h"
 #include "Poco/Crypto/ECKey.h"
 #include "Poco/Crypto/EVPPKey.h"
+#include "Poco/Crypto/CipherFactory.h"
+#include "Poco/Crypto/Cipher.h"
+#include "Poco/Crypto/X509Certificate.h"
 #include "Poco/TemporaryFile.h"
 #include "Poco/StreamCopier.h"
 #include "CppUnit/TestCaller.h"
@@ -28,6 +32,58 @@ using Poco::TemporaryFile;
 using Poco::StreamCopier;
 
 
+static const std::string anyPemRSA(
+	"-----BEGIN CERTIFICATE-----\r\n"
+	"MIICaDCCAdECCQCzfxSsk7yaLjANBgkqhkiG9w0BAQUFADBzMQswCQYDVQQGEwJB\r\n"
+	"VDESMBAGA1UECBMJQ2FyaW50aGlhMRIwEAYDVQQHEwlTdC4gSmFrb2IxDzANBgNV\r\n"
+	"BAoTBkFwcEluZjEPMA0GA1UEAxMGQXBwSW5mMRowGAYJKoZIhvcNAQkBFgthcHBA\r\n"
+	"aW5mLmNvbTAeFw0wNjAzMDExMzA3MzFaFw0wNjAzMzExMzA3MzFaMH4xCzAJBgNV\r\n"
+	"BAYTAkFUMRIwEAYDVQQIEwlDYXJpbnRoaWExETAPBgNVBAcTCFN0IEpha29iMRww\r\n"
+	"GgYDVQQKExNBcHBsaWVkIEluZm9ybWF0aWNzMQowCAYDVQQDFAEqMR4wHAYJKoZI\r\n"
+	"hvcNAQkBFg9pbmZvQGFwcGluZi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ\r\n"
+	"AoGBAJHGyXDHyCYoWz+65ltNwwZbhwOGnxr9P1WMATuFJh0bPBZxKbZRdbTm9KhZ\r\n"
+	"OlvsEIsfgiYdsxURYIqXfEgISYLZcZY0pQwGEOmB+0NeC/+ENSfOlNSthx6zSVlc\r\n"
+	"zhJ7+dJOGwepHAiLr1fRuc5jogYLraE+lKTnqAAFfzwvti77AgMBAAEwDQYJKoZI\r\n"
+	"hvcNAQEFBQADgYEAY/ZoeY1ukkEJX7259NeoVM0oahlulWV0rlCqyaeosOiDORPT\r\n"
+	"m6X1w/5MTCf9VyaD1zukoSZ4QqNVjHFXcXidbB7Tgt3yRuZ5PC5LIFCDPv9mgPne\r\n"
+	"mUA70yfctNfza2z3ZiQ6NDkW3mZX+1tmxYIrJQIrkVeYeqf1Gh2nyZrUMcE=\r\n"
+	"-----END CERTIFICATE-----\r\n"
+	"-----BEGIN RSA PRIVATE KEY-----\r\n"
+	"Proc-Type: 4,ENCRYPTED\r\n"
+	"DEK-Info: DES-EDE3-CBC,E7AE93C9E49184EA\r\n"
+	"\r\n"
+	"A2IqzNcWs+I5vzV+i+woDk56+yr58eU0Onw8eEvXkLjnSc58JU4327IF7yUbKWdW\r\n"
+	"Q7BYGGOkVFiZ7ANOwviDg5SUhxRDWCcW8dS6/p1vfdQ1C3qj2OwJjkpg0aDBIzJn\r\n"
+	"FzgguT3MF3ama77vxv0S3kOfmCj62MLqPGpj5pQ0/1hefRFbL8oAX8bXUN7/rmGM\r\n"
+	"Zc0QyzFZv2iQ04dY/6TNclwKPB4H0On4K+8BMs3PRkWA0clCaQaFO2+iwnk3XZfe\r\n"
+	"+MsKUEbLCpAQeYspYv1cw38dCdWq1KTP5aJk+oXgwjfX5cAaPTz74NTqTIsCcaTD\r\n"
+	"3vy7ukJYFlDR9Kyo7z8rMazYrKJslhnuRH0BhK9st9McwL957j5tZmrKyraCcmCx\r\n"
+	"dMAGcsis1va3ayYZpIpFqA4EhYrTM+6N8ZRfUap20+b5IQwHfTQDejUhL6rBwy7j\r\n"
+	"Ti5yD83/itoOMyXq2sV/XWfVD5zk/P5iv22O1EAQMhhnPB9K/I/JhuSGQJfn3cNh\r\n"
+	"ykOUYT0+vDeSeEVa+FVEP1W35G0alTbKbNs5Tb8KxJ3iDJUxokM//SvPXZy9hOVX\r\n"
+	"Y05imB04J15DaGbAHlNzunhuJi7121WV/JRXZRW9diE6hwpD8rwqi3FMuRUmy7U9\r\n"
+	"aFA5poKRAYlo9YtZ3YpFyjGKB6MfCQcB2opuSnQ/gbugV41m67uQ4CDwWLaNRkTb\r\n"
+	"GlsMBNcHnidg15Bsat5HaB7l250ukrI13Uw1MYdDUzaS3gPfw9aC4F2w0p3U+DPH\r\n"
+	"80/zePxtroR7T4/+rI136Rl+aMXDMOEGCX1TVP8rjuZzuRyUSUKC8Q==\r\n"
+	"-----END RSA PRIVATE KEY-----\r\n"
+	"-----BEGIN CERTIFICATE-----\r\n"
+	"MIICXTCCAcYCCQC1Vk/N8qR4AjANBgkqhkiG9w0BAQUFADBzMQswCQYDVQQGEwJB\r\n"
+	"VDESMBAGA1UECBMJQ2FyaW50aGlhMRIwEAYDVQQHEwlTdC4gSmFrb2IxDzANBgNV\r\n"
+	"BAoTBkFwcEluZjEPMA0GA1UEAxMGQXBwSW5mMRowGAYJKoZIhvcNAQkBFgthcHBA\r\n"
+	"aW5mLmNvbTAeFw0wNjAyMjcxMzI3MThaFw0wNjAzMjkxMzI3MThaMHMxCzAJBgNV\r\n"
+	"BAYTAkFUMRIwEAYDVQQIEwlDYXJpbnRoaWExEjAQBgNVBAcTCVN0LiBKYWtvYjEP\r\n"
+	"MA0GA1UEChMGQXBwSW5mMQ8wDQYDVQQDEwZBcHBJbmYxGjAYBgkqhkiG9w0BCQEW\r\n"
+	"C2FwcEBpbmYuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsFXiPuicN\r\n"
+	"Im4oJwF8NuaFN+lgYwcZ6dAO3ILIR3kLA2PxF8HSQLfF8J8a4odZhLhctIMAKTxm\r\n"
+	"k0w8TW5qhL8QLdGzY9vzvkgdKOkan2t3sMeXJAfrM1AphTsmgntAQazGZjOj5p4W\r\n"
+	"jDnxQ+VXAylqwjHh49eSBxM3wgoscF4iLQIDAQABMA0GCSqGSIb3DQEBBQUAA4GB\r\n"
+	"AIpfLdXiKchPvFMhQS8xTtXvrw5dVL3yImUMYs4GQi8RrjGmfGB3yMAR7B/b8v4a\r\n"
+	"+ztfusgWAWiUKuSGTk4S8YB0fsFlmOv0WDr+PyZ4Lui/a8opbyzGE7rqpnF/s0GO\r\n"
+	"M7uLCNNwIN7WhmxcWV0KZU1wTppoSWPJda1yTbBzF9XP\r\n"
+	"-----END CERTIFICATE-----\r\n"
+);
+
+
 EVPTest::EVPTest(const std::string& name): CppUnit::TestCase(name)
 {
 }
@@ -512,6 +568,124 @@ void EVPTest::testECEVPSaveLoadFileNoPass()
 }
 
 
+void EVPTest::testRSAEVPKeyFromX509()
+{
+	std::istringstream str(anyPemRSA);
+	X509Certificate cert(str);
+	EVPPKey publicKey(cert);
+	std::istringstream str2(anyPemRSA);
+	EVPPKey privateKey(0, &str2, "test");
+	Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(publicKey);
+	Cipher::Ptr pCipher2 = CipherFactory::defaultFactory().createCipher(privateKey);
+	std::string val("lets do some encryption");
+	std::string enc = pCipher->encryptString(val);
+	std::string dec = pCipher2->decryptString(enc);
+	assertTrue (dec == val);
+}
+
+
+void EVPTest::testRSAEVPKeyFromPKCS12()
+{
+	std::string file = PKCS12ContainerTest::getTestFilesPath("full");
+	PKCS12Container pkcs12(file.c_str(), "crypto");
+	assertTrue (pkcs12.hasKey());
+	EVPPKey pKey(pkcs12);
+	assertTrue (EVP_PKEY_RSA == pKey.type());
+	Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(pKey);
+	Cipher::Ptr pCipher2 = CipherFactory::defaultFactory().createCipher(pKey);
+	std::string val("lets do some encryption");
+	std::string enc = pCipher->encryptString(val);
+	std::string dec = pCipher2->decryptString(enc);
+	assertTrue (dec == val);
+}
+
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+void EVPTest::testRSAEVPKeyByLength()
+{
+	try
+	{
+		EVPPKey key(EVP_PKEY_RSA, 1024);
+		std::ostringstream strPub;
+		std::ostringstream strPriv;
+		key.save(&strPub, &strPriv);
+		std::string pubKey = strPub.str();
+		std::string privKey = strPriv.str();
+
+		// now do the round trip
+		std::istringstream iPub(pubKey);
+		std::istringstream iPriv(privKey);
+		EVPPKey key2(&iPub, &iPriv);
+
+		assertTrue (key == key2);
+		assertTrue (!(key != key2));
+
+		EVPPKey keyNE(EVP_PKEY_RSA, 2048);
+		assertTrue (key != keyNE);
+		assertTrue (!(key == keyNE));
+		assertTrue (key2 != keyNE);;
+		assertTrue (!(key2 == keyNE));
+
+		std::istringstream iPriv2(privKey);
+		EVPPKey key3(0, &iPriv2);
+		std::ostringstream strPub3;
+		key3.save(&strPub3);
+		std::string pubFromPrivate = strPub3.str();
+		assertTrue (pubFromPrivate == pubKey);
+	}
+	catch(Poco::Exception& ex)
+	{
+		std::cerr << ex.displayText() << std::endl;
+		throw;
+	}
+}
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+void EVPTest::testECEVPKeyByLength()
+{
+	try
+	{
+		EVPPKey key(EVP_PKEY_EC, NID_X9_62_prime256v1);
+		std::ostringstream strPub;
+		std::ostringstream strPriv;
+		key.save(&strPub, &strPriv);
+		std::string pubKey = strPub.str();
+		std::string privKey = strPriv.str();
+
+		// now do the round trip
+		std::istringstream iPub(pubKey);
+		std::istringstream iPriv(privKey);
+		EVPPKey key2(&iPub, &iPriv);
+
+		assertTrue (key == key2);
+		assertTrue (!(key != key2));
+
+		EVPPKey keyNE(EVP_PKEY_EC, NID_X9_62_prime256v1);
+		assertTrue (key != keyNE);
+		assertTrue (!(key == keyNE));
+		assertTrue (key2 != keyNE);;
+		assertTrue (!(key2 == keyNE));
+
+		std::istringstream iPriv2(privKey);
+		EVPPKey key3(0, &iPriv2);
+		std::ostringstream strPub3;
+		key3.save(&strPub3);
+		std::string pubFromPrivate = strPub3.str();
+		assertTrue (pubFromPrivate == pubKey);
+	}
+	catch(Poco::Exception& ex)
+	{
+		std::cerr << ex.displayText() << std::endl;
+		throw;
+	}
+}
+
+#endif // OPENSSL_VERSION_NUMBER >= 0x30000000
+#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
+
+
 void EVPTest::setUp()
 {
 }
@@ -534,6 +708,14 @@ CppUnit::Test* EVPTest::suite()
 	CppUnit_addTest(pSuite, EVPTest, testECEVPSaveLoadStreamNoPass);
 	CppUnit_addTest(pSuite, EVPTest, testECEVPSaveLoadFile);
 	CppUnit_addTest(pSuite, EVPTest, testECEVPSaveLoadFileNoPass);
+	CppUnit_addTest(pSuite, EVPTest, testRSAEVPKeyFromX509);
+	CppUnit_addTest(pSuite, EVPTest, testRSAEVPKeyFromPKCS12);
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+	CppUnit_addTest(pSuite, EVPTest, testRSAEVPKeyByLength);
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	CppUnit_addTest(pSuite, EVPTest, testECEVPKeyByLength);
+#endif // OPENSSL_VERSION_NUMBER >= 0x30000000
+#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
 
 	return pSuite;
 }
diff --git a/Crypto/testsuite/src/EVPTest.h b/Crypto/testsuite/src/EVPTest.h
index 9e0a49fe7..3cd086dd3 100644
--- a/Crypto/testsuite/src/EVPTest.h
+++ b/Crypto/testsuite/src/EVPTest.h
@@ -34,6 +34,16 @@ public:
 	void testECEVPSaveLoadFile();
 	void testECEVPSaveLoadFileNoPass();
 
+	void testRSAEVPKeyFromX509();
+	void testRSAEVPKeyFromPKCS12();
+
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+	void testRSAEVPKeyByLength();
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+	void testECEVPKeyByLength();
+#endif // OPENSSL_VERSION_NUMBER >= 0x30000000L
+#endif // OPENSSL_VERSION_NUMBER >= 0x10000000L
+
 	void setUp();
 	void tearDown();
 
diff --git a/Crypto/testsuite/src/EnvelopeTest.cpp b/Crypto/testsuite/src/EnvelopeTest.cpp
new file mode 100644
index 000000000..d377b9d1b
--- /dev/null
+++ b/Crypto/testsuite/src/EnvelopeTest.cpp
@@ -0,0 +1,147 @@
+//
+// EnvelopeTest.cpp
+//
+// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#include "EnvelopeTest.h"
+#include "CppUnit/TestCaller.h"
+#include "CppUnit/TestSuite.h"
+#include "Poco/Crypto/Envelope.h"
+#include "Poco/Crypto/EVPPKey.h"
+#include 
+
+
+using Poco::Crypto::Envelope;
+using Poco::Crypto::EVPPKey;
+
+
+EnvelopeTest::EnvelopeTest(const std::string& name): CppUnit::TestCase(name)
+{
+}
+
+
+EnvelopeTest::~EnvelopeTest()
+{
+}
+
+
+void EnvelopeTest::testOneKeyRSA()
+{
+	try
+	{
+		EVPPKey key(EVP_PKEY_RSA, 1024);
+		Envelope env(key, NID_aes_256_cbc);
+		assertEqual(env.cipherNID(), NID_aes_256_cbc);
+		std::string dec = "let's encrypt some text";
+		env.seal(dec);
+		assertTrue(env.openAsString(key, env.keys()[0]) == dec);
+	}
+	catch(const Poco::Exception& e)
+	{
+		std::cerr << e.displayText() << '\n';
+		throw;
+	}
+}
+
+
+void EnvelopeTest::testMultiKeyRSA()
+{
+	try
+	{
+		Envelope::EVPPKeyVec keyVec;
+		keyVec.emplace_back(EVP_PKEY_RSA, 1024);
+		keyVec.emplace_back(EVP_PKEY_RSA, 2048);
+		keyVec.emplace_back(EVP_PKEY_RSA, 1024);
+		Envelope env(keyVec, NID_aes_256_cbc);
+		assertEqual(env.cipherNID(), NID_aes_256_cbc);
+		std::string dec = "let's encrypt some text";
+		env.seal(dec);
+		int i = 0;
+		for (const auto& key : keyVec)
+		{
+			assertTrue(env.openAsString(key, env.keys()[i++]) == dec);
+		}
+	}
+	catch(const Poco::Exception& e)
+	{
+		std::cerr << e.displayText() << '\n';
+		throw;
+	}
+}
+
+
+void EnvelopeTest::testRSATransfer()
+{
+	try
+	{
+		EVPPKey key(EVP_PKEY_RSA, 1024);
+		Envelope env1(key, NID_aes_256_cbc);
+		std::string dec = "let's encrypt some text";
+
+		Envelope env2(key, NID_aes_256_cbc);
+		env2.setContent(env1.seal(dec));
+		assertTrue(env2.openAsString(key, env1.keys()[0], env1.iv()) == dec);
+	}
+	catch(const Poco::Exception& e)
+	{
+		std::cerr << e.displayText() << '\n';
+		throw;
+	}
+}
+
+
+void EnvelopeTest::testRSAMultiTransfer()
+{
+	try
+	{
+		Envelope::EVPPKeyVec keyVec;
+		keyVec.emplace_back(EVP_PKEY_RSA, 1024);
+		keyVec.emplace_back(EVP_PKEY_RSA, 2048);
+		keyVec.emplace_back(EVP_PKEY_RSA, 1024);
+
+		Envelope env0(keyVec, NID_aes_256_cbc);
+		std::string dec = "let's encrypt some text";
+
+		const Envelope::ByteVec enc = env0.seal(dec);
+
+		int i = 0;
+		for (const auto& key : keyVec)
+		{
+			Envelope env(key, NID_aes_256_cbc);
+			env.setContent(enc);
+			assertTrue(env.openAsString(key, env0.keys()[i++], env0.iv()) == dec);
+		}
+	}
+	catch(const Poco::Exception& e)
+	{
+		std::cerr << e.displayText() << '\n';
+		throw;
+	}
+}
+
+void EnvelopeTest::setUp()
+{
+}
+
+
+void EnvelopeTest::tearDown()
+{
+}
+
+
+CppUnit::Test* EnvelopeTest::suite()
+{
+	CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("EnvelopeTest");
+
+	CppUnit_addTest(pSuite, EnvelopeTest, testOneKeyRSA);
+	CppUnit_addTest(pSuite, EnvelopeTest, testMultiKeyRSA);
+	CppUnit_addTest(pSuite, EnvelopeTest, testRSATransfer);
+	CppUnit_addTest(pSuite, EnvelopeTest, testRSAMultiTransfer);
+
+	return pSuite;
+}
diff --git a/Crypto/testsuite/src/EnvelopeTest.h b/Crypto/testsuite/src/EnvelopeTest.h
new file mode 100644
index 000000000..6f16db500
--- /dev/null
+++ b/Crypto/testsuite/src/EnvelopeTest.h
@@ -0,0 +1,41 @@
+//
+// EnvelopeTest.h
+//
+// Definition of the EnvelopeTest class.
+//
+// Copyright (c) 2012, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#ifndef EnvelopeTest_INCLUDED
+#define EnvelopeTest_INCLUDED
+
+
+#include "Poco/Crypto/Crypto.h"
+#include "CppUnit/TestCase.h"
+
+
+class EnvelopeTest: public CppUnit::TestCase
+{
+public:
+	EnvelopeTest(const std::string& name);
+	~EnvelopeTest();
+
+	void testOneKeyRSA();
+	void testMultiKeyRSA();
+	void testRSATransfer();
+	void testRSAMultiTransfer();
+
+	void setUp();
+	void tearDown();
+
+	static CppUnit::Test* suite();
+
+private:
+};
+
+
+#endif // EnvelopeTest_INCLUDED
diff --git a/Crypto/testsuite/src/PKCS12ContainerTest.h b/Crypto/testsuite/src/PKCS12ContainerTest.h
index fdb850661..9f4c2f702 100644
--- a/Crypto/testsuite/src/PKCS12ContainerTest.h
+++ b/Crypto/testsuite/src/PKCS12ContainerTest.h
@@ -35,9 +35,10 @@ public:
 
 	static CppUnit::Test* suite();
 
-private:
-	std::string getTestFilesPath(const std::string& name,
+	static std::string getTestFilesPath(const std::string& name,
 		const std::string& ext = "p12");
+
+private:
 	void certsOnly(const Poco::Crypto::PKCS12Container& pkcs12);
 	void certsOnlyList(const Poco::Crypto::PKCS12Container::CAList& caList,
 		const Poco::Crypto::PKCS12Container::CANameList& caNamesList,
diff --git a/Crypto/testsuite/src/RSATest.cpp b/Crypto/testsuite/src/RSATest.cpp
index 5ea1eda8b..e5a978cfa 100644
--- a/Crypto/testsuite/src/RSATest.cpp
+++ b/Crypto/testsuite/src/RSATest.cpp
@@ -15,7 +15,10 @@
 #include "Poco/Crypto/CipherFactory.h"
 #include "Poco/Crypto/Cipher.h"
 #include "Poco/Crypto/X509Certificate.h"
+#include "Poco/Path.h"
+#include "Poco/File.h"
 #include 
+#include 
 
 
 using namespace Poco::Crypto;
@@ -203,6 +206,33 @@ void RSATest::testRSACipher()
 		std::string dec = pCipher->decryptString(enc);
 		assertTrue (dec == val);
 	}
+
+	RSAKey key(RSAKey::KL_1024, RSAKey::EXP_SMALL);
+	std::string pubKeyFile = Poco::Path::temp() + "poco.key.pub";
+	std::string privKeyFile = Poco::Path::temp() + "poco.key.priv";
+
+	if (Poco::File(pubKeyFile).exists()) Poco::File(pubKeyFile).remove();
+	if (Poco::File(privKeyFile).exists()) Poco::File(privKeyFile).remove();
+	std::ofstream strPub(pubKeyFile);
+	std::ofstream strPriv(privKeyFile);
+	key.save(&strPub, &strPriv);
+	strPub.close();
+	strPriv.close();
+
+    Poco::Crypto::RSAKey encryptKey(pubKeyFile);
+	Poco::Crypto::RSAKey decryptKey(pubKeyFile, privKeyFile);
+
+    Poco::Crypto::CipherFactory factory;
+    auto iengine = factory.createCipher(encryptKey);
+    auto oengine = factory.createCipher(decryptKey);
+
+    std::string ss = "test_str";
+    auto enc = iengine->encryptString(ss);
+    auto dec = oengine->decryptString(enc);
+    assertEqual (ss, dec);
+
+	delete iengine;
+	delete oengine;
 }
 
 
@@ -221,7 +251,7 @@ void RSATest::testRSACipherLarge()
 	sizes.push_back (16383);
 	sizes.push_back (16384);
 	sizes.push_back (16385);
-	
+
 	Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(RSAKey(RSAKey::KL_1024, RSAKey::EXP_SMALL));
 	for (std::vector::const_iterator it = sizes.begin(); it != sizes.end(); ++it)
 	{
@@ -243,7 +273,7 @@ void RSATest::testCertificate()
 	Cipher::Ptr pCipher = CipherFactory::defaultFactory().createCipher(publicKey);
 	Cipher::Ptr pCipher2 = CipherFactory::defaultFactory().createCipher(privateKey);
 	std::string val("lets do some encryption");
-	
+
 	std::string enc = pCipher->encryptString(val);
 	std::string dec = pCipher2->decryptString(enc);
 	assertTrue (dec == val);
diff --git a/Crypto/testsuite/src/WinCEDriver.cpp b/Crypto/testsuite/src/WinCEDriver.cpp
index 9bbd0b29b..6f0530a76 100644
--- a/Crypto/testsuite/src/WinCEDriver.cpp
+++ b/Crypto/testsuite/src/WinCEDriver.cpp
@@ -23,7 +23,7 @@ public:
 	{
 		Poco::Crypto::initializeCrypto();
 	}
-	
+
 	~CryptoInitializer()
 	{
 		Poco::Crypto::uninitializeCrypto();
@@ -42,7 +42,7 @@ int _tmain(int argc, wchar_t* argv[])
 		std::wcstombs(buffer, argv[i], sizeof(buffer));
 		args.push_back(std::string(buffer));
 	}
-	CppUnit::TestRunner runner;	
+	CppUnit::TestRunner runner;
 	runner.addTest("CryptoTestSuite", CryptoTestSuite::suite());
 	return runner.run(args) ? 0 : 1;
 }
diff --git a/Crypto/testsuite/src/WinDriver.cpp b/Crypto/testsuite/src/WinDriver.cpp
index d7f26bba6..90d085fda 100644
--- a/Crypto/testsuite/src/WinDriver.cpp
+++ b/Crypto/testsuite/src/WinDriver.cpp
@@ -22,7 +22,7 @@ public:
 	{
 		Poco::Crypto::initializeCrypto();
 	}
-	
+
 	~CryptoInitializer()
 	{
 		Poco::Crypto::uninitializeCrypto();
diff --git a/DLLVersion.rc b/DLLVersion.rc
index 75c78e578..779c4db1b 100644
--- a/DLLVersion.rc
+++ b/DLLVersion.rc
@@ -4,8 +4,8 @@
 
 #include "winres.h"
 
-#define POCO_VERSION 1,11,3,0
-#define POCO_VERSION_STR "1.11.3"
+#define POCO_VERSION 1,12,0,0
+#define POCO_VERSION_STR "1.12.0"
 
 VS_VERSION_INFO VERSIONINFO
  FILEVERSION POCO_VERSION
diff --git a/Data/CMakeLists.txt b/Data/CMakeLists.txt
index 7d1e99ea9..0772af648 100644
--- a/Data/CMakeLists.txt
+++ b/Data/CMakeLists.txt
@@ -30,7 +30,7 @@ target_link_libraries(Data PUBLIC Poco::Foundation)
 target_include_directories(Data
 	PUBLIC
 		$
-		$
+		$
 	PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 
diff --git a/Data/Data_VS90.vcproj b/Data/Data_VS90.vcproj
index 2955c9914..bdd6f6e7b 100644
--- a/Data/Data_VS90.vcproj
+++ b/Data/Data_VS90.vcproj
@@ -583,6 +583,10 @@
 					RelativePath=".\include\Poco\Data\Extraction.h"
 					>
 				
+				
+				
 				
@@ -667,6 +671,10 @@
 					RelativePath=".\include\Poco\Data\Transaction.h"
 					>
 				
+				
+				
 				
@@ -719,6 +727,10 @@
 					RelativePath=".\src\DynamicLOB.cpp"
 					>
 				
+				
+				
 				
@@ -791,6 +803,10 @@
 					RelativePath=".\src\Transaction.cpp"
 					>
 				
+				
+				
 			
 		
 		
-
+
   
     
       debug_shared
@@ -157,7 +157,7 @@
   
   
   
-    <_ProjectFileVersion>14.0.25420.1
+    <_ProjectFileVersion>16.0.32002.118
     PocoDatad
     PocoDatamdd
     PocoDatamtd
@@ -595,6 +595,7 @@
     
     
     
+    
     
   
   
@@ -703,6 +704,9 @@
     
       true
     
+    
+      true
+    
   
   
     
diff --git a/Data/Data_vs140.vcxproj.filters b/Data/Data_vs140.vcxproj.filters
index 80c320828..728781f8a 100644
--- a/Data/Data_vs140.vcxproj.filters
+++ b/Data/Data_vs140.vcxproj.filters
@@ -2,31 +2,31 @@
 
   
     
-      {4630cfec-6a3b-45dd-9d9e-0fd2052abb2d}
+      {a918a581-0b94-4c8e-9fb9-958a05520fb3}
     
     
-      {48fbd0eb-1cb1-4f72-8fff-4ae28eb87945}
+      {35b035eb-d96e-4f12-ac40-fdfcffbfa511}
     
     
-      {e4421ebf-77eb-439f-9377-260010e240a3}
+      {cbe6bea8-a94c-4022-8e34-ade5cf268bda}
     
     
-      {d68a747a-68d9-4d71-8b63-96e0a839ce19}
+      {10e6a489-5fac-49d4-8ee0-73555f49d15c}
     
     
-      {20822f2a-f72a-4717-8315-788b6ea4a799}
+      {c86ed4bd-93ce-466a-932c-1baf6d70fc6b}
     
     
-      {12285d08-05f2-4daf-8b48-7fe113c43626}
+      {749d2b0b-1512-4ce0-81f9-f94fc4d77c1c}
     
     
-      {6f51ecaf-0e63-4626-b373-9b9a635f32a3}
+      {3358309f-c181-457a-a176-572c9c29e54e}
     
     
-      {62eedc44-364a-408f-918e-dd2fb360f554}
+      {170fbdcf-8f02-4198-b22b-812d62cae3a0}
     
     
-      {4252b3e7-3a2f-4690-b64d-56cbf0a07396}
+      {8f4b30b1-f7dc-451e-b618-23b2587336aa}
     
   
   
@@ -156,6 +156,9 @@
     
       DataCore\Header Files
     
+    
+      DataCore\Header Files
+    
     
       DataCore\Header Files
     
@@ -266,6 +269,9 @@
     
       DataCore\Source Files
     
+    
+      DataCore\Source Files
+    
     
       SessionPooling\Source Files
     
diff --git a/Data/Data_vs150.vcxproj b/Data/Data_vs150.vcxproj
index c64a40fee..ac6e5ea87 100644
--- a/Data/Data_vs150.vcxproj
+++ b/Data/Data_vs150.vcxproj
@@ -157,7 +157,7 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>16.0.32002.118
     PocoDatad
     PocoDatamdd
     PocoDatamtd
@@ -595,6 +595,7 @@
     
     
     
+    
     
   
   
@@ -703,6 +704,9 @@
     
       true
     
+    
+      true
+    
   
   
     
diff --git a/Data/Data_vs150.vcxproj.filters b/Data/Data_vs150.vcxproj.filters
index ae6fa4432..59b0865a8 100644
--- a/Data/Data_vs150.vcxproj.filters
+++ b/Data/Data_vs150.vcxproj.filters
@@ -2,31 +2,31 @@
 
   
     
-      {793d98db-e0fa-4880-9db4-b0a7c9f88c68}
+      {7b0fd170-a5ff-470c-a6f2-36ab15c21f11}
     
     
-      {3d8ad51d-10e6-4f08-8410-ea40913bebba}
+      {1dac28cd-cf73-421b-924b-06f576cda9fb}
     
     
-      {4ea7edd0-e04b-4f1e-896b-5081d9b342b5}
+      {6db26f6f-4cc3-44ce-b0f6-b1bebab18fa5}
     
     
-      {cfd4b786-dcdc-423b-b5d4-c73039b20eed}
+      {bf2ebeda-2feb-4e6b-9e99-17e58078fdef}
     
     
-      {ff57a93a-487b-4129-bbef-67cdd568b2b8}
+      {92b1ea48-8b24-4e4a-aed4-a5cc247b6f4f}
     
     
-      {320cddef-7436-4a3c-b669-e831bb16315c}
+      {8c266092-f761-4a17-abe2-5c211f46273f}
     
     
-      {1ec35c1f-bc55-4077-b093-41ec1be8096a}
+      {2b1ba35d-2ae9-428b-967b-2b80ec813c16}
     
     
-      {3603e43e-380c-4622-b020-cf3910cb56d3}
+      {ee5a2056-14b3-4c70-a2e4-28cf7a1d8da8}
     
     
-      {0edc5cb3-3735-441b-a71c-eab1a3c6f02f}
+      {e36e4188-9ff6-468c-ac65-55ef1d5a4988}
     
   
   
@@ -156,6 +156,9 @@
     
       DataCore\Header Files
     
+    
+      DataCore\Header Files
+    
     
       DataCore\Header Files
     
@@ -266,6 +269,9 @@
     
       DataCore\Source Files
     
+    
+      DataCore\Source Files
+    
     
       SessionPooling\Source Files
     
diff --git a/Data/Data_vs160.vcxproj b/Data/Data_vs160.vcxproj
index 2054796c8..829557603 100644
--- a/Data/Data_vs160.vcxproj
+++ b/Data/Data_vs160.vcxproj
@@ -157,7 +157,7 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>16.0.32002.118
     PocoDatad
     PocoDatamdd
     PocoDatamtd
@@ -569,6 +569,7 @@
     
     
     
+    
     
     
     
@@ -595,6 +596,7 @@
     
     
     
+    
     
   
   
@@ -634,6 +636,9 @@
     
       true
     
+    
+      true
+    
     
       true
     
@@ -703,6 +708,9 @@
     
       true
     
+    
+      true
+    
   
   
     
diff --git a/Data/Data_vs160.vcxproj.filters b/Data/Data_vs160.vcxproj.filters
index 1b1b91beb..eed50b05b 100644
--- a/Data/Data_vs160.vcxproj.filters
+++ b/Data/Data_vs160.vcxproj.filters
@@ -2,31 +2,31 @@
 
   
     
-      {6c162c5f-b7ae-436f-a1a5-ecf733b32d81}
+      {ca802690-e052-4003-ae74-b2cd7e2c95f9}
     
     
-      {1beac889-c2f5-48df-93de-07a0658b987e}
+      {c9a3889d-4e2d-43ac-887e-3b22b1cf4ba9}
     
     
-      {d6fccab3-e509-4d0f-be51-81116507be0d}
+      {b6b0997e-c4d7-4526-88c6-614fba4407cf}
     
     
-      {3777237e-6510-4397-932b-8b99b2baf730}
+      {ca986e9c-3287-419e-8f6a-7472a96c71b9}
     
     
-      {4f1ff28e-858b-432a-8c0d-adbf7515b180}
+      {33a16a37-8706-47fb-ac35-f3e913ff6a03}
     
     
-      {22669877-0409-48ce-9ef4-815bd034f536}
+      {934c7f71-50fb-452a-94a6-c123cdaa043e}
     
     
-      {bd891b52-55cd-48f0-893f-4370dc2264ef}
+      {e6946b3f-5400-4275-a315-25a8db846def}
     
     
-      {ceffc496-da4c-44a3-9fab-95a41fde3cdc}
+      {6fd48faa-50da-4192-bf66-27068d6b2156}
     
     
-      {a80cd2cd-b1b2-40f1-96c9-fcdf376aeba4}
+      {71eaafa2-e2fe-4cb8-80e2-82ea694abeec}
     
   
   
@@ -93,6 +93,9 @@
     
       DataCore\Header Files
     
+    
+      DataCore\Header Files
+    
     
       DataCore\Header Files
     
@@ -156,6 +159,9 @@
     
       DataCore\Header Files
     
+    
+      DataCore\Header Files
+    
     
       DataCore\Header Files
     
@@ -212,6 +218,9 @@
     
       DataCore\Source Files
     
+    
+      DataCore\Source Files
+    
     
       DataCore\Source Files
     
@@ -266,6 +275,9 @@
     
       DataCore\Source Files
     
+    
+      DataCore\Source Files
+    
     
       SessionPooling\Source Files
     
diff --git a/Data/Data_vs170.sln b/Data/Data_vs170.sln
index 1e8444f55..222c7e57f 100644
--- a/Data/Data_vs170.sln
+++ b/Data/Data_vs170.sln
@@ -9,6 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\Test
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		debug_shared|ARM64 = debug_shared|ARM64
+		release_shared|ARM64 = release_shared|ARM64
+		debug_static_mt|ARM64 = debug_static_mt|ARM64
+		release_static_mt|ARM64 = release_static_mt|ARM64
+		debug_static_md|ARM64 = debug_static_md|ARM64
+		release_static_md|ARM64 = release_static_md|ARM64
 		debug_shared|Win32 = debug_shared|Win32
 		release_shared|Win32 = release_shared|Win32
 		debug_static_mt|Win32 = debug_static_mt|Win32
@@ -23,6 +29,24 @@ Global
 		release_static_md|x64 = release_static_md|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{240E83C3-368D-11DB-9FBC-00123FC423B5}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
@@ -59,6 +83,24 @@ Global
 		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_md|x64.ActiveCfg = release_static_md|x64
 		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_md|x64.Build.0 = release_static_md|x64
 		{240E83C3-368D-11DB-9FBC-00123FC423B5}.release_static_md|x64.Deploy.0 = release_static_md|x64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{1813A463-E349-4FEA-8A8E-4A41E41C0DC7}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
diff --git a/Data/Data_vs170.vcxproj b/Data/Data_vs170.vcxproj
index bc32b250e..a3f0a4dd6 100644
--- a/Data/Data_vs170.vcxproj
+++ b/Data/Data_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     Data
     {240E83C3-368D-11DB-9FBC-00123FC423B5}
     Data
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
   
     StaticLibrary
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    PocoDataA64d
+    PocoDatamdd
+    PocoDatamtd
+    PocoDataA64
+    PocoDatamd
+    PocoDatamt
     PocoDatad
     PocoDatamdd
     PocoDatamtd
@@ -171,6 +250,32 @@
     PocoDatamd
     PocoDatamt
   
+  
+    ..\binA64\
+    objA64\Data\$(Configuration)\
+    true
+  
+  
+    ..\binA64\
+    objA64\Data\$(Configuration)\
+    false
+  
+  
+    ..\libA64\
+    objA64\Data\$(Configuration)\
+  
+  
+    ..\libA64\
+    objA64\Data\$(Configuration)\
+  
+  
+    ..\libA64\
+    objA64\Data\$(Configuration)\
+  
+  
+    ..\libA64\
+    objA64\Data\$(Configuration)\
+  
   
     ..\bin\
     obj\Data\$(Configuration)\
@@ -223,6 +328,164 @@
     ..\lib64\
     obj64\Data\$(Configuration)\
   
+  
+    
+      Disabled
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;_USRDLL;Data_EXPORTS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\binA64\PocoDataA64d.dll
+      true
+      true
+      ..\binA64\PocoDataA64d.pdb
+      ..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      ..\libA64\PocoDatad.lib
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;_USRDLL;Data_EXPORTS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\binA64\PocoDataA64.dll
+      true
+      false
+      ..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      true
+      true
+      ..\libA64\PocoData.lib
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      ..\libA64\PocoDatamtd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\libA64\PocoDatamtd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\libA64\PocoDatamt.lib
+    
+  
+  
+    
+      Disabled
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      ..\libA64\PocoDatamdd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\libA64\PocoDatamdd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\Foundation\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\libA64\PocoDatamd.lib
+    
+  
   
     
       Disabled
@@ -569,6 +832,7 @@
     
     
     
+    
     
     
     
@@ -595,6 +859,7 @@
     
     
     
+    
     
   
   
@@ -634,6 +899,9 @@
     
       true
     
+    
+      true
+    
     
       true
     
@@ -703,15 +971,22 @@
     
       true
     
+    
+      true
+    
   
   
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
     
diff --git a/Data/Data_vs170.vcxproj.filters b/Data/Data_vs170.vcxproj.filters
index 341164660..b229d0a2d 100644
--- a/Data/Data_vs170.vcxproj.filters
+++ b/Data/Data_vs170.vcxproj.filters
@@ -2,31 +2,31 @@
 
   
     
-      {f0b53a30-a53e-4071-9b49-462661219222}
+      {25181de0-3e99-4db9-a218-4580b16cbb0a}
     
     
-      {0f2e4039-58d1-4d78-8e4f-fe6a9f686dd7}
+      {bf1fcd58-d750-4f91-8eea-0dc1e09013b6}
     
     
-      {f86b407a-1b0d-4d1f-8343-cddaae8df71b}
+      {9ccb9717-2829-450a-b3ea-715077fc770f}
     
     
-      {9ee70240-2f9a-45b0-b285-85f652308bb6}
+      {fa110a23-abc0-4838-8c37-2cf0a512d556}
     
     
-      {c26b342f-fe35-4572-8503-6b7f0563a496}
+      {6dd4ce47-c8de-48c7-891f-6fc47fff19e9}
     
     
-      {e57c80f0-c5be-4f68-a5e8-d45fcedccb42}
+      {5011cbf7-2ae9-4b14-9a03-bb9f9c754dc4}
     
     
-      {fd6a580d-fc0b-4016-9245-e362b3cbaef0}
+      {39e78f99-76eb-4ca6-a6e5-69380ba1e19f}
     
     
-      {c83ff916-a67d-45a0-9edd-faf1729e4aeb}
+      {c2cbcb61-3c9c-4208-aebc-bf1e7ec77703}
     
     
-      {3c94cac3-8af3-4da6-b07c-1ff6dcf0a4ab}
+      {f59283d4-ff32-4856-903b-81bd84ebb146}
     
   
   
@@ -156,6 +156,9 @@
     
       DataCore\Header Files
     
+    
+      DataCore\Header Files
+    
     
       DataCore\Header Files
     
@@ -266,6 +269,9 @@
     
       DataCore\Source Files
     
+    
+      DataCore\Source Files
+    
     
       SessionPooling\Source Files
     
diff --git a/Data/Makefile b/Data/Makefile
index ea61d29aa..ea354f6c2 100644
--- a/Data/Makefile
+++ b/Data/Makefile
@@ -8,12 +8,12 @@ include $(POCO_BASE)/build/rules/global
 
 objects = AbstractBinder AbstractBinding AbstractExtraction AbstractExtractor \
 	AbstractPreparation AbstractPreparator ArchiveStrategy Transaction \
-	Bulk Connector DataException Date DynamicLOB Limit MetaColumn \
-	PooledSessionHolder PooledSessionImpl Position \
+	Bulk Connector DataException Date DynamicLOB JSONRowFormatter \
+	Limit MetaColumn PooledSessionHolder PooledSessionImpl Position \
 	Range RecordSet Row RowFilter RowFormatter RowIterator \
 	SimpleRowFormatter Session SessionFactory SessionImpl \
 	SessionPool SessionPoolContainer SQLChannel \
-	Statement StatementCreator StatementImpl Time
+	Statement StatementCreator StatementImpl Time Transcoder
 
 target         = PocoData
 target_version = $(LIBVERSION)
diff --git a/Data/MySQL/CMakeLists.txt b/Data/MySQL/CMakeLists.txt
index f71b1453e..ce411cfea 100644
--- a/Data/MySQL/CMakeLists.txt
+++ b/Data/MySQL/CMakeLists.txt
@@ -25,7 +25,7 @@ target_link_libraries(DataMySQL PUBLIC Poco::Data MySQL::client)
 target_include_directories(DataMySQL
 	PUBLIC
 		$
-		$
+		$
 	PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 target_compile_definitions(DataMySQL PUBLIC THREADSAFE NO_TCL)
diff --git a/Data/MySQL/MySQL_vs170.sln b/Data/MySQL/MySQL_vs170.sln
index d62f78d9d..1352dbb99 100644
--- a/Data/MySQL/MySQL_vs170.sln
+++ b/Data/MySQL/MySQL_vs170.sln
@@ -9,6 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\Test
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		debug_shared|ARM64 = debug_shared|ARM64
+		release_shared|ARM64 = release_shared|ARM64
+		debug_static_mt|ARM64 = debug_static_mt|ARM64
+		release_static_mt|ARM64 = release_static_mt|ARM64
+		debug_static_md|ARM64 = debug_static_md|ARM64
+		release_static_md|ARM64 = release_static_md|ARM64
 		debug_shared|Win32 = debug_shared|Win32
 		release_shared|Win32 = release_shared|Win32
 		debug_static_mt|Win32 = debug_static_mt|Win32
@@ -23,6 +29,24 @@ Global
 		release_static_md|x64 = release_static_md|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
@@ -59,6 +83,24 @@ Global
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|x64.ActiveCfg = release_static_md|x64
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|x64.Build.0 = release_static_md|x64
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|x64.Deploy.0 = release_static_md|x64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
diff --git a/Data/MySQL/MySQL_vs170.vcxproj b/Data/MySQL/MySQL_vs170.vcxproj
index 067cd7c62..29b7943d6 100644
--- a/Data/MySQL/MySQL_vs170.vcxproj
+++ b/Data/MySQL/MySQL_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     MySQL
     {73E19FDE-1570-488C-B3DB-72A60FADD408}
     MySQL
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
   
     StaticLibrary
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    PocoDataMySQLA64d
+    PocoDataMySQLmdd
+    PocoDataMySQLmtd
+    PocoDataMySQLA64
+    PocoDataMySQLmd
+    PocoDataMySQLmt
     PocoDataMySQLd
     PocoDataMySQLmdd
     PocoDataMySQLmtd
@@ -171,6 +250,32 @@
     PocoDataMySQLmd
     PocoDataMySQLmt
   
+  
+    ..\..\binA64\
+    objA64\MySQL\$(Configuration)\
+    true
+  
+  
+    ..\..\binA64\
+    objA64\MySQL\$(Configuration)\
+    false
+  
+  
+    ..\..\libA64\
+    objA64\MySQL\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\MySQL\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\MySQL\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\MySQL\$(Configuration)\
+  
   
     ..\..\bin\
     obj\MySQL\$(Configuration)\
@@ -223,6 +328,164 @@
     ..\..\lib64\
     obj64\MySQL\$(Configuration)\
   
+  
+    
+      Disabled
+      .\include;..\..\Foundation\include;..\..\Data\include;..\..\mysql\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;_USRDLL;THREADSAFE;__LCC__;MySQL_EXPORTS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\binA64\PocoDataMySQLA64d.dll
+      true
+      true
+      ..\..\binA64\PocoDataMySQLA64d.pdb
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      ..\..\libA64\PocoDataMySQLd.lib
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\Foundation\include;..\..\Data\include;..\..\mysql\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;_USRDLL;THREADSAFE;__LCC__;MySQL_EXPORTS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\binA64\PocoDataMySQLA64.dll
+      true
+      false
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      true
+      true
+      ..\..\libA64\PocoDataMySQL.lib
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      .\include;..\..\Foundation\include;..\..\Data\include;..\..\mysql\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;__LCC__;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      ..\..\libA64\PocoDataMySQLmtd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataMySQLmtd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\Foundation\include;..\..\Data\include;..\..\mysql\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;__LCC__;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataMySQLmt.lib
+    
+  
+  
+    
+      Disabled
+      .\include;..\..\Foundation\include;..\..\Data\include;..\..\mysql\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;__LCC__;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      ..\..\libA64\PocoDataMySQLmdd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataMySQLmdd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\Foundation\include;..\..\Data\include;..\..\mysql\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;__LCC__;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataMySQLmd.lib
+    
+  
   
     
       Disabled
@@ -587,12 +850,16 @@
   
   
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
     
diff --git a/Data/MySQL/include/Poco/Data/MySQL/Connector.h b/Data/MySQL/include/Poco/Data/MySQL/Connector.h
index 14960f439..77878ac6c 100644
--- a/Data/MySQL/include/Poco/Data/MySQL/Connector.h
+++ b/Data/MySQL/include/Poco/Data/MySQL/Connector.h
@@ -35,7 +35,7 @@ public:
 
 	Connector();
 		/// Creates the Connector.
-	
+
 	virtual ~Connector();
 		/// Destroys the Connector.
 
diff --git a/Data/MySQL/include/Poco/Data/MySQL/Extractor.h b/Data/MySQL/include/Poco/Data/MySQL/Extractor.h
index 36226fc65..6952f8cd4 100644
--- a/Data/MySQL/include/Poco/Data/MySQL/Extractor.h
+++ b/Data/MySQL/include/Poco/Data/MySQL/Extractor.h
@@ -323,6 +323,10 @@ public:
 private:
 	bool realExtractFixed(std::size_t pos, enum_field_types type, void* buffer, bool isUnsigned = false);
 
+	bool extractLongLOB(std::size_t pos);
+
+	bool extractJSON(std::size_t pos);
+
 	// Prevent VC8 warning "operator= could not be generated"
 	Extractor& operator=(const Extractor&);
 
diff --git a/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h b/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h
index d06a8ba2f..e303afd27 100644
--- a/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h
+++ b/Data/MySQL/include/Poco/Data/MySQL/MySQLStatementImpl.h
@@ -40,10 +40,10 @@ class MySQL_API MySQLStatementImpl: public Poco::Data::StatementImpl
 public:
 	MySQLStatementImpl(SessionImpl& s);
 		/// Creates the MySQLStatementImpl.
-		
+
 	~MySQLStatementImpl();
 		/// Destroys the MySQLStatementImpl.
-		
+
 protected:
 	virtual std::size_t columnsReturned() const;
 		/// Returns number of columns returned by query.
@@ -51,32 +51,32 @@ protected:
 	virtual int affectedRowCount() const;
 		/// Returns the number of affected rows.
 		/// Used to find out the number of rows affected by insert, delete or update.
-	
+
 	virtual const MetaColumn& metaColumn(std::size_t pos) const;
 		/// Returns column meta data.
-		
+
 	virtual bool hasNext();
 		/// Returns true if a call to next() will return data.
-		
+
 	virtual std::size_t next();
 		/// Retrieves the next row from the resultset.
 		/// Will throw, if the resultset is empty.
-	
+
 	virtual bool canBind() const;
 		/// Returns true if a valid statement is set and we can bind.
 
 	virtual bool canCompile() const;
 		/// Returns true if another compile is possible.
-		
+
 	virtual void compileImpl();
 		/// Compiles the statement, doesn't bind yet
-		
+
 	virtual void bindImpl();
 		/// Binds parameters
-		
+
 	virtual Poco::Data::AbstractExtractor::Ptr extractor();
 		/// Returns the concrete extractor used by the statement.
-		
+
 	virtual Poco::Data::AbstractBinder::Ptr binder();
 		/// Returns the concrete binder used by the statement.
 
diff --git a/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h b/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h
index 3a45387bc..8b45e2a3b 100644
--- a/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h
+++ b/Data/MySQL/include/Poco/Data/MySQL/ResultMetadata.h
@@ -40,6 +40,9 @@ class ResultMetadata
 	/// MySQL result metadata
 {
 public:
+	~ResultMetadata();
+		/// Destroys the ResultMetadata.
+
 	void reset();
 		/// Resets the metadata.
 
@@ -64,10 +67,15 @@ public:
 	bool isNull(std::size_t pos) const;
 		/// Returns true if value at pos is null.
 
+	void adjustColumnSizeToFit(std::size_t pos);
+		/// Expands the size allocated for column to fit the length of the data.
+
 private:
+	void freeMemory();
+
 	std::vector    _columns;
 	std::vector    _row;
-	std::vector          _buffer;
+	std::vector         _buffer;
 	std::vector _lengths;
 	std::vector      _isNull; // using char instead of bool to avoid std::vector disaster
 };
diff --git a/Data/MySQL/src/Extractor.cpp b/Data/MySQL/src/Extractor.cpp
index 0ff16d340..cb06a2d5d 100644
--- a/Data/MySQL/src/Extractor.cpp
+++ b/Data/MySQL/src/Extractor.cpp
@@ -128,9 +128,15 @@ bool Extractor::extract(std::size_t pos, std::string& val)
 
 	//mysql reports TEXT types as FDT_BLOB when being extracted
 	MetaColumn::ColumnDataType columnType = _metadata.metaColumn(static_cast(pos)).type();
-	if (columnType != Poco::Data::MetaColumn::FDT_STRING && columnType != Poco::Data::MetaColumn::FDT_BLOB)
+	if (columnType != Poco::Data::MetaColumn::FDT_STRING && columnType != Poco::Data::MetaColumn::FDT_BLOB && columnType != Poco::Data::MetaColumn::FDT_JSON)
 		throw MySQLException("Extractor: not a string");
 
+	if (columnType == Poco::Data::MetaColumn::FDT_JSON && !extractJSON(pos))
+		return false;
+
+	if (columnType == Poco::Data::MetaColumn::FDT_BLOB && !extractLongLOB(pos))
+		return false;
+
 	val.assign(reinterpret_cast(_metadata.rawData(pos)), _metadata.length(pos));
 	return true;
 }
@@ -142,11 +148,14 @@ bool Extractor::extract(std::size_t pos, Poco::Data::BLOB& val)
 		throw MySQLException("Extractor: attempt to extract more parameters, than query result contain");
 
 	if (_metadata.isNull(static_cast(pos)))
-	return false;
+		return false;
 
 	if (_metadata.metaColumn(static_cast(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
 		throw MySQLException("Extractor: not a blob");
 
+	if (_metadata.metaColumn(static_cast(pos)).length() == 0 && !extractLongLOB(pos))
+		return false;
+
 	val.assignRaw(_metadata.rawData(pos), _metadata.length(pos));
 	return true;
 }
@@ -163,6 +172,9 @@ bool Extractor::extract(std::size_t pos, Poco::Data::CLOB& val)
 	if (_metadata.metaColumn(static_cast(pos)).type() != Poco::Data::MetaColumn::FDT_BLOB)
 		throw MySQLException("Extractor: not a blob");
 
+	if (_metadata.metaColumn(static_cast(pos)).length() == 0 && !extractLongLOB(pos))
+		return false;
+
 	val.assignRaw(reinterpret_cast(_metadata.rawData(pos)), _metadata.length(pos));
 	return true;
 }
@@ -263,6 +275,37 @@ bool Extractor::realExtractFixed(std::size_t pos, enum_field_types type, void* b
 	return isNull == 0;
 }
 
+bool Extractor::extractLongLOB(std::size_t pos)
+{
+	// Large LOBs (LONGBLOB and LONGTEXT) are fetched
+	// with a zero-length buffer to avoid allocating
+	// huge amounts of memory. Therefore, when extracting
+	// the buffers need to be adjusted.
+	
+	_metadata.adjustColumnSizeToFit(pos);
+	
+	MYSQL_BIND* row = _metadata.row();
+	if (!_stmt.fetchColumn(pos, &row[pos]))
+		return false;
+	
+	return true;
+}
+
+bool Extractor::extractJSON(std::size_t pos)
+{
+	// JSON columns are fetched with a zero-length
+	// buffer to avoid allocating huge amounts of memory.
+	// Therefore, when extracting the buffers need to be adjusted.
+
+	_metadata.adjustColumnSizeToFit(pos);
+
+	MYSQL_BIND* row = _metadata.row();
+	row->buffer_type = MYSQL_TYPE_JSON;
+	if (!_stmt.fetchColumn(pos, &row[pos]))
+		return false;
+
+	return true;
+}
 
 //////////////
 // Not implemented
diff --git a/Data/MySQL/src/ResultMetadata.cpp b/Data/MySQL/src/ResultMetadata.cpp
index bcc45c3d8..33c3785ed 100644
--- a/Data/MySQL/src/ResultMetadata.cpp
+++ b/Data/MySQL/src/ResultMetadata.cpp
@@ -61,6 +61,7 @@ namespace
 		case MYSQL_TYPE_DATE:
 		case MYSQL_TYPE_TIME:
 		case MYSQL_TYPE_DATETIME:
+		case MYSQL_TYPE_TIMESTAMP:
 			return sizeof(MYSQL_TIME);
 
 		case MYSQL_TYPE_DECIMAL:
@@ -71,21 +72,22 @@ namespace
 		case MYSQL_TYPE_MEDIUM_BLOB:
 		case MYSQL_TYPE_LONG_BLOB:
 		case MYSQL_TYPE_BLOB:
+		case MYSQL_TYPE_JSON:
 			return field.length;
 
 		default:
 			throw Poco::Data::MySQL::StatementException("unknown field type");
 		}
-	}	
+	}
 
 	Poco::Data::MetaColumn::ColumnDataType fieldType(const MYSQL_FIELD& field)
-		/// Convert field MySQL-type to Poco-type	
+		/// Convert field MySQL-type to Poco-type
 	{
 		bool unsig = ((field.flags & UNSIGNED_FLAG) == UNSIGNED_FLAG);
 
 		switch (field.type)
 		{
-		case MYSQL_TYPE_TINY:     
+		case MYSQL_TYPE_TINY:
 			if (unsig) return Poco::Data::MetaColumn::FDT_UINT8;
 			return Poco::Data::MetaColumn::FDT_INT8;
 
@@ -94,31 +96,32 @@ namespace
 			return Poco::Data::MetaColumn::FDT_INT16;
 
 		case MYSQL_TYPE_INT24:
-		case MYSQL_TYPE_LONG:     
+		case MYSQL_TYPE_LONG:
 			if (unsig) return Poco::Data::MetaColumn::FDT_UINT32;
 			return Poco::Data::MetaColumn::FDT_INT32;
 
-		case MYSQL_TYPE_FLOAT:    
+		case MYSQL_TYPE_FLOAT:
 			return Poco::Data::MetaColumn::FDT_FLOAT;
 
 		case MYSQL_TYPE_DECIMAL:
 		case MYSQL_TYPE_NEWDECIMAL:
-		case MYSQL_TYPE_DOUBLE:   
+		case MYSQL_TYPE_DOUBLE:
 			return Poco::Data::MetaColumn::FDT_DOUBLE;
 
-		case MYSQL_TYPE_LONGLONG: 
+		case MYSQL_TYPE_LONGLONG:
 			if (unsig) return Poco::Data::MetaColumn::FDT_UINT64;
 			return Poco::Data::MetaColumn::FDT_INT64;
-			
+
 		case MYSQL_TYPE_DATE:
 			return Poco::Data::MetaColumn::FDT_DATE;
-			
+
 		case MYSQL_TYPE_TIME:
 			return Poco::Data::MetaColumn::FDT_TIME;
-			
+
 		case MYSQL_TYPE_DATETIME:
+		case MYSQL_TYPE_TIMESTAMP:
 			return Poco::Data::MetaColumn::FDT_TIMESTAMP;
-			
+
 		case MYSQL_TYPE_STRING:
 		case MYSQL_TYPE_VAR_STRING:
 			return Poco::Data::MetaColumn::FDT_STRING;
@@ -128,6 +131,8 @@ namespace
 		case MYSQL_TYPE_LONG_BLOB:
 		case MYSQL_TYPE_BLOB:
 			return Poco::Data::MetaColumn::FDT_BLOB;
+		case MYSQL_TYPE_JSON:
+			return Poco::Data::MetaColumn::FDT_JSON;
 		default:
 			return Poco::Data::MetaColumn::FDT_UNKNOWN;
 		}
@@ -140,8 +145,15 @@ namespace Data {
 namespace MySQL {
 
 
+ResultMetadata::~ResultMetadata()
+{
+	freeMemory();
+}
+
+
 void ResultMetadata::reset()
 {
+	freeMemory();
 	_columns.resize(0);
 	_row.resize(0);
 	_buffer.resize(0);
@@ -150,14 +162,20 @@ void ResultMetadata::reset()
 }
 
 
+void ResultMetadata::freeMemory()
+{
+	for (std::vector::iterator it = _buffer.begin(); it != _buffer.end(); ++it)
+		std::free(*it);
+}
+
+
 void ResultMetadata::init(MYSQL_STMT* stmt)
 {
 	ResultMetadataHandle h(stmt);
 
 	if (!h)
 	{
-		// all right, it is normal
-		// querys such an "INSERT INTO" just does not have result at all
+		// some queries (eg. INSERT) don't have result
 		reset();
 		return;
 	}
@@ -165,7 +183,6 @@ void ResultMetadata::init(MYSQL_STMT* stmt)
 	std::size_t count = mysql_num_fields(h);
 	MYSQL_FIELD* fields = mysql_fetch_fields(h);
 
-	std::size_t commonSize = 0;
 	_columns.reserve(count);
 
 	for (std::size_t i = 0; i < count; i++)
@@ -181,29 +198,24 @@ void ResultMetadata::init(MYSQL_STMT* stmt)
 			0,                               // TODO: precision
 			!IS_NOT_NULL(fields[i].flags)    // nullable
 			));
-
-		commonSize += _columns[i].length();
 	}
 
-	_buffer.resize(commonSize);
+	_buffer.resize(count);
 	_row.resize(count);
 	_lengths.resize(count);
 	_isNull.resize(count);
 
-	std::size_t offset = 0;
-
 	for (std::size_t i = 0; i < count; i++)
 	{
 		std::memset(&_row[i], 0, sizeof(MYSQL_BIND));
 		unsigned int len = static_cast(_columns[i].length());
+		_buffer[i] = (char*) std::calloc(len, sizeof(char));
 		_row[i].buffer_type   = fields[i].type;
 		_row[i].buffer_length = len;
-		_row[i].buffer        = (len > 0) ? (&_buffer[0] + offset) : 0;
+		_row[i].buffer        = _buffer[i];
 		_row[i].length        = &_lengths[i];
 		_row[i].is_null       = reinterpret_cast(&_isNull[i]); // workaround to make it work with both MySQL 8 and earlier
 		_row[i].is_unsigned   = (fields[i].flags & UNSIGNED_FLAG) > 0;
-		
-		offset += _row[i].buffer_length;
 	}
 }
 
@@ -232,16 +244,29 @@ std::size_t ResultMetadata::length(std::size_t pos) const
 }
 
 
-const unsigned char* ResultMetadata::rawData(std::size_t pos) const 
+const unsigned char* ResultMetadata::rawData(std::size_t pos) const
 {
+	if ((_lengths[pos] == 0) && (_row[pos].buffer == nullptr))
+		return reinterpret_cast("");
+	else
+		poco_check_ptr (_row[pos].buffer);
 	return reinterpret_cast(_row[pos].buffer);
 }
 
 
-bool ResultMetadata::isNull(std::size_t pos) const 
+bool ResultMetadata::isNull(std::size_t pos) const
 {
 	return (_isNull[pos] != 0);
 }
 
 
+void ResultMetadata::adjustColumnSizeToFit(std::size_t pos)
+{
+	std::free(_buffer[pos]);
+	_buffer[pos] = (char*) std::calloc(_lengths[pos], sizeof(char));
+	_row[pos].buffer = _buffer[pos];
+	_row[pos].buffer_length = _lengths[pos];
+}
+
+
 } } } // namespace Poco::Data::MySQL
diff --git a/Data/MySQL/src/SessionImpl.cpp b/Data/MySQL/src/SessionImpl.cpp
index 3a2c865fc..dab3ada08 100644
--- a/Data/MySQL/src/SessionImpl.cpp
+++ b/Data/MySQL/src/SessionImpl.cpp
@@ -14,6 +14,7 @@
 
 #include "Poco/Data/MySQL/SessionImpl.h"
 #include "Poco/Data/MySQL/MySQLStatementImpl.h"
+#include "Poco/Data/MySQL/Utility.h"
 #include "Poco/Data/Session.h"
 #include "Poco/NumberParser.h"
 #include "Poco/String.h"
@@ -254,8 +255,29 @@ void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
 
 Poco::UInt32 SessionImpl::getTransactionIsolation() const
 {
+	const std::string MARIADB_SERVERINFO = "MariaDB";
+
 	std::string isolation;
-	getSetting("tx_isolation", isolation);
+	std::string serverInfo = Utility::serverInfo(_handle);
+	unsigned long version = Utility::serverVersion(_handle);
+
+	if (serverInfo.find(MARIADB_SERVERINFO) != std::string::npos) //MariaDB
+	{
+		getSetting("tx_isolation", isolation);
+		isolation = isolation.c_str();
+	}
+	else //MySQL
+	{
+		if (version >= 80000)
+		{
+			getSetting("transaction_isolation", isolation);
+			isolation = isolation.c_str();
+		}
+		else
+		{
+			getSetting("tx_isolation", isolation);
+		}
+	}
 	Poco::replaceInPlace(isolation, "-", " ");
 	if (MYSQL_READ_UNCOMMITTED == isolation)
 		return Session::TRANSACTION_READ_UNCOMMITTED;
diff --git a/Data/MySQL/testsuite/TestSuite_vs170.vcxproj b/Data/MySQL/testsuite/TestSuite_vs170.vcxproj
index 7298ffe2f..146f19de2 100644
--- a/Data/MySQL/testsuite/TestSuite_vs170.vcxproj
+++ b/Data/MySQL/testsuite/TestSuite_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     TestSuite
     {4D6E42AE-EB6A-47EB-A186-B8A183FABCF7}
     TestSuite
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
   
     Application
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    TestSuited
+    TestSuited
+    TestSuited
+    TestSuite
+    TestSuite
+    TestSuite
     TestSuited
     TestSuited
     TestSuited
@@ -171,6 +250,36 @@
     TestSuite
     TestSuite
   
+  
+    binA64\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
+  
+    binA64\static_mt\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\static_mt\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
+  
+    binA64\static_md\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\static_md\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
   
     bin\
     obj\TestSuite\$(Configuration)\
@@ -231,6 +340,189 @@
     obj64\TestSuite\$(Configuration)\
     false
   
+  
+    
+      Disabled
+      ..\include;..\..\..\CppUnit\include;..\..\..\mysql\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitd.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\TestSuited.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\..\CppUnit\include;..\..\..\mysql\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnit.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\TestSuite.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      ..\include;..\..\..\CppUnit\include;..\..\..\mysql\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitmtd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_mt\TestSuited.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\static_mt\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\..\CppUnit\include;..\..\..\mysql\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnitmt.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_mt\TestSuite.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      ..\include;..\..\..\CppUnit\include;..\..\..\mysql\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitmdd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_md\TestSuited.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\static_md\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\..\CppUnit\include;..\..\..\mysql\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnitmd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_md\TestSuite.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
   
     
       Disabled
diff --git a/Data/MySQL/testsuite/run-db-setup.sh b/Data/MySQL/testsuite/run-db-setup.sh
new file mode 100755
index 000000000..c675b58c8
--- /dev/null
+++ b/Data/MySQL/testsuite/run-db-setup.sh
@@ -0,0 +1,15 @@
+#!/bin/bash
+#apt-get install mariadb-server
+USER=pocotest
+PASS=pocotest
+
+mysql -uroot <date();
 	recreatePersonTimeTable();
 	_pExecutor->time();
+	recreatePersonTimestampTable();
+	_pExecutor->timestamp();
 }
 
 
@@ -469,6 +471,31 @@ void MySQLTest::testBLOBStmt()
 }
 
 
+void MySQLTest::testLongBLOB()
+{
+	if (!_pSession) fail ("Test not available.");
+
+	recreatePersonLongBLOBTable();
+	_pExecutor->longBlob();
+}
+
+void MySQLTest::testLongTEXT()
+{
+	if (!_pSession) fail ("Test not available.");
+
+	recreatePersonLongBLOBTable();
+	_pExecutor->longText();
+}
+
+void MySQLTest::testJSON()
+{
+	if (!_pSession) fail("Test not available.");
+
+	recreatePersonJSONTable();
+	_pExecutor->json();
+}
+
+
 void MySQLTest::testUnsignedInts()
 {
 	if (!_pSession) fail ("Test not available.");
@@ -752,6 +779,33 @@ void MySQLTest::recreatePersonTimeTable()
 }
 
 
+void MySQLTest::recreatePersonTimestampTable()
+{
+	dropTable("Person");
+	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Birthday TIMESTAMP(6))", now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonTimestampTable()"); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonTimestampTable()"); }
+}
+
+
+void MySQLTest::recreatePersonLongBLOBTable()
+{
+	dropTable("Person");
+	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Biography LONGTEXT)", now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail ("recreatePersonLongBLOBTable()"); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail ("recreatePersonLongBLOBTable()"); }
+}
+
+
+void MySQLTest::recreatePersonJSONTable()
+{
+	dropTable("Person");
+	try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Biography JSON)", now; }
+	catch (ConnectionException& ce) { std::cout << ce.displayText() << std::endl; fail("recreatePersonJSONTable()"); }
+	catch (StatementException& se) { std::cout << se.displayText() << std::endl; fail("recreatePersonJSONTable()"); }
+}
+
+
 void MySQLTest::recreateIntsTable()
 {
 	dropTable("Strings");
@@ -919,6 +973,9 @@ CppUnit::Test* MySQLTest::suite()
 	CppUnit_addTest(pSuite, MySQLTest, testDateTime);
 	//CppUnit_addTest(pSuite, MySQLTest, testBLOB);
 	CppUnit_addTest(pSuite, MySQLTest, testBLOBStmt);
+	CppUnit_addTest(pSuite, MySQLTest, testLongBLOB);
+	CppUnit_addTest(pSuite, MySQLTest, testLongTEXT);
+	CppUnit_addTest(pSuite, MySQLTest, testJSON);
 	CppUnit_addTest(pSuite, MySQLTest, testUnsignedInts);
 	CppUnit_addTest(pSuite, MySQLTest, testFloat);
 	CppUnit_addTest(pSuite, MySQLTest, testDouble);
diff --git a/Data/MySQL/testsuite/src/MySQLTest.h b/Data/MySQL/testsuite/src/MySQLTest.h
index 150401c41..8afdfb2d2 100644
--- a/Data/MySQL/testsuite/src/MySQLTest.h
+++ b/Data/MySQL/testsuite/src/MySQLTest.h
@@ -79,6 +79,9 @@ public:
 	void testDateTime();
 	void testBLOB();
 	void testBLOBStmt();
+	void testLongBLOB();
+	void testLongTEXT();
+	void testJSON();
 
 	void testUnsignedInts();
 	void testFloat();
@@ -117,6 +120,9 @@ private:
 	void recreatePersonDateTimeTable();
 	void recreatePersonDateTable();
 	void recreatePersonTimeTable();
+	void recreatePersonTimestampTable();
+	void recreatePersonLongBLOBTable();
+	void recreatePersonJSONTable();
 	void recreateStringsTable();
 	void recreateIntsTable();
 	void recreateUnsignedIntsTable();
diff --git a/Data/MySQL/testsuite/src/SQLExecutor.cpp b/Data/MySQL/testsuite/src/SQLExecutor.cpp
index 27beb6f44..6c036b9b4 100644
--- a/Data/MySQL/testsuite/src/SQLExecutor.cpp
+++ b/Data/MySQL/testsuite/src/SQLExecutor.cpp
@@ -1364,6 +1364,34 @@ void SQLExecutor::time()
 }
 
 
+void SQLExecutor::timestamp()
+{
+	std::string funct = "timestamp()";
+	std::string lastName("Bart");
+	std::string firstName("Simpson");
+	std::string address("Springfield");
+	DateTime birthday(1980, 4, 1, 5, 45, 12, 354, 879);
+	
+	int count = 0;
+	try { *_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(birthday), now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	assertTrue (count == 1);
+	
+	DateTime bd;
+	assertTrue (bd != birthday);
+	try { *_pSession << "SELECT Birthday FROM Person", into(bd), now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	assertTrue (bd == birthday);
+	
+	std::cout << std::endl << RecordSet(*_pSession, "SELECT * FROM Person");
+}
+
+
 void SQLExecutor::blob(unsigned int bigSize)
 {
 	std::string funct = "blob()";
@@ -1435,6 +1463,82 @@ void SQLExecutor::blobStmt()
 }
 
 
+void SQLExecutor::longBlob()
+{
+	std::string funct = "longBlob()";
+	std::string lastName("lastname");
+	std::string firstName("firstname");
+	std::string address("Address");
+	Poco::Data::CLOB biography("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 123);
+
+	int count = 0;
+	Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(biography));
+	ins.execute();
+	try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	assertTrue (count == 1);
+
+	Poco::Data::CLOB res;
+	poco_assert (res.size() == 0);
+	Statement stmt = (*_pSession << "SELECT Biography FROM Person", into(res));
+	try { stmt.execute(); }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	poco_assert (res == biography);
+}
+
+void SQLExecutor::longText()
+{
+	std::string funct = "longText()";
+	std::string lastName("lastname");
+	std::string firstName("firstname");
+	std::string address("Address");
+	std::string biography("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", 123);
+
+	int count = 0;
+	Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(biography));
+	ins.execute();
+	try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	assertTrue (count == 1);
+
+	std::string longTextRes;
+	poco_assert (longTextRes.size() == 0);
+	Statement stmt = (*_pSession << "SELECT Biography FROM Person", into(longTextRes));
+	try { stmt.execute(); }
+	catch(ConnectionException& ce){ std::cout << ce.displayText() << std::endl; fail (funct); }
+	catch(StatementException& se){ std::cout << se.displayText() << std::endl; fail (funct); }
+	poco_assert (longTextRes == biography);
+}
+
+void SQLExecutor::json()
+{
+	std::string funct = "json()";
+	std::string lastName("lastname");
+	std::string firstName("firstname");
+	std::string address("Address");
+	std::string biography(R"({"biography": {"count": 42, "title": "Lorem Ipsum", "released": true}})");
+
+	int count = 0;
+	Statement ins = (*_pSession << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(biography));
+	ins.execute();
+	try { *_pSession << "SELECT COUNT(*) FROM Person", into(count), now; }
+	catch (ConnectionException& ce) { std::cout << ce.displayText() << std::endl; fail(funct); }
+	catch (StatementException& se) { std::cout << se.displayText() << std::endl; fail(funct); }
+	assertTrue(count == 1);
+
+	Poco::Data::JSON res;
+	poco_assert(res.size() == 0);
+	Statement stmt = (*_pSession << "SELECT Biography FROM Person", into(res));
+	try { stmt.execute(); }
+	catch (ConnectionException& ce) { std::cout << ce.displayText() << std::endl; fail(funct); }
+	catch (StatementException& se) { std::cout << se.displayText() << std::endl; fail(funct); }
+	poco_assert(res == biography);
+}
+
+
 void SQLExecutor::tuples()
 {
 	typedef Tuple TupleType;
diff --git a/Data/MySQL/testsuite/src/SQLExecutor.h b/Data/MySQL/testsuite/src/SQLExecutor.h
index 03e4ffe24..0bec61457 100644
--- a/Data/MySQL/testsuite/src/SQLExecutor.h
+++ b/Data/MySQL/testsuite/src/SQLExecutor.h
@@ -83,6 +83,10 @@ public:
 	void dateTime();
 	void date();
 	void time();
+	void timestamp();
+	void longBlob();
+	void longText();
+	void json();
 	void unsignedInts();
 	void floats();
 	void doubles();
diff --git a/Data/ODBC/CMakeLists.txt b/Data/ODBC/CMakeLists.txt
index 98cd133b8..764f6a501 100644
--- a/Data/ODBC/CMakeLists.txt
+++ b/Data/ODBC/CMakeLists.txt
@@ -25,7 +25,7 @@ target_link_libraries(DataODBC PUBLIC Poco::Data ODBC::ODBC)
 target_include_directories(DataODBC
 	PUBLIC
 		$
-		$
+		$
 	PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src
 )
 target_compile_definitions(DataODBC PUBLIC THREADSAFE)
diff --git a/Data/ODBC/Makefile b/Data/ODBC/Makefile
index 00e86dc45..180a72b70 100644
--- a/Data/ODBC/Makefile
+++ b/Data/ODBC/Makefile
@@ -10,7 +10,7 @@ include ODBC.make
 
 objects = Binder ConnectionHandle Connector EnvironmentHandle \
 	Extractor ODBCException ODBCMetaColumn ODBCStatementImpl \
-	Parameter Preparator SessionImpl TypeInfo Unicode Utility 
+	Parameter Preparator SessionImpl TypeInfo Unicode Utility
 
 target         = PocoDataODBC
 target_version = $(LIBVERSION)
diff --git a/Data/ODBC/ODBC_vs170.sln b/Data/ODBC/ODBC_vs170.sln
index 9188c5035..c591617b5 100644
--- a/Data/ODBC/ODBC_vs170.sln
+++ b/Data/ODBC/ODBC_vs170.sln
@@ -9,6 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\Test
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		debug_shared|ARM64 = debug_shared|ARM64
+		release_shared|ARM64 = release_shared|ARM64
+		debug_static_mt|ARM64 = debug_static_mt|ARM64
+		release_static_mt|ARM64 = release_static_mt|ARM64
+		debug_static_md|ARM64 = debug_static_md|ARM64
+		release_static_md|ARM64 = release_static_md|ARM64
 		debug_shared|Win32 = debug_shared|Win32
 		release_shared|Win32 = release_shared|Win32
 		debug_static_mt|Win32 = debug_static_mt|Win32
@@ -23,6 +29,24 @@ Global
 		release_static_md|x64 = release_static_md|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{1B29820D-375F-11DB-837B-00123FC423B5}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
@@ -59,6 +83,24 @@ Global
 		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_md|x64.ActiveCfg = release_static_md|x64
 		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_md|x64.Build.0 = release_static_md|x64
 		{1B29820D-375F-11DB-837B-00123FC423B5}.release_static_md|x64.Deploy.0 = release_static_md|x64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{00627063-395B-4413-9099-23BDB56562FA}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{00627063-395B-4413-9099-23BDB56562FA}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{00627063-395B-4413-9099-23BDB56562FA}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{00627063-395B-4413-9099-23BDB56562FA}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
diff --git a/Data/ODBC/ODBC_vs170.vcxproj b/Data/ODBC/ODBC_vs170.vcxproj
index 24c28c8e6..52b5e120f 100644
--- a/Data/ODBC/ODBC_vs170.vcxproj
+++ b/Data/ODBC/ODBC_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     ODBC
     {1B29820D-375F-11DB-837B-00123FC423B5}
     ODBC
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
   
     StaticLibrary
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    PocoDataODBCA64d
+    PocoDataODBCmdd
+    PocoDataODBCmtd
+    PocoDataODBCA64
+    PocoDataODBCmd
+    PocoDataODBCmt
     PocoDataODBCd
     PocoDataODBCmdd
     PocoDataODBCmtd
@@ -171,6 +250,32 @@
     PocoDataODBCmd
     PocoDataODBCmt
   
+  
+    ..\..\binA64\
+    objA64\ODBC\$(Configuration)\
+    true
+  
+  
+    ..\..\binA64\
+    objA64\ODBC\$(Configuration)\
+    false
+  
+  
+    ..\..\libA64\
+    objA64\ODBC\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\ODBC\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\ODBC\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\ODBC\$(Configuration)\
+  
   
     ..\..\bin\
     obj\ODBC\$(Configuration)\
@@ -223,6 +328,166 @@
     ..\..\lib64\
     obj64\ODBC\$(Configuration)\
   
+  
+    
+      Disabled
+      .\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;_USRDLL;THREADSAFE;ODBC_EXPORTS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+      ..\..\binA64\PocoDataODBCA64d.dll
+      true
+      true
+      ..\..\binA64\PocoDataODBCA64d.pdb
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      ..\..\libA64\PocoDataODBCd.lib
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;_USRDLL;THREADSAFE;ODBC_EXPORTS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
+      ..\..\binA64\PocoDataODBCA64.dll
+      true
+      false
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      true
+      true
+      ..\..\libA64\PocoDataODBC.lib
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      .\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      ..\..\libA64\PocoDataODBCmtd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataODBCmtd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataODBCmt.lib
+    
+  
+  
+    
+      Disabled
+      .\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      ..\..\libA64\PocoDataODBCmdd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataODBCmdd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataODBCmd.lib
+    
+  
   
     
       Disabled
@@ -608,31 +873,43 @@
       true
     
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
       true
     
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
       true
@@ -643,12 +920,16 @@
   
   
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
     
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Binder.h b/Data/ODBC/include/Poco/Data/ODBC/Binder.h
index 94293c91c..473691b29 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Binder.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Binder.h
@@ -71,7 +71,9 @@ public:
 	Binder(const StatementHandle& rStmt,
 		std::size_t maxFieldSize,
 		ParameterBinding dataBinding = PB_IMMEDIATE,
-		const TypeInfo* pDataTypes = 0);
+		const TypeInfo* pDataTypes = 0,
+		Poco::TextEncoding::Ptr pFromEncoding = nullptr,
+		Poco::TextEncoding::Ptr pDBEncoding = nullptr);
 		/// Creates the Binder.
 
 	~Binder();
@@ -538,7 +540,7 @@ private:
 	}
 
 	template 
-	void bindImplContainerString(std::size_t pos, const C& val, Direction dir)
+	void bindImplContainerString(std::size_t pos, const C& valC, Direction dir)
 		/// Utility function to bind containers of strings.
 	{
 		if (isOutBound(dir) || !isInBound(dir))
@@ -547,7 +549,19 @@ private:
 		if (PB_IMMEDIATE != _paramBinding)
 			throw InvalidAccessException("Containers can only be bound immediately.");
 
-		std::size_t length = val.size();
+		const C* pVal = 0;
+		if (!transcodeRequired()) pVal = &valC;
+		else
+		{
+			pVal = new C(valC.size());
+			typename C::const_iterator valIt = valC.begin();
+			typename C::const_iterator valEnd = valC.end();
+			typename C::iterator tcIt = const_cast(pVal)->begin();
+			for (; valIt != valEnd; ++valIt, ++tcIt)
+				transcode(*valIt, *tcIt);
+		}
+
+		std::size_t length = pVal->size();
 
 		if (0 == length)
 			throw InvalidArgumentException("Empty container not allowed.");
@@ -560,7 +574,7 @@ private:
 
 		if (size == _maxFieldSize)
 		{
-			getMinValueSize(val, size);
+			getMinValueSize(*pVal, size);
 			// accomodate for terminating zero
 			if (size != _maxFieldSize) ++size;
 		}
@@ -574,20 +588,25 @@ private:
 		if (_charPtrs.size() <= pos)
 			_charPtrs.resize(pos + 1, 0);
 
-		_charPtrs[pos] = (char*) std::calloc(val.size() * size, sizeof(char));
+		_charPtrs[pos] = (char*) std::calloc(pVal->size() * size, sizeof(char));
 
+		std::string typeID = typeid(*pVal).name();
 		std::size_t strSize;
 		std::size_t offset = 0;
-		typename C::const_iterator it = val.begin();
-		typename C::const_iterator end = val.end();
+		typename C::const_iterator it = pVal->begin();
+		typename C::const_iterator end = pVal->end();
 		for (; it != end; ++it)
 		{
 			strSize = it->size();
 			if (strSize > size)
-				throw LengthExceededException("SQLBindParameter(std::vector)");
+			{
+				if (transcodeRequired()) delete pVal;
+				throw LengthExceededException(Poco::format("SQLBindParameter(%s)", typeID));
+			}
 			std::memcpy(_charPtrs[pos] + offset, it->c_str(), strSize);
 			offset += size;
 		}
+		if (transcodeRequired()) delete pVal;
 
 		if (Utility::isError(SQLBindParameter(_rStmt,
 			(SQLUSMALLINT) pos + 1,
@@ -600,7 +619,7 @@ private:
 			(SQLINTEGER) size,
 			&(*_vecLengthIndicator[pos])[0])))
 		{
-			throw StatementException(_rStmt, "SQLBindParameter(std::vector)");
+			throw StatementException(_rStmt, Poco::format("SQLBindParameter(%s)", typeID));
 		}
 	}
 
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Connector.h b/Data/ODBC/include/Poco/Data/ODBC/Connector.h
index 8849bf775..6ddfedf75 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Connector.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Connector.h
@@ -58,7 +58,7 @@ public:
 		///
 		/// This can cause issues with SQL Server, resulting in an error
 		/// ("The data types varchar and text are incompatible in the equal to operator")
-		/// when comparing against a VARCHAR. 
+		/// when comparing against a VARCHAR.
 		///
 		/// Set this to false to bind std::string to SQL_VARCHAR.
 		///
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Diagnostics.h b/Data/ODBC/include/Poco/Data/ODBC/Diagnostics.h
index 86c15fa42..818be4a1e 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Diagnostics.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Diagnostics.h
@@ -36,7 +36,7 @@ template 
 class Diagnostics
 	/// Utility class providing functionality for retrieving ODBC diagnostic
 	/// records. Diagnostics object must be created with corresponding handle
-	/// as constructor argument. During construction, diagnostic records fields 
+	/// as constructor argument. During construction, diagnostic records fields
 	/// are populated and the object is ready for querying.
 {
 public:
@@ -92,7 +92,7 @@ public:
 	}
 
 	std::string connectionName() const
-		/// Returns the connection name. 
+		/// Returns the connection name.
 		/// If there is no active connection, connection name defaults to NONE.
 		/// If connection name is not applicable for query context (such as when querying environment handle),
 		/// connection name defaults to NOT_APPLICABLE.
@@ -146,54 +146,54 @@ public:
 
 		reset();
 
-		while (!Utility::isError(SQLGetDiagRec(handleType, 
-			_handle, 
-			count, 
-			df._sqlState, 
-			&df._nativeError, 
-			df._message, 
-			SQL_MESSAGE_LENGTH, 
-			&messageLength))) 
+		while (!Utility::isError(SQLGetDiagRec(handleType,
+			_handle,
+			count,
+			df._sqlState,
+			&df._nativeError,
+			df._message,
+			SQL_MESSAGE_LENGTH,
+			&messageLength)))
 		{
 			if (1 == count)
 			{
 				// success of the following two calls is optional
 				// (they fail if connection has not been established yet
 				//  or return empty string if not applicable for the context)
-				if (Utility::isError(SQLGetDiagField(handleType, 
-					_handle, 
-					count, 
-					SQL_DIAG_CONNECTION_NAME, 
-					_connectionName, 
-					sizeof(_connectionName), 
+				if (Utility::isError(SQLGetDiagField(handleType,
+					_handle,
+					count,
+					SQL_DIAG_CONNECTION_NAME,
+					_connectionName,
+					sizeof(_connectionName),
 					&messageLength)))
 				{
-					std::size_t len = sizeof(_connectionName) > none.length() ? 
+					std::size_t len = sizeof(_connectionName) > none.length() ?
 						none.length() : sizeof(_connectionName) - 1;
 					std::memcpy(_connectionName, none.c_str(), len);
 				}
-				else if (0 == _connectionName[0]) 
+				else if (0 == _connectionName[0])
 				{
-					std::size_t len = sizeof(_connectionName) > na.length() ? 
+					std::size_t len = sizeof(_connectionName) > na.length() ?
 						na.length() : sizeof(_connectionName) - 1;
 					std::memcpy(_connectionName, na.c_str(), len);
 				}
-				
-				if (Utility::isError(SQLGetDiagField(handleType, 
-					_handle, 
-					count, 
-					SQL_DIAG_SERVER_NAME, 
-					_serverName, 
-					sizeof(_serverName), 
+
+				if (Utility::isError(SQLGetDiagField(handleType,
+					_handle,
+					count,
+					SQL_DIAG_SERVER_NAME,
+					_serverName,
+					sizeof(_serverName),
 					&messageLength)))
 				{
-					std::size_t len = sizeof(_serverName) > none.length() ? 
+					std::size_t len = sizeof(_serverName) > none.length() ?
 						none.length() : sizeof(_serverName) - 1;
 					std::memcpy(_serverName, none.c_str(), len);
 				}
-				else if (0 == _serverName[0]) 
+				else if (0 == _serverName[0])
 				{
-					std::size_t len = sizeof(_serverName) > na.length() ? 
+					std::size_t len = sizeof(_serverName) > na.length() ?
 						na.length() : sizeof(_serverName) - 1;
 					std::memcpy(_serverName, na.c_str(), len);
 				}
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Error.h b/Data/ODBC/include/Poco/Data/ODBC/Error.h
index 049cc02d1..8afc08468 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Error.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Error.h
@@ -66,11 +66,11 @@ public:
 	std::string& toString(int index, std::string& str) const
 		/// Generates the string for the diagnostic record.
 	{
-		if ((index < 0) || (index > (count() - 1))) 
+		if ((index < 0) || (index > (count() - 1)))
 			return str;
 
 		std::string s;
-		Poco::format(s, 
+		Poco::format(s,
 			"===========================\n"
 			"ODBC Diagnostic record #%d:\n"
 			"===========================\n"
@@ -90,7 +90,7 @@ public:
 	{
 		std::string str;
 
-		Poco::format(str, 
+		Poco::format(str,
 			"Connection:%s\nServer:%s\n",
 			_diagnostics.connectionName(),
 			_diagnostics.serverName());
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h
index 1779cb618..eff01dda5 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Extractor.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Extractor.h
@@ -33,7 +33,6 @@
 #include "Poco/Nullable.h"
 #include "Poco/UTFString.h"
 #include "Poco/TextEncoding.h"
-#include "Poco/TextConverter.h"
 #include "Poco/Exception.h"
 #include 
 #ifdef POCO_OS_FAMILY_WINDOWS
@@ -56,7 +55,8 @@ public:
 
 	Extractor(const StatementHandle& rStmt,
 		Preparator::Ptr pPreparator,
-		Poco::TextEncoding::Ptr pDBEncoding = nullptr);
+		Poco::TextEncoding::Ptr pDBEncoding = nullptr,
+		Poco::TextEncoding::Ptr pToEncoding = nullptr);
 		/// Creates the Extractor.
 
 	~Extractor();
@@ -592,11 +592,10 @@ private:
 		val.clear();
 		if (ret)
 		{
-			Poco::TextConverter conv(*_pDBEncoding, *_pToEncoding);
 			val.resize(res.size());
 			typename C::iterator vIt = val.begin();
 			typename C::iterator it = res.begin();
-			for (; it != res.end(); ++it, ++vIt) conv.convert(*it, *vIt);
+			for (; it != res.end(); ++it, ++vIt) transcode(*it, *vIt);
 		}
 		return ret;
 	}
@@ -607,7 +606,7 @@ private:
 		bool ret = false;
 		if (Preparator::DE_BOUND == _dataExtraction)
 		{
-			if (!_transcode)
+			if (!transcodeRequired())
 				ret = extractBoundImplContainer(pos, val);
 			else
 				ret = stringContainerExtractConvert(pos, val);
@@ -628,9 +627,6 @@ private:
 	PreparatorPtr              _pPreparator;
 	Preparator::DataExtraction _dataExtraction;
 	std::vector        _lengths;
-	Poco::TextEncoding::Ptr    _pDBEncoding;
-	bool                       _transcode;
-	Poco::TextEncoding::Ptr    _pToEncoding;
 };
 
 
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Handle.h b/Data/ODBC/include/Poco/Data/ODBC/Handle.h
index 962ffe6c8..9d9dbc60c 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Handle.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Handle.h
@@ -39,14 +39,14 @@ class Handle
 /// ODBC handle class template
 {
 public:
-	Handle(const ConnectionHandle& rConnection): 
+	Handle(const ConnectionHandle& rConnection):
 		_rConnection(rConnection),
 		_handle(0)
 			/// Creates the Handle.
 	{
-		if (Utility::isError(SQLAllocHandle(handleType, 
-			_rConnection, 
-			&_handle))) 
+		if (Utility::isError(SQLAllocHandle(handleType,
+			_rConnection,
+			&_handle)))
 		{
 			throw ODBCException("Could not allocate statement handle.");
 		}
@@ -58,7 +58,7 @@ public:
 		try
 		{
 #if defined(_DEBUG)
-			SQLRETURN rc = 
+			SQLRETURN rc =
 #endif
 			SQLFreeHandle(handleType, _handle);
 			// N.B. Destructors should not throw, but neither do we want to
diff --git a/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h b/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h
index cc9df6d36..374f34dfe 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/ODBCMetaColumn.h
@@ -39,15 +39,15 @@ class ODBC_API ODBCMetaColumn: public MetaColumn
 public:
 	explicit ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
 		/// Creates the ODBCMetaColumn.
-		
+
 	~ODBCMetaColumn();
 		/// Destroys the ODBCMetaColumn.
 
 	std::size_t dataLength() const;
-		/// A numeric value that is either the maximum or actual character length of a character 
-		/// string or binary data type. It is the maximum character length for a fixed-length data type, 
-		/// or the actual character length for a variable-length data type. Its value always excludes the 
-		/// null-termination byte that ends the character string. 
+		/// A numeric value that is either the maximum or actual character length of a character
+		/// string or binary data type. It is the maximum character length for a fixed-length data type,
+		/// or the actual character length for a variable-length data type. Its value always excludes the
+		/// null-termination byte that ends the character string.
 		/// This information is returned from the SQL_DESC_LENGTH record field of the IRD.
 
 	bool isUnsigned() const;
diff --git a/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h b/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h
index e3a6492ca..db83e6d2d 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/ODBCStatementImpl.h
@@ -76,7 +76,7 @@ protected:
 		/// Returns true if another compile is possible.
 
 	void compileImpl();
-		/// Compiles the statement, doesn't bind yet. 
+		/// Compiles the statement, doesn't bind yet.
 		/// Does nothing if the statement has already been compiled.
 
 	void bindImpl();
@@ -101,12 +101,12 @@ private:
 	typedef std::vector         ExtractorVec;
 	typedef std::vector      ColumnPtrVec;
 	typedef std::vector         ColumnPtrVecVec;
-	
+
 	static const std::string INVALID_CURSOR_STATE;
 
 	void clear();
 		/// Closes the cursor and resets indicator variables.
-	
+
 	void doBind();
 		/// Binds parameters.
 
@@ -119,8 +119,8 @@ private:
 	void doPrepare();
 		/// Prepares placeholders for data returned by statement.
 		/// It is called during statement compilation for SQL statements
-		/// returning data. For stored procedures returning datasets, 
-		/// it is called upon the first check for data availability 
+		/// returning data. For stored procedures returning datasets,
+		/// it is called upon the first check for data availability
 		/// (see hasNext() function).
 
 	bool hasData() const;
@@ -133,8 +133,8 @@ private:
 		/// Returns true if there is a row fetched but not yet extracted.
 
 	void putData();
-		/// Called whenever SQLExecute returns SQL_NEED_DATA. This is expected 
-		/// behavior for PB_AT_EXEC binding mode. 
+		/// Called whenever SQLExecute returns SQL_NEED_DATA. This is expected
+		/// behavior for PB_AT_EXEC binding mode.
 
 	void addPreparator();
 	void fillColumns();
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Parameter.h b/Data/ODBC/include/Poco/Data/ODBC/Parameter.h
index e9f11bdb5..6afc4fec1 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Parameter.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Parameter.h
@@ -36,7 +36,7 @@ class ODBC_API Parameter
 public:
 	explicit Parameter(const StatementHandle& rStmt, std::size_t colNum);
 		/// Creates the Parameter.
-		
+
 	~Parameter();
 		/// Destroys the Parameter.
 
@@ -47,11 +47,11 @@ public:
 		/// Returns the SQL data type.
 
 	std::size_t columnSize() const;
-		/// Returns the the size of the column or expression of the corresponding 
+		/// Returns the the size of the column or expression of the corresponding
 		/// parameter marker as defined by the data source.
 
 	std::size_t decimalDigits() const;
-		/// Returns the number of decimal digits of the column or expression 
+		/// Returns the number of decimal digits of the column or expression
 		/// of the corresponding parameter as defined by the data source.
 
 	bool isNullable() const;
diff --git a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
index 0b132cbc7..d67269816 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/SessionImpl.h
@@ -54,15 +54,15 @@ public:
 
 	SessionImpl(const std::string& connect,
 		std::size_t loginTimeout,
-		std::size_t maxFieldSize = ODBC_MAX_FIELD_SIZE, 
+		std::size_t maxFieldSize = ODBC_MAX_FIELD_SIZE,
 		bool autoBind = true,
 		bool autoExtract = true);
 		/// Creates the SessionImpl. Opens a connection to the database.
 		/// Throws NotConnectedException if connection was not succesful.
 
 	//@ deprecated
-	SessionImpl(const std::string& connect, 
-		Poco::Any maxFieldSize = ODBC_MAX_FIELD_SIZE, 
+	SessionImpl(const std::string& connect,
+		Poco::Any maxFieldSize = ODBC_MAX_FIELD_SIZE,
 		bool enforceCapability=false,
 		bool autoBind = true,
 		bool autoExtract = true);
@@ -144,7 +144,7 @@ public:
 
 	void setMaxFieldSize(const std::string& rName, const Poco::Any& rValue);
 		/// Sets the max field size (the default used when column size is unknown).
-		
+
 	Poco::Any getMaxFieldSize(const std::string& rName="") const;
 		/// Returns the max field size (the default used when column size is unknown).
 
@@ -154,11 +154,11 @@ public:
 	void setQueryTimeout(const std::string&, const Poco::Any& value);
 		/// Sets the timeout (in seconds) for queries.
 		/// Value must be of type int.
-		
+
 	Poco::Any getQueryTimeout(const std::string&) const;
 		/// Returns the timeout (in seconds) for queries,
 		/// or -1 if no timeout has been set.
-		
+
 	int queryTimeout() const;
 		/// Returns the timeout (in seconds) for queries,
 		/// or -1 if no timeout has been set.
@@ -230,7 +230,7 @@ inline void SessionImpl::setMaxFieldSize(const std::string& rName, const Poco::A
 	_maxFieldSize = rValue;
 }
 
-		
+
 inline Poco::Any SessionImpl::getMaxFieldSize(const std::string& rName) const
 {
 	return _maxFieldSize;
@@ -242,7 +242,7 @@ inline void SessionImpl::setDataTypeInfo(const std::string& rName, const Poco::A
 	throw InvalidAccessException();
 }
 
-		
+
 inline Poco::Any SessionImpl::dataTypeInfo(const std::string& rName) const
 {
 	return &_dataTypes;
diff --git a/Data/ODBC/include/Poco/Data/ODBC/TypeInfo.h b/Data/ODBC/include/Poco/Data/ODBC/TypeInfo.h
index f8b14a801..043bf7e72 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/TypeInfo.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/TypeInfo.h
@@ -89,12 +89,12 @@ public:
 		/// Returns information about specified data type as specified by parameter 'type'.
 		/// The requested information is specified by parameter 'param'.
 		/// Will fail with a Poco::NotFoundException thrown if the param is not found
-		
+
 	bool tryGetInfo(SQLSMALLINT type, const std::string& param, DynamicAny& result) const;
 		/// Returns information about specified data type as specified by parameter 'type' in param result.
 		/// The requested information is specified by parameter 'param'.
 		/// Will return false if the param is not found. The value of result will be not changed in this case.
-			
+
 
 	void print(std::ostream& ostr);
 		/// Prints all the types (as reported by the underlying database)
@@ -104,8 +104,8 @@ private:
 	void fillCTypes();
 	void fillSQLTypes();
 
-	DataTypeMap _cDataTypes; 
-	DataTypeMap _sqlDataTypes; 
+	DataTypeMap _cDataTypes;
+	DataTypeMap _sqlDataTypes;
 	TypeInfoVec _typeInfo;
 	SQLHDBC*    _pHDBC;
 };
diff --git a/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h b/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h
index 2cd237b94..8c22d31cc 100644
--- a/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h
+++ b/Data/ODBC/include/Poco/Data/ODBC/Unicode_WIN32.h
@@ -27,7 +27,7 @@ inline void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::wstring& target
 	/// Utility function for conversion from UTF-8 to UTF-16
 {
 	int len = length;
-	if (SQL_NTS == len) 
+	if (SQL_NTS == len)
 		len = (int) std::strlen((const char *) pSQLChar);
 
 	UnicodeConverter::toUTF16((const char *) pSQLChar, len, target);
@@ -45,7 +45,7 @@ inline void makeUTF8(Poco::Buffer& buffer, SQLINTEGER length, SQLPOINTE
 	length /= sizeof(wchar_t);
 	std::string result;
 	UnicodeConverter::toUTF8(buffer.begin(), length, result);
-	
+
 	std::memset(pTarget, 0, targetLength);
 #if defined(_MSC_VER)
 #pragma warning(push)
diff --git a/Data/ODBC/src/Binder.cpp b/Data/ODBC/src/Binder.cpp
index 28cf42fc2..9908d3c30 100644
--- a/Data/ODBC/src/Binder.cpp
+++ b/Data/ODBC/src/Binder.cpp
@@ -30,7 +30,10 @@ namespace ODBC {
 Binder::Binder(const StatementHandle& rStmt,
 	std::size_t maxFieldSize,
 	Binder::ParameterBinding dataBinding,
-	const TypeInfo* pDataTypes):
+	const TypeInfo* pDataTypes,
+	Poco::TextEncoding::Ptr pFromEncoding,
+	Poco::TextEncoding::Ptr pDBEncoding):
+	Poco::Data::AbstractBinder(pFromEncoding, pDBEncoding),
 	_rStmt(rStmt),
 	_paramBinding(dataBinding),
 	_pTypeInfo(pDataTypes),
@@ -99,13 +102,30 @@ void Binder::freeMemory()
 	DateTimeVecVec::iterator itDateTimeVec = _dateTimeVecVec.begin();
 	DateTimeVecVec::iterator itDateTimeVecEnd = _dateTimeVecVec.end();
 	for (; itDateTimeVec != itDateTimeVecEnd; ++itDateTimeVec) delete *itDateTimeVec;
+
+	if (transcodeRequired() && _inParams.size())
+	{
+		ParamMap::iterator itInParams = _inParams.begin();
+		ParamMap::iterator itInParamsEnd = _inParams.end();
+		for (; itInParams != itInParamsEnd; ++itInParams) free(itInParams->first);
+	}
 }
 
 
 void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
 {
+	char* pTCVal = 0;
+	SQLINTEGER size = 0;
+	if (transcodeRequired())
+	{
+		std::string tcVal;
+		transcode(val, tcVal);
+		size = (SQLINTEGER)tcVal.size();
+		pTCVal = reinterpret_cast(std::calloc((size_t)size+1, 1));
+		std::memcpy(pTCVal, tcVal.data(), size);
+	}
+	else size = (SQLINTEGER)val.size();
 	SQLPOINTER pVal = 0;
-	SQLINTEGER size = (SQLINTEGER) val.size();
 	SQLINTEGER colSize = 0;
 	SQLSMALLINT decDigits = 0;
 	getColSizeAndPrecision(pos, SQL_C_CHAR, colSize, decDigits, val.size());
@@ -120,8 +140,16 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
 	}
 	else if (isInBound(dir))
 	{
-		pVal = (SQLPOINTER) val.c_str();
-		_inParams.insert(ParamMap::value_type(pVal, size));
+		if (!pTCVal)
+		{
+			pVal = (SQLPOINTER)val.c_str();
+			_inParams.insert(ParamMap::value_type(pVal, size));
+		}
+		else
+		{
+			pVal = (SQLPOINTER)pTCVal;
+			_inParams.insert(ParamMap::value_type(pVal, size));
+		}
 	}
 	else
 		throw InvalidArgumentException("Parameter must be [in] OR [out] bound.");
@@ -421,12 +449,28 @@ void Binder::synchronize()
 			Utility::dateTimeSync(*it->second, *it->first);
 	}
 
-	if (_strings.size())
+	if (!transcodeRequired())
 	{
-		StringMap::iterator it = _strings.begin();
-		StringMap::iterator end = _strings.end();
-		for(; it != end; ++it)
-			it->second->assign(it->first, std::strlen(it->first));
+		if (_strings.size())
+		{
+			StringMap::iterator it = _strings.begin();
+			StringMap::iterator end = _strings.end();
+			for (; it != end; ++it)
+				it->second->assign(it->first, std::strlen(it->first));
+		}
+	}
+	else
+	{
+		if (_strings.size())
+		{
+			StringMap::iterator it = _strings.begin();
+			StringMap::iterator end = _strings.end();
+			for (; it != end; ++it)
+			{
+				std::string str(it->first, std::strlen(it->first));
+				reverseTranscode(str, *it->second);
+			}
+		}
 	}
 
 	if (_uuids.size())
diff --git a/Data/ODBC/src/ConnectionHandle.cpp b/Data/ODBC/src/ConnectionHandle.cpp
index 065031bb4..3efc04824 100644
--- a/Data/ODBC/src/ConnectionHandle.cpp
+++ b/Data/ODBC/src/ConnectionHandle.cpp
@@ -15,6 +15,8 @@
 #include "Poco/Data/ODBC/ConnectionHandle.h"
 #include "Poco/Data/ODBC/Utility.h"
 #include "Poco/Data/ODBC/ODBCException.h"
+#include "Poco/Error.h"
+#include "Poco/Debugger.h"
 
 
 namespace Poco {
@@ -22,14 +24,14 @@ namespace Data {
 namespace ODBC {
 
 
-ConnectionHandle::ConnectionHandle(EnvironmentHandle* pEnvironment): 
+ConnectionHandle::ConnectionHandle(EnvironmentHandle* pEnvironment):
 	_pEnvironment(pEnvironment ? pEnvironment : new EnvironmentHandle),
-	_hdbc(SQL_NULL_HDBC), 
+	_hdbc(SQL_NULL_HDBC),
 	_ownsEnvironment(pEnvironment ? false : true)
 {
-	if (Utility::isError(SQLAllocHandle(SQL_HANDLE_DBC, 
-		_pEnvironment->handle(), 
-		&_hdbc))) 
+	if (Utility::isError(SQLAllocHandle(SQL_HANDLE_DBC,
+		_pEnvironment->handle(),
+		&_hdbc)))
 	{
 		throw ODBCException("Could not allocate connection handle.");
 	}
@@ -42,10 +44,11 @@ ConnectionHandle::~ConnectionHandle()
 	{
 		SQLDisconnect(_hdbc);
 		SQLRETURN rc = SQLFreeHandle(SQL_HANDLE_DBC, _hdbc);
-
 		if (_ownsEnvironment) delete _pEnvironment;
-
-		poco_assert (!Utility::isError(rc));
+#if defined(_DEBUG)
+		if (Utility::isError(rc))
+			Debugger::enter(Poco::Error::getMessage(Poco::Error::last()), __FILE__, __LINE__);
+#endif
 	}
 	catch (...)
 	{
diff --git a/Data/ODBC/src/EnvironmentHandle.cpp b/Data/ODBC/src/EnvironmentHandle.cpp
index 61ce83f3d..b9c19182a 100644
--- a/Data/ODBC/src/EnvironmentHandle.cpp
+++ b/Data/ODBC/src/EnvironmentHandle.cpp
@@ -15,6 +15,8 @@
 #include "Poco/Data/ODBC/EnvironmentHandle.h"
 #include "Poco/Data/ODBC/Utility.h"
 #include "Poco/Data/ODBC/ODBCException.h"
+#include "Poco/Error.h"
+#include "Poco/Debugger.h"
 
 
 namespace Poco {
@@ -24,12 +26,12 @@ namespace ODBC {
 
 EnvironmentHandle::EnvironmentHandle(): _henv(SQL_NULL_HENV)
 {
-	if (Utility::isError(SQLAllocHandle(SQL_HANDLE_ENV, 
-			SQL_NULL_HANDLE, 
+	if (Utility::isError(SQLAllocHandle(SQL_HANDLE_ENV,
+			SQL_NULL_HANDLE,
 			&_henv)) ||
-		Utility::isError(SQLSetEnvAttr(_henv, 
-			SQL_ATTR_ODBC_VERSION, 
-			(SQLPOINTER) SQL_OV_ODBC3, 
+		Utility::isError(SQLSetEnvAttr(_henv,
+			SQL_ATTR_ODBC_VERSION,
+			(SQLPOINTER) SQL_OV_ODBC3,
 			0)))
 	{
 		throw ODBCException("Could not initialize environment.");
@@ -42,7 +44,10 @@ EnvironmentHandle::~EnvironmentHandle()
 	try
 	{
 		SQLRETURN rc = SQLFreeHandle(SQL_HANDLE_ENV, _henv);
-		poco_assert (!Utility::isError(rc));
+#if defined(_DEBUG)
+		if (Utility::isError(rc))
+			Debugger::enter(Poco::Error::getMessage(Poco::Error::last()), __FILE__, __LINE__);
+#endif
 	}
 	catch (...)
 	{
diff --git a/Data/ODBC/src/Extractor.cpp b/Data/ODBC/src/Extractor.cpp
index 90da78517..b5ce0ca4d 100644
--- a/Data/ODBC/src/Extractor.cpp
+++ b/Data/ODBC/src/Extractor.cpp
@@ -35,13 +35,11 @@ const std::string Extractor::FLD_SIZE_EXCEEDED_FMT = "Specified data size (%z by
 
 Extractor::Extractor(const StatementHandle& rStmt,
 	Preparator::Ptr pPreparator,
-	TextEncoding::Ptr pDBEncoding):
+	TextEncoding::Ptr pDBEncoding,
+	Poco::TextEncoding::Ptr pToEncoding): AbstractExtractor(pDBEncoding, pToEncoding),
 	_rStmt(rStmt),
 	_pPreparator(pPreparator),
-	_dataExtraction(pPreparator->getDataExtraction()),
-	_pDBEncoding(pDBEncoding),
-	_transcode(_pDBEncoding && !_pDBEncoding->isA("UTF-8")),
-	_pToEncoding(_transcode ? Poco::TextEncoding::find("UTF-8") : nullptr)
+	_dataExtraction(pPreparator->getDataExtraction())
 {
 }
 
@@ -707,7 +705,7 @@ bool Extractor::extract(std::size_t pos, std::string& val)
 {
 	bool ret = false;
 
-	if (!_transcode)
+	if (!transcodeRequired())
 	{
 		if (Preparator::DE_MANUAL == _dataExtraction)
 			ret = extractManualImpl(pos, val, SQL_C_CHAR);
@@ -721,8 +719,8 @@ bool Extractor::extract(std::size_t pos, std::string& val)
 			ret = extractManualImpl(pos, result, SQL_C_CHAR);
 		else
 			ret = extractBoundImpl(pos, result);
-		Poco::TextConverter converter(*_pDBEncoding, *_pToEncoding);
-		converter.convert(result, val);
+		transcode(result, val);
+		
 	}
 
 	return ret;
diff --git a/Data/ODBC/src/ODBCStatementImpl.cpp b/Data/ODBC/src/ODBCStatementImpl.cpp
index 59ffc3a45..ca22afedc 100644
--- a/Data/ODBC/src/ODBCStatementImpl.cpp
+++ b/Data/ODBC/src/ODBCStatementImpl.cpp
@@ -98,7 +98,8 @@ void ODBCStatementImpl::compileImpl()
 
 	std::size_t maxFieldSize = AnyCast(session().getProperty("maxFieldSize"));
 
-	_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT);
+	_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT, TextEncoding::find("UTF-8"),
+		TextEncoding::find(Poco::RefAnyCast(session().getProperty("dbEncoding"))));
 
 	makeInternalExtractors();
 	doPrepare();
@@ -146,7 +147,8 @@ void ODBCStatementImpl::addPreparator()
 		_preparations.push_back(new Preparator(*_preparations[0]));
 
 	_extractors.push_back(new Extractor(_stmt, _preparations.back(),
-		TextEncoding::find(Poco::RefAnyCast(session().getProperty("dbEncoding")))));
+		TextEncoding::find(Poco::RefAnyCast(session().getProperty("dbEncoding"))),
+		TextEncoding::find("UTF-8")));
 }
 
 
diff --git a/Data/ODBC/src/Parameter.cpp b/Data/ODBC/src/Parameter.cpp
index 23023779b..b7dfe2970 100644
--- a/Data/ODBC/src/Parameter.cpp
+++ b/Data/ODBC/src/Parameter.cpp
@@ -23,14 +23,14 @@ namespace Data {
 namespace ODBC {
 
 
-Parameter::Parameter(const StatementHandle& rStmt, std::size_t colNum) : 
-	_rStmt(rStmt), 
+Parameter::Parameter(const StatementHandle& rStmt, std::size_t colNum) :
+	_rStmt(rStmt),
 	_number(colNum)
 {
 	init();
 }
 
-	
+
 Parameter::~Parameter()
 {
 }
@@ -38,8 +38,8 @@ Parameter::~Parameter()
 
 void Parameter::init()
 {
-	if (Utility::isError(SQLDescribeParam(_rStmt, 
-		(SQLUSMALLINT) _number + 1, 
+	if (Utility::isError(SQLDescribeParam(_rStmt,
+		(SQLUSMALLINT) _number + 1,
 		&_dataType,
 		&_columnSize,
 		&_decimalDigits,
diff --git a/Data/ODBC/src/SessionImpl.cpp b/Data/ODBC/src/SessionImpl.cpp
index 50d83470d..dc21541a1 100644
--- a/Data/ODBC/src/SessionImpl.cpp
+++ b/Data/ODBC/src/SessionImpl.cpp
@@ -31,7 +31,7 @@ SessionImpl::SessionImpl(const std::string& connect,
 	std::size_t loginTimeout,
 	std::size_t maxFieldSize,
 	bool autoBind,
-	bool autoExtract): 
+	bool autoExtract):
 	Poco::Data::AbstractSessionImpl(connect, loginTimeout),
 		_connector(Connector::KEY),
 		_maxFieldSize(maxFieldSize),
@@ -49,7 +49,7 @@ SessionImpl::SessionImpl(const std::string& connect,
 
 
 SessionImpl::SessionImpl(const std::string& connect,
-	Poco::Any maxFieldSize, 
+	Poco::Any maxFieldSize,
 	bool enforceCapability,
 	bool autoBind,
 	bool autoExtract): Poco::Data::AbstractSessionImpl(connect),
@@ -136,20 +136,20 @@ void SessionImpl::open(const std::string& connect)
 	}
 
 	_dataTypes.fillTypeInfo(_db);
-		addProperty("dataTypeInfo", 
-		&SessionImpl::setDataTypeInfo, 
+		addProperty("dataTypeInfo",
+		&SessionImpl::setDataTypeInfo,
 		&SessionImpl::dataTypeInfo);
 
-	addFeature("autoCommit", 
-		&SessionImpl::autoCommit, 
+	addFeature("autoCommit",
+		&SessionImpl::autoCommit,
 		&SessionImpl::isAutoCommit);
 
-	addFeature("autoBind", 
-		&SessionImpl::autoBind, 
+	addFeature("autoBind",
+		&SessionImpl::autoBind,
 		&SessionImpl::isAutoBind);
 
-	addFeature("autoExtract", 
-		&SessionImpl::autoExtract, 
+	addFeature("autoExtract",
+		&SessionImpl::autoExtract,
 		&SessionImpl::isAutoExtract);
 
 	addProperty("maxFieldSize",
@@ -222,11 +222,11 @@ bool SessionImpl::canTransact() const
 	if (ODBC_TXN_CAPABILITY_UNKNOWN == _canTransact)
 	{
 		SQLUSMALLINT ret;
-		checkError(Poco::Data::ODBC::SQLGetInfo(_db, SQL_TXN_CAPABLE, &ret, 0, 0), 
+		checkError(Poco::Data::ODBC::SQLGetInfo(_db, SQL_TXN_CAPABLE, &ret, 0, 0),
 			"Failed to obtain transaction capability info.");
 
-		_canTransact = (SQL_TC_NONE != ret) ? 
-			ODBC_TXN_CAPABILITY_TRUE : 
+		_canTransact = (SQL_TC_NONE != ret) ?
+			ODBC_TXN_CAPABILITY_TRUE :
 			ODBC_TXN_CAPABILITY_FALSE;
 	}
 
@@ -329,10 +329,10 @@ Poco::UInt32 SessionImpl::transactionIsolation(SQLULEN isolation)
 
 void SessionImpl::autoCommit(const std::string&, bool val)
 {
-	checkError(Poco::Data::ODBC::SQLSetConnectAttr(_db, 
-		SQL_ATTR_AUTOCOMMIT, 
-		val ? (SQLPOINTER) SQL_AUTOCOMMIT_ON : 
-			(SQLPOINTER) SQL_AUTOCOMMIT_OFF, 
+	checkError(Poco::Data::ODBC::SQLSetConnectAttr(_db,
+		SQL_ATTR_AUTOCOMMIT,
+		val ? (SQLPOINTER) SQL_AUTOCOMMIT_ON :
+			(SQLPOINTER) SQL_AUTOCOMMIT_OFF,
 		SQL_IS_UINTEGER), "Failed to set automatic commit.");
 }
 
@@ -415,7 +415,7 @@ void SessionImpl::close()
 	{
 		commit();
 	}
-	catch (ConnectionException&) 
+	catch (ConnectionException&)
 	{
 	}
 
@@ -433,7 +433,7 @@ int SessionImpl::maxStatementLength() const
 		0,
 		0)))
 	{
-		throw ConnectionException(_db, 
+		throw ConnectionException(_db,
 			"SQLGetInfo(SQL_MAXIMUM_STATEMENT_LENGTH)");
 	}
 
diff --git a/Data/ODBC/src/TypeInfo.cpp b/Data/ODBC/src/TypeInfo.cpp
index ca5aa0eb1..d667ad00b 100644
--- a/Data/ODBC/src/TypeInfo.cpp
+++ b/Data/ODBC/src/TypeInfo.cpp
@@ -110,7 +110,7 @@ void TypeInfo::fillTypeInfo(SQLHDBC pHDBC)
 				char literalSuffix[stringSize] = { 0 };
 				char createParams[stringSize] = { 0 };
 				char localTypeName[stringSize] = { 0 };
-				
+
 				TypeInfoTup ti("TYPE_NAME", "",
 					"DATA_TYPE", 0,
 					"COLUMN_SIZE", 0,
@@ -142,10 +142,10 @@ void TypeInfo::fillTypeInfo(SQLHDBC pHDBC)
 				ti.set<4>(literalSuffix);
 				rc = SQLGetData(hstmt, 6, SQL_C_CHAR, createParams, sizeof(createParams), &ind);
 				ti.set<5>(createParams);
-				rc = SQLGetData(hstmt, 7, SQL_C_SSHORT, &ti.get<6>(), sizeof(SQLSMALLINT), &ind); 
-				rc = SQLGetData(hstmt, 8, SQL_C_SSHORT, &ti.get<7>(), sizeof(SQLSMALLINT), &ind); 
-				rc = SQLGetData(hstmt, 9, SQL_C_SSHORT, &ti.get<8>(), sizeof(SQLSMALLINT), &ind); 
-				rc = SQLGetData(hstmt, 10, SQL_C_SSHORT, &ti.get<9>(), sizeof(SQLSMALLINT), &ind); 
+				rc = SQLGetData(hstmt, 7, SQL_C_SSHORT, &ti.get<6>(), sizeof(SQLSMALLINT), &ind);
+				rc = SQLGetData(hstmt, 8, SQL_C_SSHORT, &ti.get<7>(), sizeof(SQLSMALLINT), &ind);
+				rc = SQLGetData(hstmt, 9, SQL_C_SSHORT, &ti.get<8>(), sizeof(SQLSMALLINT), &ind);
+				rc = SQLGetData(hstmt, 10, SQL_C_SSHORT, &ti.get<9>(), sizeof(SQLSMALLINT), &ind);
 				rc = SQLGetData(hstmt, 11, SQL_C_SSHORT, &ti.get<10>(), sizeof(SQLSMALLINT), &ind);
 				rc = SQLGetData(hstmt, 12, SQL_C_SSHORT, &ti.get<11>(), sizeof(SQLSMALLINT), &ind);
 				rc = SQLGetData(hstmt, 13, SQL_C_CHAR, localTypeName, sizeof(localTypeName), &ind);
@@ -192,7 +192,7 @@ bool TypeInfo::tryGetInfo(SQLSMALLINT type, const std::string& param, DynamicAny
 			return true;
 		}
 	}
-	
+
 	return false;
 }
 
@@ -239,24 +239,24 @@ void TypeInfo::print(std::ostream& ostr)
 
 	for (; it != end; ++it)
 	{
-		ostr << it->get<0>() << "\t" 
-			<< it->get<1>() << "\t" 
-			<< it->get<2>() << "\t" 
-			<< it->get<3>() << "\t" 
-			<< it->get<4>() << "\t" 
-			<< it->get<5>() << "\t" 
-			<< it->get<6>() << "\t" 
-			<< it->get<7>() << "\t" 
-			<< it->get<8>() << "\t" 
-			<< it->get<9>() << "\t" 
-			<< it->get<10>() << "\t" 
-			<< it->get<11>() << "\t" 
-			<< it->get<12>() << "\t" 
-			<< it->get<13>() << "\t" 
+		ostr << it->get<0>() << "\t"
+			<< it->get<1>() << "\t"
+			<< it->get<2>() << "\t"
+			<< it->get<3>() << "\t"
+			<< it->get<4>() << "\t"
+			<< it->get<5>() << "\t"
+			<< it->get<6>() << "\t"
+			<< it->get<7>() << "\t"
+			<< it->get<8>() << "\t"
+			<< it->get<9>() << "\t"
+			<< it->get<10>() << "\t"
+			<< it->get<11>() << "\t"
+			<< it->get<12>() << "\t"
+			<< it->get<13>() << "\t"
 			<< it->get<14>() << "\t"
-			<< it->get<15>() << "\t" 
-			<< it->get<16>() << "\t" 
-			<< it->get<17>() << "\t" 
+			<< it->get<15>() << "\t"
+			<< it->get<16>() << "\t"
+			<< it->get<17>() << "\t"
 			<< it->get<18>() << std::endl;
 	}
 }
diff --git a/Data/ODBC/src/Unicode_UNIXODBC.cpp b/Data/ODBC/src/Unicode_UNIXODBC.cpp
index 4caf097c2..1f671fed5 100644
--- a/Data/ODBC/src/Unicode_UNIXODBC.cpp
+++ b/Data/ODBC/src/Unicode_UNIXODBC.cpp
@@ -38,7 +38,7 @@ namespace ODBC {
 void makeUTF16(SQLCHAR* pSQLChar, SQLINTEGER length, std::string& target)
 {
 	int len = length;
-	if (SQL_NTS == len) 
+	if (SQL_NTS == len)
 		len = (int) std::strlen((const char *) pSQLChar);
 
 	UTF8Encoding utf8Encoding;
@@ -59,7 +59,7 @@ void makeUTF8(Poco::Buffer& buffer, SQLINTEGER length, SQLPOINTER pTar
 	std::string result;
 	if (0 != converter.convert(buffer.begin(), length, result))
 		throw DataFormatException("Error converting UTF-16 to UTF-8");
-	
+
 	std::memset(pTarget, 0, targetLength);
 	std::strncpy((char*) pTarget, result.c_str(), result.size() < targetLength ? result.size() : targetLength);
 }
@@ -69,7 +69,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
 	SQLUSMALLINT   iCol,
 	SQLUSMALLINT   iField,
 	SQLPOINTER	   pCharAttr,
-	SQLSMALLINT	   cbCharAttrMax,	
+	SQLSMALLINT	   cbCharAttrMax,
 	SQLSMALLINT*   pcbCharAttr,
 	NumAttrPtrType pNumAttr)
 {
@@ -93,7 +93,7 @@ SQLRETURN SQLColAttribute(SQLHSTMT hstmt,
 		iCol,
 		iField,
 		pCharAttr,
-		cbCharAttrMax,	
+		cbCharAttrMax,
 		pcbCharAttr,
 		pNumAttr);
 }
@@ -133,8 +133,8 @@ SQLRETURN SQLConnect(SQLHDBC hdbc,
 
 	std::string sqlPWD;
 	makeUTF16(szAuthStr, cbAuthStr, sqlPWD);
-	
-	return SQLConnectW(hdbc, 
+
+	return SQLConnectW(hdbc,
 		(SQLWCHAR*) sqlDSN.c_str(), cbDSN,
 		(SQLWCHAR*) sqlUID.c_str(), cbUID,
 		(SQLWCHAR*) sqlPWD.c_str(), cbAuthStr);
@@ -211,7 +211,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
 		makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
 		return rc;
 	}
-	
+
 
 	return SQLGetConnectAttrW(hdbc,
 		fAttribute,
@@ -231,9 +231,9 @@ SQLRETURN SQLGetCursorName(SQLHSTMT hstmt,
 
 
 SQLRETURN SQLSetDescField(SQLHDESC hdesc,
-	SQLSMALLINT iRecord, 
+	SQLSMALLINT iRecord,
 	SQLSMALLINT iField,
-	SQLPOINTER  rgbValue, 
+	SQLPOINTER  rgbValue,
 	SQLINTEGER  cbValueMax)
 {
 	if (isString(rgbValue, cbValueMax))
@@ -242,16 +242,16 @@ SQLRETURN SQLSetDescField(SQLHDESC hdesc,
 		makeUTF16((SQLCHAR*) rgbValue, cbValueMax, str);
 
 		return SQLSetDescFieldW(hdesc,
-			iRecord, 
+			iRecord,
 			iField,
-			(SQLPOINTER) str.c_str(), 
+			(SQLPOINTER) str.c_str(),
 			(SQLINTEGER) str.size() * sizeof(SQLWCHAR));
 	}
 
 	return SQLSetDescFieldW(hdesc,
-		iRecord, 
+		iRecord,
 		iField,
-		rgbValue, 
+		rgbValue,
 		cbValueMax);
 }
 
@@ -296,7 +296,7 @@ SQLRETURN SQLGetDescRec(SQLHDESC hdesc,
 	SQLSMALLINT* pfType,
 	SQLSMALLINT* pfSubType,
 	SQLLEN*      pLength,
-	SQLSMALLINT* pPrecision, 
+	SQLSMALLINT* pPrecision,
 	SQLSMALLINT* pScale,
 	SQLSMALLINT* pNullable)
 {
@@ -391,7 +391,7 @@ SQLRETURN SQLSetConnectAttr(SQLHDBC hdbc,
 
 		return SQLSetConnectAttrW(hdbc,
 			fAttribute,
-			(SQLWCHAR*) str.c_str(), 
+			(SQLWCHAR*) str.c_str(),
 			(SQLINTEGER) str.size() * sizeof(SQLWCHAR));
 	}
 
@@ -487,7 +487,7 @@ SQLRETURN SQLGetInfo(SQLHDBC hdbc,
 			pcbInfoValue);
 
 		makeUTF8(buffer, *pcbInfoValue, rgbInfoValue, cbInfoValueMax);
-		
+
 		return rc;
 	}
 
@@ -590,12 +590,12 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
 	SQLUSMALLINT fDriverCompletion)
 {
 	SQLSMALLINT len = cbConnStrIn;
-	if (SQL_NTS == len) 
+	if (SQL_NTS == len)
 		len = (SQLSMALLINT) std::strlen((const char*) szConnStrIn) + 1;
 
 	std::string connStrIn;
 	makeUTF16(szConnStrIn, len, connStrIn);
-	
+
 	Buffer out(cbConnStrOutMax);
 	SQLRETURN rc = SQLDriverConnectW(hdbc,
 		hwnd,
diff --git a/Data/ODBC/src/Unicode_WIN32.cpp b/Data/ODBC/src/Unicode_WIN32.cpp
index fe637e49b..ed472115a 100644
--- a/Data/ODBC/src/Unicode_WIN32.cpp
+++ b/Data/ODBC/src/Unicode_WIN32.cpp
@@ -97,7 +97,7 @@ SQLRETURN SQLConnect(SQLHDBC hdbc,
 
 	std::wstring sqlPWD;
 	makeUTF16(szAuthStr, cbAuthStr, sqlPWD);
-	
+
 	return SQLConnectW(hdbc,
 		(SQLWCHAR*) sqlDSN.c_str(),
 		(SQLSMALLINT) sqlDSN.size(),
@@ -155,8 +155,8 @@ SQLRETURN SQLExecDirect(SQLHSTMT hstmt,
 	std::wstring sqlStr;
 	makeUTF16(szSqlStr, cbSqlStr, sqlStr);
 
-	return SQLExecDirectW(hstmt, 
-		(SQLWCHAR*) sqlStr.c_str(), 
+	return SQLExecDirectW(hstmt,
+		(SQLWCHAR*) sqlStr.c_str(),
 		(SQLINTEGER) sqlStr.size());
 }
 
@@ -180,7 +180,7 @@ SQLRETURN SQLGetConnectAttr(SQLHDBC hdbc,
 		makeUTF8(buffer, *pcbValue, rgbValue, cbValueMax);
 		return rc;
 	}
-	
+
 
 	return SQLGetConnectAttrW(hdbc,
 		fAttribute,
@@ -200,9 +200,9 @@ SQLRETURN SQLGetCursorName(SQLHSTMT hstmt,
 
 
 SQLRETURN SQLSetDescField(SQLHDESC hdesc,
-	SQLSMALLINT iRecord, 
+	SQLSMALLINT iRecord,
 	SQLSMALLINT iField,
-	SQLPOINTER  rgbValue, 
+	SQLPOINTER  rgbValue,
 	SQLINTEGER  cbValueMax)
 {
 	if (isString(rgbValue, cbValueMax))
@@ -211,18 +211,18 @@ SQLRETURN SQLSetDescField(SQLHDESC hdesc,
 		makeUTF16((SQLCHAR*) rgbValue, cbValueMax, str);
 
 		SQLRETURN rc = SQLSetDescFieldW(hdesc,
-			iRecord, 
+			iRecord,
 			iField,
-			(SQLPOINTER) str.c_str(), 
+			(SQLPOINTER) str.c_str(),
 			(SQLINTEGER) str.size() * sizeof(std::wstring::value_type));
 
 		return rc;
 	}
 
 	return SQLSetDescFieldW(hdesc,
-		iRecord, 
+		iRecord,
 		iField,
-		rgbValue, 
+		rgbValue,
 		cbValueMax);
 }
 
@@ -266,7 +266,7 @@ SQLRETURN SQLGetDescRec(SQLHDESC hdesc,
 	SQLSMALLINT* pfType,
 	SQLSMALLINT* pfSubType,
 	SQLLEN*      pLength,
-	SQLSMALLINT* pPrecision, 
+	SQLSMALLINT* pPrecision,
 	SQLSMALLINT* pScale,
 	SQLSMALLINT* pNullable)
 {
@@ -344,8 +344,8 @@ SQLRETURN SQLPrepare(SQLHSTMT hstmt,
 	std::wstring sqlStr;
 	makeUTF16(szSqlStr, cbSqlStr, sqlStr);
 
-	return SQLPrepareW(hstmt, 
-		(SQLWCHAR*) sqlStr.c_str(), 
+	return SQLPrepareW(hstmt,
+		(SQLWCHAR*) sqlStr.c_str(),
 		(SQLINTEGER) sqlStr.size());
 }
 
@@ -362,13 +362,13 @@ SQLRETURN SQLSetConnectAttr(SQLHDBC hdbc,
 
 		return SQLSetConnectAttrW(hdbc,
 			fAttribute,
-			(SQLWCHAR*) str.c_str(), 
+			(SQLWCHAR*) str.c_str(),
 			(SQLINTEGER) str.size() * sizeof(std::wstring::value_type));
 	}
 
 	return SQLSetConnectAttrW(hdbc,
 		fAttribute,
-		rgbValue, 
+		rgbValue,
 		cbValue);
 }
 
@@ -576,7 +576,7 @@ SQLRETURN SQLDriverConnect(SQLHDBC hdbc,
 {
 	std::wstring connStrIn;
 	int len = cbConnStrIn;
-	if (SQL_NTS == len) 
+	if (SQL_NTS == len)
 		len = (int) std::strlen((const char*) szConnStrIn);
 
 	Poco::UnicodeConverter::toUTF16((const char *) szConnStrIn, len, connStrIn);
diff --git a/Data/ODBC/src/Utility.cpp b/Data/ODBC/src/Utility.cpp
index 62a22a40b..8d3b4a5e5 100644
--- a/Data/ODBC/src/Utility.cpp
+++ b/Data/ODBC/src/Utility.cpp
@@ -41,7 +41,7 @@ Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
 	SQLSMALLINT len2 = length;
 	RETCODE rc = 0;
 
-	if (!Utility::isError(rc = SQLDrivers(henv, 
+	if (!Utility::isError(rc = SQLDrivers(henv,
 		SQL_FETCH_FIRST,
 		desc,
 		length,
@@ -52,12 +52,12 @@ Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
 	{
 		do
 		{
-			driverMap.insert(DSNMap::value_type(std::string((char *) desc), 
+			driverMap.insert(DSNMap::value_type(std::string((char *) desc),
 				std::string((char *) attr)));
 			std::memset(desc, 0, length);
 			std::memset(attr, 0, length);
 			len2 = length;
-		}while (!Utility::isError(rc = SQLDrivers(henv, 
+		}while (!Utility::isError(rc = SQLDrivers(henv,
 			SQL_FETCH_NEXT,
 			desc,
 			length,
@@ -67,7 +67,7 @@ Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
 			&len2)));
 	}
 
-	if (SQL_NO_DATA != rc) 
+	if (SQL_NO_DATA != rc)
 		throw EnvironmentException(henv);
 
 	return driverMap;
@@ -88,7 +88,7 @@ Utility::DSNMap& Utility::dataSources(Utility::DSNMap& dsnMap)
 	SQLSMALLINT len2 = length;
 	RETCODE rc = 0;
 
-	while (!Utility::isError(rc = Poco::Data::ODBC::SQLDataSources(henv, 
+	while (!Utility::isError(rc = Poco::Data::ODBC::SQLDataSources(henv,
 		SQL_FETCH_NEXT,
 		dsn,
 		SQL_MAX_DSN_LENGTH,
@@ -103,7 +103,7 @@ Utility::DSNMap& Utility::dataSources(Utility::DSNMap& dsnMap)
 		len2 = length;
 	}
 
-	if (SQL_NO_DATA != rc) 
+	if (SQL_NO_DATA != rc)
 		throw EnvironmentException(henv);
 
 	return dsnMap;
diff --git a/Data/ODBC/testsuite/TestSuite_vs170.vcxproj b/Data/ODBC/testsuite/TestSuite_vs170.vcxproj
index 92dfd5979..214f11b4e 100644
--- a/Data/ODBC/testsuite/TestSuite_vs170.vcxproj
+++ b/Data/ODBC/testsuite/TestSuite_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     TestSuite
     {00627063-395B-4413-9099-23BDB56562FA}
     TestSuite
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
+  
+    Application
+    MultiByte
+    v143
+  
   
     Application
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    TestSuited
+    TestSuited
+    TestSuited
+    TestSuite
+    TestSuite
+    TestSuite
     TestSuited
     TestSuited
     TestSuited
@@ -171,6 +250,36 @@
     TestSuite
     TestSuite
   
+  
+    binA64\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
+  
+    binA64\static_mt\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\static_mt\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
+  
+    binA64\static_md\
+    objA64\TestSuite\$(Configuration)\
+    true
+  
+  
+    binA64\static_md\
+    objA64\TestSuite\$(Configuration)\
+    false
+  
   
     bin\
     obj\TestSuite\$(Configuration)\
@@ -231,6 +340,189 @@
     obj64\TestSuite\$(Configuration)\
     false
   
+  
+    
+      Disabled
+      ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitd.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\TestSuited.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnit.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\TestSuite.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitmtd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_mt\TestSuited.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\static_mt\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnitmt.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_mt\TestSuite.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      CppUnitmdd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_md\TestSuited.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      true
+      true
+      binA64\static_md\TestSuited.pdb
+      Console
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      CppUnitmd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;iphlpapi.lib;%(AdditionalDependencies)
+      binA64\static_md\TestSuite.exe
+      ..\..\..\libA64;%(AdditionalLibraryDirectories)
+      false
+      Console
+      true
+      true
+      MachineARM64
+    
+  
   
     
       Disabled
diff --git a/Data/ODBC/testsuite/src/ODBCAccessTest.cpp b/Data/ODBC/testsuite/src/ODBCAccessTest.cpp
index 12bea3710..55aec9ba7 100644
--- a/Data/ODBC/testsuite/src/ODBCAccessTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCAccessTest.cpp
@@ -40,7 +40,7 @@ std::string ODBCAccessTest::_dbConnString;
 Poco::Data::ODBC::Utility::DriverMap ODBCAccessTest::_drivers;
 
 
-ODBCAccessTest::ODBCAccessTest(const std::string& name): 
+ODBCAccessTest::ODBCAccessTest(const std::string& name):
 	CppUnit::TestCase(name)
 {
 }
@@ -123,13 +123,13 @@ bool ODBCAccessTest::canConnect(const std::string& driver, const std::string& ds
 	{
 		if (((itDrv->first).find(driver) != std::string::npos))
 		{
-			std::cout << "Driver found: " << itDrv->first 
+			std::cout << "Driver found: " << itDrv->first
 				<< " (" << itDrv->second << ')' << std::endl;
 			break;
 		}
 	}
 
-	if (_drivers.end() == itDrv) 
+	if (_drivers.end() == itDrv)
 	{
 		std::cout << driver << " driver NOT found, tests not available." << std::endl;
 		return false;
@@ -142,7 +142,7 @@ bool ODBCAccessTest::canConnect(const std::string& driver, const std::string& ds
 	{
 		if (itDSN->first == dsn && itDSN->second == driver)
 		{
-			std::cout << "DSN found: " << itDSN->first 
+			std::cout << "DSN found: " << itDSN->first
 				<< " (" << itDSN->second << ')' << std::endl;
 			format(_dbConnString, "DSN=%s", dsn);
 			return true;
diff --git a/Data/ODBC/testsuite/src/ODBCAccessTest.h b/Data/ODBC/testsuite/src/ODBCAccessTest.h
index 498b23f27..18bd6ce11 100644
--- a/Data/ODBC/testsuite/src/ODBCAccessTest.h
+++ b/Data/ODBC/testsuite/src/ODBCAccessTest.h
@@ -25,7 +25,7 @@
 class ODBCAccessTest: public CppUnit::TestCase
 	/// MS Access ODBC test class
 	/// Tested:
-	/// 
+	///
 	/// Driver		|	DB		| OS
 	/// ------------+-----------+------------------------------------------
 	///	4.00.6305.00| Jet 4.0	| MS Windows XP Professional x64 v.2003/SP1
diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp
index f5c2ff79f..c880ad6fb 100644
--- a/Data/ODBC/testsuite/src/ODBCDB2Test.cpp
+++ b/Data/ODBC/testsuite/src/ODBCDB2Test.cpp
@@ -66,7 +66,7 @@ std::string          ODBCDB2Test::_connectString = "Driver=" DB2_ODBC_DRIVER ";"
 	"Pwd=" DB2_PWD ";";
 
 
-ODBCDB2Test::ODBCDB2Test(const std::string& name): 
+ODBCDB2Test::ODBCDB2Test(const std::string& name):
 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
 {
 }
@@ -110,7 +110,7 @@ void ODBCDB2Test::testBareboneODBC()
 void ODBCDB2Test::testBLOB()
 {
 	if (!_pSession) fail ("Test not available.");
-	
+
 	const std::size_t maxFldSize = 1000000;
 	_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1));
 	recreatePersonBLOBTable();
@@ -120,7 +120,7 @@ void ODBCDB2Test::testBLOB()
 		_pExecutor->blob(maxFldSize);
 		fail ("must fail");
 	}
-	catch (DataException&) 
+	catch (DataException&)
 	{
 		_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize));
 	}
@@ -183,14 +183,14 @@ void ODBCDB2Test::testStoredProcedure()
 			"BEGIN "
 			" SET outParam = inParam*inParam; "
 			"END" , now;
-		
+
 
 		i = 2;
 		int j = 0;
 		*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
 		assertTrue (4 == j);
 		dropObject("PROCEDURE", "storedProcedure");
-	
+
 		*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
 			"BEGIN "
 			" SET ioParam = ioParam*ioParam; "
@@ -209,7 +209,7 @@ void ODBCDB2Test::testStoredProcedure()
 			" SET outParam = inParam; "
 			"END" , now;
 
-		std::string inParam = 
+		std::string inParam =
 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
 			"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
@@ -272,7 +272,7 @@ void ODBCDB2Test::testStoredProcedureDynamicAny()
 	for (int k = 0; k < 8;)
 	{
 		_pSession->setFeature("autoBind", bindValue(k));
-		
+
 		DynamicAny i = 2;
 		DynamicAny j = 0;
 
@@ -319,12 +319,12 @@ void ODBCDB2Test::testStoredFunction()
 		*_pSession << "{? = call storedFunction()}", out(i), now;
 		assertTrue (-1 == i);
 		dropObject("PROCEDURE", "storedFunction");
-		
+
 		*_pSession << "CREATE PROCEDURE storedFunction(inParam INTEGER) "
 			"BEGIN "
 			" RETURN inParam*inParam; "
 			"END" , now;
-		
+
 		i = 2;
 		int result = 0;
 		*_pSession << "{? = call storedFunction(?)}", out(result), in(i), now;
@@ -342,7 +342,7 @@ void ODBCDB2Test::testStoredFunction()
 		result = 0;
 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), in(i), out(j), now;
 		assertTrue (4 == j);
-		assertTrue (j == result); 
+		assertTrue (j == result);
 		dropObject("PROCEDURE", "storedFunction");
 
 		*_pSession << "CREATE PROCEDURE storedFunction(INOUT param1 INTEGER, INOUT param2 INTEGER) "
@@ -360,7 +360,7 @@ void ODBCDB2Test::testStoredFunction()
 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(i), io(j), now;
 		assertTrue (1 == j);
 		assertTrue (2 == i);
-		assertTrue (3 == result); 
+		assertTrue (3 == result);
 
 		Tuple params(1, 2);
 		assertTrue (1 == params.get<0>());
@@ -369,7 +369,7 @@ void ODBCDB2Test::testStoredFunction()
 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(params), now;
 		assertTrue (1 == params.get<1>());
 		assertTrue (2 == params.get<0>());
-		assertTrue (3 == result); 
+		assertTrue (3 == result);
 
 		dropObject("PROCEDURE", "storedFunction");
 
@@ -545,14 +545,14 @@ void ODBCDB2Test::recreateNullsTable(const std::string& notNull)
 void ODBCDB2Test::recreateMiscTable()
 {
 	dropObject("TABLE", "MiscTest");
-	try 
-	{ 
+	try
+	{
 		session() << "CREATE TABLE MiscTest "
 			"(First VARCHAR(30),"
 			"Second BLOB,"
 			"Third INTEGER,"
 			"Fourth FLOAT,"
-			"Fifth TIMESTAMP)", now; 
+			"Fifth TIMESTAMP)", now;
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
 }
@@ -563,19 +563,19 @@ void ODBCDB2Test::recreateLogTable()
 	dropObject("TABLE", "T_POCO_LOG");
 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
 
-	try 
-	{ 
+	try
+	{
 		std::string sql = "CREATE TABLE %s "
 			"(Source VARCHAR(100),"
 			"Name VARCHAR(100),"
 			"ProcessId INTEGER,"
 			"Thread VARCHAR(100), "
-			"ThreadId INTEGER," 
+			"ThreadId INTEGER,"
 			"Priority INTEGER,"
 			"Text VARCHAR(100),"
-			"DateTime TIMESTAMP)"; 
+			"DateTime TIMESTAMP)";
 
-		session() << sql, "T_POCO_LOG", now; 
+		session() << sql, "T_POCO_LOG", now;
 		session() << sql, "T_POCO_LOG_ARCHIVE", now;
 
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
diff --git a/Data/ODBC/testsuite/src/ODBCDB2Test.h b/Data/ODBC/testsuite/src/ODBCDB2Test.h
index e0e18da75..57263707f 100644
--- a/Data/ODBC/testsuite/src/ODBCDB2Test.h
+++ b/Data/ODBC/testsuite/src/ODBCDB2Test.h
@@ -21,7 +21,7 @@
 class ODBCDB2Test: public ODBCTest
 	/// IBM DB2 UDB ODBC test class
 	/// Tested:
-	/// 
+	///
 	/// Driver		|	DB				| OS
 	/// ------------+-------------------+------------------------------------------
 	///	9.01.00.356 | DB2 Express-C 9.1	| MS Windows XP Professional x64 v.2003/SP1
diff --git a/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp b/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp
index ed539e13e..bd90d438a 100644
--- a/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCMySQLTest.cpp
@@ -61,7 +61,7 @@ std::string          ODBCMySQLTest::_connectString = "DRIVER={" MYSQL_ODBC_DRIVE
 	"PWD=" MYSQL_PWD ";";
 
 
-ODBCMySQLTest::ODBCMySQLTest(const std::string& name): 
+ODBCMySQLTest::ODBCMySQLTest(const std::string& name):
 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
 {
 	_pExecutor->execute("SET @@global.sql_mode= '';"); // disable strict mode
@@ -120,7 +120,7 @@ So, we skip this test.
 void ODBCMySQLTest::testBLOB()
 {
 	if (!_pSession) fail ("Test not available.");
-	
+
 	const std::size_t maxFldSize = 65534;
 	_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1));
 	recreatePersonBLOBTable();
@@ -130,7 +130,7 @@ void ODBCMySQLTest::testBLOB()
 		_pExecutor->blob(maxFldSize);
 		fail ("must fail");
 	}
-	catch (DataException&) 
+	catch (DataException&)
 	{
 		_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize));
 	}
@@ -182,10 +182,10 @@ void ODBCMySQLTest::testNull()
 
 void ODBCMySQLTest::testStoredProcedure()
 {
-	//MySQL is currently buggy in this area: 
+	//MySQL is currently buggy in this area:
 	// http://bugs.mysql.com/bug.php?id=17898
 	// http://bugs.mysql.com/bug.php?id=27632
-	// Additionally, the standard ODBC stored procedure call syntax 
+	// Additionally, the standard ODBC stored procedure call syntax
 	// {call storedProcedure(?)} is currently (3.51.12.00) not supported.
 	// See http://bugs.mysql.com/bug.php?id=26535
 	// Poco::Data support for MySQL ODBC is postponed until the above
@@ -195,10 +195,10 @@ void ODBCMySQLTest::testStoredProcedure()
 
 void ODBCMySQLTest::testStoredFunction()
 {
-	//MySQL is currently buggy in this area: 
+	//MySQL is currently buggy in this area:
 	// http://bugs.mysql.com/bug.php?id=17898
 	// http://bugs.mysql.com/bug.php?id=27632
-	// Additionally, the standard ODBC stored procedure call syntax 
+	// Additionally, the standard ODBC stored procedure call syntax
 	// {call storedProcedure(?)} is currently (3.51.12.00) not supported.
 	// See http://bugs.mysql.com/bug.php?id=26535
 	// Poco::Data support for MySQL ODBC is postponed until the above
@@ -390,19 +390,19 @@ void ODBCMySQLTest::recreateLogTable()
 	dropObject("TABLE", "T_POCO_LOG");
 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
 
-	try 
-	{ 
+	try
+	{
 		std::string sql = "CREATE TABLE %s "
 			"(Source VARCHAR(100),"
 			"Name VARCHAR(100),"
 			"ProcessId INTEGER,"
 			"Thread VARCHAR(100), "
-			"ThreadId INTEGER," 
+			"ThreadId INTEGER,"
 			"Priority INTEGER,"
 			"Text VARCHAR(100),"
-			"DateTime DATETIME)"; 
+			"DateTime DATETIME)";
 
-		session() << sql, "T_POCO_LOG", now; 
+		session() << sql, "T_POCO_LOG", now;
 		session() << sql, "T_POCO_LOG_ARCHIVE", now;
 
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
diff --git a/Data/ODBC/testsuite/src/ODBCMySQLTest.h b/Data/ODBC/testsuite/src/ODBCMySQLTest.h
index c1ea5dc5d..ce1104109 100644
--- a/Data/ODBC/testsuite/src/ODBCMySQLTest.h
+++ b/Data/ODBC/testsuite/src/ODBCMySQLTest.h
@@ -21,8 +21,8 @@
 class ODBCMySQLTest: public ODBCTest
 	/// MySQL ODBC test class
 	/// Tested:
-	/// 
-	/// Driver          | DB                        | OS                                        | Driver Manager 
+	///
+	/// Driver          | DB                        | OS                                        | Driver Manager
 	/// ----------------+---------------------------+-------------------------------------------+---------------------
 	/// 03.51.12.00     | MySQL 5.0.27-community-nt | MS Windows XP Professional x64 v.2003/SP1 | 3.526.3959.0
 	///  3.51.11.-6     | MySQL 5.0.27-community-nt | Ubuntu 7.04 (2.6.20-15-generic #2 SMP)    | unixODBC 2.2.11.-13
@@ -41,7 +41,7 @@ public:
 	void testStoredFunction();
 
 	void testNull();
-	
+
 	void testMultipleResults();
 	void testFilter();
 
diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp
index fc90a070e..29091efe3 100644
--- a/Data/ODBC/testsuite/src/ODBCOracleTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCOracleTest.cpp
@@ -81,7 +81,7 @@ std::string          ODBCOracleTest::_connectString = "DRIVER={" ORACLE_ODBC_DRI
 	"APA=T;" // thread safety (T/F), default T
 	"DBA=W;"; // write access (R/W)
 
-const std::string ODBCOracleTest::MULTI_INSERT = 
+const std::string ODBCOracleTest::MULTI_INSERT =
 	"BEGIN "
 	"INSERT INTO Test VALUES ('1', 2, 3.5);"
 	"INSERT INTO Test VALUES ('2', 3, 4.5);"
@@ -94,7 +94,7 @@ const std::string ODBCOracleTest::MULTI_SELECT =
 	"{CALL multiResultsProcedure()}";
 
 
-ODBCOracleTest::ODBCOracleTest(const std::string& name): 
+ODBCOracleTest::ODBCOracleTest(const std::string& name):
 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
 {
 }
@@ -139,27 +139,27 @@ void ODBCOracleTest::testBarebone()
 			"OPEN ret5 FOR SELECT * FROM Test WHERE First = '5';"
 			"END multiResultsProcedure;" , now;
 
-	_pExecutor->bareboneODBCMultiResultTest(_connectString, 
-		tableCreateString, 
-		SQLExecutor::PB_IMMEDIATE, 
+	_pExecutor->bareboneODBCMultiResultTest(_connectString,
+		tableCreateString,
+		SQLExecutor::PB_IMMEDIATE,
 		SQLExecutor::DE_MANUAL,
 		MULTI_INSERT,
 		MULTI_SELECT);
-	_pExecutor->bareboneODBCMultiResultTest(_connectString, 
-		tableCreateString, 
-		SQLExecutor::PB_IMMEDIATE, 
+	_pExecutor->bareboneODBCMultiResultTest(_connectString,
+		tableCreateString,
+		SQLExecutor::PB_IMMEDIATE,
 		SQLExecutor::DE_BOUND,
 		MULTI_INSERT,
 		MULTI_SELECT);
-	_pExecutor->bareboneODBCMultiResultTest(_connectString, 
-		tableCreateString, 
-		SQLExecutor::PB_AT_EXEC, 
+	_pExecutor->bareboneODBCMultiResultTest(_connectString,
+		tableCreateString,
+		SQLExecutor::PB_AT_EXEC,
 		SQLExecutor::DE_MANUAL,
 		MULTI_INSERT,
 		MULTI_SELECT);
-	_pExecutor->bareboneODBCMultiResultTest(_connectString, 
-		tableCreateString, 
-		SQLExecutor::PB_AT_EXEC, 
+	_pExecutor->bareboneODBCMultiResultTest(_connectString,
+		tableCreateString,
+		SQLExecutor::PB_AT_EXEC,
 		SQLExecutor::DE_BOUND,
 		MULTI_INSERT,
 		MULTI_SELECT);
@@ -178,7 +178,7 @@ void ODBCOracleTest::testBLOB()
 		executor().blob(maxFldSize);
 		fail ("must fail");
 	}
-	catch (DataException&) 
+	catch (DataException&)
 	{
 		session().setProperty("maxFieldSize", Poco::Any(maxFldSize));
 	}
@@ -277,7 +277,7 @@ void ODBCOracleTest::testStoredProcedure()
 		k += 2;
 	}
 
-	
+
 	//strings only work with auto-binding
 	session().setFeature("autoBind", true);
 
@@ -286,7 +286,7 @@ void ODBCOracleTest::testStoredProcedure()
 		" BEGIN outParam := inParam; "
 		"END storedProcedure;" , now;
 
-	std::string inParam = 
+	std::string inParam =
 		"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
 		"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
 		"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
@@ -342,7 +342,7 @@ void ODBCOracleTest::testStoredProcedureDynamicAny()
 	for (int k = 0; k < 8;)
 	{
 		session().setFeature("autoBind", bindValue(k));
-		
+
 		DynamicAny i = 2;
 		DynamicAny j = 0;
 
@@ -391,15 +391,15 @@ void ODBCOracleTest::testCursorStoredProcedure()
 			" OPEN ret FOR "
 			" SELECT * "
 			" FROM Person "
-			" WHERE Age < ageLimit " 
+			" WHERE Age < ageLimit "
 			" ORDER BY Age DESC; "
 			" END storedCursorProcedure;" , now;
 
 		people.clear();
 		int age = 13;
-		
+
 		*_pSession << "{call storedCursorProcedure(?)}", in(age), into(people), now;
-		
+
 		assertTrue (2 == people.size());
 		assertTrue (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
 		assertTrue (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
@@ -460,7 +460,7 @@ void ODBCOracleTest::testStoredFunction()
 		result = 0;
 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), in(i), out(j), now;
 		assertTrue (4 == j);
-		assertTrue (j == result); 
+		assertTrue (j == result);
 		dropObject("FUNCTION", "storedFunction");
 
 		*_pSession << "CREATE OR REPLACE "
@@ -475,8 +475,8 @@ void ODBCOracleTest::testStoredFunction()
 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(i), io(j), now;
 		assertTrue (1 == j);
 		assertTrue (2 == i);
-		assertTrue (3 == result); 
-		
+		assertTrue (3 == result);
+
 		Tuple params(1, 2);
 		assertTrue (1 == params.get<0>());
 		assertTrue (2 == params.get<1>());
@@ -484,9 +484,9 @@ void ODBCOracleTest::testStoredFunction()
 		*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(params), now;
 		assertTrue (1 == params.get<1>());
 		assertTrue (2 == params.get<0>());
-		assertTrue (3 == result); 
+		assertTrue (3 == result);
 		dropObject("FUNCTION", "storedFunction");
-		
+
 		k += 2;
 	}
 
@@ -530,16 +530,16 @@ void ODBCOracleTest::testCursorStoredFunction()
 			" OPEN ret FOR "
 			" SELECT * "
 			" FROM Person "
-			" WHERE Age < ageLimit " 
+			" WHERE Age < ageLimit "
 			" ORDER BY Age DESC; "
 			" RETURN ret; "
 			" END storedCursorFunction;" , now;
 
 		people.clear();
 		int age = 13;
-		
+
 		*_pSession << "{call storedCursorFunction(?)}", in(age), into(people), now;
-		
+
 		assertTrue (2 == people.size());
 		assertTrue (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
 		assertTrue (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
@@ -553,7 +553,7 @@ void ODBCOracleTest::testCursorStoredFunction()
 
 		dropObject("TABLE", "Person");
 		dropObject("FUNCTION", "storedCursorFunction");
-		
+
 		k += 2;
 	}
 }
@@ -611,7 +611,7 @@ void ODBCOracleTest::testAutoTransaction()
 	assertTrue (0 == count);
 
 	session().setFeature("autoCommit", false);
-	
+
 	try
 	{
 		AutoTransaction at(session());
@@ -794,14 +794,14 @@ void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
 void ODBCOracleTest::recreateMiscTable()
 {
 	dropObject("TABLE", "MiscTest");
-	try 
-	{ 
+	try
+	{
 		session() << "CREATE TABLE MiscTest "
 			"(First VARCHAR(30),"
 			"Second BLOB,"
 			"Third INTEGER,"
 			"Fourth NUMBER,"
-			"Fifth TIMESTAMP)", now; 
+			"Fifth TIMESTAMP)", now;
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
 }
@@ -812,20 +812,20 @@ void ODBCOracleTest::recreateLogTable()
 	dropObject("TABLE", "T_POCO_LOG");
 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
 
-	try 
-	{ 
+	try
+	{
 		std::string sql = "CREATE TABLE %s "
 			"(Source VARCHAR(100),"
 			"Name VARCHAR(100),"
 			"ProcessId INTEGER,"
 			"Thread VARCHAR(100), "
-			"ThreadId INTEGER," 
+			"ThreadId INTEGER,"
 			"Priority INTEGER,"
 			"Text VARCHAR(100),"
-			"DateTime TIMESTAMP)"; 
+			"DateTime TIMESTAMP)";
 
-		session() << sql, "T_POCO_LOG", now; 
-		session() << sql, "T_POCO_LOG_ARCHIVE", now; 
+		session() << sql, "T_POCO_LOG", now;
+		session() << sql, "T_POCO_LOG_ARCHIVE", now;
 
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
diff --git a/Data/ODBC/testsuite/src/ODBCOracleTest.h b/Data/ODBC/testsuite/src/ODBCOracleTest.h
index 92a1bbcaf..168710be2 100644
--- a/Data/ODBC/testsuite/src/ODBCOracleTest.h
+++ b/Data/ODBC/testsuite/src/ODBCOracleTest.h
@@ -21,7 +21,7 @@
 class ODBCOracleTest: public ODBCTest
 	/// Oracle ODBC test class
 	/// Tested:
-	/// 
+	///
 	/// Driver		|	DB							| OS
 	/// ------------+-------------------------------+------------------------------------------
 	///	10.02.00.01	| Oracle9i Release 9.2.0.4.0	| MS Windows XP Professional x64 v.2003/SP1
@@ -51,7 +51,7 @@ public:
 
 private:
 	static void testBarebone();
-	
+
 	void dropObject(const std::string& type, const std::string& name);
 	void recreateNullableTable();
 	void recreatePersonTable();
@@ -72,7 +72,7 @@ private:
 
 	static ODBCTest::SessionPtr _pSession;
 	static ODBCTest::ExecPtr    _pExecutor;
-	
+
 	static std::string _driver;
 	static std::string _dsn;
 	static std::string _uid;
diff --git a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp
index 2c2f1cf34..81d467b59 100644
--- a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.cpp
@@ -75,7 +75,7 @@ std::string          ODBCPostgreSQLTest::_driver = POSTGRESQL_ODBC_DRIVER;
 std::string          ODBCPostgreSQLTest::_dsn = POSTGRESQL_DSN;
 std::string          ODBCPostgreSQLTest::_uid = POSTGRESQL_UID;
 std::string          ODBCPostgreSQLTest::_pwd = POSTGRESQL_PWD;
-std::string ODBCPostgreSQLTest::_connectString = 
+std::string ODBCPostgreSQLTest::_connectString =
 	"DRIVER=" POSTGRESQL_ODBC_DRIVER ";"
 	"DATABASE=" POSTGRESQL_DB ";"
 	"SERVER=" POSTGRESQL_SERVER ";"
@@ -114,7 +114,7 @@ std::string ODBCPostgreSQLTest::_connectString =
 	"ReadOnly=0;";
 
 
-ODBCPostgreSQLTest::ODBCPostgreSQLTest(const std::string& name): 
+ODBCPostgreSQLTest::ODBCPostgreSQLTest(const std::string& name):
 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
 {
 }
@@ -179,7 +179,7 @@ void ODBCPostgreSQLTest::testBLOB()
 		executor().blob(maxFldSize);
 		fail ("must fail");
 	}
-	catch (DataException&) 
+	catch (DataException&)
 	{
 		session().setProperty("maxFieldSize", Poco::Any(maxFldSize));
 	}
@@ -207,7 +207,7 @@ void ODBCPostgreSQLTest::testStoredFunction()
 		session().setFeature("autoExtract", bindValue(k+1));
 
 		dropObject("FUNCTION", "storedFunction()");
-		try 
+		try
 		{
 			session() << "CREATE FUNCTION storedFunction() RETURNS INTEGER AS '"
 				"BEGIN "
@@ -223,7 +223,7 @@ void ODBCPostgreSQLTest::testStoredFunction()
 		assertTrue (-1 == i);
 		dropObject("FUNCTION", "storedFunction()");
 
-		try 
+		try
 		{
 			session() << "CREATE FUNCTION storedFunction(INTEGER) RETURNS INTEGER AS '"
 				"BEGIN "
@@ -241,7 +241,7 @@ void ODBCPostgreSQLTest::testStoredFunction()
 		dropObject("FUNCTION", "storedFunction(INTEGER)");
 
 		dropObject("FUNCTION", "storedFunction(TIMESTAMP)");
-		try 
+		try
 		{
 			session() << "CREATE FUNCTION storedFunction(TIMESTAMP) RETURNS TIMESTAMP AS '"
 				"BEGIN "
@@ -259,23 +259,23 @@ void ODBCPostgreSQLTest::testStoredFunction()
 		dropObject("FUNCTION", "storedFunction(TIMESTAMP)");
 
 		dropObject("FUNCTION", "storedFunction(TEXT, TEXT)");
-		try 
+		try
 		{
 			session() << "CREATE FUNCTION storedFunction(TEXT,TEXT) RETURNS TEXT AS '"
 				"BEGIN "
 				" RETURN $1 || '', '' || $2 || ''!'';"
 				"END;'"
-				"LANGUAGE 'plpgsql'" , now; 
+				"LANGUAGE 'plpgsql'" , now;
 		}
 		catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (func); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (func); }
-		
+
 		std::string param1 = "Hello";
 		std::string param2 = "world";
 		std::string ret;
-		try 
+		try
 		{
-			session() << "{? = call storedFunction(?,?)}", out(ret), in(param1), in(param2), now; 
+			session() << "{? = call storedFunction(?,?)}", out(ret), in(param1), in(param2), now;
 		}
 		catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (func); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (func); }
@@ -346,13 +346,13 @@ void ODBCPostgreSQLTest::configurePLPgSQL()
 			"RETURNS OPAQUE "
 			"AS '%splpgsql.dll' "
 			"LANGUAGE 'C';", _libDir), now;
-		
+
 		session() << "CREATE LANGUAGE 'plpgsql' "
 			"HANDLER plpgsql_call_handler "
 			"LANCOMPILER 'PL/pgSQL'", now;
 
-	}catch(StatementException& ex) 
-	{  
+	}catch(StatementException& ex)
+	{
 		if (1 != ex.diagnostics().nativeError(0))
 			throw;
 	}
@@ -522,15 +522,15 @@ void ODBCPostgreSQLTest::recreateBoolTable()
 void ODBCPostgreSQLTest::recreateMiscTable()
 {
 	dropObject("TABLE", "MiscTest");
-	try 
-	{ 
+	try
+	{
 		// Mammoth does not bind columns properly
 		session() << "CREATE TABLE MiscTest "
 			"(First VARCHAR(30),"
 			"Second BYTEA,"
 			"Third INTEGER,"
 			"Fourth FLOAT,"
-			"Fifth TIMESTAMP)", now; 
+			"Fifth TIMESTAMP)", now;
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
 }
@@ -541,20 +541,20 @@ void ODBCPostgreSQLTest::recreateLogTable()
 	dropObject("TABLE", "T_POCO_LOG");
 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
 
-	try 
-	{ 
+	try
+	{
 		std::string sql = "CREATE TABLE %s "
 			"(Source VARCHAR,"
 			"Name VARCHAR,"
 			"ProcessId INTEGER,"
 			"Thread VARCHAR, "
-			"ThreadId INTEGER," 
+			"ThreadId INTEGER,"
 			"Priority INTEGER,"
 			"Text VARCHAR,"
-			"DateTime TIMESTAMP)"; 
+			"DateTime TIMESTAMP)";
 
-		session() << sql, "T_POCO_LOG", now; 
-		session() << sql, "T_POCO_LOG_ARCHIVE", now; 
+		session() << sql, "T_POCO_LOG", now;
+		session() << sql, "T_POCO_LOG_ARCHIVE", now;
 
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
diff --git a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h
index 072d670b7..37b47a7b9 100644
--- a/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h
+++ b/Data/ODBC/testsuite/src/ODBCPostgreSQLTest.h
@@ -25,15 +25,15 @@
 class ODBCPostgreSQLTest: public ODBCTest
 	/// PostgreSQL ODBC test class
 	/// Tested:
-	/// 
+	///
 	/// Driver		   |	DB                | OS                                        | Driver Manager     |Notes
 	/// ---------------+----------------------+-------------------------------------------+--------------------+--------------------------
 	///	07.03.02.60	   | PostgreSQL 7.4.6     | MS Windows XP Professional x64 v.2003/SP1 | 3.526.3959.0       | BLOB fails (missing 'lo')
 	/// 08.01.02.00    | PostgreSQL 8.1.5-1   | MS Windows XP Professional x64 v.2003/SP1 | 3.526.3959.0       |
 	/// 1:08.01.0200-2 | PostgreSQL 8.1.5-1   | Ubuntu 7.04 (2.6.20-15-generic #2 SMP)    | unixODBC 2.2.11.-13|
-	/// Mammoth ODBCng |                      |                                           |                    | 
+	/// Mammoth ODBCng |                      |                                           |                    |
 	/// (0.99.00.122)  | PostgreSQL 8.1.5-1   | MS Windows XP Professional x64 v.2003/SP1 | 3.526.3959.0       |
-	/// 
+	///
 {
 public:
 	ODBCPostgreSQLTest(const std::string& name);
@@ -71,8 +71,8 @@ private:
 
 	void configurePLPgSQL();
 		/// Configures PL/pgSQL in the database. A reasonable defaults
-		/// for the interpreter location on WIN32 and POSIX platforms are 
-		/// supplied (see installDir member variable). 
+		/// for the interpreter location on WIN32 and POSIX platforms are
+		/// supplied (see installDir member variable).
 		/// If these do not work, user must determine the proper location,
 		/// modify the function and recompile.
 		/// Alternative is direct database configuration for PL/pgSQL usage.
diff --git a/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp b/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp
index bff4d1dc5..97a6c919f 100644
--- a/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCSQLServerTest.cpp
@@ -87,6 +87,7 @@ using Poco::DateTime;
 
 
 ODBCTest::SessionPtr ODBCSQLServerTest::_pSession;
+ODBCTest::SessionPtr ODBCSQLServerTest::_pEncSession;
 ODBCTest::ExecPtr    ODBCSQLServerTest::_pExecutor;
 std::string          ODBCSQLServerTest::_driver = MS_SQL_SERVER_ODBC_DRIVER;
 std::string          ODBCSQLServerTest::_dsn = MS_SQL_SERVER_DSN;
@@ -106,7 +107,7 @@ std::string ODBCSQLServerTest::_connectString = "DRIVER=" MS_SQL_SERVER_ODBC_DRI
 	;
 
 
-ODBCSQLServerTest::ODBCSQLServerTest(const std::string& name): 
+ODBCSQLServerTest::ODBCSQLServerTest(const std::string& name):
 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
 {
 }
@@ -127,13 +128,13 @@ void ODBCSQLServerTest::testBareboneODBC()
 		"Fifth FLOAT,"
 		"Sixth DATETIME)";
 
-	executor().bareboneODBCTest(dbConnString(), tableCreateString, 
+	executor().bareboneODBCTest(dbConnString(), tableCreateString,
 		SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL, true, "CONVERT(VARBINARY(30),?)");
-	executor().bareboneODBCTest(dbConnString(), tableCreateString, 
+	executor().bareboneODBCTest(dbConnString(), tableCreateString,
 		SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND, true, "CONVERT(VARBINARY(30),?)");
-	executor().bareboneODBCTest(dbConnString(), tableCreateString, 
+	executor().bareboneODBCTest(dbConnString(), tableCreateString,
 		SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL, true, "CONVERT(VARBINARY(30),?)");
-	executor().bareboneODBCTest(dbConnString(), tableCreateString, 
+	executor().bareboneODBCTest(dbConnString(), tableCreateString,
 		SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, true, "CONVERT(VARBINARY(30),?)");
 
 	tableCreateString = "CREATE TABLE Test "
@@ -254,7 +255,7 @@ void ODBCSQLServerTest::testStoredProcedure()
 			"SET @outParam = -1; "
 			"END;"
 		, now;
-		
+
 		int i = 0;
 		session() << "{call storedProcedure(?)}", out(i), now;
 		assertTrue (-1 == i);
@@ -297,8 +298,8 @@ void ODBCSQLServerTest::testStoredProcedure()
 	}
 /*TODO - currently fails with following error:
 
-[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid parameter 
-2 (''):  Data type 0x23 is a deprecated large object, or LOB, but is marked as output parameter.  
+[Microsoft][ODBC SQL Server Driver][SQL Server]Invalid parameter
+2 (''):  Data type 0x23 is a deprecated large object, or LOB, but is marked as output parameter.
 Deprecated types are not supported as output parameters.  Use current large object types instead.
 
 	session().setFeature("autoBind", true);
@@ -339,16 +340,16 @@ void ODBCSQLServerTest::testCursorStoredProcedure()
 			"BEGIN "
 			" SELECT * "
 			" FROM Person "
-			" WHERE Age < @ageLimit " 
+			" WHERE Age < @ageLimit "
 			" ORDER BY Age DESC; "
 			"END;"
 		, now;
 
 		people.clear();
 		int age = 13;
-		
+
 		session() << "{call storedCursorProcedure(?)}", in(age), into(people), now;
-		
+
 		assertTrue (2 == people.size());
 		assertTrue (Person("Simpson", "Bart", "Springfield", 12) == people[0]);
 		assertTrue (Person("Simpson", "Lisa", "Springfield", 10) == people[1]);
@@ -409,7 +410,7 @@ void ODBCSQLServerTest::testStoredProcedureDynamicAny()
 	for (int k = 0; k < 8;)
 	{
 		session().setFeature("autoBind", bindValue(k));
-		
+
 		DynamicAny i = 2;
 		DynamicAny j = 0;
 
@@ -506,7 +507,7 @@ void ODBCSQLServerTest::testStoredFunction()
 		session() << "{? = call storedFunction(?, ?)}", out(result), io(i), io(j), now;
 		assertTrue (1 == j);
 		assertTrue (2 == i);
-		assertTrue (3 == result); 
+		assertTrue (3 == result);
 
 		Tuple params(1, 2);
 		assertTrue (1 == params.get<0>());
@@ -515,7 +516,7 @@ void ODBCSQLServerTest::testStoredFunction()
 		session() << "{? = call storedFunction(?, ?)}", out(result), io(params), now;
 		assertTrue (1 == params.get<1>());
 		assertTrue (2 == params.get<0>());
-		assertTrue (3 == result); 
+		assertTrue (3 == result);
 
 		dropObject("PROCEDURE", "storedFunction");
 
@@ -683,15 +684,15 @@ void ODBCSQLServerTest::recreateBoolTable()
 void ODBCSQLServerTest::recreateMiscTable()
 {
 	dropObject("TABLE", "MiscTest");
-	try 
-	{ 
+	try
+	{
 		session() << "CREATE TABLE MiscTest "
 			"(First VARCHAR(30),"
 			"Second VARBINARY(30),"
 			"Third INTEGER,"
 			"Fourth FLOAT,"
 			"Fifth DATETIME,"
-			"Sixth BIT)", now; 
+			"Sixth BIT)", now;
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
 }
@@ -702,20 +703,20 @@ void ODBCSQLServerTest::recreateLogTable()
 	dropObject("TABLE", "T_POCO_LOG");
 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
 
-	try 
-	{ 
+	try
+	{
 		std::string sql = "CREATE TABLE %s "
 			"(Source VARCHAR(max),"
 			"Name VARCHAR(max),"
 			"ProcessId INTEGER,"
 			"Thread VARCHAR(max), "
-			"ThreadId INTEGER," 
+			"ThreadId INTEGER,"
 			"Priority INTEGER,"
 			"Text VARCHAR(max),"
 			"DateTime DATETIME)";
 
-		session() << sql, "T_POCO_LOG", now; 
-		session() << sql, "T_POCO_LOG_ARCHIVE", now; 
+		session() << sql, "T_POCO_LOG", now;
+		session() << sql, "T_POCO_LOG_ARCHIVE", now;
 
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@@ -733,13 +734,28 @@ void ODBCSQLServerTest::recreateUnicodeTable()
 }
 
 
+void ODBCSQLServerTest::recreateEncodingTables()
+{
+#if defined (POCO_ODBC_UNICODE)
+	dropObject("TABLE", "Latin1Table");
+	try { session() << "CREATE TABLE Latin1Table (str NVARCHAR(30))", now; }
+	catch (ConnectionException& ce) { std::cout << ce.toString() << std::endl; fail("recreateEncodingTables()"); }
+	catch (StatementException& se) { std::cout << se.toString() << std::endl; fail("recreateEncodingTables()"); }
+#endif
+}
+
+
 CppUnit::Test* ODBCSQLServerTest::suite()
 {
 	if ((_pSession = init(_driver, _dsn, _uid, _pwd, _connectString, _db)))
 	{
 		std::cout << "*** Connected to [" << _driver << "] test database." << std::endl;
+		std::string enc = "Latin1";
+		if ((_pEncSession = init(_driver, _dsn, _uid, _pwd, _connectString, _db, enc)))
+			std::cout << "*** Connected to [" << _driver << "] test database, encoding: [" << enc << "]." << std::endl;
+		// ...
 
-		_pExecutor = new SQLExecutor(_driver + " SQL Executor", _pSession);
+		_pExecutor = new SQLExecutor(_driver + " SQL Executor", _pSession, _pEncSession);
 
 		CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ODBCSQLServerTest");
 
@@ -822,6 +838,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
 		CppUnit_addTest(pSuite, ODBCSQLServerTest, testTransactor);
 		CppUnit_addTest(pSuite, ODBCSQLServerTest, testNullable);
 		CppUnit_addTest(pSuite, ODBCSQLServerTest, testUnicode);
+		CppUnit_addTest(pSuite, ODBCSQLServerTest, testEncoding);
 		CppUnit_addTest(pSuite, ODBCSQLServerTest, testReconnect);
 
 		return pSuite;
diff --git a/Data/ODBC/testsuite/src/ODBCSQLServerTest.h b/Data/ODBC/testsuite/src/ODBCSQLServerTest.h
index 67a6fedbe..40de51413 100644
--- a/Data/ODBC/testsuite/src/ODBCSQLServerTest.h
+++ b/Data/ODBC/testsuite/src/ODBCSQLServerTest.h
@@ -25,7 +25,7 @@
 class ODBCSQLServerTest: public ODBCTest
 	/// SQLServer ODBC test class
 	/// Tested:
-	/// 
+	///
 	/// Driver				|	DB								| OS
 	/// --------------------+-----------------------------------+------------------------------------------
 	/// 2000.86.1830.00		| SQL Server Express 9.0.2047		| MS Windows XP Professional x64 v.2003/SP1
@@ -48,7 +48,7 @@ public:
 	void testCursorStoredProcedure();
 	void testStoredProcedureAny();
 	void testStoredProcedureDynamicAny();
-	
+
 	void testStoredFunction();
 
 	static CppUnit::Test* suite();
@@ -74,8 +74,10 @@ private:
 	void recreateMiscTable();
 	void recreateLogTable();
 	void recreateUnicodeTable();
+	void recreateEncodingTables();
 
 	static SessionPtr  _pSession;
+	static SessionPtr  _pEncSession;
 	static ExecPtr     _pExecutor;
 	static std::string _driver;
 	static std::string _dsn;
diff --git a/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp b/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp
index 645a9a8b9..61b4bcf60 100644
--- a/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCSQLiteTest.cpp
@@ -45,11 +45,11 @@ std::string          ODBCSQLiteTest::_driver = SQLITE_ODBC_DRIVER;
 std::string          ODBCSQLiteTest::_dsn = SQLITE_DSN;
 std::string          ODBCSQLiteTest::_uid = "";
 std::string          ODBCSQLiteTest::_pwd = "";
-std::string          ODBCSQLiteTest::_connectString = "Driver=" SQLITE_ODBC_DRIVER 
+std::string          ODBCSQLiteTest::_connectString = "Driver=" SQLITE_ODBC_DRIVER
 	";Database=" SQLITE_DB ";";
 
 
-ODBCSQLiteTest::ODBCSQLiteTest(const std::string& name): 
+ODBCSQLiteTest::ODBCSQLiteTest(const std::string& name):
 	ODBCTest(name, _pSession, _pExecutor, _dsn, _uid, _pwd, _connectString)
 {
 }
@@ -116,7 +116,7 @@ void ODBCSQLiteTest::testAffectedRows()
 		// why "WHERE 1" is necessary here
 		_pExecutor->affectedRows("WHERE 1");
 		i += 2;
-	}	
+	}
 }
 
 
@@ -156,7 +156,7 @@ void ODBCSQLiteTest::dropObject(const std::string& type, const std::string& name
 			}
 		}
 
-		if (!ignoreError) 
+		if (!ignoreError)
 		{
 			std::cout << ex.toString() << std::endl;
 			throw;
@@ -273,15 +273,15 @@ void ODBCSQLiteTest::recreateNullsTable(const std::string& notNull)
 void ODBCSQLiteTest::recreateMiscTable()
 {
 	dropObject("TABLE", "MiscTest");
-	try 
-	{ 
+	try
+	{
 		// SQLite fails with BLOB bulk operations
 		session() << "CREATE TABLE MiscTest "
 			"(First VARCHAR(30),"
 			//"Second BLOB,"
 			"Third INTEGER,"
 			"Fourth REAL,"
-			"Fifth DATETIME)", now; 
+			"Fifth DATETIME)", now;
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateMiscTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateMiscTable()"); }
 }
@@ -292,20 +292,20 @@ void ODBCSQLiteTest::recreateLogTable()
 	dropObject("TABLE", "T_POCO_LOG");
 	dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
 
-	try 
-	{ 
+	try
+	{
 		std::string sql = "CREATE TABLE %s "
 			"(Source VARCHAR,"
 			"Name VARCHAR,"
 			"ProcessId INTEGER,"
 			"Thread VARCHAR, "
-			"ThreadId INTEGER," 
+			"ThreadId INTEGER,"
 			"Priority INTEGER,"
 			"Text VARCHAR,"
 			"DateTime DATETIME)";
 
-		session() << sql, "T_POCO_LOG", now; 
-		session() << sql, "T_POCO_LOG_ARCHIVE", now; 
+		session() << sql, "T_POCO_LOG", now;
+		session() << sql, "T_POCO_LOG_ARCHIVE", now;
 
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
diff --git a/Data/ODBC/testsuite/src/ODBCSQLiteTest.h b/Data/ODBC/testsuite/src/ODBCSQLiteTest.h
index 83a6d1ed6..b878c1574 100644
--- a/Data/ODBC/testsuite/src/ODBCSQLiteTest.h
+++ b/Data/ODBC/testsuite/src/ODBCSQLiteTest.h
@@ -21,7 +21,7 @@
 class ODBCSQLiteTest: public ODBCTest
 	/// SQLite3 ODBC test class
 	/// Tested:
-	/// 
+	///
 	/// Driver		|	DB			| OS
 	/// ------------+---------------+------------------------------------------
 	///	00.70.00.00	| SQLite 3.*	| MS Windows XP Professional x64 v.2003/SP1
diff --git a/Data/ODBC/testsuite/src/ODBCTest.cpp b/Data/ODBC/testsuite/src/ODBCTest.cpp
index 41668eee0..6d5e98b7b 100644
--- a/Data/ODBC/testsuite/src/ODBCTest.cpp
+++ b/Data/ODBC/testsuite/src/ODBCTest.cpp
@@ -49,7 +49,7 @@ using Poco::NotFoundException;
 
 
 ODBCTest::Drivers ODBCTest::_drivers;
-const bool        ODBCTest::_bindValues[8] = 
+const bool        ODBCTest::_bindValues[8] =
 	{true, true, true, false, false, true, false, false};
 
 
@@ -59,7 +59,7 @@ ODBCTest::ODBCTest(const std::string& name,
 	std::string& rDSN,
 	std::string& rUID,
 	std::string& rPwd,
-	std::string& rConnectString): 
+	std::string& rConnectString):
 	CppUnit::TestCase(name),
 	_pSession(pSession),
 	_pExecutor(pExecutor),
@@ -212,7 +212,7 @@ void ODBCTest::testInsertVector()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertVector();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -227,7 +227,7 @@ void ODBCTest::testInsertEmptyVector()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertEmptyVector();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -257,7 +257,7 @@ void ODBCTest::testComplexTypeList()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->complexTypeList();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -272,7 +272,7 @@ void ODBCTest::testInsertList()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertList();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -287,7 +287,7 @@ void ODBCTest::testInsertEmptyList()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertEmptyList();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -317,7 +317,7 @@ void ODBCTest::testComplexTypeDeque()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->complexTypeDeque();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -332,7 +332,7 @@ void ODBCTest::testInsertDeque()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertDeque();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -347,7 +347,7 @@ void ODBCTest::testInsertEmptyDeque()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertEmptyDeque();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -362,7 +362,7 @@ void ODBCTest::testAffectedRows()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->affectedRows();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -377,7 +377,7 @@ void ODBCTest::testInsertSingleBulk()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertSingleBulk();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -392,7 +392,7 @@ void ODBCTest::testInsertSingleBulkVec()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->insertSingleBulkVec();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -422,7 +422,7 @@ void ODBCTest::testLimitZero()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->limitZero();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -432,7 +432,7 @@ void ODBCTest::testLimitOnce()
 
 	recreateIntsTable();
 	_pExecutor->limitOnce();
-	
+
 }
 
 
@@ -579,7 +579,7 @@ void ODBCTest::testMultiSetComplex()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->multiSetComplex();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -654,7 +654,7 @@ void ODBCTest::testSelectIntoSingleStep()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->selectIntoSingleStep();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -669,7 +669,7 @@ void ODBCTest::testSelectIntoSingleFail()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->selectIntoSingleFail();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -684,7 +684,7 @@ void ODBCTest::testLowerLimitOk()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->lowerLimitOk();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -699,7 +699,7 @@ void ODBCTest::testSingleSelect()
 		_pSession->setFeature("autoExtract", bindValue(i+1));
 		_pExecutor->singleSelect();
 		i += 2;
-	}	
+	}
 }
 
 
@@ -1252,6 +1252,25 @@ void ODBCTest::testUnicode()
 }
 
 
+void ODBCTest::testEncoding()
+{
+#if defined (POCO_ODBC_UNICODE)
+	if (!_pSession) fail("Test not available.");
+
+	for (int i = 0; i < 8;)
+	{
+		recreateEncodingTables();
+		_pSession->setFeature("autoBind", bindValue(i));
+		_pSession->setFeature("autoExtract", bindValue(i + 1));
+		_pExecutor->encoding(_rConnectString);
+		i += 2;
+	}
+#else
+	std::cout << "Not an UNICODE build, skipping." << std::endl;
+#endif
+}
+
+
 void ODBCTest::testReconnect()
 {
 	if (!_pSession) fail ("Test not available.");
@@ -1281,13 +1300,13 @@ bool ODBCTest::canConnect(const std::string& driver,
 	{
 		if (((itDrv->first).find(driver) != std::string::npos))
 		{
-			std::cout << "Driver found: " << itDrv->first 
+			std::cout << "Driver found: " << itDrv->first
 				<< " (" << itDrv->second << ')' << std::endl;
 			break;
 		}
 	}
 
-	if (_drivers.end() == itDrv) 
+	if (_drivers.end() == itDrv)
 	{
 		dsn = "";
 		uid = "";
@@ -1341,15 +1360,19 @@ ODBCTest::SessionPtr ODBCTest::init(const std::string& driver,
 	std::string& uid,
 	std::string& pwd,
 	std::string& dbConnString,
-	const std::string& db)
+	const std::string& db,
+	const std::string& dbEncoding)
 {
 	Utility::drivers(_drivers);
 	if (!canConnect(driver, dsn, uid, pwd, dbConnString, db)) return 0;
-	
+
 	try
 	{
 		std::cout << "Conecting to [" << dbConnString << ']' << std::endl;
-		return new Session(Poco::Data::ODBC::Connector::KEY, dbConnString, 5);
+		SessionPtr ptr = new Session(Poco::Data::ODBC::Connector::KEY, dbConnString, 5);
+		if (!dbEncoding.empty())
+			ptr->setProperty("dbEncoding", dbEncoding);
+		return ptr;
 	}catch (ConnectionFailedException& ex)
 	{
 		std::cout << ex.displayText() << std::endl;
diff --git a/Data/ODBC/testsuite/src/ODBCTest.h b/Data/ODBC/testsuite/src/ODBCTest.h
index d574ea8c2..1971e6db9 100644
--- a/Data/ODBC/testsuite/src/ODBCTest.h
+++ b/Data/ODBC/testsuite/src/ODBCTest.h
@@ -151,6 +151,7 @@ public:
 	virtual void testNullable();
 
 	virtual void testUnicode();
+	virtual void testEncoding();
 
 	virtual void testReconnect();
 
@@ -177,13 +178,15 @@ protected:
 	virtual void recreateMiscTable();
 	virtual void recreateLogTable();
 	virtual void recreateUnicodeTable();
+	virtual void recreateEncodingTables();
 
 	static SessionPtr init(const std::string& driver,
 		std::string& dsn,
 		std::string& uid,
 		std::string& pwd,
 		std::string& dbConnString,
-		const std::string& db = "");
+		const std::string& db = "",
+		const std::string& dbEncoding = "");
 
 	static bool canConnect(const std::string& driver,
 		std::string& dsn,
@@ -218,38 +221,38 @@ private:
 // inlines
 //
 
-inline void ODBCTest::testStoredProcedure() 
-{ 
+inline void ODBCTest::testStoredProcedure()
+{
 	throw Poco::NotImplementedException("ODBCTest::testStoredProcedure()");
 }
 
 
-inline void ODBCTest::testStoredProcedureAny() 
-{ 
+inline void ODBCTest::testStoredProcedureAny()
+{
 	throw Poco::NotImplementedException("ODBCTest::testStoredProcedureAny()");
 }
 
 
-inline void ODBCTest::testStoredProcedureDynamicAny() 
-{ 
+inline void ODBCTest::testStoredProcedureDynamicAny()
+{
 	throw Poco::NotImplementedException("ODBCTest::testStoredProcedureDynamicAny()");
 }
 
 
-inline void ODBCTest::testStoredFunction() 
-{ 
+inline void ODBCTest::testStoredFunction()
+{
 	throw Poco::NotImplementedException("ODBCTest::testStoredFunction()");
 }
 
 
-inline void ODBCTest::testStoredFunctionAny() 
-{ 
+inline void ODBCTest::testStoredFunctionAny()
+{
 	throw Poco::NotImplementedException("ODBCTest::testStoredFunctionAny()");
 }
 
 
-inline void ODBCTest::testStoredFunctionDynamicAny() 
-{ 
+inline void ODBCTest::testStoredFunctionDynamicAny()
+{
 	throw Poco::NotImplementedException("ODBCTest::testStoredFunctionDynamicAny()");
 }
 
@@ -261,109 +264,109 @@ inline void ODBCTest::dropObject(const std::string& type, const std::string& nam
 
 
 inline void ODBCTest::recreateNullableTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateNullableTable()");
 }
 
 
 inline void ODBCTest::recreatePersonTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreatePersonTable()");
 }
 
 
 inline void ODBCTest::recreatePersonTupleTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreatePersonTupleTable()");
 }
 
 
 inline void ODBCTest::recreatePersonBLOBTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreatePersonBLOBTable()");
 }
 
 
 inline void ODBCTest::recreatePersonDateTimeTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreatePersonDateTimeTable()");
 }
 
 
 inline void ODBCTest::recreatePersonDateTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreatePersonDateTable()");
 }
 
 
 inline void ODBCTest::recreatePersonTimeTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreatePersonTimeTable()");
 }
 
 
 inline void ODBCTest::recreateStringsTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateStringsTable()");
 }
 
 
 inline void ODBCTest::recreateIntsTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateIntsTable()");
 }
 
 
 inline void ODBCTest::recreateFloatsTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateFloatsTable()");
 }
 
 
 inline void ODBCTest::recreateUUIDsTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateUUIDsTable()");
 }
 
 
 inline void ODBCTest::recreateTuplesTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateTuplesTable()");
 }
 
 
 inline void ODBCTest::recreateVectorsTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateVectorsTable()");
 }
 
 
 inline void ODBCTest::recreateAnysTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateAnysTable()");
 }
 
 
 inline void ODBCTest::recreateNullsTable(const std::string&)
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateNullsTable()");
 }
 
 
 inline void ODBCTest::recreateBoolTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateBoolTable()");
 }
 
 
 inline void ODBCTest::recreateMiscTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateMiscTable()");
 }
 
 
 inline void ODBCTest::recreateLogTable()
-{ 
+{
 	throw Poco::NotImplementedException("ODBCTest::recreateLogTable()");
 }
 
@@ -374,48 +377,54 @@ inline void ODBCTest::recreateUnicodeTable()
 }
 
 
-inline bool ODBCTest::bindValue(int i) 
-{ 
+inline void ODBCTest::recreateEncodingTables()
+{
+	throw Poco::NotImplementedException("ODBCTest::recreateUnicodeTables()");
+}
+
+
+inline bool ODBCTest::bindValue(int i)
+{
 	poco_assert (i < 8);
-	return _bindValues[i]; 
+	return _bindValues[i];
 }
 
 
-inline Poco::Data::Session& ODBCTest::session() 
-{ 
+inline Poco::Data::Session& ODBCTest::session()
+{
 	poco_check_ptr (_pSession);
-	return *_pSession; 
+	return *_pSession;
 }
 
 
-inline SQLExecutor& ODBCTest::executor() 
-{ 
+inline SQLExecutor& ODBCTest::executor()
+{
 	poco_check_ptr (_pExecutor);
-	return *_pExecutor; 
+	return *_pExecutor;
 }
 
 
-inline const std::string& ODBCTest::dsn() 
-{ 
-	return _rDSN; 
+inline const std::string& ODBCTest::dsn()
+{
+	return _rDSN;
 }
 
 
-inline const std::string& ODBCTest::uid() 
-{ 
-	return _rUID; 
+inline const std::string& ODBCTest::uid()
+{
+	return _rUID;
 }
 
 
-inline const std::string& ODBCTest::pwd() 
-{ 
-	return _rPwd; 
+inline const std::string& ODBCTest::pwd()
+{
+	return _rPwd;
 }
 
 
-inline const std::string& ODBCTest::dbConnString() 
-{ 
-	return _rConnectString; 
+inline const std::string& ODBCTest::dbConnString()
+{
+	return _rConnectString;
 }
 
 
diff --git a/Data/ODBC/testsuite/src/ODBCTestSuite.cpp b/Data/ODBC/testsuite/src/ODBCTestSuite.cpp
index 64e508e62..d9d418a6b 100644
--- a/Data/ODBC/testsuite/src/ODBCTestSuite.cpp
+++ b/Data/ODBC/testsuite/src/ODBCTestSuite.cpp
@@ -26,15 +26,15 @@ CppUnit::Test* ODBCTestSuite::suite()
 
 	// WARNING!
 	// On Win XP Pro, the PostgreSQL connection fails if attempted after DB2 w/ following error:
-	// 
-	// sqlState="IM003" 
-	// message="Specified driver could not be loaded due to system error  127 (PostgreSQL ANSI)." 
-	// nativeError=160 
+	//
+	// sqlState="IM003"
+	// message="Specified driver could not be loaded due to system error  127 (PostgreSQL ANSI)."
+	// nativeError=160
 	// System error 127 is "The specified procedure could not be found."
 	// This problem does not manifest with Mammoth ODBCng PostgreSQL driver.
 	//
 	// Oracle tests do not exit cleanly if Oracle driver is loaded after DB2.
-	// 
+	//
 	// For the time being, the workaround is to connect to DB2 after connecting to PostgreSQL and Oracle.
 
 	addTest(pSuite, ODBCMySQLTest::suite());
diff --git a/Data/ODBC/testsuite/src/SQLExecutor.cpp b/Data/ODBC/testsuite/src/SQLExecutor.cpp
index 95aa2270b..84f44c7aa 100644
--- a/Data/ODBC/testsuite/src/SQLExecutor.cpp
+++ b/Data/ODBC/testsuite/src/SQLExecutor.cpp
@@ -180,9 +180,9 @@ template <>
 class TypeHandler
 {
 public:
-	static void bind(std::size_t pos, 
-		const Person& obj, 
-		AbstractBinder::Ptr pBinder, 
+	static void bind(std::size_t pos,
+		const Person& obj,
+		AbstractBinder::Ptr pBinder,
 		AbstractBinder::Direction dir = AbstractBinder::PD_IN)
 	{
 		// the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
@@ -231,9 +231,9 @@ template <>
 class TypeHandler
 {
 public:
-	static void bind(std::size_t pos, 
-		const RefCountedPerson& obj, 
-		AbstractBinder::Ptr pBinder, 
+	static void bind(std::size_t pos,
+		const RefCountedPerson& obj,
+		AbstractBinder::Ptr pBinder,
 		AbstractBinder::Direction dir = AbstractBinder::PD_IN)
 	{
 		// the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Age INTEGER(3))
@@ -281,7 +281,7 @@ private:
 } } // namespace Poco::Data
 
 
-const std::string SQLExecutor::MULTI_INSERT = 
+const std::string SQLExecutor::MULTI_INSERT =
 	"INSERT INTO Test VALUES ('1', 2, 3.5);"
 	"INSERT INTO Test VALUES ('2', 3, 4.5);"
 	"INSERT INTO Test VALUES ('3', 4, 5.5);"
@@ -296,9 +296,10 @@ const std::string SQLExecutor::MULTI_SELECT =
 	"SELECT * FROM Test WHERE First = '5';";
 
 
-SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession): 
+SQLExecutor::SQLExecutor(const std::string& name, Poco::Data::Session* pSession, Poco::Data::Session* pEncSession):
 	CppUnit::TestCase(name),
-	_pSession(pSession)
+	_pSession(pSession),
+	_pEncSession(pEncSession)
 {
 }
 
@@ -308,9 +309,9 @@ SQLExecutor::~SQLExecutor()
 }
 
 
-void SQLExecutor::bareboneODBCTest(const std::string& dbConnString, 
-	const std::string& tableCreateString, 
-	SQLExecutor::DataBinding bindMode, 
+void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
+	const std::string& tableCreateString,
+	SQLExecutor::DataBinding bindMode,
 	SQLExecutor::DataExtraction extractMode,
 	bool doTime,
 	const std::string& blobPlaceholder)
@@ -348,7 +349,7 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 
 		rc = SQLGetTypeInfo(hstmt, SQL_TYPE_TIMESTAMP);
 		poco_odbc_check_stmt (rc, hstmt);
-		
+
 		rc = SQLFetch(hstmt);
 		assertTrue (SQL_SUCCEEDED(rc) || SQL_NO_DATA == rc);
 
@@ -413,15 +414,15 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 			if (SQLExecutor::PB_AT_EXEC == bindMode)
 				li[0] = SQL_LEN_DATA_AT_EXEC(size);
 
-			rc = SQLBindParameter(hstmt, 
-				(SQLUSMALLINT) 1, 
-				SQL_PARAM_INPUT, 
-				SQL_C_CHAR, 
-				SQL_LONGVARCHAR, 
+			rc = SQLBindParameter(hstmt,
+				(SQLUSMALLINT) 1,
+				SQL_PARAM_INPUT,
+				SQL_C_CHAR,
+				SQL_LONGVARCHAR,
 				(SQLUINTEGER) size,
 				0,
-				(SQLPOINTER) str[0].c_str(), 
-				size, 
+				(SQLPOINTER) str[0].c_str(),
+				size,
 				&li[0]);
 			poco_odbc_check_stmt (rc, hstmt);
 
@@ -430,15 +431,15 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 				li[1] = SQL_LEN_DATA_AT_EXEC(size);
 			else li[1] = SQL_NTS;
 
-			rc = SQLBindParameter(hstmt, 
-				(SQLUSMALLINT) 2, 
-				SQL_PARAM_INPUT, 
-				SQL_C_CHAR, 
-				SQL_LONGVARCHAR, 
+			rc = SQLBindParameter(hstmt,
+				(SQLUSMALLINT) 2,
+				SQL_PARAM_INPUT,
+				SQL_C_CHAR,
+				SQL_LONGVARCHAR,
 				(SQLUINTEGER) size,
 				0,
-				(SQLPOINTER) str[1].c_str(), 
-				size, 
+				(SQLPOINTER) str[1].c_str(),
+				size,
 				&li[1]);
 			poco_odbc_check_stmt (rc, hstmt);
 
@@ -447,39 +448,39 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 				li[2] = SQL_LEN_DATA_AT_EXEC(size);
 			else li[2] = size;
 
-			rc = SQLBindParameter(hstmt, 
-				(SQLUSMALLINT) 3, 
-				SQL_PARAM_INPUT, 
-				SQL_C_BINARY, 
-				SQL_LONGVARBINARY, 
+			rc = SQLBindParameter(hstmt,
+				(SQLUSMALLINT) 3,
+				SQL_PARAM_INPUT,
+				SQL_C_BINARY,
+				SQL_LONGVARBINARY,
 				(SQLUINTEGER) size,
 				0,
-				(SQLPOINTER) str[2].data(), 
-				size, 
+				(SQLPOINTER) str[2].data(),
+				size,
 				&li[2]);
 			poco_odbc_check_stmt (rc, hstmt);
 
-			rc = SQLBindParameter(hstmt, 
-				(SQLUSMALLINT) 4, 
-				SQL_PARAM_INPUT, 
-				SQL_C_SLONG, 
-				SQL_INTEGER, 
+			rc = SQLBindParameter(hstmt,
+				(SQLUSMALLINT) 4,
+				SQL_PARAM_INPUT,
+				SQL_C_SLONG,
+				SQL_INTEGER,
 				0,
 				0,
-				(SQLPOINTER) &fourth, 
-				0, 
+				(SQLPOINTER) &fourth,
+				0,
 				0);
 			poco_odbc_check_stmt (rc, hstmt);
 
-			rc = SQLBindParameter(hstmt, 
-				(SQLUSMALLINT) 5, 
-				SQL_PARAM_INPUT, 
-				SQL_C_FLOAT, 
-				SQL_REAL, 
+			rc = SQLBindParameter(hstmt,
+				(SQLUSMALLINT) 5,
+				SQL_PARAM_INPUT,
+				SQL_C_FLOAT,
+				SQL_REAL,
 				0,
 				1,
-				(SQLPOINTER) &fifth, 
-				0, 
+				(SQLPOINTER) &fifth,
+				0,
 				0);
 			poco_odbc_check_stmt (rc, hstmt);
 
@@ -498,14 +499,14 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 			else
 				std::cerr << '[' << name() << ']' << " Warning: could not get SQL_TYPE_TIMESTAMP parameter description." << std::endl;
 
-			rc = SQLBindParameter(hstmt, 
-				(SQLUSMALLINT) 6, 
-				SQL_PARAM_INPUT, 
-				SQL_C_TYPE_TIMESTAMP, 
-				SQL_TYPE_TIMESTAMP, 
+			rc = SQLBindParameter(hstmt,
+				(SQLUSMALLINT) 6,
+				SQL_PARAM_INPUT,
+				SQL_C_TYPE_TIMESTAMP,
+				SQL_TYPE_TIMESTAMP,
 				dateTimeColSize,
 				dateTimeDecDigits,
-				(SQLPOINTER) &sixth, 
+				(SQLPOINTER) &sixth,
 				0,
 				0);
 			poco_odbc_check_stmt (rc, hstmt);
@@ -519,9 +520,9 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 				while (SQL_NEED_DATA == (rc = SQLParamData(hstmt, &pParam)))
 				{
 					SQLINTEGER dataSize = 0;
-					// Data size should be ignored for non-null, 
-					// non-variable length fields, but SQLite ODBC 
-					// driver insists on it always being the actual 
+					// Data size should be ignored for non-null,
+					// non-variable length fields, but SQLite ODBC
+					// driver insists on it always being the actual
 					// data length
 
 					if (pParam == (SQLPOINTER) str[0].c_str())
@@ -557,55 +558,55 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 
 			if (SQLExecutor::DE_BOUND == extractMode)
 			{
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 1, 
-					SQL_C_CHAR, 
-					(SQLPOINTER) chr[0], 
-					(SQLINTEGER) sizeof(chr[0]), 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 1,
+					SQL_C_CHAR,
+					(SQLPOINTER) chr[0],
+					(SQLINTEGER) sizeof(chr[0]),
 					&lengths[0]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 2, 
-					SQL_C_CHAR, 
-					(SQLPOINTER) chr[1], 
-					(SQLINTEGER) sizeof(chr[1]), 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 2,
+					SQL_C_CHAR,
+					(SQLPOINTER) chr[1],
+					(SQLINTEGER) sizeof(chr[1]),
 					&lengths[1]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 3, 
-					SQL_C_BINARY, 
-					(SQLPOINTER) chr[2], 
-					(SQLINTEGER) sizeof(chr[2]), 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 3,
+					SQL_C_BINARY,
+					(SQLPOINTER) chr[2],
+					(SQLINTEGER) sizeof(chr[2]),
 					&lengths[2]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 4, 
-					SQL_C_SLONG, 
-					(SQLPOINTER) &fourth, 
-					(SQLINTEGER) 0, 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 4,
+					SQL_C_SLONG,
+					(SQLPOINTER) &fourth,
+					(SQLINTEGER) 0,
 					&lengths[3]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 5, 
-					SQL_C_FLOAT, 
-					(SQLPOINTER) &fifth, 
-					(SQLINTEGER) 0, 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 5,
+					SQL_C_FLOAT,
+					(SQLPOINTER) &fifth,
+					(SQLINTEGER) 0,
 					&lengths[4]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 6, 
-					SQL_C_TYPE_TIMESTAMP, 
-					(SQLPOINTER) &sixth, 
-					(SQLINTEGER) 0, 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 6,
+					SQL_C_TYPE_TIMESTAMP,
+					(SQLPOINTER) &sixth,
+					(SQLINTEGER) 0,
 					&lengths[5]);
 				poco_odbc_check_stmt (rc, hstmt);
 			}
-			
+
 			rc = SQLExecute(hstmt);
 			poco_odbc_check_stmt (rc, hstmt);
 			rc = SQLFetch(hstmt);
@@ -614,67 +615,67 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 			if (SQLExecutor::DE_MANUAL == extractMode)
 			{
 				SQLLEN len = lengths[0] = 0;
-				while (SQL_SUCCESS_WITH_INFO == (rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 1, 
-					SQL_C_CHAR, 
-					chr[0] + len, 
+				while (SQL_SUCCESS_WITH_INFO == (rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 1,
+					SQL_C_CHAR,
+					chr[0] + len,
 					sizeof(chr[0]) - len,
 					&lengths[0])))
 				{
 					len += lengths[0];
-					if (!lengths[0] || len >= sizeof(chr[1])) 
+					if (!lengths[0] || len >= sizeof(chr[1]))
 						break;
 				}
 				poco_odbc_check_stmt (rc, hstmt);
 
 				len = lengths[1] = 0;
-				while (SQL_SUCCESS_WITH_INFO == (rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 2, 
-					SQL_C_CHAR, 
-					chr[1] + len, 
+				while (SQL_SUCCESS_WITH_INFO == (rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 2,
+					SQL_C_CHAR,
+					chr[1] + len,
 					sizeof(chr[1]) - len,
 					&lengths[1])))
 				{
 					len += lengths[1];
-					if (!lengths[1] || len >= sizeof(chr[1])) 
+					if (!lengths[1] || len >= sizeof(chr[1]))
 						break;
 				}
 				poco_odbc_check_stmt (rc, hstmt);
 
 				len = lengths[2] = 0;
-				while (SQL_SUCCESS_WITH_INFO == (rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 3, 
-					SQL_C_BINARY, 
-					chr[2] + len, 
+				while (SQL_SUCCESS_WITH_INFO == (rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 3,
+					SQL_C_BINARY,
+					chr[2] + len,
 					sizeof(chr[2]) - len,
 					&lengths[2])))
 				{
 					len += lengths[1];
-					if (!lengths[2] || len >= sizeof(chr[2])) 
+					if (!lengths[2] || len >= sizeof(chr[2]))
 						break;
 				}
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 4, 
-					SQL_C_SLONG, 
-					&fourth, 
+				rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 4,
+					SQL_C_SLONG,
+					&fourth,
 					0,
 					&lengths[3]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 5, 
-					SQL_C_FLOAT, 
-					&fifth, 
+				rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 5,
+					SQL_C_FLOAT,
+					&fifth,
 					0,
 					&lengths[4]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 6, 
-					SQL_C_TYPE_TIMESTAMP, 
-					&sixth, 
+				rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 6,
+					SQL_C_TYPE_TIMESTAMP,
+					&sixth,
 					0,
 					&lengths[5]);
 				poco_odbc_check_stmt (rc, hstmt);
@@ -727,9 +728,9 @@ void SQLExecutor::bareboneODBCTest(const std::string& dbConnString,
 }
 
 
-void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString, 
-	const std::string& tableCreateString, 
-	SQLExecutor::DataBinding bindMode, 
+void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
+	const std::string& tableCreateString,
+	SQLExecutor::DataBinding bindMode,
 	SQLExecutor::DataExtraction extractMode,
 	const std::string& insert,
 	const std::string& select)
@@ -801,11 +802,11 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
 			poco_odbc_check_stmt (rc, hstmt);
 			if (SQLExecutor::DE_BOUND == extractMode)
 			{
-				rc = SQLBindCol(hstmt, 
-						(SQLUSMALLINT) 1, 
-						SQL_C_SLONG, 
-						(SQLPOINTER) &count, 
-						(SQLINTEGER) 0, 
+				rc = SQLBindCol(hstmt,
+						(SQLUSMALLINT) 1,
+						SQL_C_SLONG,
+						(SQLPOINTER) &count,
+						(SQLINTEGER) 0,
 						&length);
 				poco_odbc_check_stmt (rc, hstmt);
 			}
@@ -818,10 +819,10 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
 
 			if (SQLExecutor::DE_MANUAL == extractMode)
 			{
-				rc = SQLGetData(hstmt, 
-					(SQLUSMALLINT) 1, 
-					SQL_C_SLONG, 
-					&count, 
+				rc = SQLGetData(hstmt,
+					(SQLUSMALLINT) 1,
+					SQL_C_SLONG,
+					&count,
 					0,
 					&length);
 				poco_odbc_check_stmt (rc, hstmt);
@@ -840,34 +841,34 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
 			SQLLEN lengths[3] = { 0 };
 			int second = 0;
 			float third = 0.0f;
-			
+
 			if (SQLExecutor::DE_BOUND == extractMode)
 			{
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 1, 
-					SQL_C_CHAR, 
-					(SQLPOINTER) chr, 
-					(SQLINTEGER) 4, 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 1,
+					SQL_C_CHAR,
+					(SQLPOINTER) chr,
+					(SQLINTEGER) 4,
 					&lengths[0]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 2, 
-					SQL_C_SLONG, 
-					(SQLPOINTER) &second, 
-					(SQLINTEGER) 0, 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 2,
+					SQL_C_SLONG,
+					(SQLPOINTER) &second,
+					(SQLINTEGER) 0,
 					&lengths[1]);
 				poco_odbc_check_stmt (rc, hstmt);
 
-				rc = SQLBindCol(hstmt, 
-					(SQLUSMALLINT) 3, 
-					SQL_C_FLOAT, 
-					(SQLPOINTER) &third, 
-					(SQLINTEGER) 0, 
+				rc = SQLBindCol(hstmt,
+					(SQLUSMALLINT) 3,
+					SQL_C_FLOAT,
+					(SQLPOINTER) &third,
+					(SQLINTEGER) 0,
 					&lengths[2]);
 				poco_odbc_check_stmt (rc, hstmt);
 			}
-			
+
 			rc = SQLExecute(hstmt);
 			poco_odbc_check_stmt (rc, hstmt);
 
@@ -883,26 +884,26 @@ void SQLExecutor::bareboneODBCMultiResultTest(const std::string& dbConnString,
 
 				if (SQLExecutor::DE_MANUAL == extractMode)
 				{
-					rc = SQLGetData(hstmt, 
-						(SQLUSMALLINT) 1, 
-						SQL_C_CHAR, 
-						chr, 
+					rc = SQLGetData(hstmt,
+						(SQLUSMALLINT) 1,
+						SQL_C_CHAR,
+						chr,
 						4,
 						&lengths[0]);
 					poco_odbc_check_stmt (rc, hstmt);
 
-					rc = SQLGetData(hstmt, 
-						(SQLUSMALLINT) 2, 
-						SQL_C_SLONG, 
-						&second, 
+					rc = SQLGetData(hstmt,
+						(SQLUSMALLINT) 2,
+						SQL_C_SLONG,
+						&second,
 						0,
 						&lengths[1]);
 					poco_odbc_check_stmt (rc, hstmt);
 
-					rc = SQLGetData(hstmt, 
-						(SQLUSMALLINT) 3, 
-						SQL_C_FLOAT, 
-						&third, 
+					rc = SQLGetData(hstmt,
+						(SQLUSMALLINT) 3,
+						SQL_C_FLOAT,
+						&third,
 						0,
 						&lengths[2]);
 					poco_odbc_check_stmt (rc, hstmt);
@@ -1567,7 +1568,7 @@ void SQLExecutor::insertSingleBulkVec()
 {
 	std::string funct = "insertSingleBulkVec()";
 	std::vector data;
-	
+
 	for (int x = 0; x < 100; ++x)
 		data.push_back(x);
 
@@ -1673,9 +1674,9 @@ void SQLExecutor::limitPrepare()
 		data.push_back(x);
 	}
 
-	try 
-	{ 
-		Statement stmt = (session() << "INSERT INTO Strings VALUES (?)", use(data)); 
+	try
+	{
+		Statement stmt = (session() << "INSERT INTO Strings VALUES (?)", use(data));
 		assertTrue (100 == stmt.execute());
 	}
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
@@ -1737,13 +1738,13 @@ void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
 	std::vector strings(size, "abc");
 	std::vector floats(size, .5);
 	std::vector dateTimes(size);
-	
+
 	Stopwatch sw;
-	try 
+	try
 	{
 		sw.start();
-		session() << "INSERT INTO MiscTest (First, Third, Fourth, Fifth) VALUES (?,?,?,?)", 
-			use(strings), 
+		session() << "INSERT INTO MiscTest (First, Third, Fourth, Fifth) VALUES (?,?,?,?)",
+			use(strings),
 			use(ints),
 			use(floats),
 			use(dateTimes), now;
@@ -1757,18 +1758,18 @@ void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try 
+	try
 	{
 		sw.restart();
-		session() << "INSERT INTO MiscTest (First, Third, Fourth, Fifth) VALUES (?,?,?,?)", 
-			use(strings, bulk), 
+		session() << "INSERT INTO MiscTest (First, Third, Fourth, Fifth) VALUES (?,?,?,?)",
+			use(strings, bulk),
 			use(ints, bulk),
 			use(floats, bulk),
 			use(dateTimes, bulk), now;
 		sw.stop();
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-	
+
 	double bulkTime = sw.elapsed() / 1000.0;
 
 	double speedup;
@@ -1780,10 +1781,10 @@ void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
 	else
 		speedup = time / bulkTime;
 
-	std::cout << "INSERT => Size:" << size 
-		<< ", Time: " << time 
-		<< ", Bulk Time: " << bulkTime 
-		<< " [ms], Speedup: " << speedup 
+	std::cout << "INSERT => Size:" << size
+		<< ", Time: " << time
+		<< ", Bulk Time: " << bulkTime
+		<< " [ms], Speedup: " << speedup
 		<< 'x' << std::endl;
 
 	ints.clear();
@@ -1791,19 +1792,19 @@ void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
 	floats.clear();
 	dateTimes.clear();
 
-	try 
-	{ 
+	try
+	{
 		sw.restart();
-		session() << "SELECT First, Third, Fourth, Fifth FROM MiscTest", 
-			into(strings), 
-			into(ints), 
+		session() << "SELECT First, Third, Fourth, Fifth FROM MiscTest",
+			into(strings),
+			into(ints),
 			into(floats),
 			into(dateTimes),
-			now; 
+			now;
 		sw.stop();
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-	
+
 	time = sw.elapsed() / 1000.0;
 
 	assertTrue (ints.size() == size);
@@ -1812,20 +1813,20 @@ void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
 	strings.clear();
 	floats.clear();
 	dateTimes.clear();
-	
-	try 
-	{ 
+
+	try
+	{
 		sw.restart();
-		session() << "SELECT First, Third, Fourth, Fifth FROM MiscTest", 
+		session() << "SELECT First, Third, Fourth, Fifth FROM MiscTest",
 			into(strings, bulk(size)),
 			into(ints, bulk(size)),
 			into(floats, bulk(size)),
 			into(dateTimes, bulk(size)),
-			now; 
+			now;
 		sw.stop();
 	} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-	
+
 	bulkTime = sw.elapsed() / 1000.0;
 
 	assertTrue (ints.size() == size);
@@ -1838,10 +1839,10 @@ void SQLExecutor::doBulkPerformance(Poco::UInt32 size)
 	else
 		speedup = time / bulkTime;
 
-	std::cout << "SELECT => Size:" << size 
-		<< ", Time: " << time 
-		<< ", Bulk Time: " << bulkTime 
-		<< " [ms], Speedup: " << speedup 
+	std::cout << "SELECT => Size:" << size
+		<< ", Time: " << time
+		<< ", Bulk Time: " << bulkTime
+		<< " [ms], Speedup: " << speedup
 		<< 'x' << std::endl;
 }
 
@@ -2077,7 +2078,7 @@ void SQLExecutor::multiMapComplex()
 	people.insert(std::make_pair("LN1", p1));
 	people.insert(std::make_pair("LN1", p1));
 	people.insert(std::make_pair("LN2", p2));
-	
+
 	try { session() << "INSERT INTO Person VALUES (?,?,?,?)", use(people), now; }
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
@@ -2139,7 +2140,7 @@ void SQLExecutor::selectIntoSingleStep()
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 	assertTrue (count == 2);
 	Person result;
-	Statement stmt = (session() << "SELECT * FROM Person", into(result), limit(1)); 
+	Statement stmt = (session() << "SELECT * FROM Person", into(result), limit(1));
 	stmt.execute();
 	assertTrue (result == p1);
 	assertTrue (!stmt.done());
@@ -2405,7 +2406,7 @@ void SQLExecutor::blob(int bigSize, const std::string& blobPlaceholder)
 
 	CLOB img("0123456789", 10);
 	int count = 0;
-	try { session() << format("INSERT INTO Person VALUES (?,?,?,%s)", blobPlaceholder), 
+	try { session() << format("INSERT INTO Person VALUES (?,?,?,%s)", blobPlaceholder),
 		use(lastName), use(firstName), use(address), use(img), now; }
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
@@ -2431,7 +2432,7 @@ void SQLExecutor::blob(int bigSize, const std::string& blobPlaceholder)
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try { session() << format("INSERT INTO Person VALUES (?,?,?,%s)", blobPlaceholder), 
+	try { session() << format("INSERT INTO Person VALUES (?,?,?,%s)", blobPlaceholder),
 		use(lastName), use(firstName), use(address), use(big), now; }
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
@@ -2509,11 +2510,11 @@ void SQLExecutor::date()
 
 	Date bornDate(1965, 6, 18);
 	int count = 0;
-	try { session() << "INSERT INTO Person VALUES (?,?,?,?)", 
-		use(lastName), 
-		use(firstName), 
-		use(address), 
-		use(bornDate), 
+	try { session() << "INSERT INTO Person VALUES (?,?,?,?)",
+		use(lastName),
+		use(firstName),
+		use(address),
+		use(bornDate),
 		now; }
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
@@ -2548,11 +2549,11 @@ void SQLExecutor::time()
 
 	Time bornTime (5, 35, 1);
 	int count = 0;
-	try { session() << "INSERT INTO Person VALUES (?,?,?,?)", 
-		use(lastName), 
-		use(firstName), 
-		use(address), 
-		use(bornTime), 
+	try { session() << "INSERT INTO Person VALUES (?,?,?,?)",
+		use(lastName),
+		use(firstName),
+		use(address),
+		use(bornTime),
 		now; }
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
@@ -2600,7 +2601,7 @@ void SQLExecutor::tupleVector()
 	typedef Tuple TupleType;
 	std::string funct = "tupleVector()";
 	TupleType t(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19);
-	Tuple 
+	Tuple
 		t10(10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29);
 	TupleType t100(100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119);
 	std::vector v;
@@ -2639,8 +2640,8 @@ void SQLExecutor::internalExtraction()
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try 
-	{ 
+	try
+	{
 		Statement stmt = (session() << "SELECT * FROM Vectors", now);
 		RecordSet rset(stmt);
 
@@ -2696,7 +2697,7 @@ void SQLExecutor::internalExtraction()
 
 		i = rset.value("str0", 2);
 		assertTrue (5 == i);
-		
+
 		const Column >& col = rset.column >(0);
 		Column >::Iterator it = col.begin();
 		Column >::Iterator end = col.end();
@@ -2736,7 +2737,7 @@ void SQLExecutor::internalExtraction()
 
 		try	{ rset.value(0,0); fail ("must fail"); }
 		catch (BadCastException&) {	}
-		
+
 		stmt = (session() << "DELETE FROM Vectors", now);
 		rset = stmt;
 
@@ -2761,8 +2762,8 @@ void SQLExecutor::filter(const std::string& query, const std::string& intFldName
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try 
-	{ 
+	try
+	{
 		Statement stmt = (session() << query, now);
 		RecordSet rset(stmt);
 		assertTrue (rset.totalRowCount() == 4);
@@ -2772,11 +2773,11 @@ void SQLExecutor::filter(const std::string& query, const std::string& intFldName
 		assertTrue (!pRF->isEmpty());
 
 		Var da;
-		try 
+		try
 		{
 			da = rset.value(0, 1);
 			fail ("must fail");
-		} catch (InvalidAccessException&) 
+		} catch (InvalidAccessException&)
 		{
 			da = rset.value(0, 1, false);
 			assertTrue (2 == da);
@@ -2845,22 +2846,22 @@ void SQLExecutor::internalBulkExtraction()
 		age[i] = i;
 	}
 
-	try 
-	{ 
-		session() << "INSERT INTO Person VALUES (?,?,?,?)", 
-			use(lastName, bulk), 
-			use(firstName, bulk), 
-			use(address, bulk), 
-			use(age, bulk), 
-			now; 
+	try
+	{
+		session() << "INSERT INTO Person VALUES (?,?,?,?)",
+			use(lastName, bulk),
+			use(firstName, bulk),
+			use(address, bulk),
+			use(age, bulk),
+			now;
 	}
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try 
-	{ 
+	try
+	{
 		Statement stmt = (session() << "SELECT * FROM Person", bulk(size), now);
-		RecordSet rset(stmt); 
+		RecordSet rset(stmt);
 		assertTrue (size == rset.rowCount());
 		assertTrue ("LN0" == rset["LastName"]);
 		assertTrue (0 == rset["Age"]);
@@ -2874,10 +2875,10 @@ void SQLExecutor::internalBulkExtraction()
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try 
-	{ 
+	try
+	{
 		Statement stmt = (session() << "SELECT * FROM Person", limit(size), bulk, now);
-		RecordSet rset(stmt); 
+		RecordSet rset(stmt);
 		assertTrue (size == rset.rowCount());
 		assertTrue ("LN0" == rset["LastName"]);
 		assertTrue (0 == rset["Age"]);
@@ -2970,8 +2971,8 @@ void SQLExecutor::internalStorageType()
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-	try 
-	{ 
+	try
+	{
 		std::vector::iterator it = manips.begin();
 		std::vector::iterator end = manips.end();
 
@@ -3028,15 +3029,15 @@ void SQLExecutor::notNulls(const std::string& sqlState)
 	{
 		session() << "INSERT INTO NullTest (i,r,v) VALUES (?,?,?)", use(null), use(null), use(null), now;
 		fail ("must fail");
-	}catch (StatementException& se) 
-	{ 
+	}catch (StatementException& se)
+	{
 		//double check if we're failing for the right reason
 		//default sqlState value is "23502"; some drivers report "HY???" codes
 		if (se.diagnostics().fields().size())
 		{
 			std::string st = se.diagnostics().sqlState(0);
 			if (sqlState != st)
-				std::cerr << '[' << name() << ']' << " Warning: expected SQL state [" << sqlState << 
+				std::cerr << '[' << name() << ']' << " Warning: expected SQL state [" << sqlState <<
 					"], received [" << se.diagnostics().sqlState(0) << "] instead." << std::endl;
 		}
 	}
@@ -3184,7 +3185,7 @@ void SQLExecutor::rowIterator()
 	std::ostringstream osLoop;
 	RecordSet::Iterator it = rset.begin();
 	RecordSet::Iterator end = rset.end();
-	for (int i = 1; it != end; ++it, ++i) 
+	for (int i = 1; it != end; ++it, ++i)
 	{
 		assertTrue (it->get(0) == i);
 		osLoop << *it;
@@ -3201,7 +3202,7 @@ void SQLExecutor::rowIterator()
 	assertTrue (!pRF->isEmpty());
 	it = rset.begin();
 	end = rset.end();
-	for (int i = 1; it != end; ++it, ++i) 
+	for (int i = 1; it != end; ++it, ++i)
 	{
 		assertTrue (it->get(0) == i);
 		assertTrue (1 == i);
@@ -3278,7 +3279,7 @@ void SQLExecutor::asynchronous(int rowCount)
 	Statement::Result result = stmt.executeAsync();
 	assertTrue (!stmt.isAsync());
 	result.wait();
-	
+
 	Statement stmt1 = (tmp << "SELECT * FROM Strings", into(data), async, now);
 	assertTrue (stmt1.isAsync());
 	assertTrue (stmt1.wait() == rowCount);
@@ -3301,7 +3302,7 @@ void SQLExecutor::asynchronous(int rowCount)
 	assertTrue (stmt.isAsync());
 	stmt.wait();
 	assertTrue (stmt.execute() == 0);
-	
+
 	// +++ if this part of the test case fails, increase the rowCount until achieved
 	//  that first execute is still executing when the second one is called
 	try {
@@ -3337,7 +3338,7 @@ void SQLExecutor::asynchronous(int rowCount)
 	assertTrue (data.size() == 0);
 	assertTrue (!stmt2.done());
 	std::size_t rows = 0;
-	
+
 	for (int i = 0; !stmt2.done(); i += step)
 	{
 		stmt2.execute();
@@ -3503,8 +3504,8 @@ void SQLExecutor::sqlChannel(const std::string& connect)
 		rs2.moveNext();
 		assertTrue ("WarningSource" == rs2["Source"]);
 		assertTrue ("f Warning sync message" == rs2["Text"]);
-		
-	} 
+
+	}
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("sqlChannel()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("sqlChannel()"); }
 }
@@ -3517,7 +3518,7 @@ void SQLExecutor::sqlLogger(const std::string& connect)
 		Logger& root = Logger::root();
 		root.setChannel(new SQLChannel(Poco::Data::ODBC::Connector::KEY, connect, "TestSQLChannel"));
 		root.setLevel(Message::PRIO_INFORMATION);
-		
+
 		root.information("a Informational message");
 		root.warning("b Warning message");
 		root.debug("Debug message");
@@ -3530,26 +3531,27 @@ void SQLExecutor::sqlLogger(const std::string& connect)
 		rs.moveNext();
 		assertTrue ("TestSQLChannel" == rs["Source"]);
 		assertTrue ("b Warning message" == rs["Text"]);
-	} 
+		root.setChannel(nullptr);
+	}
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("sqlLogger()"); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("sqlLogger()"); }
 }
 
 
 void SQLExecutor::setTransactionIsolation(Session& session, Poco::UInt32 ti)
-{ 
+{
 	if (session.hasTransactionIsolation(ti))
 	{
 		std::string funct = "setTransactionIsolation()";
 
-		try 
+		try
 		{
 			Transaction t(session, false);
 			t.setIsolation(ti);
-			
+
 			assertTrue (ti == t.getIsolation());
 			assertTrue (t.isIsolation(ti));
-			
+
 			assertTrue (ti == session.getTransactionIsolation());
 			assertTrue (session.isTransactionIsolation(ti));
 		}
@@ -3712,11 +3714,11 @@ void SQLExecutor::transaction(const std::string& connect)
 		Transaction trans(session());
 		assertTrue (trans.isActive());
 		assertTrue (session().isTransaction());
-		
+
 		try { session() << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; }
 		catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-		
+
 		assertTrue (session().isTransaction());
 		assertTrue (trans.isActive());
 
@@ -3768,7 +3770,7 @@ void SQLExecutor::transaction(const std::string& connect)
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 	assertTrue (0 == count);
-	try 
+	try
 	{
 		stmt1.wait(5000);
 		if (local.getTransactionIsolation() == Session::TRANSACTION_READ_UNCOMMITTED)
@@ -3816,7 +3818,7 @@ void SQLExecutor::transaction(const std::string& connect)
 	assertTrue (0 == count);
 
 	trans.execute(sql);
-	
+
 	Statement stmt3 = (local << "SELECT COUNT(*) FROM Person", into(locCount), now);
 	assertTrue (2 == locCount);
 
@@ -3868,7 +3870,7 @@ void SQLExecutor::transactor()
 	try { session() << "DELETE FROM Person", now; session().commit();}
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-	
+
 	try { session() << "SELECT count(*) FROM Person", into(count), now; }
 	catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 	catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
@@ -3959,7 +3961,7 @@ void SQLExecutor::nullable()
 	assertTrue (rs.isNull("EmptyInteger"));
 	assertTrue (rs.isNull("EmptyFloat"));
 	assertTrue (rs.isNull("EmptyDateTime"));
-	
+
 	Var di = 1;
 	Var df = 1.5;
 	Var ds = "abc";
@@ -3969,7 +3971,7 @@ void SQLExecutor::nullable()
 	assertTrue (!df.isEmpty());
 	assertTrue (!ds.isEmpty());
 	assertTrue (!dd.isEmpty());
-	
+
 	Statement stmt = (session() << "SELECT EmptyString, EmptyInteger, EmptyFloat, EmptyDateTime FROM NullableTest", into(ds), into(di), into(df), into(dd), now);
 
 	assertTrue (di.isEmpty());
@@ -4002,9 +4004,9 @@ void SQLExecutor::reconnect()
 	assertTrue (session().isConnected());
 	session().close();
 	assertTrue (!session().isConnected());
-	try 
+	try
 	{
-		session() << "SELECT LastName FROM Person", into(result), now;  
+		session() << "SELECT LastName FROM Person", into(result), now;
 		fail ("must fail");
 	}
 	catch(NotConnectedException&){ }
@@ -4033,4 +4035,55 @@ void SQLExecutor::unicode(const std::string& dbConnString)
 	session() << "SELECT str FROM UnicodeTable", into(wtext), now;
 	Poco::UnicodeConverter::convert(wtext, text);
 	assertTrue (text == std::string((const char*)supp));
-}
\ No newline at end of file
+}
+
+
+void SQLExecutor::encoding(const std::string& dbConnString)
+{
+	try
+	{
+		const unsigned char latinChars[] = { 'g', 252, 'n', 't', 'e', 'r', 0 };
+		const unsigned char utf8Chars[] = { 'g', 195, 188, 'n', 't', 'e', 'r', 0 };
+		std::string latinText((const char*)latinChars);
+		std::string utf8TextIn((const char*)utf8Chars);
+
+		session(true) << "INSERT INTO Latin1Table VALUES (?)", use(utf8TextIn), now;
+
+		std::string latinTextOut;
+		session() << "SELECT str FROM Latin1Table", into(latinTextOut), now;
+		assertTrue(latinText == latinTextOut);
+
+		std::string utf8TextOut;
+		session(true) << "SELECT str FROM Latin1Table", into(utf8TextOut), now;
+		assertTrue(utf8TextIn == utf8TextOut);
+
+		const unsigned char latinChars2[] = { 'G', 220, 'N', 'T', 'E', 'R', 0 };
+		const unsigned char utf8Chars2[] = { 'G', 195, 156, 'N', 'T', 'E', 'R', 0 };
+		std::string latinText2 = (const char*)latinChars2;
+		std::string utf8TextIn2 = (const char*)utf8Chars2;
+
+		session(true) << "INSERT INTO Latin1Table VALUES (?)", use(utf8TextIn2), now;
+
+		std::vector textOutVec;
+		session() << "SELECT str FROM Latin1Table", into(textOutVec), now;
+		assertTrue(textOutVec.size() == 2);
+		assertTrue(textOutVec[0] == latinText);
+		assertTrue(textOutVec[1] == latinText2);
+
+		textOutVec.clear();
+		session(true) << "SELECT str FROM Latin1Table", into(textOutVec), now;
+		assertTrue(textOutVec.size() == 2);
+		assertTrue(textOutVec[0] == utf8TextIn);
+		assertTrue(textOutVec[1] == utf8TextIn2);
+	}
+	catch (Poco::Exception& ex)
+	{
+		std::cout << ex.displayText() << std::endl;
+		throw;
+	}
+	catch (std::exception& ex)
+	{
+		std::cout << ex.what() << std::endl;
+		throw;
+	}
+}
diff --git a/Data/ODBC/testsuite/src/SQLExecutor.h b/Data/ODBC/testsuite/src/SQLExecutor.h
index fe220e73f..5f21805d7 100644
--- a/Data/ODBC/testsuite/src/SQLExecutor.h
+++ b/Data/ODBC/testsuite/src/SQLExecutor.h
@@ -80,14 +80,14 @@ public:
 		PB_IMMEDIATE,
 		PB_AT_EXEC
 	};
-	
+
 	enum DataExtraction
 	{
 		DE_MANUAL,
 		DE_BOUND
 	};
 
-	SQLExecutor(const std::string& name, Poco::Data::Session* _pSession);
+	SQLExecutor(const std::string& name, Poco::Data::Session* pSession, Poco::Data::Session* pEncSession = 0);
 	~SQLExecutor();
 
 	void execute(const std::string& sql);
@@ -95,22 +95,22 @@ public:
 
 	void bareboneODBCTest(const std::string& dbConnString,
 		const std::string& tableCreateString,
-		DataBinding bindMode, 
+		DataBinding bindMode,
 		DataExtraction extractMode,
 		bool doTime=true,
 		const std::string& blobPlaceholder="?");
 
-	void bareboneODBCMultiResultTest(const std::string& dbConnString, 
-		const std::string& tableCreateString, 
-		SQLExecutor::DataBinding bindMode, 
+	void bareboneODBCMultiResultTest(const std::string& dbConnString,
+		const std::string& tableCreateString,
+		SQLExecutor::DataBinding bindMode,
 		SQLExecutor::DataExtraction extractMode,
 		const std::string& insert = MULTI_INSERT,
 		const std::string& select = MULTI_SELECT);
-		/// The above two functions use "bare bone" ODBC API calls  
+		/// The above two functions use "bare bone" ODBC API calls
 		/// (i.e. calls are not "wrapped" in PocoData framework structures).
 		/// The purpose of the functions is to verify that a driver behaves
-		/// correctly as well as to determine its capabilities 
-		/// (e.g. SQLGetData() restrictions relaxation policy, if any). 
+		/// correctly as well as to determine its capabilities
+		/// (e.g. SQLGetData() restrictions relaxation policy, if any).
 		/// If these test pass, subsequent tests failures are likely ours.
 
 	void zeroRows();
@@ -158,7 +158,7 @@ public:
 		C4 floats;
 		C5 dateTimes(size);
 		C6 bools;
-		
+
 		for (int i = 0; i < size; ++i)
 		{
 			ints.push_back(i);
@@ -168,12 +168,12 @@ public:
 			bools.push_back(0 == i % 2);
 		}
 
-		try 
+		try
 		{
-			session() << 
-				Poco::format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder), 
-				use(strings), 
-				use(blobs), 
+			session() <<
+				Poco::format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder),
+				use(strings),
+				use(blobs),
 				use(ints),
 				use(floats),
 				use(dateTimes),
@@ -185,12 +185,12 @@ public:
 		catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-		try 
+		try
 		{
-			session() <<  
+			session() <<
 				Poco::format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder),
-				use(strings, bulk), 
-				use(blobs, bulk), 
+				use(strings, bulk),
+				use(blobs, bulk),
 				use(ints, bulk),
 				use(floats, bulk),
 				use(dateTimes, bulk),
@@ -204,20 +204,20 @@ public:
 		floats.clear();
 		dateTimes.clear();
 		bools.clear();
-		
-		try 
-		{ 
-			session() << "SELECT * FROM MiscTest ORDER BY Third", 
-				into(strings), 
-				into(blobs), 
-				into(ints), 
+
+		try
+		{
+			session() << "SELECT * FROM MiscTest ORDER BY Third",
+				into(strings),
+				into(blobs),
+				into(ints),
 				into(floats),
 				into(dateTimes),
 				into(bools),
-				now; 
+				now;
 		} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-		
+
 		std::string number = Poco::NumberFormatter::format(size - 1);
 		assert (size == ints.size());
 		assert (0 == ints.front());
@@ -235,16 +235,16 @@ public:
 
 		ints.clear();
 
-		try 
-		{ 
-			session() << "SELECT First FROM MiscTest", into(ints, bulk(size)), limit(size+1), now; 
+		try
+		{
+			session() << "SELECT First FROM MiscTest", into(ints, bulk(size)), limit(size+1), now;
 			fail ("must fail");
 		}
 		catch(Poco::InvalidArgumentException&){ }
 
-		try 
-		{ 
-			session() << "SELECT First FROM MiscTest", into(ints), bulk(size), now; 
+		try
+		{
+			session() << "SELECT First FROM MiscTest", into(ints), bulk(size), now;
 			fail ("must fail");
 		}
 		catch(Poco::InvalidAccessException&){ }
@@ -258,17 +258,17 @@ public:
 		dateTimes.clear();
 		bools.clear();
 		bools.resize(size);
-		
-		try 
-		{ 
-			session() << "SELECT First, Second, Third, Fourth, Fifth, Sixth FROM MiscTest ORDER BY Third", 
+
+		try
+		{
+			session() << "SELECT First, Second, Third, Fourth, Fifth, Sixth FROM MiscTest ORDER BY Third",
 				into(strings, bulk),
 				into(blobs, bulk(size)),
 				into(ints, bulk(size)),
 				into(floats, bulk),
 				into(dateTimes, bulk(size)),
 				into(bools, bulk),
-				now; 
+				now;
 		} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
@@ -300,7 +300,7 @@ public:
 		C3 blobs;
 		C4 floats;
 		C5 dateTimes(size);
-	
+
 		for (int i = 0; i < size; ++i)
 		{
 			ints.push_back(i);
@@ -309,11 +309,11 @@ public:
 			floats.push_back(i + .5);
 		}
 
-		try 
+		try
 		{
-			session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?)", 
-				use(strings), 
-				use(blobs), 
+			session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?)",
+				use(strings),
+				use(blobs),
 				use(ints),
 				use(floats),
 				use(dateTimes), now;
@@ -324,35 +324,35 @@ public:
 		catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
 
-		try 
+		try
 		{
-			session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?)", 
-				use(strings, bulk), 
-				use(blobs, bulk), 
+			session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?)",
+				use(strings, bulk),
+				use(blobs, bulk),
 				use(ints, bulk),
 				use(floats, bulk),
 				use(dateTimes, bulk), now;
 		} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-		
+
 		ints.clear();
 		strings.clear();
 		blobs.clear();
 		floats.clear();
 		dateTimes.clear();
 
-		try 
-		{ 
-			session() << "SELECT * FROM MiscTest ORDER BY First", 
-				into(strings), 
-				into(blobs), 
-				into(ints), 
+		try
+		{
+			session() << "SELECT * FROM MiscTest ORDER BY First",
+				into(strings),
+				into(blobs),
+				into(ints),
 				into(floats),
 				into(dateTimes),
-				now; 
+				now;
 		} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-		
+
 		std::string number = Poco::NumberFormatter::format(size - 1);
 		assert (size == ints.size());
 		assert (0 == ints.front());
@@ -368,16 +368,16 @@ public:
 
 		ints.clear();
 
-		try 
-		{ 
-			session() << "SELECT First FROM MiscTest", into(ints, bulk(size)), limit(size+1), now; 
+		try
+		{
+			session() << "SELECT First FROM MiscTest", into(ints, bulk(size)), limit(size+1), now;
 			fail ("must fail");
 		}
 		catch(Poco::InvalidArgumentException&){ }
 
-		try 
-		{ 
-			session() << "SELECT First FROM MiscTest", into(ints), bulk(size), now; 
+		try
+		{
+			session() << "SELECT First FROM MiscTest", into(ints), bulk(size), now;
 			fail ("must fail");
 		}
 		catch(Poco::InvalidAccessException&){ }
@@ -387,19 +387,19 @@ public:
 		blobs.clear();
 		floats.clear();
 		dateTimes.clear();
-		
-		try 
-		{ 
-			session() << "SELECT * FROM MiscTest ORDER BY First", 
+
+		try
+		{
+			session() << "SELECT * FROM MiscTest ORDER BY First",
 				into(strings, bulk(size)),
 				into(blobs, bulk(size)),
 				into(ints, bulk(size)),
 				into(floats, bulk(size)),
 				into(dateTimes, bulk(size)),
-				now; 
+				now;
 		} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
 		catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
-		
+
 		assert (size == ints.size());
 		assert (0 == ints.front());
 		assert (size - 1 == ints.back());
@@ -474,7 +474,7 @@ public:
 	void tupleVector();
 
 	void internalExtraction();
-	void filter(const std::string& query = 
+	void filter(const std::string& query =
 		"SELECT * FROM Vectors ORDER BY int0 ASC",
 		const std::string& intFldName = "int0");
 
@@ -487,11 +487,11 @@ public:
 	void stdVectorBool();
 
 	void asynchronous(int rowCount = 500);
-	
+
 	void any();
 	void dynamicAny();
 
-	void multipleResults(const std::string& sql = 
+	void multipleResults(const std::string& sql =
 		"SELECT * FROM Person WHERE Age = ?; "
 		"SELECT Age FROM Person WHERE FirstName = 'Bart'; "
 		"SELECT * FROM Person WHERE Age = ? OR Age = ? ORDER BY Age;");
@@ -505,6 +505,7 @@ public:
 	void nullable();
 
 	void unicode(const std::string& dbConnString);
+	void encoding(const std::string& dbConnString);
 
 	void reconnect();
 
@@ -514,15 +515,24 @@ private:
 
 	void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);
 
-	Poco::Data::Session& session();
+	Poco::Data::Session& session(bool enc = false);
 	Poco::Data::Session* _pSession;
+	Poco::Data::Session* _pEncSession;
 };
 
 
-inline Poco::Data::Session& SQLExecutor::session()
+inline Poco::Data::Session& SQLExecutor::session(bool enc)
 {
-	poco_check_ptr (_pSession);
-	return *_pSession;
+	if (!enc)
+	{
+		poco_check_ptr(_pSession);
+		return *_pSession;
+	}
+	else
+	{
+		poco_check_ptr(_pEncSession);
+		return *_pEncSession;
+	}
 }
 
 
diff --git a/Data/PostgreSQL/CMakeLists.txt b/Data/PostgreSQL/CMakeLists.txt
index f727fc0c7..d02c2f106 100644
--- a/Data/PostgreSQL/CMakeLists.txt
+++ b/Data/PostgreSQL/CMakeLists.txt
@@ -25,7 +25,7 @@ target_link_libraries(DataPostgreSQL PUBLIC Poco::Data PostgreSQL::client)
 target_include_directories(DataPostgreSQL
 	PUBLIC
 		$
-		$
+		$
 	PRIVATE
 		${CMAKE_CURRENT_SOURCE_DIR}/src
 )
diff --git a/Data/PostgreSQL/Makefile b/Data/PostgreSQL/Makefile
index 5882ea9ef..c3efddb2e 100644
--- a/Data/PostgreSQL/Makefile
+++ b/Data/PostgreSQL/Makefile
@@ -8,7 +8,7 @@ include $(POCO_BASE)/build/rules/global
 
 include PostgreSQL.make
 
-objects = Extractor Binder SessionImpl Connector \
+objects = Extractor BinaryExtractor Binder SessionImpl Connector \
 	PostgreSQLStatementImpl PostgreSQLException \
 	SessionHandle StatementExecutor PostgreSQLTypes Utility
 
diff --git a/Data/PostgreSQL/PostgreSQL_VS90.vcproj b/Data/PostgreSQL/PostgreSQL_VS90.vcproj
index b7abb43be..80534fd1b 100644
--- a/Data/PostgreSQL/PostgreSQL_VS90.vcproj
+++ b/Data/PostgreSQL/PostgreSQL_VS90.vcproj
@@ -504,6 +504,10 @@
 			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
 			>
+			
+			
 			
@@ -550,6 +554,10 @@
 			Filter="h;hpp;hxx;hm;inl;inc;xsd"
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
 			>
+			
+			
 			
diff --git a/Data/PostgreSQL/PostgreSQL_vs140.vcxproj b/Data/PostgreSQL/PostgreSQL_vs140.vcxproj
index 03fae02a6..8e08092ac 100644
--- a/Data/PostgreSQL/PostgreSQL_vs140.vcxproj
+++ b/Data/PostgreSQL/PostgreSQL_vs140.vcxproj
@@ -541,6 +541,9 @@
     
   
   
+    
+      true
+    
     
       true
     
@@ -573,6 +576,7 @@
     
   
   
+    
     
     
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs140.vcxproj.filters b/Data/PostgreSQL/PostgreSQL_vs140.vcxproj.filters
index f3edc2bbb..c71d3e09f 100644
--- a/Data/PostgreSQL/PostgreSQL_vs140.vcxproj.filters
+++ b/Data/PostgreSQL/PostgreSQL_vs140.vcxproj.filters
@@ -11,6 +11,9 @@
     
   
   
+    
+      Source Files
+    
     
       Source Files
     
@@ -43,6 +46,9 @@
     
   
   
+    
+      Header Files
+    
     
       Header Files
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs150.vcxproj b/Data/PostgreSQL/PostgreSQL_vs150.vcxproj
index 4d47d7fa2..69b920311 100644
--- a/Data/PostgreSQL/PostgreSQL_vs150.vcxproj
+++ b/Data/PostgreSQL/PostgreSQL_vs150.vcxproj
@@ -541,6 +541,9 @@
     
   
   
+    
+      true
+    
     
       true
     
@@ -573,6 +576,7 @@
     
   
   
+    
     
     
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs150.vcxproj.filters b/Data/PostgreSQL/PostgreSQL_vs150.vcxproj.filters
index f3edc2bbb..c71d3e09f 100644
--- a/Data/PostgreSQL/PostgreSQL_vs150.vcxproj.filters
+++ b/Data/PostgreSQL/PostgreSQL_vs150.vcxproj.filters
@@ -11,6 +11,9 @@
     
   
   
+    
+      Source Files
+    
     
       Source Files
     
@@ -43,6 +46,9 @@
     
   
   
+    
+      Header Files
+    
     
       Header Files
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs160.vcxproj b/Data/PostgreSQL/PostgreSQL_vs160.vcxproj
index 67d62c9b7..f7fbf3ceb 100644
--- a/Data/PostgreSQL/PostgreSQL_vs160.vcxproj
+++ b/Data/PostgreSQL/PostgreSQL_vs160.vcxproj
@@ -541,6 +541,9 @@
     
   
   
+    
+      true
+    
     
       true
     
@@ -573,6 +576,7 @@
     
   
   
+    
     
     
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs160.vcxproj.filters b/Data/PostgreSQL/PostgreSQL_vs160.vcxproj.filters
index f3edc2bbb..c71d3e09f 100644
--- a/Data/PostgreSQL/PostgreSQL_vs160.vcxproj.filters
+++ b/Data/PostgreSQL/PostgreSQL_vs160.vcxproj.filters
@@ -11,6 +11,9 @@
     
   
   
+    
+      Source Files
+    
     
       Source Files
     
@@ -43,6 +46,9 @@
     
   
   
+    
+      Header Files
+    
     
       Header Files
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs170.sln b/Data/PostgreSQL/PostgreSQL_vs170.sln
index 268cd3b1e..ebfbf7850 100644
--- a/Data/PostgreSQL/PostgreSQL_vs170.sln
+++ b/Data/PostgreSQL/PostgreSQL_vs170.sln
@@ -9,6 +9,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestSuite", "testsuite\Test
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		debug_shared|ARM64 = debug_shared|ARM64
+		release_shared|ARM64 = release_shared|ARM64
+		debug_static_mt|ARM64 = debug_static_mt|ARM64
+		release_static_mt|ARM64 = release_static_mt|ARM64
+		debug_static_md|ARM64 = debug_static_md|ARM64
+		release_static_md|ARM64 = release_static_md|ARM64
 		debug_shared|Win32 = debug_shared|Win32
 		release_shared|Win32 = release_shared|Win32
 		debug_static_mt|Win32 = debug_static_mt|Win32
@@ -23,6 +29,24 @@ Global
 		release_static_md|x64 = release_static_md|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
@@ -59,6 +83,24 @@ Global
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|x64.ActiveCfg = release_static_md|x64
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|x64.Build.0 = release_static_md|x64
 		{73E19FDE-1570-488C-B3DB-72A60FADD408}.release_static_md|x64.Deploy.0 = release_static_md|x64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|ARM64.Build.0 = debug_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|ARM64.Deploy.0 = debug_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_shared|ARM64.ActiveCfg = release_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_shared|ARM64.Build.0 = release_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_shared|ARM64.Deploy.0 = release_shared|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_mt|ARM64.Deploy.0 = debug_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_mt|ARM64.Deploy.0 = release_static_mt|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_static_md|ARM64.Deploy.0 = debug_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_md|ARM64.Build.0 = release_static_md|ARM64
+		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.release_static_md|ARM64.Deploy.0 = release_static_md|ARM64
 		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|Win32.ActiveCfg = debug_shared|Win32
 		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|Win32.Build.0 = debug_shared|Win32
 		{C1B1BB96-5198-48EB-AB48-9A0A0B54FB15}.debug_shared|Win32.Deploy.0 = debug_shared|Win32
diff --git a/Data/PostgreSQL/PostgreSQL_vs170.vcxproj b/Data/PostgreSQL/PostgreSQL_vs170.vcxproj
index 37748402f..20c711b26 100644
--- a/Data/PostgreSQL/PostgreSQL_vs170.vcxproj
+++ b/Data/PostgreSQL/PostgreSQL_vs170.vcxproj
@@ -1,6 +1,10 @@
 
-
+
   
+    
+      debug_shared
+      ARM64
+    
     
       debug_shared
       Win32
@@ -9,6 +13,10 @@
       debug_shared
       x64
     
+    
+      debug_static_md
+      ARM64
+    
     
       debug_static_md
       Win32
@@ -17,6 +25,10 @@
       debug_static_md
       x64
     
+    
+      debug_static_mt
+      ARM64
+    
     
       debug_static_mt
       Win32
@@ -25,6 +37,10 @@
       debug_static_mt
       x64
     
+    
+      release_shared
+      ARM64
+    
     
       release_shared
       Win32
@@ -33,6 +49,10 @@
       release_shared
       x64
     
+    
+      release_static_md
+      ARM64
+    
     
       release_static_md
       Win32
@@ -41,6 +61,10 @@
       release_static_md
       x64
     
+    
+      release_static_mt
+      ARM64
+    
     
       release_static_mt
       Win32
@@ -51,6 +75,7 @@
     
   
   
+    17.0
     PostgreSQL
     {73E19FDE-1570-488C-B3DB-72A60FADD408}
     PostgreSQL
@@ -87,6 +112,36 @@
     MultiByte
     v143
   
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    StaticLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
+  
+    DynamicLibrary
+    MultiByte
+    v143
+  
   
     StaticLibrary
     MultiByte
@@ -137,6 +192,24 @@
   
     
   
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
+  
+    
+  
   
     
   
@@ -157,7 +230,13 @@
   
   
   
-    <_ProjectFileVersion>15.0.28307.799
+    <_ProjectFileVersion>17.0.32505.173
+    PocoDataPostgreSQLA64d
+    PocoDataPostgreSQLmdd
+    PocoDataPostgreSQLmtd
+    PocoDataPostgreSQLA64
+    PocoDataPostgreSQLmd
+    PocoDataPostgreSQLmt
     PocoDataPostgreSQLd
     PocoDataPostgreSQLmdd
     PocoDataPostgreSQLmtd
@@ -171,6 +250,32 @@
     PocoDataPostgreSQLmd
     PocoDataPostgreSQLmt
   
+  
+    ..\..\binA64\
+    objA64\PostgreSQL\$(Configuration)\
+    true
+  
+  
+    ..\..\binA64\
+    objA64\PostgreSQL\$(Configuration)\
+    false
+  
+  
+    ..\..\libA64\
+    objA64\PostgreSQL\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\PostgreSQL\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\PostgreSQL\$(Configuration)\
+  
+  
+    ..\..\libA64\
+    objA64\PostgreSQL\$(Configuration)\
+  
   
     ..\..\bin\
     obj\PostgreSQL\$(Configuration)\
@@ -223,6 +328,164 @@
     ..\..\lib64\
     obj64\PostgreSQL\$(Configuration)\
   
+  
+    
+      Disabled
+      .\include;..\..\postgresql\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;_USRDLL;PostgreSQL_EXPORTS;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\binA64\PocoDataPostgreSQLA64d.dll
+      true
+      true
+      ..\..\binA64\PocoDataPostgreSQLA64d.pdb
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      ..\..\libA64\PocoDataPostgreSQLd.lib
+      MachineARM64
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\postgresql\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;_USRDLL;PostgreSQL_EXPORTS;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\binA64\PocoDataPostgreSQLA64.dll
+      true
+      false
+      ..\..\libA64;%(AdditionalLibraryDirectories)
+      Console
+      true
+      true
+      ..\..\libA64\PocoDataPostgreSQL.lib
+      MachineARM64
+    
+  
+  
+    
+      Disabled
+      .\include;..\..\postgresql\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebug
+      true
+      true
+      true
+      true
+      
+      ..\..\libA64\PocoDataPostgreSQLmtd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataPostgreSQLmtd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\postgresql\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreaded
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataPostgreSQLmt.lib
+    
+  
+  
+    
+      Disabled
+      .\include;..\..\postgresql\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      EnableFastChecks
+      MultiThreadedDebugDLL
+      true
+      true
+      true
+      true
+      
+      ..\..\libA64\PocoDataPostgreSQLmdd.pdb
+      Level3
+      ProgramDatabase
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataPostgreSQLmdd.lib
+    
+  
+  
+    
+      MaxSpeed
+      OnlyExplicitInline
+      true
+      Speed
+      true
+      .\include;..\..\postgresql\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)
+      WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)
+      true
+      MultiThreadedDLL
+      false
+      true
+      true
+      true
+      
+      Level3
+      
+      Default
+      true
+    
+    
+      ..\..\libA64\PocoDataPostgreSQLmd.lib
+    
+  
   
     
       Disabled
@@ -541,6 +804,9 @@
     
   
   
+    
+      true
+    
     
       true
     
@@ -573,6 +839,7 @@
     
   
   
+    
     
     
     
@@ -587,12 +854,16 @@
   
   
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
     
diff --git a/Data/PostgreSQL/PostgreSQL_vs170.vcxproj.filters b/Data/PostgreSQL/PostgreSQL_vs170.vcxproj.filters
index f3edc2bbb..c71d3e09f 100644
--- a/Data/PostgreSQL/PostgreSQL_vs170.vcxproj.filters
+++ b/Data/PostgreSQL/PostgreSQL_vs170.vcxproj.filters
@@ -11,6 +11,9 @@
     
   
   
+    
+      Source Files
+    
     
       Source Files
     
@@ -43,6 +46,9 @@
     
   
   
+    
+      Header Files
+    
     
       Header Files
     
diff --git a/Data/PostgreSQL/include/Poco/Data/PostgreSQL/BinaryExtractor.h b/Data/PostgreSQL/include/Poco/Data/PostgreSQL/BinaryExtractor.h
new file mode 100644
index 000000000..f5701d25b
--- /dev/null
+++ b/Data/PostgreSQL/include/Poco/Data/PostgreSQL/BinaryExtractor.h
@@ -0,0 +1,346 @@
+//
+// BinaryExtractor.h
+//
+// Library: Data/PostgreSQL
+// Package: PostgreSQL
+// Module:  Extractor
+//
+// Definition of the BinaryExtractor class.
+//
+// Copyright (c) 2015, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier:	BSL-1.0
+//
+
+
+#ifndef SQL_PostgreSQL_BinaryExtractor_INCLUDED
+#define SQL_PostgreSQL_BinaryExtractor_INCLUDED
+
+
+#include "Poco/Data/PostgreSQL/PostgreSQL.h"
+#include "Poco/Data/PostgreSQL/PostgreSQLTypes.h"
+#include "Poco/Data/PostgreSQL/StatementExecutor.h"
+#include "Poco/Data/AbstractExtractor.h"
+#include "Poco/Data/LOB.h"
+#include "Poco/Types.h"
+#include "Poco/Any.h"
+#include "Poco/DynamicAny.h"
+#include "Poco/Dynamic/Var.h"
+
+
+namespace Poco {
+namespace Data {
+namespace PostgreSQL {
+
+
+class PostgreSQL_API BinaryExtractor: public Poco::Data::AbstractExtractor
+	/// Extracts and converts data values from the result row returned by PostgreSQL.
+	/// If NULL is received, the incoming val value is not changed and false is returned
+{
+public:
+	using Ptr = SharedPtr;
+
+	BinaryExtractor(StatementExecutor& st);
+		/// Creates the Extractor.
+
+	virtual ~BinaryExtractor();
+		/// Destroys the Extractor.
+
+	virtual bool extract(std::size_t pos, Poco::Int8& val);
+		/// Extracts an Int8.
+
+	virtual bool extract(std::size_t pos, Poco::UInt8& val);
+		/// Extracts an UInt8.
+
+	virtual bool extract(std::size_t pos, Poco::Int16& val);
+		/// Extracts an Int16.
+
+	virtual bool extract(std::size_t pos, Poco::UInt16& val);
+		/// Extracts an UInt16.
+
+	virtual bool extract(std::size_t pos, Poco::Int32& val);
+		/// Extracts an Int32.
+
+	virtual bool extract(std::size_t pos, Poco::UInt32& val);
+		/// Extracts an UInt32.
+
+	virtual bool extract(std::size_t pos, Poco::Int64& val);
+		/// Extracts an Int64.
+
+	virtual bool extract(std::size_t pos, Poco::UInt64& val);
+		/// Extracts an UInt64.
+
+#ifndef POCO_INT64_IS_LONG
+	virtual bool extract(std::size_t pos, long& val);
+		/// Extracts a long. Returns false if null was received.
+
+	virtual bool extract(std::size_t pos, unsigned long& val);
+		/// Extracts an unsigned long. Returns false if null was received.
+#endif
+
+	virtual bool extract(std::size_t pos, bool& val);
+		/// Extracts a boolean.
+
+	virtual bool extract(std::size_t pos, float& val);
+		/// Extracts a float.
+
+	virtual bool extract(std::size_t pos, double& val);
+		/// Extracts a double.
+
+	virtual bool extract(std::size_t pos, char& val);
+		/// Extracts a single character.
+
+	virtual bool extract(std::size_t pos, std::string& val);
+		/// Extracts a string.
+
+	virtual bool extract(std::size_t pos, Poco::Data::BLOB& val);
+		/// Extracts a BLOB.
+
+	virtual bool extract(std::size_t pos, Poco::Data::CLOB& val);
+		/// Extracts a CLOB.
+
+	virtual bool extract(std::size_t pos, DateTime& val);
+		/// Extracts a DateTime. Returns false if null was received.
+
+	virtual bool extract(std::size_t pos, Date& val);
+		/// Extracts a Date. Returns false if null was received.
+
+	virtual bool extract(std::size_t pos, Time& val);
+		/// Extracts a Time. Returns false if null was received.
+
+	virtual bool extract(std::size_t pos, UUID& val);
+		/// Extracts a UUID. Returns false if null was received.
+
+	virtual bool extract(std::size_t pos, Any& val);
+		/// Extracts an Any. Returns false if null was received.
+
+	virtual bool extract(std::size_t pos, Dynamic::Var& val);
+		/// Extracts a Dynamic::Var. Returns false if null was received.
+
+	virtual bool isNull(std::size_t col, std::size_t row);
+		/// Returns true if the value at [col,row] position is null.
+
+	virtual void reset();
+		/// Resets any information internally cached by the extractor.
+
+	////////////
+	// Not implemented extract functions
+	////////////
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an Int8 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an Int8 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an Int8 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an UInt8 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an UInt8 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an UInt8 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an Int16 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an Int16 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an Int16 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an UInt16 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an UInt16 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an UInt16 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an Int32 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an Int32 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an Int32 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an UInt32 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an UInt32 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an UInt32 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an Int64 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an Int64 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an Int64 list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts an UInt64 vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts an UInt64 deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts an UInt64 list.
+
+#ifndef POCO_INT64_IS_LONG
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a long vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a long deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a long list.
+#endif
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a boolean vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a boolean deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a boolean list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a float vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a float deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a float list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a double vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a double deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a double list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a character vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a character deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a character list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a string vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a string deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a string list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a BLOB vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a BLOB deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a BLOB list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a CLOB vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a CLOB deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a CLOB list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a DateTime vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a DateTime deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a DateTime list.
+
+	virtual bool extract(std::size_t pos, std::vector& val);
+		/// Extracts a Date vector.
+
+	virtual bool extract(std::size_t pos, std::deque& val);
+		/// Extracts a Date deque.
+
+	virtual bool extract(std::size_t pos, std::list& val);
+		/// Extracts a Date list.
+
+	virtual bool extract(std::size_t pos, std::vector
   
     
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
+      true
       true
       true
     
diff --git a/Data/SQLite/include/Poco/Data/SQLite/Notifier.h b/Data/SQLite/include/Poco/Data/SQLite/Notifier.h
index 10a165007..ceabe7efa 100644
--- a/Data/SQLite/include/Poco/Data/SQLite/Notifier.h
+++ b/Data/SQLite/include/Poco/Data/SQLite/Notifier.h
@@ -35,15 +35,15 @@ namespace SQLite {
 
 class SQLite_API Notifier
 	/// Notifier is a wrapper for SQLite callback calls. It supports event callbacks
-	/// for insert, update, delete, commit and rollback events. While (un)registering 
-	/// callbacks is thread-safe, execution of the callbacks themselves are not; 
-	/// it is the user's responsibility to ensure the thread-safey of the functions 
+	/// for insert, update, delete, commit and rollback events. While (un)registering
+	/// callbacks is thread-safe, execution of the callbacks themselves are not;
+	/// it is the user's responsibility to ensure the thread-safey of the functions
 	/// they provide as callback target. Additionally, commit callbacks may prevent
 	/// database transactions from succeeding (see sqliteCommitCallbackFn documentation
-	/// for details). 
-	/// 
+	/// for details).
+	///
 	/// There can be only one set of callbacks per session (i.e. registering a new
-	/// callback automatically unregisters the previous one). All callbacks are 
+	/// callback automatically unregisters the previous one). All callbacks are
 	/// registered and enabled at Notifier contruction time and can be disabled
 	/// at a later point time.
 {
@@ -53,9 +53,9 @@ public:
 
 	typedef Poco::BasicEvent Event;
 
-	// 
+	//
 	// Events
-	// 
+	//
 	Event update;
 	Event insert;
 	Event erase;
@@ -113,7 +113,7 @@ public:
 		/// Disables all callbacks.
 
 	static void sqliteUpdateCallbackFn(void* pVal, int opCode, const char* pDB, const char* pTable, Poco::Int64 row);
-		/// Update callback event dispatcher. Determines the type of the event, updates the row number 
+		/// Update callback event dispatcher. Determines the type of the event, updates the row number
 		/// and triggers the event.
 
 	static int sqliteCommitCallbackFn(void* pVal);
@@ -165,9 +165,9 @@ private:
 };
 
 
-// 
+//
 // inlines
-// 
+//
 
 inline bool Notifier::operator == (const Notifier& other) const
 {
diff --git a/Data/SQLite/include/Poco/Data/SQLite/SQLiteStatementImpl.h b/Data/SQLite/include/Poco/Data/SQLite/SQLiteStatementImpl.h
index 1044beb7e..75a5afdb8 100644
--- a/Data/SQLite/include/Poco/Data/SQLite/SQLiteStatementImpl.h
+++ b/Data/SQLite/include/Poco/Data/SQLite/SQLiteStatementImpl.h
@@ -55,7 +55,7 @@ protected:
 	int affectedRowCount() const;
 		/// Returns the number of affected rows.
 		/// Used to find out the number of rows affected by insert, delete or update.
-		/// All changes are counted, even if they are later undone by a ROLLBACK or ABORT. 
+		/// All changes are counted, even if they are later undone by a ROLLBACK or ABORT.
 		/// Changes associated with creating and dropping tables are not counted.
 
 	const MetaColumn& metaColumn(std::size_t pos) const;
diff --git a/Data/SQLite/include/Poco/Data/SQLite/SessionImpl.h b/Data/SQLite/include/Poco/Data/SQLite/SessionImpl.h
index 893e1a9a1..9d6d292cb 100644
--- a/Data/SQLite/include/Poco/Data/SQLite/SessionImpl.h
+++ b/Data/SQLite/include/Poco/Data/SQLite/SessionImpl.h
@@ -19,6 +19,7 @@
 
 
 #include "Poco/Data/SQLite/SQLite.h"
+#include "Poco/Data/SQLite/Utility.h"
 #include "Poco/Data/SQLite/Connector.h"
 #include "Poco/Data/SQLite/Binder.h"
 #include "Poco/Data/AbstractSessionImpl.h"
@@ -53,16 +54,16 @@ public:
 
 	void open(const std::string& connect = "");
 		/// Opens a connection to the Database.
-		/// 
-		/// An in-memory system database (sys), with a single table (dual) 
+		///
+		/// An in-memory system database (sys), with a single table (dual)
 		/// containing single field (dummy) is attached to the database.
 		/// The in-memory system database is used to force change count
-		/// to be reset to zero on every new query (or batch of queries) 
+		/// to be reset to zero on every new query (or batch of queries)
 		/// execution. Without this functionality, select statements
 		/// executions that do not return any rows return the count of
 		/// changes effected by the most recent insert, update or delete.
 		/// In-memory system database can be queried and updated but can not
-		/// be dropped. It may be used for other purposes 
+		/// be dropped. It may be used for other purposes
 		/// in the future.
 
 	void close();
@@ -117,6 +118,12 @@ public:
 	bool isAutoCommit(const std::string& name="") const;
 		/// Returns autocommit property value.
 
+	void setTransactionType(TransactionType transactionType);
+		/// Sets begin transaction type for the session.
+
+	TransactionType getTransactionType() const;
+		/// Returns begin transaction type.
+
 	const std::string& connectorName() const;
 		/// Returns the name of the connector.
 
@@ -124,16 +131,20 @@ protected:
 	void setConnectionTimeout(const std::string& prop, const Poco::Any& value);
 	Poco::Any getConnectionTimeout(const std::string& prop) const;
 
+	void setTransactionType(const std::string &prop, const Poco::Any& value);
+	Poco::Any getTransactionType(const std::string& prop) const;
 private:
 	std::string _connector;
 	sqlite3*    _pDB;
 	bool        _connected;
 	bool        _isTransaction;
+	TransactionType _transactionType;
 	int         _timeout;
 	mutable
 	Poco::Mutex _mutex;
-
 	static const std::string DEFERRED_BEGIN_TRANSACTION;
+	static const std::string EXCLUSIVE_BEGIN_TRANSACTION;
+	static const std::string IMMEDIATE_BEGIN_TRANSACTION; 
 	static const std::string COMMIT_TRANSACTION;
 	static const std::string ABORT_TRANSACTION;
 };
@@ -148,7 +159,7 @@ inline bool SessionImpl::canTransact() const
 }
 
 
-inline 	bool SessionImpl::isTransaction() const
+inline bool SessionImpl::isTransaction() const
 {
 	return _isTransaction;
 }
@@ -165,6 +176,10 @@ inline std::size_t SessionImpl::getConnectionTimeout() const
 	return static_cast(_timeout/1000);
 }
 
+inline TransactionType SessionImpl::getTransactionType() const
+{
+	return _transactionType;
+}
 
 } } } // namespace Poco::Data::SQLite
 
diff --git a/Data/SQLite/include/Poco/Data/SQLite/Utility.h b/Data/SQLite/include/Poco/Data/SQLite/Utility.h
index 55170471c..c4d6e050b 100644
--- a/Data/SQLite/include/Poco/Data/SQLite/Utility.h
+++ b/Data/SQLite/include/Poco/Data/SQLite/Utility.h
@@ -43,6 +43,17 @@ class SQLite_API Utility
 	/// Various utility functions for SQLite.
 {
 public:
+
+	// SQLite Transaction type
+	static const std::string TRANSACTION_TYPE_PROPERTY_KEY;
+
+	enum class TransactionType
+	{
+		DEFERRED,
+		EXCLUSIVE,
+		IMMEDIATE
+	};
+
 	static const std::string SQLITE_DATE_FORMAT;
 	static const std::string SQLITE_TIME_FORMAT;
 	typedef std::map TypeMap;
@@ -73,37 +84,37 @@ public:
 	static bool fileToMemory(sqlite3* pInMemory, const std::string& fileName);
 		/// Loads the contents of a database file on disk into an opened
 		/// database in memory.
-		/// 
+		///
 		/// Returns true if succesful.
 
 	static bool fileToMemory(const Session& session, const std::string& fileName);
 		/// Loads the contents of a database file on disk into an opened
 		/// database in memory.
-		/// 
+		///
 		/// Returns true if succesful.
 
 	static bool memoryToFile(const std::string& fileName, sqlite3* pInMemory);
 		/// Saves the contents of an opened database in memory to the
 		/// database on disk.
-		/// 
+		///
 		/// Returns true if succesful.
 
 	static bool memoryToFile(const std::string& fileName, const Session& session);
 		/// Saves the contents of an opened database in memory to the
 		/// database on disk.
-		/// 
+		///
 		/// Returns true if succesful.
 
 	static bool isThreadSafe();
 		/// Returns true if SQLite was compiled in multi-thread or serialized mode.
 		/// See http://www.sqlite.org/c3ref/threadsafe.html for details.
-		/// 
+		///
 		/// Returns true if succesful
 
 	static bool setThreadMode(int mode);
 		/// Sets the threading mode to single, multi or serialized.
 		/// See http://www.sqlite.org/threadsafe.html for details.
-		/// 
+		///
 		/// Returns true if succesful
 
 	static int getThreadMode();
@@ -111,7 +122,7 @@ public:
 
 	typedef void(*UpdateCallbackType)(void*, int, const char*, const char*, Poco::Int64);
 		/// Update callback function type.
- 
+
 	typedef int(*CommitCallbackType)(void*);
 		/// Commit callback function type.
 
@@ -120,13 +131,13 @@ public:
 
 	template 
 	static bool registerUpdateHandler(sqlite3* pDB, CBT callbackFn, T* pParam)
-		/// Registers the callback for (1)(insert, delete, update), (2)(commit) or 
+		/// Registers the callback for (1)(insert, delete, update), (2)(commit) or
 		/// or (3)(rollback) events. Only one function per group can be registered
 		/// at a time. Registration is not thread-safe. Storage pointed to by pParam
 		/// must remain valid as long as registration is active. Registering with
 		/// callbackFn set to zero disables notifications.
-		/// 
-		/// See http://www.sqlite.org/c3ref/update_hook.html and 
+		///
+		/// See http://www.sqlite.org/c3ref/update_hook.html and
 		/// http://www.sqlite.org/c3ref/commit_hook.html for details.
 	{
 		typedef std::pair CBPair;
@@ -190,11 +201,11 @@ private:
 	Utility();
 		/// Maps SQLite column declared types to Poco::Data types through
 		/// static TypeMap member.
-		/// 
+		///
 		/// Note: SQLite is type-agnostic and it is the end-user responsibility
-		/// to ensure that column declared data type corresponds to the type of 
+		/// to ensure that column declared data type corresponds to the type of
 		/// data actually held in the database.
-		/// 
+		///
 		/// Column types are case-insensitive.
 
 	Utility(const Utility&);
@@ -210,6 +221,9 @@ private:
 };
 
 
+using TransactionType = Utility::TransactionType;
+
+
 //
 // inlines
 //
diff --git a/Data/SQLite/src/Notifier.cpp b/Data/SQLite/src/Notifier.cpp
index 9beb75663..163cfc4a2 100644
--- a/Data/SQLite/src/Notifier.cpp
+++ b/Data/SQLite/src/Notifier.cpp
@@ -57,10 +57,10 @@ Notifier::~Notifier()
 bool Notifier::enableUpdate()
 {
 	Poco::Mutex::ScopedLock l(_mutex);
-	
+
 	if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteUpdateCallbackFn, this))
 		_enabledEvents |= SQLITE_NOTIFY_UPDATE;
-	
+
 	return updateEnabled();
 }
 
@@ -68,10 +68,10 @@ bool Notifier::enableUpdate()
 bool Notifier::disableUpdate()
 {
 	Poco::Mutex::ScopedLock l(_mutex);
-	
+
 	if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::UpdateCallbackType) 0, this))
 		_enabledEvents &= ~SQLITE_NOTIFY_UPDATE;
-	
+
 	return !updateEnabled();
 }
 
@@ -85,10 +85,10 @@ bool Notifier::updateEnabled() const
 bool Notifier::enableCommit()
 {
 	Poco::Mutex::ScopedLock l(_mutex);
-	
+
 	if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteCommitCallbackFn, this))
 		_enabledEvents |= SQLITE_NOTIFY_COMMIT;
-	
+
 	return commitEnabled();
 }
 
@@ -96,10 +96,10 @@ bool Notifier::enableCommit()
 bool Notifier::disableCommit()
 {
 	Poco::Mutex::ScopedLock l(_mutex);
-	
+
 	if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::CommitCallbackType) 0, this))
 		_enabledEvents &= ~SQLITE_NOTIFY_COMMIT;
-	
+
 	return !commitEnabled();
 }
 
@@ -113,10 +113,10 @@ bool Notifier::commitEnabled() const
 bool Notifier::enableRollback()
 {
 	Poco::Mutex::ScopedLock l(_mutex);
-	
+
 	if (Utility::registerUpdateHandler(Utility::dbHandle(_session), &sqliteRollbackCallbackFn, this))
 		_enabledEvents |= SQLITE_NOTIFY_ROLLBACK;
-	
+
 	return rollbackEnabled();
 }
 
@@ -127,7 +127,7 @@ bool Notifier::disableRollback()
 
 	if (Utility::registerUpdateHandler(Utility::dbHandle(_session), (Utility::RollbackCallbackType) 0, this))
 		_enabledEvents &= ~SQLITE_NOTIFY_ROLLBACK;
-	
+
 	return !rollbackEnabled();
 }
 
@@ -154,7 +154,7 @@ void Notifier::sqliteUpdateCallbackFn(void* pVal, int opCode, const char* pDB, c
 {
 	poco_check_ptr(pVal);
 	Notifier* pV = reinterpret_cast(pVal);
-	
+
 	if (opCode == Utility::OPERATION_INSERT)
 	{
 		pV->_table = pTable;
diff --git a/Data/SQLite/src/SQLiteStatementImpl.cpp b/Data/SQLite/src/SQLiteStatementImpl.cpp
index 746b50c01..ec3e469d9 100644
--- a/Data/SQLite/src/SQLiteStatementImpl.cpp
+++ b/Data/SQLite/src/SQLiteStatementImpl.cpp
@@ -46,7 +46,7 @@ SQLiteStatementImpl::SQLiteStatementImpl(Poco::Data::SessionImpl& rSession, sqli
 {
 	_columns.resize(1);
 }
-	
+
 
 SQLiteStatementImpl::~SQLiteStatementImpl()
 {
@@ -287,7 +287,7 @@ std::size_t SQLiteStatementImpl::next()
 	{
 		Utility::throwException(_pDB, _nextResponse, std::string("Iterator Error: trying to access the next value"));
 	}
-	
+
 	return 1u;
 }
 
diff --git a/Data/SQLite/src/SessionImpl.cpp b/Data/SQLite/src/SessionImpl.cpp
index 9d1583e9e..da6c7dd89 100644
--- a/Data/SQLite/src/SessionImpl.cpp
+++ b/Data/SQLite/src/SessionImpl.cpp
@@ -40,6 +40,8 @@ namespace SQLite {
 
 
 const std::string SessionImpl::DEFERRED_BEGIN_TRANSACTION("BEGIN DEFERRED");
+const std::string SessionImpl::EXCLUSIVE_BEGIN_TRANSACTION("BEGIN EXCLUSIVE");
+const std::string SessionImpl::IMMEDIATE_BEGIN_TRANSACTION("BEGIN IMMEDIATE");
 const std::string SessionImpl::COMMIT_TRANSACTION("COMMIT");
 const std::string SessionImpl::ABORT_TRANSACTION("ROLLBACK");
 
@@ -49,7 +51,8 @@ SessionImpl::SessionImpl(const std::string& fileName, std::size_t loginTimeout):
 	_connector(Connector::KEY),
 	_pDB(0),
 	_connected(false),
-	_isTransaction(false)
+	_isTransaction(false),
+	_transactionType(TransactionType::DEFERRED)
 {
 	open();
 	setConnectionTimeout(loginTimeout);
@@ -58,6 +61,7 @@ SessionImpl::SessionImpl(const std::string& fileName, std::size_t loginTimeout):
 		&SessionImpl::autoCommit,
 		&SessionImpl::isAutoCommit);
 	addProperty("connectionTimeout", &SessionImpl::setConnectionTimeout, &SessionImpl::getConnectionTimeout);
+	addProperty(Utility::TRANSACTION_TYPE_PROPERTY_KEY, &SessionImpl::setTransactionType, &SessionImpl::getTransactionType);
 }
 
 
@@ -85,7 +89,18 @@ void SessionImpl::begin()
 {
 	Poco::Mutex::ScopedLock l(_mutex);
 	SQLiteStatementImpl tmp(*this, _pDB);
-	tmp.add(DEFERRED_BEGIN_TRANSACTION);
+	switch (_transactionType)
+	{
+	case TransactionType::DEFERRED:
+		tmp.add(DEFERRED_BEGIN_TRANSACTION);
+		break;
+	case TransactionType::EXCLUSIVE:
+		tmp.add(EXCLUSIVE_BEGIN_TRANSACTION);
+		break;
+	case TransactionType::IMMEDIATE:
+		tmp.add(IMMEDIATE_BEGIN_TRANSACTION);
+		break;
+	}
 	tmp.execute();
 	_isTransaction = true;
 }
@@ -161,6 +176,8 @@ void SessionImpl::open(const std::string& connect)
 			rc = sqlite3_open_v2(connectionString().c_str(), &_pDB,
 				SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_URI, NULL);
 			if (rc == SQLITE_OK) break;
+			if (!_pDB)
+				throw ConnectionFailedException(std::string(sqlite3_errstr(rc)));
 			if (sw.elapsedSeconds() >= tout)
 			{
 				Utility::throwException(_pDB, rc);
@@ -223,6 +240,20 @@ Poco::Any SessionImpl::getConnectionTimeout(const std::string& prop) const
 	return Poco::Any(_timeout/1000);
 }
 
+void SessionImpl::setTransactionType(TransactionType transactionType) 
+{
+	_transactionType = transactionType;
+}
+
+void SessionImpl::setTransactionType(const std::string &prop, const Poco::Any& value) 
+{
+	setTransactionType(Poco::RefAnyCast(value));
+}
+
+Poco::Any SessionImpl::getTransactionType(const std::string& prop) const 
+{
+	return Poco::Any(_transactionType);
+}
 
 void SessionImpl::autoCommit(const std::string&, bool)
 {
diff --git a/Data/SQLite/src/Utility.cpp b/Data/SQLite/src/Utility.cpp
index 60af9c3bb..d07426326 100644
--- a/Data/SQLite/src/Utility.cpp
+++ b/Data/SQLite/src/Utility.cpp
@@ -37,6 +37,8 @@ namespace Data {
 namespace SQLite {
 
 
+const std::string Utility::TRANSACTION_TYPE_PROPERTY_KEY = "transactionType";
+
 const int Utility::THREAD_MODE_SINGLE = SQLITE_CONFIG_SINGLETHREAD;
 const int Utility::THREAD_MODE_MULTI = SQLITE_CONFIG_MULTITHREAD;
 const int Utility::THREAD_MODE_SERIAL = SQLITE_CONFIG_SERIALIZED;
diff --git a/Data/SQLite/src/sqlite3.c b/Data/SQLite/src/sqlite3.c
index 89faea5b2..eb8d7d5cd 100644
--- a/Data/SQLite/src/sqlite3.c
+++ b/Data/SQLite/src/sqlite3.c
@@ -1,6 +1,6 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.36.0.  By combining all the individual C code files into this
+** version 3.38.5.  By combining all the individual C code files into this
 ** single large file, the entire code can be compiled as a single translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
@@ -22,793 +22,6 @@
 #ifndef SQLITE_PRIVATE
 # define SQLITE_PRIVATE static
 #endif
-/************** Begin file ctime.c *******************************************/
-/*
-** 2010 February 23
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file implements routines used to report what compile-time options
-** SQLite was built with.
-*/
-
-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */
-
-/*
-** Include the configuration header output by 'configure' if we're using the
-** autoconf-based build
-*/
-#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H)
-#include "config.h"
-#define SQLITECONFIG_H 1
-#endif
-
-/* These macros are provided to "stringify" the value of the define
-** for those options in which the value is meaningful. */
-#define CTIMEOPT_VAL_(opt) #opt
-#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
-
-/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This
-** option requires a separate macro because legal values contain a single
-** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */
-#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2
-#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt)
-
-/*
-** An array of names of all compile-time options.  This array should
-** be sorted A-Z.
-**
-** This array looks large, but in a typical installation actually uses
-** only a handful of compile-time options, so most times this array is usually
-** rather short and uses little memory space.
-*/
-static const char * const sqlite3azCompileOpt[] = {
-
-/*
-** BEGIN CODE GENERATED BY tool/mkctime.tcl
-*/
-#if SQLITE_32BIT_ROWID
-  "32BIT_ROWID",
-#endif
-#if SQLITE_4_BYTE_ALIGNED_MALLOC
-  "4_BYTE_ALIGNED_MALLOC",
-#endif
-#if SQLITE_64BIT_STATS
-  "64BIT_STATS",
-#endif
-#ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN
-# if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1
-  "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN),
-# endif
-#endif
-#if SQLITE_ALLOW_URI_AUTHORITY
-  "ALLOW_URI_AUTHORITY",
-#endif
-#ifdef SQLITE_BITMASK_TYPE
-  "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE),
-#endif
-#if SQLITE_BUG_COMPATIBLE_20160819
-  "BUG_COMPATIBLE_20160819",
-#endif
-#if SQLITE_CASE_SENSITIVE_LIKE
-  "CASE_SENSITIVE_LIKE",
-#endif
-#if SQLITE_CHECK_PAGES
-  "CHECK_PAGES",
-#endif
-#if defined(__clang__) && defined(__clang_major__)
-  "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "."
-                    CTIMEOPT_VAL(__clang_minor__) "."
-                    CTIMEOPT_VAL(__clang_patchlevel__),
-#elif defined(_MSC_VER)
-  "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER),
-#elif defined(__GNUC__) && defined(__VERSION__)
-  "COMPILER=gcc-" __VERSION__,
-#endif
-#if SQLITE_COVERAGE_TEST
-  "COVERAGE_TEST",
-#endif
-#if SQLITE_DEBUG
-  "DEBUG",
-#endif
-#if SQLITE_DEFAULT_AUTOMATIC_INDEX
-  "DEFAULT_AUTOMATIC_INDEX",
-#endif
-#if SQLITE_DEFAULT_AUTOVACUUM
-  "DEFAULT_AUTOVACUUM",
-#endif
-#ifdef SQLITE_DEFAULT_CACHE_SIZE
-  "DEFAULT_CACHE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_CACHE_SIZE),
-#endif
-#if SQLITE_DEFAULT_CKPTFULLFSYNC
-  "DEFAULT_CKPTFULLFSYNC",
-#endif
-#ifdef SQLITE_DEFAULT_FILE_FORMAT
-  "DEFAULT_FILE_FORMAT=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_FORMAT),
-#endif
-#ifdef SQLITE_DEFAULT_FILE_PERMISSIONS
-  "DEFAULT_FILE_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_PERMISSIONS),
-#endif
-#if SQLITE_DEFAULT_FOREIGN_KEYS
-  "DEFAULT_FOREIGN_KEYS",
-#endif
-#ifdef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
-  "DEFAULT_JOURNAL_SIZE_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT),
-#endif
-#ifdef SQLITE_DEFAULT_LOCKING_MODE
-  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
-#endif
-#ifdef SQLITE_DEFAULT_LOOKASIDE
-  "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE),
-#endif
-#ifdef SQLITE_DEFAULT_MEMSTATUS
-# if SQLITE_DEFAULT_MEMSTATUS != 1
-  "DEFAULT_MEMSTATUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_MEMSTATUS),
-# endif
-#endif
-#ifdef SQLITE_DEFAULT_MMAP_SIZE
-  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
-#endif
-#ifdef SQLITE_DEFAULT_PAGE_SIZE
-  "DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_PAGE_SIZE),
-#endif
-#ifdef SQLITE_DEFAULT_PCACHE_INITSZ
-  "DEFAULT_PCACHE_INITSZ=" CTIMEOPT_VAL(SQLITE_DEFAULT_PCACHE_INITSZ),
-#endif
-#ifdef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS
-  "DEFAULT_PROXYDIR_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_PROXYDIR_PERMISSIONS),
-#endif
-#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
-  "DEFAULT_RECURSIVE_TRIGGERS",
-#endif
-#ifdef SQLITE_DEFAULT_ROWEST
-  "DEFAULT_ROWEST=" CTIMEOPT_VAL(SQLITE_DEFAULT_ROWEST),
-#endif
-#ifdef SQLITE_DEFAULT_SECTOR_SIZE
-  "DEFAULT_SECTOR_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_SECTOR_SIZE),
-#endif
-#ifdef SQLITE_DEFAULT_SYNCHRONOUS
-  "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS),
-#endif
-#ifdef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
-  "DEFAULT_WAL_AUTOCHECKPOINT=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT),
-#endif
-#ifdef SQLITE_DEFAULT_WAL_SYNCHRONOUS
-  "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS),
-#endif
-#ifdef SQLITE_DEFAULT_WORKER_THREADS
-  "DEFAULT_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WORKER_THREADS),
-#endif
-#if SQLITE_DIRECT_OVERFLOW_READ
-  "DIRECT_OVERFLOW_READ",
-#endif
-#if SQLITE_DISABLE_DIRSYNC
-  "DISABLE_DIRSYNC",
-#endif
-#if SQLITE_DISABLE_FTS3_UNICODE
-  "DISABLE_FTS3_UNICODE",
-#endif
-#if SQLITE_DISABLE_FTS4_DEFERRED
-  "DISABLE_FTS4_DEFERRED",
-#endif
-#if SQLITE_DISABLE_INTRINSIC
-  "DISABLE_INTRINSIC",
-#endif
-#if SQLITE_DISABLE_LFS
-  "DISABLE_LFS",
-#endif
-#if SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
-  "DISABLE_PAGECACHE_OVERFLOW_STATS",
-#endif
-#if SQLITE_DISABLE_SKIPAHEAD_DISTINCT
-  "DISABLE_SKIPAHEAD_DISTINCT",
-#endif
-#ifdef SQLITE_ENABLE_8_3_NAMES
-  "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES),
-#endif
-#if SQLITE_ENABLE_API_ARMOR
-  "ENABLE_API_ARMOR",
-#endif
-#if SQLITE_ENABLE_ATOMIC_WRITE
-  "ENABLE_ATOMIC_WRITE",
-#endif
-#if SQLITE_ENABLE_BATCH_ATOMIC_WRITE
-  "ENABLE_BATCH_ATOMIC_WRITE",
-#endif
-#if SQLITE_ENABLE_BYTECODE_VTAB
-  "ENABLE_BYTECODE_VTAB",
-#endif
-#ifdef SQLITE_ENABLE_CEROD
-  "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD),
-#endif
-#if SQLITE_ENABLE_COLUMN_METADATA
-  "ENABLE_COLUMN_METADATA",
-#endif
-#if SQLITE_ENABLE_COLUMN_USED_MASK
-  "ENABLE_COLUMN_USED_MASK",
-#endif
-#if SQLITE_ENABLE_COSTMULT
-  "ENABLE_COSTMULT",
-#endif
-#if SQLITE_ENABLE_CURSOR_HINTS
-  "ENABLE_CURSOR_HINTS",
-#endif
-#if SQLITE_ENABLE_DBPAGE_VTAB
-  "ENABLE_DBPAGE_VTAB",
-#endif
-#if SQLITE_ENABLE_DBSTAT_VTAB
-  "ENABLE_DBSTAT_VTAB",
-#endif
-#if SQLITE_ENABLE_EXPENSIVE_ASSERT
-  "ENABLE_EXPENSIVE_ASSERT",
-#endif
-#if SQLITE_ENABLE_EXPLAIN_COMMENTS
-  "ENABLE_EXPLAIN_COMMENTS",
-#endif
-#if SQLITE_ENABLE_FTS3
-  "ENABLE_FTS3",
-#endif
-#if SQLITE_ENABLE_FTS3_PARENTHESIS
-  "ENABLE_FTS3_PARENTHESIS",
-#endif
-#if SQLITE_ENABLE_FTS3_TOKENIZER
-  "ENABLE_FTS3_TOKENIZER",
-#endif
-#if SQLITE_ENABLE_FTS4
-  "ENABLE_FTS4",
-#endif
-#if SQLITE_ENABLE_FTS5
-  "ENABLE_FTS5",
-#endif
-#if SQLITE_ENABLE_GEOPOLY
-  "ENABLE_GEOPOLY",
-#endif
-#if SQLITE_ENABLE_HIDDEN_COLUMNS
-  "ENABLE_HIDDEN_COLUMNS",
-#endif
-#if SQLITE_ENABLE_ICU
-  "ENABLE_ICU",
-#endif
-#if SQLITE_ENABLE_IOTRACE
-  "ENABLE_IOTRACE",
-#endif
-#if SQLITE_ENABLE_JSON1
-  "ENABLE_JSON1",
-#endif
-#if SQLITE_ENABLE_LOAD_EXTENSION
-  "ENABLE_LOAD_EXTENSION",
-#endif
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
-  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
-#endif
-#if SQLITE_ENABLE_MATH_FUNCTIONS
-  "ENABLE_MATH_FUNCTIONS",
-#endif
-#if SQLITE_ENABLE_MEMORY_MANAGEMENT
-  "ENABLE_MEMORY_MANAGEMENT",
-#endif
-#if SQLITE_ENABLE_MEMSYS3
-  "ENABLE_MEMSYS3",
-#endif
-#if SQLITE_ENABLE_MEMSYS5
-  "ENABLE_MEMSYS5",
-#endif
-#if SQLITE_ENABLE_MULTIPLEX
-  "ENABLE_MULTIPLEX",
-#endif
-#if SQLITE_ENABLE_NORMALIZE
-  "ENABLE_NORMALIZE",
-#endif
-#if SQLITE_ENABLE_NULL_TRIM
-  "ENABLE_NULL_TRIM",
-#endif
-#if SQLITE_ENABLE_OFFSET_SQL_FUNC
-  "ENABLE_OFFSET_SQL_FUNC",
-#endif
-#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
-  "ENABLE_OVERSIZE_CELL_CHECK",
-#endif
-#if SQLITE_ENABLE_PREUPDATE_HOOK
-  "ENABLE_PREUPDATE_HOOK",
-#endif
-#if SQLITE_ENABLE_QPSG
-  "ENABLE_QPSG",
-#endif
-#if SQLITE_ENABLE_RBU
-  "ENABLE_RBU",
-#endif
-#if SQLITE_ENABLE_RTREE
-  "ENABLE_RTREE",
-#endif
-#if SQLITE_ENABLE_SELECTTRACE
-  "ENABLE_SELECTTRACE",
-#endif
-#if SQLITE_ENABLE_SESSION
-  "ENABLE_SESSION",
-#endif
-#if SQLITE_ENABLE_SNAPSHOT
-  "ENABLE_SNAPSHOT",
-#endif
-#if SQLITE_ENABLE_SORTER_REFERENCES
-  "ENABLE_SORTER_REFERENCES",
-#endif
-#if SQLITE_ENABLE_SQLLOG
-  "ENABLE_SQLLOG",
-#endif
-#if SQLITE_ENABLE_STAT4
-  "ENABLE_STAT4",
-#endif
-#if SQLITE_ENABLE_STMTVTAB
-  "ENABLE_STMTVTAB",
-#endif
-#if SQLITE_ENABLE_STMT_SCANSTATUS
-  "ENABLE_STMT_SCANSTATUS",
-#endif
-#if SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-  "ENABLE_UNKNOWN_SQL_FUNCTION",
-#endif
-#if SQLITE_ENABLE_UNLOCK_NOTIFY
-  "ENABLE_UNLOCK_NOTIFY",
-#endif
-#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
-  "ENABLE_UPDATE_DELETE_LIMIT",
-#endif
-#if SQLITE_ENABLE_URI_00_ERROR
-  "ENABLE_URI_00_ERROR",
-#endif
-#if SQLITE_ENABLE_VFSTRACE
-  "ENABLE_VFSTRACE",
-#endif
-#if SQLITE_ENABLE_WHERETRACE
-  "ENABLE_WHERETRACE",
-#endif
-#if SQLITE_ENABLE_ZIPVFS
-  "ENABLE_ZIPVFS",
-#endif
-#if SQLITE_EXPLAIN_ESTIMATED_ROWS
-  "EXPLAIN_ESTIMATED_ROWS",
-#endif
-#if SQLITE_EXTRA_IFNULLROW
-  "EXTRA_IFNULLROW",
-#endif
-#ifdef SQLITE_EXTRA_INIT
-  "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT),
-#endif
-#ifdef SQLITE_EXTRA_SHUTDOWN
-  "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN),
-#endif
-#ifdef SQLITE_FTS3_MAX_EXPR_DEPTH
-  "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH),
-#endif
-#if SQLITE_FTS5_ENABLE_TEST_MI
-  "FTS5_ENABLE_TEST_MI",
-#endif
-#if SQLITE_FTS5_NO_WITHOUT_ROWID
-  "FTS5_NO_WITHOUT_ROWID",
-#endif
-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
-  "HAVE_ISNAN",
-#endif
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
-# if SQLITE_HOMEGROWN_RECURSIVE_MUTEX != 1
-  "HOMEGROWN_RECURSIVE_MUTEX=" CTIMEOPT_VAL(SQLITE_HOMEGROWN_RECURSIVE_MUTEX),
-# endif
-#endif
-#if SQLITE_IGNORE_AFP_LOCK_ERRORS
-  "IGNORE_AFP_LOCK_ERRORS",
-#endif
-#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
-  "IGNORE_FLOCK_LOCK_ERRORS",
-#endif
-#if SQLITE_INLINE_MEMCPY
-  "INLINE_MEMCPY",
-#endif
-#if SQLITE_INT64_TYPE
-  "INT64_TYPE",
-#endif
-#ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX
-  "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX),
-#endif
-#if SQLITE_LIKE_DOESNT_MATCH_BLOBS
-  "LIKE_DOESNT_MATCH_BLOBS",
-#endif
-#if SQLITE_LOCK_TRACE
-  "LOCK_TRACE",
-#endif
-#if SQLITE_LOG_CACHE_SPILL
-  "LOG_CACHE_SPILL",
-#endif
-#ifdef SQLITE_MALLOC_SOFT_LIMIT
-  "MALLOC_SOFT_LIMIT=" CTIMEOPT_VAL(SQLITE_MALLOC_SOFT_LIMIT),
-#endif
-#ifdef SQLITE_MAX_ATTACHED
-  "MAX_ATTACHED=" CTIMEOPT_VAL(SQLITE_MAX_ATTACHED),
-#endif
-#ifdef SQLITE_MAX_COLUMN
-  "MAX_COLUMN=" CTIMEOPT_VAL(SQLITE_MAX_COLUMN),
-#endif
-#ifdef SQLITE_MAX_COMPOUND_SELECT
-  "MAX_COMPOUND_SELECT=" CTIMEOPT_VAL(SQLITE_MAX_COMPOUND_SELECT),
-#endif
-#ifdef SQLITE_MAX_DEFAULT_PAGE_SIZE
-  "MAX_DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_DEFAULT_PAGE_SIZE),
-#endif
-#ifdef SQLITE_MAX_EXPR_DEPTH
-  "MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_EXPR_DEPTH),
-#endif
-#ifdef SQLITE_MAX_FUNCTION_ARG
-  "MAX_FUNCTION_ARG=" CTIMEOPT_VAL(SQLITE_MAX_FUNCTION_ARG),
-#endif
-#ifdef SQLITE_MAX_LENGTH
-  "MAX_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LENGTH),
-#endif
-#ifdef SQLITE_MAX_LIKE_PATTERN_LENGTH
-  "MAX_LIKE_PATTERN_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LIKE_PATTERN_LENGTH),
-#endif
-#ifdef SQLITE_MAX_MEMORY
-  "MAX_MEMORY=" CTIMEOPT_VAL(SQLITE_MAX_MEMORY),
-#endif
-#ifdef SQLITE_MAX_MMAP_SIZE
-  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
-#endif
-#ifdef SQLITE_MAX_MMAP_SIZE_
-  "MAX_MMAP_SIZE_=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE_),
-#endif
-#ifdef SQLITE_MAX_PAGE_COUNT
-  "MAX_PAGE_COUNT=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_COUNT),
-#endif
-#ifdef SQLITE_MAX_PAGE_SIZE
-  "MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE),
-#endif
-#ifdef SQLITE_MAX_SCHEMA_RETRY
-  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
-#endif
-#ifdef SQLITE_MAX_SQL_LENGTH
-  "MAX_SQL_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_SQL_LENGTH),
-#endif
-#ifdef SQLITE_MAX_TRIGGER_DEPTH
-  "MAX_TRIGGER_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_TRIGGER_DEPTH),
-#endif
-#ifdef SQLITE_MAX_VARIABLE_NUMBER
-  "MAX_VARIABLE_NUMBER=" CTIMEOPT_VAL(SQLITE_MAX_VARIABLE_NUMBER),
-#endif
-#ifdef SQLITE_MAX_VDBE_OP
-  "MAX_VDBE_OP=" CTIMEOPT_VAL(SQLITE_MAX_VDBE_OP),
-#endif
-#ifdef SQLITE_MAX_WORKER_THREADS
-  "MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS),
-#endif
-#if SQLITE_MEMDEBUG
-  "MEMDEBUG",
-#endif
-#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
-  "MIXED_ENDIAN_64BIT_FLOAT",
-#endif
-#if SQLITE_MMAP_READWRITE
-  "MMAP_READWRITE",
-#endif
-#if SQLITE_MUTEX_NOOP
-  "MUTEX_NOOP",
-#endif
-#if SQLITE_MUTEX_OMIT
-  "MUTEX_OMIT",
-#endif
-#if SQLITE_MUTEX_PTHREADS
-  "MUTEX_PTHREADS",
-#endif
-#if SQLITE_MUTEX_W32
-  "MUTEX_W32",
-#endif
-#if SQLITE_NEED_ERR_NAME
-  "NEED_ERR_NAME",
-#endif
-#if SQLITE_NOINLINE
-  "NOINLINE",
-#endif
-#if SQLITE_NO_SYNC
-  "NO_SYNC",
-#endif
-#if SQLITE_OMIT_ALTERTABLE
-  "OMIT_ALTERTABLE",
-#endif
-#if SQLITE_OMIT_ANALYZE
-  "OMIT_ANALYZE",
-#endif
-#if SQLITE_OMIT_ATTACH
-  "OMIT_ATTACH",
-#endif
-#if SQLITE_OMIT_AUTHORIZATION
-  "OMIT_AUTHORIZATION",
-#endif
-#if SQLITE_OMIT_AUTOINCREMENT
-  "OMIT_AUTOINCREMENT",
-#endif
-#if SQLITE_OMIT_AUTOINIT
-  "OMIT_AUTOINIT",
-#endif
-#if SQLITE_OMIT_AUTOMATIC_INDEX
-  "OMIT_AUTOMATIC_INDEX",
-#endif
-#if SQLITE_OMIT_AUTORESET
-  "OMIT_AUTORESET",
-#endif
-#if SQLITE_OMIT_AUTOVACUUM
-  "OMIT_AUTOVACUUM",
-#endif
-#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
-  "OMIT_BETWEEN_OPTIMIZATION",
-#endif
-#if SQLITE_OMIT_BLOB_LITERAL
-  "OMIT_BLOB_LITERAL",
-#endif
-#if SQLITE_OMIT_CAST
-  "OMIT_CAST",
-#endif
-#if SQLITE_OMIT_CHECK
-  "OMIT_CHECK",
-#endif
-#if SQLITE_OMIT_COMPLETE
-  "OMIT_COMPLETE",
-#endif
-#if SQLITE_OMIT_COMPOUND_SELECT
-  "OMIT_COMPOUND_SELECT",
-#endif
-#if SQLITE_OMIT_CONFLICT_CLAUSE
-  "OMIT_CONFLICT_CLAUSE",
-#endif
-#if SQLITE_OMIT_CTE
-  "OMIT_CTE",
-#endif
-#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT)
-  "OMIT_DATETIME_FUNCS",
-#endif
-#if SQLITE_OMIT_DECLTYPE
-  "OMIT_DECLTYPE",
-#endif
-#if SQLITE_OMIT_DEPRECATED
-  "OMIT_DEPRECATED",
-#endif
-#if SQLITE_OMIT_DESERIALIZE
-  "OMIT_DESERIALIZE",
-#endif
-#if SQLITE_OMIT_DISKIO
-  "OMIT_DISKIO",
-#endif
-#if SQLITE_OMIT_EXPLAIN
-  "OMIT_EXPLAIN",
-#endif
-#if SQLITE_OMIT_FLAG_PRAGMAS
-  "OMIT_FLAG_PRAGMAS",
-#endif
-#if SQLITE_OMIT_FLOATING_POINT
-  "OMIT_FLOATING_POINT",
-#endif
-#if SQLITE_OMIT_FOREIGN_KEY
-  "OMIT_FOREIGN_KEY",
-#endif
-#if SQLITE_OMIT_GET_TABLE
-  "OMIT_GET_TABLE",
-#endif
-#if SQLITE_OMIT_HEX_INTEGER
-  "OMIT_HEX_INTEGER",
-#endif
-#if SQLITE_OMIT_INCRBLOB
-  "OMIT_INCRBLOB",
-#endif
-#if SQLITE_OMIT_INTEGRITY_CHECK
-  "OMIT_INTEGRITY_CHECK",
-#endif
-#if SQLITE_OMIT_INTROSPECTION_PRAGMAS
-  "OMIT_INTROSPECTION_PRAGMAS",
-#endif
-#if SQLITE_OMIT_LIKE_OPTIMIZATION
-  "OMIT_LIKE_OPTIMIZATION",
-#endif
-#if SQLITE_OMIT_LOAD_EXTENSION
-  "OMIT_LOAD_EXTENSION",
-#endif
-#if SQLITE_OMIT_LOCALTIME
-  "OMIT_LOCALTIME",
-#endif
-#if SQLITE_OMIT_LOOKASIDE
-  "OMIT_LOOKASIDE",
-#endif
-#if SQLITE_OMIT_MEMORYDB
-  "OMIT_MEMORYDB",
-#endif
-#if SQLITE_OMIT_OR_OPTIMIZATION
-  "OMIT_OR_OPTIMIZATION",
-#endif
-#if SQLITE_OMIT_PAGER_PRAGMAS
-  "OMIT_PAGER_PRAGMAS",
-#endif
-#if SQLITE_OMIT_PARSER_TRACE
-  "OMIT_PARSER_TRACE",
-#endif
-#if SQLITE_OMIT_POPEN
-  "OMIT_POPEN",
-#endif
-#if SQLITE_OMIT_PRAGMA
-  "OMIT_PRAGMA",
-#endif
-#if SQLITE_OMIT_PROGRESS_CALLBACK
-  "OMIT_PROGRESS_CALLBACK",
-#endif
-#if SQLITE_OMIT_QUICKBALANCE
-  "OMIT_QUICKBALANCE",
-#endif
-#if SQLITE_OMIT_REINDEX
-  "OMIT_REINDEX",
-#endif
-#if SQLITE_OMIT_SCHEMA_PRAGMAS
-  "OMIT_SCHEMA_PRAGMAS",
-#endif
-#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
-  "OMIT_SCHEMA_VERSION_PRAGMAS",
-#endif
-#if SQLITE_OMIT_SHARED_CACHE
-  "OMIT_SHARED_CACHE",
-#endif
-#if SQLITE_OMIT_SHUTDOWN_DIRECTORIES
-  "OMIT_SHUTDOWN_DIRECTORIES",
-#endif
-#if SQLITE_OMIT_SUBQUERY
-  "OMIT_SUBQUERY",
-#endif
-#if SQLITE_OMIT_TCL_VARIABLE
-  "OMIT_TCL_VARIABLE",
-#endif
-#if SQLITE_OMIT_TEMPDB
-  "OMIT_TEMPDB",
-#endif
-#if SQLITE_OMIT_TEST_CONTROL
-  "OMIT_TEST_CONTROL",
-#endif
-#ifdef SQLITE_OMIT_TRACE
-# if SQLITE_OMIT_TRACE != 1
-  "OMIT_TRACE=" CTIMEOPT_VAL(SQLITE_OMIT_TRACE),
-# endif
-#endif
-#if SQLITE_OMIT_TRIGGER
-  "OMIT_TRIGGER",
-#endif
-#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
-  "OMIT_TRUNCATE_OPTIMIZATION",
-#endif
-#if SQLITE_OMIT_UTF16
-  "OMIT_UTF16",
-#endif
-#if SQLITE_OMIT_VACUUM
-  "OMIT_VACUUM",
-#endif
-#if SQLITE_OMIT_VIEW
-  "OMIT_VIEW",
-#endif
-#if SQLITE_OMIT_VIRTUALTABLE
-  "OMIT_VIRTUALTABLE",
-#endif
-#if SQLITE_OMIT_WAL
-  "OMIT_WAL",
-#endif
-#if SQLITE_OMIT_WSD
-  "OMIT_WSD",
-#endif
-#if SQLITE_OMIT_XFER_OPT
-  "OMIT_XFER_OPT",
-#endif
-#if SQLITE_PCACHE_SEPARATE_HEADER
-  "PCACHE_SEPARATE_HEADER",
-#endif
-#if SQLITE_PERFORMANCE_TRACE
-  "PERFORMANCE_TRACE",
-#endif
-#ifdef SQLITE_POWERSAFE_OVERWRITE
-# if SQLITE_POWERSAFE_OVERWRITE != 1
-  "POWERSAFE_OVERWRITE=" CTIMEOPT_VAL(SQLITE_POWERSAFE_OVERWRITE),
-# endif
-#endif
-#if SQLITE_PREFER_PROXY_LOCKING
-  "PREFER_PROXY_LOCKING",
-#endif
-#if SQLITE_PROXY_DEBUG
-  "PROXY_DEBUG",
-#endif
-#if SQLITE_REVERSE_UNORDERED_SELECTS
-  "REVERSE_UNORDERED_SELECTS",
-#endif
-#if SQLITE_RTREE_INT_ONLY
-  "RTREE_INT_ONLY",
-#endif
-#if SQLITE_SECURE_DELETE
-  "SECURE_DELETE",
-#endif
-#if SQLITE_SMALL_STACK
-  "SMALL_STACK",
-#endif
-#ifdef SQLITE_SORTER_PMASZ
-  "SORTER_PMASZ=" CTIMEOPT_VAL(SQLITE_SORTER_PMASZ),
-#endif
-#if SQLITE_SOUNDEX
-  "SOUNDEX",
-#endif
-#ifdef SQLITE_STAT4_SAMPLES
-  "STAT4_SAMPLES=" CTIMEOPT_VAL(SQLITE_STAT4_SAMPLES),
-#endif
-#ifdef SQLITE_STMTJRNL_SPILL
-  "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL),
-#endif
-#if SQLITE_SUBSTR_COMPATIBILITY
-  "SUBSTR_COMPATIBILITY",
-#endif
-#if (!defined(SQLITE_WIN32_MALLOC) \
-     && !defined(SQLITE_ZERO_MALLOC) \
-     && !defined(SQLITE_MEMDEBUG) \
-    ) || defined(SQLITE_SYSTEM_MALLOC)
-  "SYSTEM_MALLOC",
-#endif
-#if SQLITE_TCL
-  "TCL",
-#endif
-#ifdef SQLITE_TEMP_STORE
-  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
-#endif
-#if SQLITE_TEST
-  "TEST",
-#endif
-#if defined(SQLITE_THREADSAFE)
-  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
-#elif defined(THREADSAFE)
-  "THREADSAFE=" CTIMEOPT_VAL(THREADSAFE),
-#else
-  "THREADSAFE=1",
-#endif
-#if SQLITE_UNLINK_AFTER_CLOSE
-  "UNLINK_AFTER_CLOSE",
-#endif
-#if SQLITE_UNTESTABLE
-  "UNTESTABLE",
-#endif
-#if SQLITE_USER_AUTHENTICATION
-  "USER_AUTHENTICATION",
-#endif
-#if SQLITE_USE_ALLOCA
-  "USE_ALLOCA",
-#endif
-#if SQLITE_USE_FCNTL_TRACE
-  "USE_FCNTL_TRACE",
-#endif
-#if SQLITE_USE_URI
-  "USE_URI",
-#endif
-#if SQLITE_VDBE_COVERAGE
-  "VDBE_COVERAGE",
-#endif
-#if SQLITE_WIN32_MALLOC
-  "WIN32_MALLOC",
-#endif
-#if SQLITE_ZERO_MALLOC
-  "ZERO_MALLOC",
-#endif
-/*
-** END CODE GENERATED BY tool/mkctime.tcl
-*/
-};
-
-SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
-  *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]);
-  return (const char**)sqlite3azCompileOpt;
-}
-
-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
-
-/************** End of ctime.c ***********************************************/
 /************** Begin file sqliteInt.h ***************************************/
 /*
 ** 2001 September 15
@@ -1074,6 +287,17 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){
 # define _USE_32BIT_TIME_T
 #endif
 
+/* Optionally #include a user-defined header, whereby compilation options
+** may be set prior to where they take effect, but after platform setup.
+** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include
+** file.
+*/
+#ifdef SQLITE_CUSTOM_INCLUDE
+# define INC_STRINGIFY_(f) #f
+# define INC_STRINGIFY(f) INC_STRINGIFY_(f)
+# include INC_STRINGIFY(SQLITE_CUSTOM_INCLUDE)
+#endif
+
 /* The public SQLite interface.  The _FILE_OFFSET_BITS macro must appear
 ** first in QNX.  Also, the _USE_32BIT_TIME_T macro must appear first for
 ** MinGW.
@@ -1125,7 +349,30 @@ extern "C" {
 
 
 /*
-** Provide the ability to override linkage features of the interface.
+** Facilitate override of interface linkage and calling conventions.
+** Be aware that these macros may not be used within this particular
+** translation of the amalgamation and its associated header file.
+**
+** The SQLITE_EXTERN and SQLITE_API macros are used to instruct the
+** compiler that the target identifier should have external linkage.
+**
+** The SQLITE_CDECL macro is used to set the calling convention for
+** public functions that accept a variable number of arguments.
+**
+** The SQLITE_APICALL macro is used to set the calling convention for
+** public functions that accept a fixed number of arguments.
+**
+** The SQLITE_STDCALL macro is no longer used and is now deprecated.
+**
+** The SQLITE_CALLBACK macro is used to set the calling convention for
+** function pointers.
+**
+** The SQLITE_SYSAPI macro is used to set the calling convention for
+** functions provided by the operating system.
+**
+** Currently, the SQLITE_CDECL, SQLITE_APICALL, SQLITE_CALLBACK, and
+** SQLITE_SYSAPI macros are used only when building for environments
+** that require non-default calling conventions.
 */
 #ifndef SQLITE_EXTERN
 # define SQLITE_EXTERN extern
@@ -1205,9 +452,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.36.0"
-#define SQLITE_VERSION_NUMBER 3036000
-#define SQLITE_SOURCE_ID      "2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5"
+#define SQLITE_VERSION        "3.38.5"
+#define SQLITE_VERSION_NUMBER 3038005
+#define SQLITE_SOURCE_ID      "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -1619,12 +866,13 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
 #define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
 #define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
+#define SQLITE_CONSTRAINT_DATATYPE     (SQLITE_CONSTRAINT |(12<<8))
 #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
 #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
 #define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
 #define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
-#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))
+#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8)) /* internal use only */
 
 /*
 ** CAPI3REF: Flags For File Open Operations
@@ -1632,6 +880,19 @@ SQLITE_API int sqlite3_exec(
 ** These bit values are intended for use in the
 ** 3rd parameter to the [sqlite3_open_v2()] interface and
 ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
+**
+** Only those flags marked as "Ok for sqlite3_open_v2()" may be
+** used as the third argument to the [sqlite3_open_v2()] interface.
+** The other flags have historically been ignored by sqlite3_open_v2(),
+** though future versions of SQLite might change so that an error is
+** raised if any of the disallowed bits are passed into sqlite3_open_v2().
+** Applications should not depend on the historical behavior.
+**
+** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into
+** [sqlite3_open_v2()] does *not* cause the underlying database file
+** to be opened using O_EXCL.  Passing SQLITE_OPEN_EXCLUSIVE into
+** [sqlite3_open_v2()] has historically be a no-op and might become an
+** error in future versions of SQLite.
 */
 #define SQLITE_OPEN_READONLY         0x00000001  /* Ok for sqlite3_open_v2() */
 #define SQLITE_OPEN_READWRITE        0x00000002  /* Ok for sqlite3_open_v2() */
@@ -1654,6 +915,7 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
 #define SQLITE_OPEN_WAL              0x00080000  /* VFS only */
 #define SQLITE_OPEN_NOFOLLOW         0x01000000  /* Ok for sqlite3_open_v2() */
+#define SQLITE_OPEN_EXRESCODE        0x02000000  /* Extended result codes */
 
 /* Reserved:                         0x00F00000 */
 /* Legacy compatibility: */
@@ -3546,11 +2808,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
 ** CAPI3REF: Count The Number Of Rows Modified
 ** METHOD: sqlite3
 **
-** ^This function returns the number of rows modified, inserted or
+** ^These functions return the number of rows modified, inserted or
 ** deleted by the most recently completed INSERT, UPDATE or DELETE
 ** statement on the database connection specified by the only parameter.
-** ^Executing any other type of SQL statement does not modify the value
-** returned by this function.
+** The two functions are identical except for the type of the return value
+** and that if the number of rows modified by the most recent INSERT, UPDATE
+** or DELETE is greater than the maximum value supported by type "int", then
+** the return value of sqlite3_changes() is undefined. ^Executing any other
+** type of SQL statement does not modify the value returned by these functions.
 **
 ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
 ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers],
@@ -3599,16 +2864,21 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
 ** 
 */
 SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*);
 
 /*
 ** CAPI3REF: Total Number Of Rows Modified
 ** METHOD: sqlite3
 **
-** ^This function returns the total number of rows inserted, modified or
+** ^These functions return the total number of rows inserted, modified or
 ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
 ** since the database connection was opened, including those executed as
-** part of trigger programs. ^Executing any other type of SQL statement
-** does not affect the value returned by sqlite3_total_changes().
+** part of trigger programs. The two functions are identical except for the
+** type of the return value and that if the number of rows modified by the
+** connection exceeds the maximum value supported by type "int", then
+** the return value of sqlite3_total_changes() is undefined. ^Executing
+** any other type of SQL statement does not affect the value returned by
+** sqlite3_total_changes().
 **
 ** ^Changes made as part of [foreign key actions] are included in the
 ** count, but those made as part of REPLACE constraint resolution are
@@ -3636,6 +2906,7 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** 
 */
 SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*);
 
 /*
 ** CAPI3REF: Interrupt A Long-Running Query
@@ -4465,6 +3736,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** the default shared cache setting provided by
 ** [sqlite3_enable_shared_cache()].)^
 **
+** [[OPEN_EXRESCODE]] ^(
[SQLITE_OPEN_EXRESCODE]
+**
The database connection comes up in "extended result code mode". +** In other words, the database behaves has if +** [sqlite3_extended_result_codes(db,1)] where called on the database +** connection as soon as the connection is created. In addition to setting +** the extended result code mode, this flag also causes [sqlite3_open_v2()] +** to return an extended result code.
+** ** [[OPEN_NOFOLLOW]] ^(
[SQLITE_OPEN_NOFOLLOW]
**
The database filename is not allowed to be a symbolic link
** )^ @@ -4472,7 +3751,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] -** then the behavior is undefined. +** then the behavior is undefined. Historic versions of SQLite +** have silently ignored surplus bits in the flags parameter to +** sqlite3_open_v2(), however that behavior might not be carried through +** into future versions of SQLite and so applications should not rely +** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op +** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause +** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE +** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not +** by sqlite3_open_v2(). ** ** ^The fourth parameter to sqlite3_open_v2() is the name of the ** [sqlite3_vfs] object that defines the operating system interface that @@ -4843,13 +4130,14 @@ SQLITE_API void sqlite3_free_filename(char*); ** sqlite3_extended_errcode() might change with each API call. ** Except, there are some interfaces that are guaranteed to never ** change the value of the error code. The error-code preserving -** interfaces are: +** interfaces include the following: ** **
    **
  • sqlite3_errcode() **
  • sqlite3_extended_errcode() **
  • sqlite3_errmsg() **
  • sqlite3_errmsg16() +**
  • sqlite3_error_offset() **
** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -4864,6 +4152,13 @@ SQLITE_API void sqlite3_free_filename(char*); ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** +** ^If the most recent error references a specific token in the input +** SQL, the sqlite3_error_offset() interface returns the byte offset +** of the start of that token. ^The byte offset returned by +** sqlite3_error_offset() assumes that the input SQL is UTF8. +** ^If the most recent error does not reference a specific token in the input +** SQL, then the sqlite3_error_offset() function returns -1. +** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. @@ -4883,6 +4178,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Prepared Statement Object @@ -5240,12 +4536,17 @@ SQLITE_API int sqlite3_prepare16_v3( ** are managed by SQLite and are automatically freed when the prepared ** statement is finalized. ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, -** is obtained from [sqlite3_malloc()] and must be free by the application +** is obtained from [sqlite3_malloc()] and must be freed by the application ** by passing it to [sqlite3_free()]. +** +** ^The sqlite3_normalized_sql() interface is only available if +** the [SQLITE_ENABLE_NORMALIZE] compile-time option is defined. */ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +#ifdef SQLITE_ENABLE_NORMALIZE SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); +#endif /* ** CAPI3REF: Determine If An SQL Statement Writes The Database @@ -5289,6 +4590,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a ** read-only no-op if the table already exists, but ** sqlite3_stmt_readonly() still returns false for such a statement. +** +** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] +** statement, then sqlite3_stmt_readonly(X) returns the same value as +** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -5357,6 +4662,8 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** ** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()] +** are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. ** Unprotected sqlite3_value objects may only be used as arguments @@ -5978,6 +5285,10 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** +** ^Strings returned by sqlite3_column_text16() always have the endianness +** which is native to the platform, regardless of the text encoding set +** for the database. +** ** Warning: ^The object returned by [sqlite3_column_value()] is an ** [unprotected sqlite3_value] object. In a multithreaded environment, ** an unprotected sqlite3_value object may only be used safely with @@ -5991,7 +5302,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** -** The these routines may attempt to convert the datatype of the result. +** These routines may attempt to convert the datatype of the result. ** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions @@ -6016,7 +5327,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** TEXT BLOB No change ** BLOB INTEGER [CAST] to INTEGER ** BLOB FLOAT [CAST] to REAL -** BLOB TEXT Add a zero terminator if needed +** BLOB TEXT [CAST] to TEXT, ensure zero terminator ** ** )^ ** @@ -7429,6 +6740,72 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +/* +** CAPI3REF: Autovacuum Compaction Amount Callback +** METHOD: sqlite3 +** +** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback +** function C that is invoked prior to each autovacuum of the database +** file. ^The callback is passed a copy of the generic data pointer (P), +** the schema-name of the attached database that is being autovacuumed, +** the the size of the database file in pages, the number of free pages, +** and the number of bytes per page, respectively. The callback should +** return the number of free pages that should be removed by the +** autovacuum. ^If the callback returns zero, then no autovacuum happens. +** ^If the value returned is greater than or equal to the number of +** free pages, then a complete autovacuum happens. +** +**

^If there are multiple ATTACH-ed database files that are being +** modified as part of a transaction commit, then the autovacuum pages +** callback is invoked separately for each file. +** +**

The callback is not reentrant. The callback function should +** not attempt to invoke any other SQLite interface. If it does, bad +** things may happen, including segmentation faults and corrupt database +** files. The callback function should be a simple function that +** does some arithmetic on its input parameters and returns a result. +** +** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional +** destructor for the P parameter. ^If X is not NULL, then X(P) is +** invoked whenever the database connection closes or when the callback +** is overwritten by another invocation of sqlite3_autovacuum_pages(). +** +**

^There is only one autovacuum pages callback per database connection. +** ^Each call to the sqlite3_autovacuum_pages() interface overrides all +** previous invocations for that database connection. ^If the callback +** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, +** then the autovacuum steps callback is cancelled. The return value +** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might +** be some other error code if something goes wrong. The current +** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other +** return codes might be added in future releases. +** +**

If no autovacuum pages callback is specified (the usual case) or +** a NULL pointer is provided for the callback, +** then the default behavior is to vacuum all free pages. So, in other +** words, the default behavior is the same as if the callback function +** were something like this: +** +**

+**     unsigned int demonstration_autovac_pages_callback(
+**       void *pClientData,
+**       const char *zSchema,
+**       unsigned int nDbPage,
+**       unsigned int nFreePage,
+**       unsigned int nBytePerPage
+**     ){
+**       return nFreePage;
+**     }
+** 
+*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, + void(*)(void*) +); + + /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 @@ -8070,24 +7447,56 @@ struct sqlite3_index_info { ** ** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents -** an operator that is part of a constraint term in the wHERE clause of +** an operator that is part of a constraint term in the WHERE clause of ** a query that uses a [virtual table]. +** +** ^The left-hand operand of the operator is given by the corresponding +** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand +** operand is the rowid. +** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET +** operators have no left-hand operand, and so for those operators the +** corresponding aConstraint[].iColumn is meaningless and should not be +** used. +** +** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through +** value 255 are reserved to represent functions that are overloaded +** by the [xFindFunction|xFindFunction method] of the virtual table +** implementation. +** +** The right-hand operands for each constraint might be accessible using +** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand +** operand is only available if it appears as a single constant literal +** in the input SQL. If the right-hand operand is another column or an +** expression (even a constant expression) or a parameter, then the +** sqlite3_vtab_rhs_value() probably will not be able to extract it. +** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and +** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand +** and hence calls to sqlite3_vtab_rhs_value() for those operators will +** always return SQLITE_NOTFOUND. +** +** The collating sequence to be used for comparison can be found using +** the [sqlite3_vtab_collation()] interface. For most real-world virtual +** tables, the collating sequence of constraints does not matter (for example +** because the constraints are numeric) and so the sqlite3_vtab_collation() +** interface is no commonly needed. */ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -#define SQLITE_INDEX_CONSTRAINT_NE 68 -#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -#define SQLITE_INDEX_CONSTRAINT_IS 72 -#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -8116,7 +7525,7 @@ struct sqlite3_index_info { ** destructor. ** ** ^If the third parameter (the pointer to the sqlite3_module object) is -** NULL then no new module is create and any existing modules with the +** NULL then no new module is created and any existing modules with the ** same name are dropped. ** ** See also: [sqlite3_drop_modules()] @@ -8892,7 +8301,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 -#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -9415,6 +8825,16 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle. ** +** [[SQLITE_STMTSTATUS_FILTER_MISS]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] +**
SQLITE_STMTSTATUS_FILTER_HIT
+** SQLITE_STMTSTATUS_FILTER_MISS
+**
^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join +** step was bypassed because a Bloom filter returned not-found. The +** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of +** times that the Bloom filter returned a find, and thus the join step +** had to be processed as normal. +** ** [[SQLITE_STMTSTATUS_MEMUSED]]
SQLITE_STMTSTATUS_MEMUSED
**
^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually @@ -9429,6 +8849,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_VM_STEP 4 #define SQLITE_STMTSTATUS_REPREPARE 5 #define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_FILTER_MISS 7 +#define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 /* @@ -10092,8 +9514,9 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); ** ** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any -** previously registered write-ahead log callback. ^Note that the -** [sqlite3_wal_autocheckpoint()] interface and the +** previously registered write-ahead log callback. ^The return value is +** a copy of the third parameter from the previous call, if any, or 0. +** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** overwrite any prior [sqlite3_wal_hook()] settings. */ @@ -10396,19 +9819,269 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** METHOD: sqlite3_index_info ** ** This function may only be called from within a call to the [xBestIndex] -** method of a [virtual table]. +** method of a [virtual table]. This function returns a pointer to a string +** that is the name of the appropriate collation sequence to use for text +** comparisons on the constraint identified by its arguments. ** -** The first argument must be the sqlite3_index_info object that is the -** first parameter to the xBestIndex() method. The second argument must be -** an index into the aConstraint[] array belonging to the sqlite3_index_info -** structure passed to xBestIndex. This function returns a pointer to a buffer -** containing the name of the collation sequence for the corresponding -** constraint. +** The first argument must be the pointer to the [sqlite3_index_info] object +** that is the first parameter to the xBestIndex() method. The second argument +** must be an index into the aConstraint[] array belonging to the +** sqlite3_index_info structure passed to xBestIndex. +** +** Important: +** The first parameter must be the same pointer that is passed into the +** xBestMethod() method. The first parameter may not be a pointer to a +** different [sqlite3_index_info] object, even an exact copy. +** +** The return value is computed as follows: +** +**
    +**
  1. If the constraint comes from a WHERE clause expression that contains +** a [COLLATE operator], then the name of the collation specified by +** that COLLATE operator is returned. +**

  2. If there is no COLLATE operator, but the column that is the subject +** of the constraint specifies an alternative collating sequence via +** a [COLLATE clause] on the column definition within the CREATE TABLE +** statement that was passed into [sqlite3_declare_vtab()], then the +** name of that alternative collating sequence is returned. +**

  3. Otherwise, "BINARY" is returned. +**

*/ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +/* +** CAPI3REF: Determine if a virtual table query is DISTINCT +** METHOD: sqlite3_index_info +** +** This API may only be used from within an [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this +** interface from outside of xBestIndex() is undefined and probably harmful. +** +** ^The sqlite3_vtab_distinct() interface returns an integer that is +** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() +** gives the virtual table additional information about how the query +** planner wants the output to be ordered. As long as the virtual table +** can meet the ordering requirements of the query planner, it may set +** the "orderByConsumed" flag. +** +**
  1. +** ^If the sqlite3_vtab_distinct() interface returns 0, that means +** that the query planner needs the virtual table to return all rows in the +** sort order defined by the "nOrderBy" and "aOrderBy" fields of the +** [sqlite3_index_info] object. This is the default expectation. If the +** virtual table outputs all rows in sorted order, then it is always safe for +** the xBestIndex method to set the "orderByConsumed" flag, regardless of +** the return value from sqlite3_vtab_distinct(). +**

  2. +** ^(If the sqlite3_vtab_distinct() interface returns 1, that means +** that the query planner does not need the rows to be returned in sorted order +** as long as all rows with the same values in all columns identified by the +** "aOrderBy" field are adjacent.)^ This mode is used when the query planner +** is doing a GROUP BY. +**

  3. +** ^(If the sqlite3_vtab_distinct() interface returns 2, that means +** that the query planner does not need the rows returned in any particular +** order, as long as rows with the same values in all "aOrderBy" columns +** are adjacent.)^ ^(Furthermore, only a single row for each particular +** combination of values in the columns identified by the "aOrderBy" field +** needs to be returned.)^ ^It is always ok for two or more rows with the same +** values in all "aOrderBy" columns to be returned, as long as all such rows +** are adjacent. ^The virtual table may, if it chooses, omit extra rows +** that have the same value for all columns identified by "aOrderBy". +** ^However omitting the extra rows is optional. +** This mode is used for a DISTINCT query. +**

+** +** ^For the purposes of comparing virtual table output values to see if the +** values are same value for sorting purposes, two NULL values are considered +** to be the same. In other words, the comparison operator is "IS" +** (or "IS NOT DISTINCT FROM") and not "==". +** +** If a virtual table implementation is unable to meet the requirements +** specified above, then it must not set the "orderByConsumed" flag in the +** [sqlite3_index_info] object or an incorrect answer may result. +** +** ^A virtual table implementation is always free to return rows in any order +** it wants, as long as the "orderByConsumed" flag is not set. ^When the +** the "orderByConsumed" flag is unset, the query planner will add extra +** [bytecode] to ensure that the final results returned by the SQL query are +** ordered correctly. The use of the "orderByConsumed" flag and the +** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful +** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" +** flag might help queries against a virtual table to run faster. Being +** overly aggressive and setting the "orderByConsumed" flag when it is not +** valid to do so, on the other hand, might cause SQLite to return incorrect +** results. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); + +/* +** CAPI3REF: Identify and handle IN constraints in xBestIndex +** +** This interface may only be used from within an +** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. +** The result of invoking this interface from any other context is +** undefined and probably harmful. +** +** ^(A constraint on a virtual table of the form +** "[IN operator|column IN (...)]" is +** communicated to the xBestIndex method as a +** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use +** this constraint, it must set the corresponding +** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under +** the usual mode of handling IN operators, SQLite generates [bytecode] +** that invokes the [xFilter|xFilter() method] once for each value +** on the right-hand side of the IN operator.)^ Thus the virtual table +** only sees a single value from the right-hand side of the IN operator +** at a time. +** +** In some cases, however, it would be advantageous for the virtual +** table to see all values on the right-hand of the IN operator all at +** once. The sqlite3_vtab_in() interfaces facilitates this in two ways: +** +**
    +**
  1. +** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) +** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint +** is an [IN operator] that can be processed all at once. ^In other words, +** sqlite3_vtab_in() with -1 in the third argument is a mechanism +** by which the virtual table can ask SQLite if all-at-once processing +** of the IN operator is even possible. +** +**

  2. +** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates +** to SQLite that the virtual table does or does not want to process +** the IN operator all-at-once, respectively. ^Thus when the third +** parameter (F) is non-negative, this interface is the mechanism by +** which the virtual table tells SQLite how it wants to process the +** IN operator. +**

+** +** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times +** within the same xBestIndex method call. ^For any given P,N pair, +** the return value from sqlite3_vtab_in(P,N,F) will always be the same +** within the same xBestIndex call. ^If the interface returns true +** (non-zero), that means that the constraint is an IN operator +** that can be processed all-at-once. ^If the constraint is not an IN +** operator or cannot be processed all-at-once, then the interface returns +** false. +** +** ^(All-at-once processing of the IN operator is selected if both of the +** following conditions are met: +** +**
    +**
  1. The P->aConstraintUsage[N].argvIndex value is set to a positive +** integer. This is how the virtual table tells SQLite that it wants to +** use the N-th constraint. +** +**

  2. The last call to sqlite3_vtab_in(P,N,F) for which F was +** non-negative had F>=1. +**

)^ +** +** ^If either or both of the conditions above are false, then SQLite uses +** the traditional one-at-a-time processing strategy for the IN constraint. +** ^If both conditions are true, then the argvIndex-th parameter to the +** xFilter method will be an [sqlite3_value] that appears to be NULL, +** but which can be passed to [sqlite3_vtab_in_first()] and +** [sqlite3_vtab_in_next()] to find all values on the right-hand side +** of the IN constraint. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); + +/* +** CAPI3REF: Find all elements on the right-hand side of an IN constraint. +** +** These interfaces are only useful from within the +** [xFilter|xFilter() method] of a [virtual table] implementation. +** The result of invoking these interfaces from any other context +** is undefined and probably harmful. +** +** The X parameter in a call to sqlite3_vtab_in_first(X,P) or +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the +** xFilter method which invokes these routines, and specifically +** a parameter that was previously selected for all-at-once IN constraint +** processing use the [sqlite3_vtab_in()] interface in the +** [xBestIndex|xBestIndex method]. ^(If the X parameter is not +** an xFilter argument that was selected for all-at-once IN constraint +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. +** +** ^(Use these routines to access all values on the right-hand side +** of the IN constraint using code like the following: +** +**
+**    for(rc=sqlite3_vtab_in_first(pList, &pVal);
+**        rc==SQLITE_OK && pVal
+**        rc=sqlite3_vtab_in_next(pList, &pVal)
+**    ){
+**      // do something with pVal
+**    }
+**    if( rc!=SQLITE_OK ){
+**      // an error has occurred
+**    }
+** 
)^ +** +** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) +** routines return SQLITE_OK and set *P to point to the first or next value +** on the RHS of the IN constraint. ^If there are no more values on the +** right hand side of the IN constraint, then *P is set to NULL and these +** routines return [SQLITE_DONE]. ^The return value might be +** some other value, such as SQLITE_NOMEM, in the event of a malfunction. +** +** The *ppOut values returned by these routines are only valid until the +** next call to either of these routines or until the end of the xFilter +** method from which these routines were called. If the virtual table +** implementation needs to retain the *ppOut values for longer, it must make +** copies. The *ppOut values are [protected sqlite3_value|protected]. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); + +/* +** CAPI3REF: Constraint values in xBestIndex() +** METHOD: sqlite3_index_info +** +** This API may only be used from within the [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this interface +** from outside of an xBestIndex method are undefined and probably harmful. +** +** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within +** the [xBestIndex] method of a [virtual table] implementation, with P being +** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and +** J being a 0-based index into P->aConstraint[], then this routine +** attempts to set *V to the value of the right-hand operand of +** that constraint if the right-hand operand is known. ^If the +** right-hand operand is not known, then *V is set to a NULL pointer. +** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th +** constraint is not available. ^The sqlite3_vtab_rhs_value() interface +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if +** something goes wrong. +** +** The sqlite3_vtab_rhs_value() interface is usually only successful if +** the right-hand operand of a constraint is a literal value in the original +** SQL statement. If the right-hand operand is an expression or a reference +** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() +** will probably return [SQLITE_NOTFOUND]. +** +** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and +** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such +** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ +** +** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value +** and remains valid for the duration of the xBestIndex method call. +** ^When xBestIndex returns, the sqlite3_value object returned by +** sqlite3_vtab_rhs_value() is automatically deallocated. +** +** The "_rhs_" in the name of this routine is an abbreviation for +** "Right-Hand Side". +*/ +SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); + /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} @@ -10960,6 +10633,10 @@ SQLITE_API unsigned char *sqlite3_serialize( ** database is currently in a read transaction or is involved in a backup ** operation. ** +** It is not possible to deserialized into the TEMP database. If the +** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the +** function returns SQLITE_ERROR. +** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. @@ -13442,7 +13119,7 @@ struct fts5_api { ** autoconf-based build */ #if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) -/* #include "config.h" */ +#include "config.h" #define SQLITECONFIG_H 1 #endif @@ -13678,11 +13355,12 @@ struct fts5_api { #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || \ - (__has_extension(c_atomic) && __has_extension(c_atomic_store_n)) +#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +# define SQLITE_ATOMIC_INTRINSICS 1 # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) #else +# define SQLITE_ATOMIC_INTRINSICS 0 # define AtomicLoad(PTR) (*(PTR)) # define AtomicStore(PTR,VAL) (*(PTR) = (VAL)) #endif @@ -13887,11 +13565,12 @@ struct fts5_api { ** is significant and used at least once. On switch statements ** where multiple cases go to the same block of code, testcase() ** can insure that all cases are evaluated. -** */ -#ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE void sqlite3Coverage(int); -# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +# ifndef SQLITE_AMALGAMATION + extern unsigned int sqlite3CoverageCounter; +# endif +# define testcase(X) if( X ){ sqlite3CoverageCounter += (unsigned)__LINE__; } #else # define testcase(X) #endif @@ -13921,6 +13600,14 @@ SQLITE_PRIVATE void sqlite3Coverage(int); # define VVA_ONLY(X) #endif +/* +** Disable ALWAYS() and NEVER() (make them pass-throughs) for coverage +** and mutation testing +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif + /* ** The ALWAYS and NEVER macros surround boolean expressions which ** are intended to always be true or false, respectively. Such @@ -13936,7 +13623,7 @@ SQLITE_PRIVATE void sqlite3Coverage(int); ** be true and false so that the unreachable code they specify will ** not be counted as untested code. */ -#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) # define ALWAYS(X) (1) # define NEVER(X) (0) #elif !defined(NDEBUG) @@ -13947,26 +13634,6 @@ SQLITE_PRIVATE void sqlite3Coverage(int); # define NEVER(X) (X) #endif -/* -** The harmless(X) macro indicates that expression X is usually false -** but can be true without causing any problems, but we don't know of -** any way to cause X to be true. -** -** In debugging and testing builds, this macro will abort if X is ever -** true. In this way, developers are alerted to a possible test case -** that causes X to be true. If a harmless macro ever fails, that is -** an opportunity to change the macro into a testcase() and add a new -** test case to the test suite. -** -** For normal production builds, harmless(X) is a no-op, since it does -** not matter whether expression X is true or false. -*/ -#ifdef SQLITE_DEBUG -# define harmless(X) assert(!(X)); -#else -# define harmless(X) -#endif - /* ** Some conditionals are optimizations only. In other words, if the ** conditionals are replaced with a constant 1 (true) or 0 (false) then @@ -14030,6 +13697,13 @@ SQLITE_PRIVATE void sqlite3Coverage(int); # undef SQLITE_ENABLE_EXPLAIN_COMMENTS #endif +/* +** SQLITE_OMIT_VIRTUALTABLE implies SQLITE_OMIT_ALTERTABLE +*/ +#if defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_ALTERTABLE) +# define SQLITE_OMIT_ALTERTABLE +#endif + /* ** Return true (non-zero) if the input is an integer that is too large ** to fit in 32-bits. This macro is used inside of various testcase() @@ -14142,7 +13816,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); /* ** Number of entries in a hash table */ -/* #define sqliteHashCount(H) ((H)->count) // NOT USED */ +#define sqliteHashCount(H) ((H)->count) #endif /* SQLITE_HASH_H */ @@ -14174,8 +13848,8 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_LP 22 #define TK_RP 23 #define TK_AS 24 -#define TK_WITHOUT 25 -#define TK_COMMA 26 +#define TK_COMMA 25 +#define TK_WITHOUT 26 #define TK_ABORT 27 #define TK_ACTION 28 #define TK_AFTER 29 @@ -14261,78 +13935,79 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_SLASH 109 #define TK_REM 110 #define TK_CONCAT 111 -#define TK_COLLATE 112 -#define TK_BITNOT 113 -#define TK_ON 114 -#define TK_INDEXED 115 -#define TK_STRING 116 -#define TK_JOIN_KW 117 -#define TK_CONSTRAINT 118 -#define TK_DEFAULT 119 -#define TK_NULL 120 -#define TK_PRIMARY 121 -#define TK_UNIQUE 122 -#define TK_CHECK 123 -#define TK_REFERENCES 124 -#define TK_AUTOINCR 125 -#define TK_INSERT 126 -#define TK_DELETE 127 -#define TK_UPDATE 128 -#define TK_SET 129 -#define TK_DEFERRABLE 130 -#define TK_FOREIGN 131 -#define TK_DROP 132 -#define TK_UNION 133 -#define TK_ALL 134 -#define TK_EXCEPT 135 -#define TK_INTERSECT 136 -#define TK_SELECT 137 -#define TK_VALUES 138 -#define TK_DISTINCT 139 -#define TK_DOT 140 -#define TK_FROM 141 -#define TK_JOIN 142 -#define TK_USING 143 -#define TK_ORDER 144 -#define TK_GROUP 145 -#define TK_HAVING 146 -#define TK_LIMIT 147 -#define TK_WHERE 148 -#define TK_RETURNING 149 -#define TK_INTO 150 -#define TK_NOTHING 151 -#define TK_FLOAT 152 -#define TK_BLOB 153 -#define TK_INTEGER 154 -#define TK_VARIABLE 155 -#define TK_CASE 156 -#define TK_WHEN 157 -#define TK_THEN 158 -#define TK_ELSE 159 -#define TK_INDEX 160 -#define TK_ALTER 161 -#define TK_ADD 162 -#define TK_WINDOW 163 -#define TK_OVER 164 -#define TK_FILTER 165 -#define TK_COLUMN 166 -#define TK_AGG_FUNCTION 167 -#define TK_AGG_COLUMN 168 -#define TK_TRUEFALSE 169 -#define TK_ISNOT 170 -#define TK_FUNCTION 171 -#define TK_UMINUS 172 -#define TK_UPLUS 173 -#define TK_TRUTH 174 -#define TK_REGISTER 175 -#define TK_VECTOR 176 -#define TK_SELECT_COLUMN 177 -#define TK_IF_NULL_ROW 178 -#define TK_ASTERISK 179 -#define TK_SPAN 180 -#define TK_ERROR 181 -#define TK_SPACE 182 -#define TK_ILLEGAL 183 +#define TK_PTR 112 +#define TK_COLLATE 113 +#define TK_BITNOT 114 +#define TK_ON 115 +#define TK_INDEXED 116 +#define TK_STRING 117 +#define TK_JOIN_KW 118 +#define TK_CONSTRAINT 119 +#define TK_DEFAULT 120 +#define TK_NULL 121 +#define TK_PRIMARY 122 +#define TK_UNIQUE 123 +#define TK_CHECK 124 +#define TK_REFERENCES 125 +#define TK_AUTOINCR 126 +#define TK_INSERT 127 +#define TK_DELETE 128 +#define TK_UPDATE 129 +#define TK_SET 130 +#define TK_DEFERRABLE 131 +#define TK_FOREIGN 132 +#define TK_DROP 133 +#define TK_UNION 134 +#define TK_ALL 135 +#define TK_EXCEPT 136 +#define TK_INTERSECT 137 +#define TK_SELECT 138 +#define TK_VALUES 139 +#define TK_DISTINCT 140 +#define TK_DOT 141 +#define TK_FROM 142 +#define TK_JOIN 143 +#define TK_USING 144 +#define TK_ORDER 145 +#define TK_GROUP 146 +#define TK_HAVING 147 +#define TK_LIMIT 148 +#define TK_WHERE 149 +#define TK_RETURNING 150 +#define TK_INTO 151 +#define TK_NOTHING 152 +#define TK_FLOAT 153 +#define TK_BLOB 154 +#define TK_INTEGER 155 +#define TK_VARIABLE 156 +#define TK_CASE 157 +#define TK_WHEN 158 +#define TK_THEN 159 +#define TK_ELSE 160 +#define TK_INDEX 161 +#define TK_ALTER 162 +#define TK_ADD 163 +#define TK_WINDOW 164 +#define TK_OVER 165 +#define TK_FILTER 166 +#define TK_COLUMN 167 +#define TK_AGG_FUNCTION 168 +#define TK_AGG_COLUMN 169 +#define TK_TRUEFALSE 170 +#define TK_ISNOT 171 +#define TK_FUNCTION 172 +#define TK_UMINUS 173 +#define TK_UPLUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_SPACE 183 +#define TK_ILLEGAL 184 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14438,7 +14113,7 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); ** number of pages. A negative number N translations means that a buffer ** of -1024*N bytes is allocated and used for as many pages as it will hold. ** -** The default value of "20" was choosen to minimize the run-time of the +** The default value of "20" was chosen to minimize the run-time of the ** speedtest1 test program with options: --shrink-memory --reprepare */ #ifndef SQLITE_DEFAULT_PCACHE_INITSZ @@ -14600,6 +14275,7 @@ typedef INT16_TYPE LogEst; # define SQLITE_PTRSIZE __SIZEOF_POINTER__ # elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ + (defined(__APPLE__) && defined(__POWERPC__)) || \ (defined(__TOS_AIX__) && !defined(__64BIT__)) # define SQLITE_PTRSIZE 4 # else @@ -14794,11 +14470,25 @@ struct BusyHandler { /* ** Name of table that holds the database schema. +** +** The PREFERRED names are used whereever possible. But LEGACY is also +** used for backwards compatibility. +** +** 1. Queries can use either the PREFERRED or the LEGACY names +** 2. The sqlite3_set_authorizer() callback uses the LEGACY name +** 3. The PRAGMA table_list statement uses the PREFERRED name +** +** The LEGACY names are stored in the internal symbol hash table +** in support of (2). Names are translated using sqlite3PreferredTableName() +** for (3). The sqlite3FindTable() function takes care of translating +** names for (1). +** +** Note that "sqlite_temp_schema" can also be called "temp.sqlite_schema". */ -#define DFLT_SCHEMA_TABLE "sqlite_master" -#define DFLT_TEMP_SCHEMA_TABLE "sqlite_temp_master" -#define ALT_SCHEMA_TABLE "sqlite_schema" -#define ALT_TEMP_SCHEMA_TABLE "sqlite_temp_schema" +#define LEGACY_SCHEMA_TABLE "sqlite_master" +#define LEGACY_TEMP_SCHEMA_TABLE "sqlite_temp_master" +#define PREFERRED_SCHEMA_TABLE "sqlite_schema" +#define PREFERRED_TEMP_SCHEMA_TABLE "sqlite_temp_schema" /* @@ -14810,7 +14500,7 @@ struct BusyHandler { ** The name of the schema table. The name is different for TEMP. */ #define SCHEMA_TABLE(x) \ - ((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE) + ((!OMIT_TEMPDB)&&(x==1)?LEGACY_TEMP_SCHEMA_TABLE:LEGACY_SCHEMA_TABLE) /* ** A convenience macro that returns the number of elements in @@ -14959,10 +14649,11 @@ typedef struct With With; /* ** A bit in a Bitmask */ -#define MASKBIT(n) (((Bitmask)1)<<(n)) -#define MASKBIT64(n) (((u64)1)<<(n)) -#define MASKBIT32(n) (((unsigned int)1)<<(n)) -#define ALLBITS ((Bitmask)-1) +#define MASKBIT(n) (((Bitmask)1)<<(n)) +#define MASKBIT64(n) (((u64)1)<<(n)) +#define MASKBIT32(n) (((unsigned int)1)<<(n)) +#define SMASKBIT32(n) ((n)<=31?((unsigned int)1)<<(n):0) +#define ALLBITS ((Bitmask)-1) /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer @@ -15351,7 +15042,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); #define BTREE_BLOBKEY 2 /* Table has keys only - no data */ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); -SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, i64*); SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int); @@ -15475,13 +15166,17 @@ SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); #endif SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( +SQLITE_PRIVATE int sqlite3BtreeTableMoveto( BtCursor*, - UnpackedRecord *pUnKey, i64 intKey, int bias, int *pRes ); +SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( + BtCursor*, + UnpackedRecord *pUnKey, + int *pRes +); SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); @@ -15832,35 +15527,35 @@ typedef struct VdbeOpList VdbeOpList; #define OP_If 18 /* jump */ #define OP_Not 19 /* same as TK_NOT, synopsis: r[P2]= !r[P1] */ #define OP_IfNot 20 /* jump */ -#define OP_IfNullRow 21 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ -#define OP_SeekLT 22 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekLE 23 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGE 24 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekGT 25 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IfNotOpen 26 /* jump, synopsis: if( !csr[P1] ) goto P2 */ -#define OP_IfNoHope 27 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NoConflict 28 /* jump, synopsis: key=r[P3@P4] */ -#define OP_NotFound 29 /* jump, synopsis: key=r[P3@P4] */ -#define OP_Found 30 /* jump, synopsis: key=r[P3@P4] */ -#define OP_SeekRowid 31 /* jump, synopsis: intkey=r[P3] */ -#define OP_NotExists 32 /* jump, synopsis: intkey=r[P3] */ -#define OP_Last 33 /* jump */ -#define OP_IfSmaller 34 /* jump */ -#define OP_SorterSort 35 /* jump */ -#define OP_Sort 36 /* jump */ -#define OP_Rewind 37 /* jump */ -#define OP_IdxLE 38 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGT 39 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxLT 40 /* jump, synopsis: key=r[P3@P4] */ -#define OP_IdxGE 41 /* jump, synopsis: key=r[P3@P4] */ -#define OP_RowSetRead 42 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_IsNullOrType 21 /* jump, synopsis: if typeof(r[P1]) IN (P3,5) goto P2 */ +#define OP_IfNullRow 22 /* jump, synopsis: if P1.nullRow then r[P3]=NULL, goto P2 */ +#define OP_SeekLT 23 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekLE 24 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGE 25 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekGT 26 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IfNotOpen 27 /* jump, synopsis: if( !csr[P1] ) goto P2 */ +#define OP_IfNoHope 28 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NoConflict 29 /* jump, synopsis: key=r[P3@P4] */ +#define OP_NotFound 30 /* jump, synopsis: key=r[P3@P4] */ +#define OP_Found 31 /* jump, synopsis: key=r[P3@P4] */ +#define OP_SeekRowid 32 /* jump, synopsis: intkey=r[P3] */ +#define OP_NotExists 33 /* jump, synopsis: intkey=r[P3] */ +#define OP_Last 34 /* jump */ +#define OP_IfSmaller 35 /* jump */ +#define OP_SorterSort 36 /* jump */ +#define OP_Sort 37 /* jump */ +#define OP_Rewind 38 /* jump */ +#define OP_IdxLE 39 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGT 40 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxLT 41 /* jump, synopsis: key=r[P3@P4] */ +#define OP_IdxGE 42 /* jump, synopsis: key=r[P3@P4] */ #define OP_Or 43 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */ #define OP_And 44 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */ -#define OP_RowSetTest 45 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ -#define OP_Program 46 /* jump */ -#define OP_FkIfZero 47 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ -#define OP_IfPos 48 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ -#define OP_IfNotZero 49 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_RowSetRead 45 /* jump, synopsis: r[P3]=rowset(P1) */ +#define OP_RowSetTest 46 /* jump, synopsis: if r[P3] in rowset(P1) goto P2 */ +#define OP_Program 47 /* jump */ +#define OP_FkIfZero 48 /* jump, synopsis: if fkctr[P1]==0 goto P2 */ +#define OP_IfPos 49 /* jump, synopsis: if r[P1]>0 then r[P1]-=P3, goto P2 */ #define OP_IsNull 50 /* jump, same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */ #define OP_NotNull 51 /* jump, same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */ #define OP_Ne 52 /* jump, same as TK_NE, synopsis: IF r[P3]!=r[P1] */ @@ -15870,49 +15565,49 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Lt 56 /* jump, same as TK_LT, synopsis: IF r[P3]=r[P1] */ #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */ -#define OP_DecrJumpZero 59 /* jump, synopsis: if (--r[P1])==0 goto P2 */ -#define OP_IncrVacuum 60 /* jump */ -#define OP_VNext 61 /* jump */ -#define OP_Init 62 /* jump, synopsis: Start at P2 */ -#define OP_PureFunc 63 /* synopsis: r[P3]=func(r[P2@NP]) */ -#define OP_Function 64 /* synopsis: r[P3]=func(r[P2@NP]) */ -#define OP_Return 65 -#define OP_EndCoroutine 66 -#define OP_HaltIfNull 67 /* synopsis: if r[P3]=null halt */ -#define OP_Halt 68 -#define OP_Integer 69 /* synopsis: r[P2]=P1 */ -#define OP_Int64 70 /* synopsis: r[P2]=P4 */ -#define OP_String 71 /* synopsis: r[P2]='P4' (len=P1) */ -#define OP_Null 72 /* synopsis: r[P2..P3]=NULL */ -#define OP_SoftNull 73 /* synopsis: r[P1]=NULL */ -#define OP_Blob 74 /* synopsis: r[P2]=P4 (len=P1) */ -#define OP_Variable 75 /* synopsis: r[P2]=parameter(P1,P4) */ -#define OP_Move 76 /* synopsis: r[P2@P3]=r[P1@P3] */ -#define OP_Copy 77 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ -#define OP_SCopy 78 /* synopsis: r[P2]=r[P1] */ -#define OP_IntCopy 79 /* synopsis: r[P2]=r[P1] */ -#define OP_ChngCntRow 80 /* synopsis: output=r[P1] */ -#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 82 -#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 84 -#define OP_Cast 85 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 86 -#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -#define OP_ZeroOrNull 89 /* synopsis: r[P2] = 0 OR NULL */ -#define OP_Offset 90 /* synopsis: r[P3] = sqlite_offset(P1) */ -#define OP_Column 91 /* synopsis: r[P3]=PX */ -#define OP_Affinity 92 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 93 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 94 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 95 -#define OP_SetCookie 96 -#define OP_ReopenIdx 97 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 98 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 99 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenDup 100 -#define OP_OpenAutoindex 101 /* synopsis: nColumn=P2 */ +#define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */ +#define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */ +#define OP_IncrVacuum 61 /* jump */ +#define OP_VNext 62 /* jump */ +#define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */ +#define OP_Init 64 /* jump, synopsis: Start at P2 */ +#define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */ +#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */ +#define OP_Return 67 +#define OP_EndCoroutine 68 +#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */ +#define OP_Halt 70 +#define OP_Integer 71 /* synopsis: r[P2]=P1 */ +#define OP_Int64 72 /* synopsis: r[P2]=P4 */ +#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */ +#define OP_Null 74 /* synopsis: r[P2..P3]=NULL */ +#define OP_SoftNull 75 /* synopsis: r[P1]=NULL */ +#define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */ +#define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */ +#define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */ +#define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ +#define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */ +#define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */ +#define OP_FkCheck 82 +#define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 84 +#define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 86 +#define OP_Cast 87 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 88 +#define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */ +#define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 93 /* synopsis: r[P3]=PX */ +#define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */ +#define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 97 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 98 +#define OP_SetCookie 99 +#define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */ #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 157 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 158 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 159 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 160 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 161 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 162 -#define OP_CursorLock 163 -#define OP_CursorUnlock 164 -#define OP_TableLock 165 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 166 -#define OP_VCreate 167 -#define OP_VDestroy 168 -#define OP_VOpen 169 -#define OP_VColumn 170 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 171 -#define OP_Pagecount 172 -#define OP_MaxPgcnt 173 -#define OP_Trace 174 -#define OP_CursorHint 175 -#define OP_ReleaseReg 176 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 177 -#define OP_Explain 178 -#define OP_Abortable 179 +#define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 113 +#define OP_BitNot 114 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 116 /* synopsis: nColumn=P2 */ +#define OP_String8 117 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_SorterOpen 118 +#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */ +#define OP_Close 121 +#define OP_ColumnsUsed 122 +#define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 126 /* synopsis: r[P2]=rowid */ +#define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 128 +#define OP_Delete 129 +#define OP_ResetCount 130 +#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 132 /* synopsis: r[P2]=data */ +#define OP_RowData 133 /* synopsis: r[P2]=data */ +#define OP_Rowid 134 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 135 +#define OP_SeekEnd 136 +#define OP_IdxInsert 137 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 138 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 142 +#define OP_Destroy 143 +#define OP_Clear 144 +#define OP_ResetSorter 145 +#define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 147 +#define OP_ParseSchema 148 +#define OP_LoadAnalysis 149 +#define OP_DropTable 150 +#define OP_DropIndex 151 +#define OP_DropTrigger 152 +#define OP_Real 153 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_IntegrityCk 154 +#define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 156 +#define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 165 +#define OP_CursorLock 166 +#define OP_CursorUnlock 167 +#define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 169 +#define OP_VCreate 170 +#define OP_VDestroy 171 +#define OP_VOpen 172 +#define OP_VInitIn 173 /* synopsis: r[P2]=ValueList(P1,P3) */ +#define OP_VColumn 174 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 175 +#define OP_Pagecount 176 +#define OP_MaxPgcnt 177 +#define OP_FilterAdd 178 /* synopsis: filter(P1) += key(P3@P4) */ +#define OP_Trace 179 +#define OP_CursorHint 180 +#define OP_ReleaseReg 181 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 182 +#define OP_Explain 183 +#define OP_Abortable 184 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -16005,27 +15705,28 @@ typedef struct VdbeOpList VdbeOpList; #define OPFLG_INITIALIZER {\ /* 0 */ 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x10,\ /* 8 */ 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x03, 0x03,\ -/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x01, 0x09, 0x09,\ -/* 24 */ 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09, 0x09,\ -/* 32 */ 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ -/* 40 */ 0x01, 0x01, 0x23, 0x26, 0x26, 0x0b, 0x01, 0x01,\ -/* 48 */ 0x03, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ -/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00,\ -/* 64 */ 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\ -/* 72 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\ -/* 80 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ -/* 88 */ 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10,\ -/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26,\ +/* 16 */ 0x01, 0x01, 0x03, 0x12, 0x03, 0x03, 0x01, 0x09,\ +/* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\ +/* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\ +/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\ +/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\ +/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\ +/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\ +/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\ +/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\ +/* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\ +/* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\ /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ -/* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ -/* 120 */ 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 128 */ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, 0x04,\ -/* 136 */ 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x10,\ -/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,\ -/* 152 */ 0x10, 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00,\ +/* 112 */ 0x00, 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\ +/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\ +/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\ +/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 152 */ 0x00, 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\ /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 176 */ 0x00, 0x00, 0x00, 0x00,} +/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\ +/* 176 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 184 */ 0x00,} /* The resolve3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -16033,7 +15734,7 @@ typedef struct VdbeOpList VdbeOpList; ** generated this include file strives to group all JUMP opcodes ** together near the beginning of the list. */ -#define SQLITE_MX_JUMP_OPCODE 62 /* Maximum JUMP opcode */ +#define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */ /************** End of opcodes.h *********************************************/ /************** Continuing where we left off in vdbe.h ***********************/ @@ -17094,6 +16795,7 @@ struct sqlite3 { u32 nSchemaLock; /* Do not reset the schema when non-zero */ unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ + int errByteOffset; /* Byte offset of error in SQL statement */ int errMask; /* & result codes with this before returning */ int iSysErrno; /* Errno value from last system error */ u32 dbOptFlags; /* Flags to enable/disable optimizations */ @@ -17110,10 +16812,10 @@ struct sqlite3 { u8 mTrace; /* zero or more SQLITE_TRACE flags */ u8 noSharedCache; /* True if no shared-cache backends */ u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ + u8 eOpenState; /* Current condition of the connection */ int nextPagesize; /* Pagesize after VACUUM if >0 */ - u32 magic; /* Magic number for detect library misuse */ - int nChange; /* Value returned by sqlite3_changes() */ - int nTotalChange; /* Value returned by sqlite3_total_changes() */ + i64 nChange; /* Value returned by sqlite3_changes() */ + i64 nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ struct sqlite3InitInfo { /* Information used during initialization */ @@ -17123,7 +16825,7 @@ struct sqlite3 { unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ unsigned imposterTable : 1; /* Building an imposter table */ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ - char **azInit; /* "type", "name", and "tbl_name" columns */ + const char **azInit; /* "type", "name", and "tbl_name" columns */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ @@ -17133,10 +16835,10 @@ struct sqlite3 { int nExtension; /* Number of loaded extensions */ void **aExtension; /* Array of shared library handles */ union { - void (*xLegacy)(void*,const char*); /* Legacy trace function */ - int (*xV2)(u32,void*,void*,void*); /* V2 Trace function */ + void (*xLegacy)(void*,const char*); /* mTrace==SQLITE_TRACE_LEGACY */ + int (*xV2)(u32,void*,void*,void*); /* All other mTrace values */ } trace; - void *pTraceArg; /* Argument to the trace function */ + void *pTraceArg; /* Argument to the trace function */ #ifndef SQLITE_OMIT_DEPRECATED void (*xProfile)(void*,const char*,u64); /* Profiling function */ void *pProfileArg; /* Argument to profile function */ @@ -17147,6 +16849,9 @@ struct sqlite3 { void (*xRollbackCallback)(void*); /* Invoked at every commit. */ void *pUpdateArg; void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64); + void *pAutovacPagesArg; /* Client argument to autovac_pages */ + void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */ + unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32); Parse *pParse; /* Current parse */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK void *pPreUpdateArg; /* First argument to xPreUpdateCallback */ @@ -17276,6 +16981,7 @@ struct sqlite3 { #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */ /* DELETE, or UPDATE and return */ /* the count using a callback. */ +#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG @@ -17322,6 +17028,11 @@ struct sqlite3 { #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ #define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ #define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */ +#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */ + /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */ +#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */ +#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */ +#define SQLITE_BalancedMerge 0x00200000 /* Balance multi-way merges */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -17336,17 +17047,16 @@ struct sqlite3 { */ #define ConstFactorOk(P) ((P)->okConstFactor) -/* -** Possible values for the sqlite.magic field. -** The numbers are obtained at random and have no special meaning, other -** than being distinct from one another. +/* Possible values for the sqlite3.eOpenState field. +** The numbers are randomly selected such that a minimum of three bits must +** change to convert any number to another or to zero */ -#define SQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */ -#define SQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */ -#define SQLITE_MAGIC_SICK 0x4b771290 /* Error and awaiting close */ -#define SQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */ -#define SQLITE_MAGIC_ERROR 0xb5357930 /* An SQLITE_MISUSE error occurred */ -#define SQLITE_MAGIC_ZOMBIE 0x64cffc7f /* Close with last statement close */ +#define SQLITE_STATE_OPEN 0x76 /* Database is open */ +#define SQLITE_STATE_CLOSED 0xce /* Database is closed */ +#define SQLITE_STATE_SICK 0xba /* Error and awaiting close */ +#define SQLITE_STATE_BUSY 0x6d /* Database currently in use */ +#define SQLITE_STATE_ERROR 0xd5 /* An SQLITE_MISUSE error occurred */ +#define SQLITE_STATE_ZOMBIE 0xa7 /* Close with last statement close */ /* ** Each SQL function is defined by an instance of the following @@ -17371,7 +17081,7 @@ struct FuncDef { union { FuncDef *pHash; /* Next with a different name but the same hash */ FuncDestructor *pDestructor; /* Reference counted destructor function */ - } u; + } u; /* pHash if SQLITE_FUNC_BUILTIN, pDestructor otherwise */ }; /* @@ -17401,12 +17111,13 @@ struct FuncDestructor { ** are assert() statements in the code to verify this. ** ** Value constraints (enforced via assert()): -** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg -** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG -** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG -** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API -** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API -** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS +** SQLITE_FUNC_MINMAX == NC_MinMaxAgg == SF_MinMaxAgg +** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd +** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG +** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG +** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API +** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API +** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -17431,6 +17142,8 @@ struct FuncDestructor { #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */ #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */ +#define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */ +#define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */ /* Identifier numbers for each in-line function */ #define INLINEFUNC_coalesce 0 @@ -17493,7 +17206,7 @@ struct FuncDestructor { ** are interpreted in the same way as the first 4 parameters to ** FUNCTION(). ** -** WFUNCTION(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) +** WAGGREGATE(zName, nArg, iArg, xStep, xFinal, xValue, xInverse) ** Used to create an aggregate function definition implemented by ** the C functions xStep and xFinal. The first four parameters ** are interpreted in the same way as the first 4 parameters to @@ -17508,44 +17221,55 @@ struct FuncDestructor { ** parameter. */ #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define MFUNCTION(zName, nArg, xPtr, xFunc) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } +#define JFUNCTION(zName, nArg, iArg, xFunc) \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ - {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define TEST_FUNC(zName, nArg, iArg, mFlags) \ - {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \ SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \ 0, 0, xFunc, 0, 0, 0, #zName, {0} } #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ - {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \ - {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \ pArg, 0, xFunc, 0, 0, 0, #zName, } #define LIKEFUNC(zName, nArg, arg, flags) \ - {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \ (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} } #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \ - {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ + {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \ SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}} #define INTERNAL_FUNCTION(zName, nArg, xFunc) \ - {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ + {nArg, SQLITE_FUNC_BUILTIN|\ + SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ 0, 0, xFunc, 0, 0, 0, #zName, {0} } @@ -17601,18 +17325,42 @@ struct Module { ** or equal to the table column index. It is ** equal if and only if there are no VIRTUAL ** columns to the left. +** +** Notes on zCnName: +** The zCnName field stores the name of the column, the datatype of the +** column, and the collating sequence for the column, in that order, all in +** a single allocation. Each string is 0x00 terminated. The datatype +** is only included if the COLFLAG_HASTYPE bit of colFlags is set and the +** collating sequence name is only included if the COLFLAG_HASCOLL bit is +** set. */ struct Column { - char *zName; /* Name of this column, \000, then the type */ - Expr *pDflt; /* Default value or GENERATED ALWAYS AS value */ - char *zColl; /* Collating sequence. If NULL, use the default */ - u8 notNull; /* An OE_ code for handling a NOT NULL constraint */ - char affinity; /* One of the SQLITE_AFF_... values */ - u8 szEst; /* Estimated size of value in this column. sizeof(INT)==1 */ - u8 hName; /* Column name hash for faster lookup */ - u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ + char *zCnName; /* Name of this column */ + unsigned notNull :4; /* An OE_ code for handling a NOT NULL constraint */ + unsigned eCType :4; /* One of the standard types */ + char affinity; /* One of the SQLITE_AFF_... values */ + u8 szEst; /* Est size of value in this column. sizeof(INT)==1 */ + u8 hName; /* Column name hash for faster lookup */ + u16 iDflt; /* 1-based index of DEFAULT. 0 means "none" */ + u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; +/* Allowed values for Column.eCType. +** +** Values must match entries in the global constant arrays +** sqlite3StdTypeLen[] and sqlite3StdType[]. Each value is one more +** than the offset into these arrays for the corresponding name. +** Adjust the SQLITE_N_STDTYPE value if adding or removing entries. +*/ +#define COLTYPE_CUSTOM 0 /* Type appended to zName */ +#define COLTYPE_ANY 1 +#define COLTYPE_BLOB 2 +#define COLTYPE_INT 3 +#define COLTYPE_INTEGER 4 +#define COLTYPE_REAL 5 +#define COLTYPE_TEXT 6 +#define SQLITE_N_STDTYPE 6 /* Number of standard types */ + /* Allowed values for Column.colFlags. ** ** Constraints: @@ -17629,6 +17377,7 @@ struct Column { #define COLFLAG_STORED 0x0040 /* GENERATED ALWAYS AS ... STORED */ #define COLFLAG_NOTAVAIL 0x0080 /* STORED column not yet calculated */ #define COLFLAG_BUSY 0x0100 /* Blocks recursion on GENERATED columns */ +#define COLFLAG_HASCOLL 0x0200 /* Has collating sequence name in zCnName */ #define COLFLAG_GENERATED 0x0060 /* Combo: _STORED, _VIRTUAL */ #define COLFLAG_NOINSERT 0x0062 /* Combo: _HIDDEN, _STORED, _VIRTUAL */ @@ -17758,15 +17507,13 @@ struct VTable { #define SQLITE_VTABRISK_High 2 /* -** The schema for each SQL table and view is represented in memory -** by an instance of the following structure. +** The schema for each SQL table, virtual table, and view is represented +** in memory by an instance of the following structure. */ struct Table { char *zName; /* Name of the table or view */ Column *aCol; /* Information about each column */ Index *pIndex; /* List of SQL indexes on this table. */ - Select *pSelect; /* NULL for tables. Points to definition if a view. */ - FKey *pFKey; /* Linked list of all foreign keys in this table */ char *zColAff; /* String defining the affinity of each column */ ExprList *pCheck; /* All CHECK constraints */ /* ... also used as column name list in a VIEW */ @@ -17782,15 +17529,24 @@ struct Table { LogEst costMult; /* Cost multiplier for using this table */ #endif u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */ -#ifndef SQLITE_OMIT_ALTERTABLE - int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ -#endif -#ifndef SQLITE_OMIT_VIRTUALTABLE - int nModuleArg; /* Number of arguments to the module */ - char **azModuleArg; /* 0: module 1: schema 2: vtab name 3...: args */ - VTable *pVTable; /* List of VTable objects. */ -#endif - Trigger *pTrigger; /* List of triggers stored in pSchema */ + u8 eTabType; /* 0: normal, 1: virtual, 2: view */ + union { + struct { /* Used by ordinary tables: */ + int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ + FKey *pFKey; /* Linked list of all foreign keys in this table */ + ExprList *pDfltList; /* DEFAULT clauses on various columns. + ** Or the AS clause for generated columns. */ + } tab; + struct { /* Used by views: */ + Select *pSelect; /* View definition */ + } view; + struct { /* Used by virtual tables only: */ + int nArg; /* Number of arguments to the module */ + char **azArg; /* 0: module 1: schema 2: vtab name 3...: args */ + VTable *p; /* List of VTable objects. */ + } vtab; + } u; + Trigger *pTrigger; /* List of triggers on this object */ Schema *pSchema; /* Schema that contains this table */ }; @@ -17809,24 +17565,35 @@ struct Table { ** TF_HasStored == COLFLAG_STORED ** TF_HasHidden == COLFLAG_HIDDEN */ -#define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_HasHidden 0x0002 /* Has one or more hidden columns */ -#define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ -#define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ -#define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ -#define TF_HasVirtual 0x0020 /* Has one or more VIRTUAL columns */ -#define TF_HasStored 0x0040 /* Has one or more STORED columns */ -#define TF_HasGenerated 0x0060 /* Combo: HasVirtual + HasStored */ -#define TF_WithoutRowid 0x0080 /* No rowid. PRIMARY KEY is the key */ -#define TF_StatsUsed 0x0100 /* Query planner decisions affected by +#define TF_Readonly 0x00000001 /* Read-only system table */ +#define TF_HasHidden 0x00000002 /* Has one or more hidden columns */ +#define TF_HasPrimaryKey 0x00000004 /* Table has a primary key */ +#define TF_Autoincrement 0x00000008 /* Integer primary key is autoincrement */ +#define TF_HasStat1 0x00000010 /* nRowLogEst set from sqlite_stat1 */ +#define TF_HasVirtual 0x00000020 /* Has one or more VIRTUAL columns */ +#define TF_HasStored 0x00000040 /* Has one or more STORED columns */ +#define TF_HasGenerated 0x00000060 /* Combo: HasVirtual + HasStored */ +#define TF_WithoutRowid 0x00000080 /* No rowid. PRIMARY KEY is the key */ +#define TF_StatsUsed 0x00000100 /* Query planner decisions affected by ** Index.aiRowLogEst[] values */ -#define TF_NoVisibleRowid 0x0200 /* No user-visible "rowid" column */ -#define TF_OOOHidden 0x0400 /* Out-of-Order hidden columns */ -#define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ -#define TF_Shadow 0x1000 /* True for a shadow table */ -#define TF_HasStat4 0x2000 /* STAT4 info available for this table */ -#define TF_Ephemeral 0x4000 /* An ephemeral table */ -#define TF_Eponymous 0x8000 /* An eponymous virtual table */ +#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */ +#define TF_OOOHidden 0x00000400 /* Out-of-Order hidden columns */ +#define TF_HasNotNull 0x00000800 /* Contains NOT NULL constraints */ +#define TF_Shadow 0x00001000 /* True for a shadow table */ +#define TF_HasStat4 0x00002000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x00004000 /* An ephemeral table */ +#define TF_Eponymous 0x00008000 /* An eponymous virtual table */ +#define TF_Strict 0x00010000 /* STRICT mode */ + +/* +** Allowed values for Table.eTabType +*/ +#define TABTYP_NORM 0 /* Ordinary table */ +#define TABTYP_VTAB 1 /* Virtual table */ +#define TABTYP_VIEW 2 /* A view */ + +#define IsView(X) ((X)->eTabType==TABTYP_VIEW) +#define IsOrdinaryTable(X) ((X)->eTabType==TABTYP_NORM) /* ** Test to see whether or not a table is a virtual table. This is @@ -17834,9 +17601,9 @@ struct Table { ** table support is omitted from the build. */ #ifndef SQLITE_OMIT_VIRTUALTABLE -# define IsVirtual(X) ((X)->nModuleArg) +# define IsVirtual(X) ((X)->eTabType==TABTYP_VTAB) # define ExprIsVtab(X) \ - ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->nModuleArg) + ((X)->op==TK_COLUMN && (X)->y.pTab!=0 && (X)->y.pTab->eTabType==TABTYP_VTAB) #else # define IsVirtual(X) 0 # define ExprIsVtab(X) 0 @@ -18225,10 +17992,10 @@ typedef int ynVar; ** tree. ** ** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB, -** or TK_STRING), then Expr.token contains the text of the SQL literal. If -** the expression is a variable (TK_VARIABLE), then Expr.token contains the +** or TK_STRING), then Expr.u.zToken contains the text of the SQL literal. If +** the expression is a variable (TK_VARIABLE), then Expr.u.zToken contains the ** variable name. Finally, if the expression is an SQL function (TK_FUNCTION), -** then Expr.token contains the name of the function. +** then Expr.u.zToken contains the name of the function. ** ** Expr.pRight and Expr.pLeft are the left and right subexpressions of a ** binary operator. Either or both may be NULL. @@ -18268,7 +18035,7 @@ typedef int ynVar; ** help reduce memory requirements, sometimes an Expr object will be ** truncated. And to reduce the number of memory allocations, sometimes ** two or more Expr objects will be stored in a single memory allocation, -** together with Expr.zToken strings. +** together with Expr.u.zToken strings. ** ** If the EP_Reduced and EP_TokenOnly flags are set when ** an Expr object is truncated. When EP_Reduced is set, then all @@ -18324,7 +18091,10 @@ struct Expr { ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ - int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + union { + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + int iOfst; /* else: start of token from start of statement */ + } w; AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -18337,8 +18107,7 @@ struct Expr { } y; }; -/* -** The following are the meanings of bits in the Expr.flags field. +/* The following are the meanings of bits in the Expr.flags field. ** Value restrictions: ** ** EP_Agg == NC_HasAgg == SF_HasAgg @@ -18377,14 +18146,12 @@ struct Expr { #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ /* 0x80000000 // Available */ -/* -** The EP_Propagate mask is a set of properties that automatically propagate +/* The EP_Propagate mask is a set of properties that automatically propagate ** upwards into parent nodes. */ #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) -/* -** These macros can be used to test, set, or clear bits in the +/* Macros can be used to test, set, or clear bits in the ** Expr.flags field. */ #define ExprHasProperty(E,P) (((E)->flags&(P))!=0) @@ -18394,6 +18161,16 @@ struct Expr { #define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse) +/* Macros used to ensure that the correct members of unions are accessed +** in Expr. +*/ +#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) +#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) +#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) +#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) +#define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) +#define ExprUseYWin(E) (((E)->flags&EP_WinFunc)!=0) +#define ExprUseYSub(E) (((E)->flags&EP_Subrtn)!=0) /* Flags for use with Expr.vvaFlags */ @@ -18476,11 +18253,12 @@ struct ExprList { unsigned bSorterRef :1; /* Defer evaluation until after sorting */ unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ union { - struct { + struct { /* Used by any ExprList other than Parse.pConsExpr */ u16 iOrderByCol; /* For ORDER BY, column number in result set */ u16 iAlias; /* Index into Parse.aAlias[] for zName */ } x; - int iConstExprReg; /* Register in which Expr value is cached */ + int iConstExprReg; /* Register in which Expr value is cached. Used only + ** by Parse.pConstExpr */ } u; } a[1]; /* One slot for each expression in the list */ }; @@ -18518,6 +18296,13 @@ struct IdList { /* ** The SrcItem object represents a single term in the FROM clause of a query. ** The SrcList object is mostly an array of SrcItems. +** +** Union member validity: +** +** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc +** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy +** u2.pIBIndex fg.isIndexedBy && !fg.isCte +** u2.pCteUse fg.isCte && !fg.isIndexedBy */ struct SrcItem { Schema *pSchema; /* Schema to which this item is fixed */ @@ -18666,31 +18451,33 @@ struct NameContext { ** Allowed values for the NameContext, ncFlags field. ** ** Value constraints (all checked via assert()): -** NC_HasAgg == SF_HasAgg == EP_Agg -** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX +** NC_HasAgg == SF_HasAgg == EP_Agg +** NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX +** NC_OrderAgg == SF_OrderByReqd == SQLITE_FUNC_ANYORDER ** NC_HasWin == EP_Win ** */ -#define NC_AllowAgg 0x00001 /* Aggregate functions are allowed here */ -#define NC_PartIdx 0x00002 /* True if resolving a partial index WHERE */ -#define NC_IsCheck 0x00004 /* True if resolving a CHECK constraint */ -#define NC_GenCol 0x00008 /* True for a GENERATED ALWAYS AS clause */ -#define NC_HasAgg 0x00010 /* One or more aggregate functions seen */ -#define NC_IdxExpr 0x00020 /* True if resolving columns of CREATE INDEX */ -#define NC_SelfRef 0x0002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ -#define NC_VarSelect 0x00040 /* A correlated subquery has been seen */ -#define NC_UEList 0x00080 /* True if uNC.pEList is used */ -#define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ -#define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ -#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */ -#define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ -#define NC_Complex 0x02000 /* True if a function or subquery seen */ -#define NC_AllowWin 0x04000 /* Window functions are allowed here */ -#define NC_HasWin 0x08000 /* One or more window functions seen */ -#define NC_IsDDL 0x10000 /* Resolving names in a CREATE statement */ -#define NC_InAggFunc 0x20000 /* True if analyzing arguments to an agg func */ -#define NC_FromDDL 0x40000 /* SQL text comes from sqlite_schema */ -#define NC_NoSelect 0x80000 /* Do not descend into sub-selects */ +#define NC_AllowAgg 0x000001 /* Aggregate functions are allowed here */ +#define NC_PartIdx 0x000002 /* True if resolving a partial index WHERE */ +#define NC_IsCheck 0x000004 /* True if resolving a CHECK constraint */ +#define NC_GenCol 0x000008 /* True for a GENERATED ALWAYS AS clause */ +#define NC_HasAgg 0x000010 /* One or more aggregate functions seen */ +#define NC_IdxExpr 0x000020 /* True if resolving columns of CREATE INDEX */ +#define NC_SelfRef 0x00002e /* Combo: PartIdx, isCheck, GenCol, and IdxExpr */ +#define NC_VarSelect 0x000040 /* A correlated subquery has been seen */ +#define NC_UEList 0x000080 /* True if uNC.pEList is used */ +#define NC_UAggInfo 0x000100 /* True if uNC.pAggInfo is used */ +#define NC_UUpsert 0x000200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x000400 /* True if uNC.iBaseReg is used */ +#define NC_MinMaxAgg 0x001000 /* min/max aggregates seen. See note above */ +#define NC_Complex 0x002000 /* True if a function or subquery seen */ +#define NC_AllowWin 0x004000 /* Window functions are allowed here */ +#define NC_HasWin 0x008000 /* One or more window functions seen */ +#define NC_IsDDL 0x010000 /* Resolving names in a CREATE statement */ +#define NC_InAggFunc 0x020000 /* True if analyzing arguments to an agg func */ +#define NC_FromDDL 0x040000 /* SQL text comes from sqlite_schema */ +#define NC_NoSelect 0x080000 /* Do not descend into sub-selects */ +#define NC_OrderAgg 0x8000000 /* Has an aggregate other than count/min/max */ /* ** An instance of the following object describes a single ON CONFLICT @@ -18773,9 +18560,10 @@ struct Select { ** "Select Flag". ** ** Value constraints (all checked via assert()) -** SF_HasAgg == NC_HasAgg -** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX -** SF_FixedLimit == WHERE_USE_LIMIT +** SF_HasAgg == NC_HasAgg +** SF_MinMaxAgg == NC_MinMaxAgg == SQLITE_FUNC_MINMAX +** SF_OrderByReqd == NC_OrderAgg == SQLITE_FUNC_ANYORDER +** SF_FixedLimit == WHERE_USE_LIMIT */ #define SF_Distinct 0x0000001 /* Output should be DISTINCT */ #define SF_All 0x0000002 /* Includes the ALL keyword */ @@ -18800,10 +18588,11 @@ struct Select { #define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */ #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ -#define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */ +#define SF_UFSrcCheck 0x0800000 /* Check pSrc as required by UPDATE...FROM */ #define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ #define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ #define SF_CopyCte 0x4000000 /* SELECT statement is a copy of a CTE */ +#define SF_OrderByReqd 0x8000000 /* The ORDER BY clause may not be omitted */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -19045,7 +18834,8 @@ struct Parse { AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ - Parse *pParentParse; /* Parent parser if this parser is nested */ + TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ union { int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ Returning *pReturning; /* The RETURNING clause */ @@ -19066,6 +18856,7 @@ struct Parse { **************************************************************************/ int aTempReg[8]; /* Holding area for temporary registers */ + Parse *pOuterParse; /* Outer Parse object when nested */ Token sNameToken; /* Token with unqualified schema object name */ /************************************************************************ @@ -19100,14 +18891,14 @@ struct Parse { Token sArg; /* Complete text of a module argument */ Table **apVtabLock; /* Pointer to virtual tables needing locking */ #endif - TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif }; +/* Allowed values for Parse.eParseMode +*/ #define PARSE_MODE_NORMAL 0 #define PARSE_MODE_DECLARE_VTAB 1 #define PARSE_MODE_RENAME 2 @@ -19116,7 +18907,8 @@ struct Parse { /* ** Sizes and pointers of various parts of the Parse object. */ -#define PARSE_HDR_SZ offsetof(Parse,aTempReg) /* Recursive part w/o aColCache*/ +#define PARSE_HDR(X) (((char*)(X))+offsetof(Parse,zErrMsg)) +#define PARSE_HDR_SZ (offsetof(Parse,aTempReg)-offsetof(Parse,zErrMsg)) /* Recursive part w/o aColCache*/ #define PARSE_RECURSE_SZ offsetof(Parse,sLastToken) /* Recursive part */ #define PARSE_TAIL_SZ (sizeof(Parse)-PARSE_RECURSE_SZ) /* Non-recursive part */ #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ @@ -19329,8 +19121,10 @@ typedef struct { /* ** Allowed values for mInitFlags */ +#define INITFLAG_AlterMask 0x0003 /* Types of ALTER */ #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ +#define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning @@ -19409,6 +19203,7 @@ struct Sqlite3Config { int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ + int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */ int iOnceResetThreshold; /* When to reset OP_Once counters */ u32 szSorterRef; /* Min size in bytes to use sorter-refs */ unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */ @@ -19451,8 +19246,8 @@ struct Walker { int n; /* A counter */ int iCur; /* A cursor number */ SrcList *pSrcList; /* FROM clause */ - struct SrcCount *pSrcCount; /* Counting column references */ struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ + struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */ int *aiCol; /* array of column indexes */ struct IdxCover *pIdxCover; /* Check for index coverage */ struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */ @@ -19637,7 +19432,7 @@ SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p); SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*); SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin); -SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*, int); +SQLITE_PRIVATE int sqlite3WindowCompare(const Parse*, const Window*, const Window*, int); SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Select*); SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*); @@ -19769,8 +19564,8 @@ SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); -SQLITE_PRIVATE int sqlite3MallocSize(void*); -SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); +SQLITE_PRIVATE int sqlite3MallocSize(const void*); +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, const void*); SQLITE_PRIVATE void *sqlite3PageMalloc(int); SQLITE_PRIVATE void sqlite3PageFree(void*); SQLITE_PRIVATE void sqlite3MemSetDefault(void); @@ -19886,9 +19681,10 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); SQLITE_PRIVATE void sqlite3Dequote(char*); SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); +SQLITE_PRIVATE void sqlite3DequoteToken(Token*); SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); -SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); +SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*); SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); @@ -19905,16 +19701,17 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*); -SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); -SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*); +SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); +SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*); SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); +SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse*, int, ExprList*); SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); -SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); +SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int); SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); @@ -19930,6 +19727,10 @@ SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); +SQLITE_PRIVATE void sqlite3ColumnSetExpr(Parse*,Table*,Column*,Expr*); +SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table*,Column*); +SQLITE_PRIVATE void sqlite3ColumnSetColl(sqlite3*,Column*,const char*zColl); +SQLITE_PRIVATE const char *sqlite3ColumnColl(Column*); SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); SQLITE_PRIVATE void sqlite3GenerateColumnNames(Parse *pParse, Select *pSelect); SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); @@ -19951,14 +19752,14 @@ SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*); #else # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */ #endif -SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*); +SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token,Token); SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*); SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*); -SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u32,Select*); SQLITE_PRIVATE void sqlite3AddReturning(Parse*,ExprList*); SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); @@ -20044,10 +19845,12 @@ SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*); SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, Upsert*); -SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*, + ExprList*,Select*,u16,int); SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); @@ -20068,7 +19871,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS -SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int); +SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Table*, Column*, int); #endif SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); @@ -20087,23 +19890,24 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); +SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*); SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *); SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*); SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); -SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); -SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); -SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int); -SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); -SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, const Token*); +SQLITE_PRIVATE int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*,Expr*,int); +SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList*,const ExprList*, int); +SQLITE_PRIVATE int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int); SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int); SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); -SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); +SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*); SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); #ifndef SQLITE_UNTESTABLE SQLITE_PRIVATE void sqlite3PrngSaveState(void); @@ -20125,10 +19929,11 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr*,const SrcItem*); #ifdef SQLITE_ENABLE_CURSOR_HINTS SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif -SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr*, int*); SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); SQLITE_PRIVATE int sqlite3IsRowid(const char*); @@ -20153,17 +19958,22 @@ SQLITE_PRIVATE void sqlite3MayAbort(Parse*); SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*); SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*); -SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); -SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); -SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); -SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); -SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,const Expr*,int); +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,const ExprList*,int); +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,const SrcList*,int); +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,const IdList*); +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,const Select*,int); SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3*); +#endif SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); @@ -20253,14 +20063,8 @@ SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); SQLITE_PRIVATE LogEst sqlite3LogEst(u64); SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); -#ifndef SQLITE_OMIT_VIRTUALTABLE SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); -#endif -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_ENABLE_STAT4) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); -#endif SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int); SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int); @@ -20295,7 +20099,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); SQLITE_PRIVATE char sqlite3CompareAffinity(const Expr *pExpr, char aff2); SQLITE_PRIVATE int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity); -SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table*,int); +SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table*,int); SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr); SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); @@ -20324,14 +20128,14 @@ SQLITE_PRIVATE void sqlite3SetTextEncoding(sqlite3 *db, u8); SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr); SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr); SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(const Parse *pParse, Expr*, const Token*, int); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(const Parse*,Expr*,const char*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr*); SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*); SQLITE_PRIVATE int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*); -SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, i64); SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); @@ -20356,11 +20160,15 @@ SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); #ifndef SQLITE_OMIT_UTF16 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); #endif -SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); +SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, const Expr *, u8, u8, sqlite3_value **); SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); #ifndef SQLITE_AMALGAMATION SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; SQLITE_PRIVATE const char sqlite3StrBINARY[]; +SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[]; +SQLITE_PRIVATE const char sqlite3StdTypeAffinity[]; +SQLITE_PRIVATE const char sqlite3StdTypeMap[]; +SQLITE_PRIVATE const char *sqlite3StdType[]; SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; SQLITE_PRIVATE const unsigned char *sqlite3aLTb; SQLITE_PRIVATE const unsigned char *sqlite3aEQb; @@ -20404,9 +20212,9 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); -SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse*, SrcList*, Token*); -SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); -SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse*, SrcList*, const Token*); +SQLITE_PRIVATE const void *sqlite3RenameTokenMap(Parse*, const void*, const Token*); +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, const void *pTo, const void *pFrom); SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); @@ -20443,15 +20251,20 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, FuncDestructor *pDestructor ); SQLITE_PRIVATE void sqlite3NoopDestructor(void*); -SQLITE_PRIVATE void sqlite3OomFault(sqlite3*); +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3*); SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum*, int); SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); +SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum*, u8); +SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*); SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3*,const char*); +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3*,const Expr*); SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); @@ -20502,7 +20315,7 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); #endif #ifdef SQLITE_OMIT_VIRTUALTABLE -# define sqlite3VtabClear(Y) +# define sqlite3VtabClear(D,T) # define sqlite3VtabSync(X,Y) SQLITE_OK # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) @@ -20539,9 +20352,11 @@ SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db); #ifndef SQLITE_OMIT_VIRTUALTABLE SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName); SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*); +SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*); #else # define sqlite3ShadowTableName(A,B) 0 # define sqlite3IsShadowTableOf(A,B,C) 0 +# define sqlite3MarkAllShadowTablesOf(A,B) #endif SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); @@ -20554,11 +20369,17 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); + SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) +SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info*); +#endif SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); -SQLITE_PRIVATE void sqlite3ParserReset(Parse*); +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse*,sqlite3*); +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse*); SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); @@ -20584,7 +20405,7 @@ SQLITE_PRIVATE With *sqlite3WithPush(Parse*, With*, u8); # define sqlite3CteDelete(D,C) # define sqlite3CteWithAdd(P,W,C) ((void*)0) # define sqlite3WithDelete(x,y) -# define sqlite3WithPush(x,y,z) +# define sqlite3WithPush(x,y,z) ((void*)0) #endif #ifndef SQLITE_OMIT_UPSERT SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); @@ -20617,6 +20438,7 @@ SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3*,int); #else #define sqlite3FkActions(a,b,c,d,e,f) #define sqlite3FkCheck(a,b,c,d,e,f) @@ -20624,6 +20446,7 @@ SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); #define sqlite3FkOldmask(a,b) 0 #define sqlite3FkRequired(a,b,c,d) 0 #define sqlite3FkReferences(a) 0 + #define sqlite3FkClearTriggerCache(a,b) #endif #ifndef SQLITE_OMIT_FOREIGN_KEY SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); @@ -20681,7 +20504,7 @@ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); #if SQLITE_MAX_EXPR_DEPTH>0 -SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *); +SQLITE_PRIVATE int sqlite3SelectExprHeight(const Select *); SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); #else #define sqlite3SelectExprHeight(x) 0 @@ -20752,8 +20575,8 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); */ #ifdef SQLITE_MEMDEBUG SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8); -SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8); -SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugHasType(const void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugNoType(const void*,u8); #else # define sqlite3MemdebugSetType(X,Y) /* no-op */ # define sqlite3MemdebugHasType(X,Y) 1 @@ -20778,10 +20601,10 @@ SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*); SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*); #endif -SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr); -SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr); SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int); -SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int); +SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int); SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*); #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS @@ -20791,6 +20614,993 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); #endif /* SQLITEINT_H */ /************** End of sqliteInt.h *******************************************/ +/************** Begin file os_common.h ***************************************/ +/* +** 2004 May 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains macros and a little bit of code that is common to +** all of the platform-specific files (os_*.c) and is #included into those +** files. +** +** This file should be #included by the os_*.c files only. It is not a +** general purpose header file. +*/ +#ifndef _OS_COMMON_H_ +#define _OS_COMMON_H_ + +/* +** At least two bugs have slipped in because we changed the MEMORY_DEBUG +** macro to SQLITE_DEBUG and some older makefiles have not yet made the +** switch. The following code should catch this problem at compile-time. +*/ +#ifdef MEMORY_DEBUG +# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." +#endif + +/* +** Macros for performance tracing. Normally turned off. Only works +** on i486 hardware. +*/ +#ifdef SQLITE_PERFORMANCE_TRACE + +/* +** hwtime.h contains inline assembler code for implementing +** high-performance timing routines. +*/ +/************** Include hwtime.h in the middle of os_common.h ****************/ +/************** Begin file hwtime.h ******************************************/ +/* +** 2008 May 27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +****************************************************************************** +** +** This file contains inline asm code for retrieving "high-performance" +** counters for x86 and x86_64 class CPUs. +*/ +#ifndef SQLITE_HWTIME_H +#define SQLITE_HWTIME_H + +/* +** The following routine only works on pentium-class (or newer) processors. +** It uses the RDTSC opcode to read the cycle count value out of the +** processor and returns that value. This can be used for high-res +** profiling. +*/ +#if !defined(__STRICT_ANSI__) && \ + (defined(__GNUC__) || defined(_MSC_VER)) && \ + (defined(i386) || defined(__i386__) || defined(_M_IX86)) + + #if defined(__GNUC__) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned int lo, hi; + __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); + return (sqlite_uint64)hi << 32 | lo; + } + + #elif defined(_MSC_VER) + + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ + __asm { + rdtsc + ret ; return value at EDX:EAX + } + } + + #endif + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long val; + __asm__ __volatile__ ("rdtsc" : "=A" (val)); + return val; + } + +#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) + + __inline__ sqlite_uint64 sqlite3Hwtime(void){ + unsigned long long retval; + unsigned long junk; + __asm__ __volatile__ ("\n\ + 1: mftbu %1\n\ + mftb %L0\n\ + mftbu %0\n\ + cmpw %0,%1\n\ + bne 1b" + : "=r" (retval), "=r" (junk)); + return retval; + } + +#else + + /* + ** asm() is needed for hardware timing support. Without asm(), + ** disable the sqlite3Hwtime() routine. + ** + ** sqlite3Hwtime() is only used for some obscure debugging + ** and analysis configurations, not in any deliverable, so this + ** should not be a great loss. + */ +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } + +#endif + +#endif /* !defined(SQLITE_HWTIME_H) */ + +/************** End of hwtime.h **********************************************/ +/************** Continuing where we left off in os_common.h ******************/ + +static sqlite_uint64 g_start; +static sqlite_uint64 g_elapsed; +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start +#define TIMER_ELAPSED g_elapsed +#else +#define TIMER_START +#define TIMER_END +#define TIMER_ELAPSED ((sqlite_uint64)0) +#endif + +/* +** If we compile with the SQLITE_TEST macro set, then the following block +** of code will give us the ability to simulate a disk I/O error. This +** is used for testing the I/O recovery logic. +*/ +#if defined(SQLITE_TEST) +SQLITE_API extern int sqlite3_io_error_hit; +SQLITE_API extern int sqlite3_io_error_hardhit; +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_persist; +SQLITE_API extern int sqlite3_io_error_benign; +SQLITE_API extern int sqlite3_diskfull_pending; +SQLITE_API extern int sqlite3_diskfull; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) +#define SimulateIOError(CODE) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ + { local_ioerr(); CODE; } +static void local_ioerr(){ + IOTRACE(("IOERR\n")); + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; +} +#define SimulateDiskfullError(CODE) \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ + local_ioerr(); \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ + CODE; \ + }else{ \ + sqlite3_diskfull_pending--; \ + } \ + } +#else +#define SimulateIOErrorBenign(X) +#define SimulateIOError(A) +#define SimulateDiskfullError(A) +#endif /* defined(SQLITE_TEST) */ + +/* +** When testing, keep a count of the number of open files. +*/ +#if defined(SQLITE_TEST) +SQLITE_API extern int sqlite3_open_file_count; +#define OpenCounter(X) sqlite3_open_file_count+=(X) +#else +#define OpenCounter(X) +#endif /* defined(SQLITE_TEST) */ + +#endif /* !defined(_OS_COMMON_H_) */ + +/************** End of os_common.h *******************************************/ +/************** Begin file ctime.c *******************************************/ +/* DO NOT EDIT! +** This file is automatically generated by the script in the canonical +** SQLite source tree at tool/mkctimec.tcl. +** +** To modify this header, edit any of the various lists in that script +** which specify categories of generated conditionals in this file. +*/ + +/* +** 2010 February 23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements routines used to report what compile-time options +** SQLite was built with. +*/ +#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS /* IMP: R-16824-07538 */ + +/* +** Include the configuration header output by 'configure' if we're using the +** autoconf-based build +*/ +#if defined(_HAVE_SQLITE_CONFIG_H) && !defined(SQLITECONFIG_H) +/* #include "config.h" */ +#define SQLITECONFIG_H 1 +#endif + +/* These macros are provided to "stringify" the value of the define +** for those options in which the value is meaningful. */ +#define CTIMEOPT_VAL_(opt) #opt +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt) + +/* Like CTIMEOPT_VAL, but especially for SQLITE_DEFAULT_LOOKASIDE. This +** option requires a separate macro because legal values contain a single +** comma. e.g. (-DSQLITE_DEFAULT_LOOKASIDE="100,100") */ +#define CTIMEOPT_VAL2_(opt1,opt2) #opt1 "," #opt2 +#define CTIMEOPT_VAL2(opt) CTIMEOPT_VAL2_(opt) +/* #include "sqliteInt.h" */ + +/* +** An array of names of all compile-time options. This array should +** be sorted A-Z. +** +** This array looks large, but in a typical installation actually uses +** only a handful of compile-time options, so most times this array is usually +** rather short and uses little memory space. +*/ +static const char * const sqlite3azCompileOpt[] = { + +#ifdef SQLITE_32BIT_ROWID + "32BIT_ROWID", +#endif +#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC + "4_BYTE_ALIGNED_MALLOC", +#endif +#ifdef SQLITE_64BIT_STATS + "64BIT_STATS", +#endif +#ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN +# if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1 + "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), +# endif +#endif +#ifdef SQLITE_ALLOW_URI_AUTHORITY + "ALLOW_URI_AUTHORITY", +#endif +#ifdef SQLITE_ATOMIC_INTRINSICS + "ATOMIC_INTRINSICS=" CTIMEOPT_VAL(SQLITE_ATOMIC_INTRINSICS), +#endif +#ifdef SQLITE_BITMASK_TYPE + "BITMASK_TYPE=" CTIMEOPT_VAL(SQLITE_BITMASK_TYPE), +#endif +#ifdef SQLITE_BUG_COMPATIBLE_20160819 + "BUG_COMPATIBLE_20160819", +#endif +#ifdef SQLITE_CASE_SENSITIVE_LIKE + "CASE_SENSITIVE_LIKE", +#endif +#ifdef SQLITE_CHECK_PAGES + "CHECK_PAGES", +#endif +#if defined(__clang__) && defined(__clang_major__) + "COMPILER=clang-" CTIMEOPT_VAL(__clang_major__) "." + CTIMEOPT_VAL(__clang_minor__) "." + CTIMEOPT_VAL(__clang_patchlevel__), +#elif defined(_MSC_VER) + "COMPILER=msvc-" CTIMEOPT_VAL(_MSC_VER), +#elif defined(__GNUC__) && defined(__VERSION__) + "COMPILER=gcc-" __VERSION__, +#endif +#ifdef SQLITE_COVERAGE_TEST + "COVERAGE_TEST", +#endif +#ifdef SQLITE_DEBUG + "DEBUG", +#endif +#ifdef SQLITE_DEFAULT_AUTOMATIC_INDEX + "DEFAULT_AUTOMATIC_INDEX", +#endif +#ifdef SQLITE_DEFAULT_AUTOVACUUM + "DEFAULT_AUTOVACUUM", +#endif +#ifdef SQLITE_DEFAULT_CACHE_SIZE + "DEFAULT_CACHE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_CACHE_SIZE), +#endif +#ifdef SQLITE_DEFAULT_CKPTFULLFSYNC + "DEFAULT_CKPTFULLFSYNC", +#endif +#ifdef SQLITE_DEFAULT_FILE_FORMAT + "DEFAULT_FILE_FORMAT=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_FORMAT), +#endif +#ifdef SQLITE_DEFAULT_FILE_PERMISSIONS + "DEFAULT_FILE_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_FILE_PERMISSIONS), +#endif +#ifdef SQLITE_DEFAULT_FOREIGN_KEYS + "DEFAULT_FOREIGN_KEYS", +#endif +#ifdef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT + "DEFAULT_JOURNAL_SIZE_LIMIT=" CTIMEOPT_VAL(SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT), +#endif +#ifdef SQLITE_DEFAULT_LOCKING_MODE + "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE), +#endif +#ifdef SQLITE_DEFAULT_LOOKASIDE + "DEFAULT_LOOKASIDE=" CTIMEOPT_VAL2(SQLITE_DEFAULT_LOOKASIDE), +#endif +#ifdef SQLITE_DEFAULT_MEMSTATUS +# if SQLITE_DEFAULT_MEMSTATUS != 1 + "DEFAULT_MEMSTATUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_MEMSTATUS), +# endif +#endif +#ifdef SQLITE_DEFAULT_MMAP_SIZE + "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE), +#endif +#ifdef SQLITE_DEFAULT_PAGE_SIZE + "DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_PAGE_SIZE), +#endif +#ifdef SQLITE_DEFAULT_PCACHE_INITSZ + "DEFAULT_PCACHE_INITSZ=" CTIMEOPT_VAL(SQLITE_DEFAULT_PCACHE_INITSZ), +#endif +#ifdef SQLITE_DEFAULT_PROXYDIR_PERMISSIONS + "DEFAULT_PROXYDIR_PERMISSIONS=" CTIMEOPT_VAL(SQLITE_DEFAULT_PROXYDIR_PERMISSIONS), +#endif +#ifdef SQLITE_DEFAULT_RECURSIVE_TRIGGERS + "DEFAULT_RECURSIVE_TRIGGERS", +#endif +#ifdef SQLITE_DEFAULT_ROWEST + "DEFAULT_ROWEST=" CTIMEOPT_VAL(SQLITE_DEFAULT_ROWEST), +#endif +#ifdef SQLITE_DEFAULT_SECTOR_SIZE + "DEFAULT_SECTOR_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_SECTOR_SIZE), +#endif +#ifdef SQLITE_DEFAULT_SYNCHRONOUS + "DEFAULT_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_SYNCHRONOUS), +#endif +#ifdef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT + "DEFAULT_WAL_AUTOCHECKPOINT=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_AUTOCHECKPOINT), +#endif +#ifdef SQLITE_DEFAULT_WAL_SYNCHRONOUS + "DEFAULT_WAL_SYNCHRONOUS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WAL_SYNCHRONOUS), +#endif +#ifdef SQLITE_DEFAULT_WORKER_THREADS + "DEFAULT_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_DEFAULT_WORKER_THREADS), +#endif +#ifdef SQLITE_DIRECT_OVERFLOW_READ + "DIRECT_OVERFLOW_READ", +#endif +#ifdef SQLITE_DISABLE_DIRSYNC + "DISABLE_DIRSYNC", +#endif +#ifdef SQLITE_DISABLE_FTS3_UNICODE + "DISABLE_FTS3_UNICODE", +#endif +#ifdef SQLITE_DISABLE_FTS4_DEFERRED + "DISABLE_FTS4_DEFERRED", +#endif +#ifdef SQLITE_DISABLE_INTRINSIC + "DISABLE_INTRINSIC", +#endif +#ifdef SQLITE_DISABLE_LFS + "DISABLE_LFS", +#endif +#ifdef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS + "DISABLE_PAGECACHE_OVERFLOW_STATS", +#endif +#ifdef SQLITE_DISABLE_SKIPAHEAD_DISTINCT + "DISABLE_SKIPAHEAD_DISTINCT", +#endif +#ifdef SQLITE_ENABLE_8_3_NAMES + "ENABLE_8_3_NAMES=" CTIMEOPT_VAL(SQLITE_ENABLE_8_3_NAMES), +#endif +#ifdef SQLITE_ENABLE_API_ARMOR + "ENABLE_API_ARMOR", +#endif +#ifdef SQLITE_ENABLE_ATOMIC_WRITE + "ENABLE_ATOMIC_WRITE", +#endif +#ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE + "ENABLE_BATCH_ATOMIC_WRITE", +#endif +#ifdef SQLITE_ENABLE_BYTECODE_VTAB + "ENABLE_BYTECODE_VTAB", +#endif +#ifdef SQLITE_ENABLE_CEROD + "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), +#endif +#ifdef SQLITE_ENABLE_COLUMN_METADATA + "ENABLE_COLUMN_METADATA", +#endif +#ifdef SQLITE_ENABLE_COLUMN_USED_MASK + "ENABLE_COLUMN_USED_MASK", +#endif +#ifdef SQLITE_ENABLE_COSTMULT + "ENABLE_COSTMULT", +#endif +#ifdef SQLITE_ENABLE_CURSOR_HINTS + "ENABLE_CURSOR_HINTS", +#endif +#ifdef SQLITE_ENABLE_DBPAGE_VTAB + "ENABLE_DBPAGE_VTAB", +#endif +#ifdef SQLITE_ENABLE_DBSTAT_VTAB + "ENABLE_DBSTAT_VTAB", +#endif +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT + "ENABLE_EXPENSIVE_ASSERT", +#endif +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + "ENABLE_EXPLAIN_COMMENTS", +#endif +#ifdef SQLITE_ENABLE_FTS3 + "ENABLE_FTS3", +#endif +#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS + "ENABLE_FTS3_PARENTHESIS", +#endif +#ifdef SQLITE_ENABLE_FTS3_TOKENIZER + "ENABLE_FTS3_TOKENIZER", +#endif +#ifdef SQLITE_ENABLE_FTS4 + "ENABLE_FTS4", +#endif +#ifdef SQLITE_ENABLE_FTS5 + "ENABLE_FTS5", +#endif +#ifdef SQLITE_ENABLE_GEOPOLY + "ENABLE_GEOPOLY", +#endif +#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS + "ENABLE_HIDDEN_COLUMNS", +#endif +#ifdef SQLITE_ENABLE_ICU + "ENABLE_ICU", +#endif +#ifdef SQLITE_ENABLE_IOTRACE + "ENABLE_IOTRACE", +#endif +#ifdef SQLITE_ENABLE_LOAD_EXTENSION + "ENABLE_LOAD_EXTENSION", +#endif +#ifdef SQLITE_ENABLE_LOCKING_STYLE + "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), +#endif +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS", +#endif +#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT + "ENABLE_MEMORY_MANAGEMENT", +#endif +#ifdef SQLITE_ENABLE_MEMSYS3 + "ENABLE_MEMSYS3", +#endif +#ifdef SQLITE_ENABLE_MEMSYS5 + "ENABLE_MEMSYS5", +#endif +#ifdef SQLITE_ENABLE_MULTIPLEX + "ENABLE_MULTIPLEX", +#endif +#ifdef SQLITE_ENABLE_NORMALIZE + "ENABLE_NORMALIZE", +#endif +#ifdef SQLITE_ENABLE_NULL_TRIM + "ENABLE_NULL_TRIM", +#endif +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + "ENABLE_OFFSET_SQL_FUNC", +#endif +#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK + "ENABLE_OVERSIZE_CELL_CHECK", +#endif +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + "ENABLE_PREUPDATE_HOOK", +#endif +#ifdef SQLITE_ENABLE_QPSG + "ENABLE_QPSG", +#endif +#ifdef SQLITE_ENABLE_RBU + "ENABLE_RBU", +#endif +#ifdef SQLITE_ENABLE_RTREE + "ENABLE_RTREE", +#endif +#ifdef SQLITE_ENABLE_SELECTTRACE + "ENABLE_SELECTTRACE", +#endif +#ifdef SQLITE_ENABLE_SESSION + "ENABLE_SESSION", +#endif +#ifdef SQLITE_ENABLE_SNAPSHOT + "ENABLE_SNAPSHOT", +#endif +#ifdef SQLITE_ENABLE_SORTER_REFERENCES + "ENABLE_SORTER_REFERENCES", +#endif +#ifdef SQLITE_ENABLE_SQLLOG + "ENABLE_SQLLOG", +#endif +#ifdef SQLITE_ENABLE_STAT4 + "ENABLE_STAT4", +#endif +#ifdef SQLITE_ENABLE_STMTVTAB + "ENABLE_STMTVTAB", +#endif +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + "ENABLE_STMT_SCANSTATUS", +#endif +#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION + "ENABLE_UNKNOWN_SQL_FUNCTION", +#endif +#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY + "ENABLE_UNLOCK_NOTIFY", +#endif +#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT + "ENABLE_UPDATE_DELETE_LIMIT", +#endif +#ifdef SQLITE_ENABLE_URI_00_ERROR + "ENABLE_URI_00_ERROR", +#endif +#ifdef SQLITE_ENABLE_VFSTRACE + "ENABLE_VFSTRACE", +#endif +#ifdef SQLITE_ENABLE_WHERETRACE + "ENABLE_WHERETRACE", +#endif +#ifdef SQLITE_ENABLE_ZIPVFS + "ENABLE_ZIPVFS", +#endif +#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS + "EXPLAIN_ESTIMATED_ROWS", +#endif +#ifdef SQLITE_EXTRA_IFNULLROW + "EXTRA_IFNULLROW", +#endif +#ifdef SQLITE_EXTRA_INIT + "EXTRA_INIT=" CTIMEOPT_VAL(SQLITE_EXTRA_INIT), +#endif +#ifdef SQLITE_EXTRA_SHUTDOWN + "EXTRA_SHUTDOWN=" CTIMEOPT_VAL(SQLITE_EXTRA_SHUTDOWN), +#endif +#ifdef SQLITE_FTS3_MAX_EXPR_DEPTH + "FTS3_MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_FTS3_MAX_EXPR_DEPTH), +#endif +#ifdef SQLITE_FTS5_ENABLE_TEST_MI + "FTS5_ENABLE_TEST_MI", +#endif +#ifdef SQLITE_FTS5_NO_WITHOUT_ROWID + "FTS5_NO_WITHOUT_ROWID", +#endif +#if HAVE_ISNAN || SQLITE_HAVE_ISNAN + "HAVE_ISNAN", +#endif +#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX +# if SQLITE_HOMEGROWN_RECURSIVE_MUTEX != 1 + "HOMEGROWN_RECURSIVE_MUTEX=" CTIMEOPT_VAL(SQLITE_HOMEGROWN_RECURSIVE_MUTEX), +# endif +#endif +#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS + "IGNORE_AFP_LOCK_ERRORS", +#endif +#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS + "IGNORE_FLOCK_LOCK_ERRORS", +#endif +#ifdef SQLITE_INLINE_MEMCPY + "INLINE_MEMCPY", +#endif +#ifdef SQLITE_INT64_TYPE + "INT64_TYPE", +#endif +#ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX + "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), +#endif +#ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS + "LIKE_DOESNT_MATCH_BLOBS", +#endif +#ifdef SQLITE_LOCK_TRACE + "LOCK_TRACE", +#endif +#ifdef SQLITE_LOG_CACHE_SPILL + "LOG_CACHE_SPILL", +#endif +#ifdef SQLITE_MALLOC_SOFT_LIMIT + "MALLOC_SOFT_LIMIT=" CTIMEOPT_VAL(SQLITE_MALLOC_SOFT_LIMIT), +#endif +#ifdef SQLITE_MAX_ATTACHED + "MAX_ATTACHED=" CTIMEOPT_VAL(SQLITE_MAX_ATTACHED), +#endif +#ifdef SQLITE_MAX_COLUMN + "MAX_COLUMN=" CTIMEOPT_VAL(SQLITE_MAX_COLUMN), +#endif +#ifdef SQLITE_MAX_COMPOUND_SELECT + "MAX_COMPOUND_SELECT=" CTIMEOPT_VAL(SQLITE_MAX_COMPOUND_SELECT), +#endif +#ifdef SQLITE_MAX_DEFAULT_PAGE_SIZE + "MAX_DEFAULT_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_DEFAULT_PAGE_SIZE), +#endif +#ifdef SQLITE_MAX_EXPR_DEPTH + "MAX_EXPR_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_EXPR_DEPTH), +#endif +#ifdef SQLITE_MAX_FUNCTION_ARG + "MAX_FUNCTION_ARG=" CTIMEOPT_VAL(SQLITE_MAX_FUNCTION_ARG), +#endif +#ifdef SQLITE_MAX_LENGTH + "MAX_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LENGTH), +#endif +#ifdef SQLITE_MAX_LIKE_PATTERN_LENGTH + "MAX_LIKE_PATTERN_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_LIKE_PATTERN_LENGTH), +#endif +#ifdef SQLITE_MAX_MEMORY + "MAX_MEMORY=" CTIMEOPT_VAL(SQLITE_MAX_MEMORY), +#endif +#ifdef SQLITE_MAX_MMAP_SIZE + "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE), +#endif +#ifdef SQLITE_MAX_MMAP_SIZE_ + "MAX_MMAP_SIZE_=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE_), +#endif +#ifdef SQLITE_MAX_PAGE_COUNT + "MAX_PAGE_COUNT=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_COUNT), +#endif +#ifdef SQLITE_MAX_PAGE_SIZE + "MAX_PAGE_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_PAGE_SIZE), +#endif +#ifdef SQLITE_MAX_SCHEMA_RETRY + "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY), +#endif +#ifdef SQLITE_MAX_SQL_LENGTH + "MAX_SQL_LENGTH=" CTIMEOPT_VAL(SQLITE_MAX_SQL_LENGTH), +#endif +#ifdef SQLITE_MAX_TRIGGER_DEPTH + "MAX_TRIGGER_DEPTH=" CTIMEOPT_VAL(SQLITE_MAX_TRIGGER_DEPTH), +#endif +#ifdef SQLITE_MAX_VARIABLE_NUMBER + "MAX_VARIABLE_NUMBER=" CTIMEOPT_VAL(SQLITE_MAX_VARIABLE_NUMBER), +#endif +#ifdef SQLITE_MAX_VDBE_OP + "MAX_VDBE_OP=" CTIMEOPT_VAL(SQLITE_MAX_VDBE_OP), +#endif +#ifdef SQLITE_MAX_WORKER_THREADS + "MAX_WORKER_THREADS=" CTIMEOPT_VAL(SQLITE_MAX_WORKER_THREADS), +#endif +#ifdef SQLITE_MEMDEBUG + "MEMDEBUG", +#endif +#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT + "MIXED_ENDIAN_64BIT_FLOAT", +#endif +#ifdef SQLITE_MMAP_READWRITE + "MMAP_READWRITE", +#endif +#ifdef SQLITE_MUTEX_NOOP + "MUTEX_NOOP", +#endif +#ifdef SQLITE_MUTEX_OMIT + "MUTEX_OMIT", +#endif +#ifdef SQLITE_MUTEX_PTHREADS + "MUTEX_PTHREADS", +#endif +#ifdef SQLITE_MUTEX_W32 + "MUTEX_W32", +#endif +#ifdef SQLITE_NEED_ERR_NAME + "NEED_ERR_NAME", +#endif +#ifdef SQLITE_NO_SYNC + "NO_SYNC", +#endif +#ifdef SQLITE_OMIT_ALTERTABLE + "OMIT_ALTERTABLE", +#endif +#ifdef SQLITE_OMIT_ANALYZE + "OMIT_ANALYZE", +#endif +#ifdef SQLITE_OMIT_ATTACH + "OMIT_ATTACH", +#endif +#ifdef SQLITE_OMIT_AUTHORIZATION + "OMIT_AUTHORIZATION", +#endif +#ifdef SQLITE_OMIT_AUTOINCREMENT + "OMIT_AUTOINCREMENT", +#endif +#ifdef SQLITE_OMIT_AUTOINIT + "OMIT_AUTOINIT", +#endif +#ifdef SQLITE_OMIT_AUTOMATIC_INDEX + "OMIT_AUTOMATIC_INDEX", +#endif +#ifdef SQLITE_OMIT_AUTORESET + "OMIT_AUTORESET", +#endif +#ifdef SQLITE_OMIT_AUTOVACUUM + "OMIT_AUTOVACUUM", +#endif +#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION + "OMIT_BETWEEN_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_BLOB_LITERAL + "OMIT_BLOB_LITERAL", +#endif +#ifdef SQLITE_OMIT_CAST + "OMIT_CAST", +#endif +#ifdef SQLITE_OMIT_CHECK + "OMIT_CHECK", +#endif +#ifdef SQLITE_OMIT_COMPLETE + "OMIT_COMPLETE", +#endif +#ifdef SQLITE_OMIT_COMPOUND_SELECT + "OMIT_COMPOUND_SELECT", +#endif +#ifdef SQLITE_OMIT_CONFLICT_CLAUSE + "OMIT_CONFLICT_CLAUSE", +#endif +#ifdef SQLITE_OMIT_CTE + "OMIT_CTE", +#endif +#if defined(SQLITE_OMIT_DATETIME_FUNCS) || defined(SQLITE_OMIT_FLOATING_POINT) + "OMIT_DATETIME_FUNCS", +#endif +#ifdef SQLITE_OMIT_DECLTYPE + "OMIT_DECLTYPE", +#endif +#ifdef SQLITE_OMIT_DEPRECATED + "OMIT_DEPRECATED", +#endif +#ifdef SQLITE_OMIT_DESERIALIZE + "OMIT_DESERIALIZE", +#endif +#ifdef SQLITE_OMIT_DISKIO + "OMIT_DISKIO", +#endif +#ifdef SQLITE_OMIT_EXPLAIN + "OMIT_EXPLAIN", +#endif +#ifdef SQLITE_OMIT_FLAG_PRAGMAS + "OMIT_FLAG_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_FLOATING_POINT + "OMIT_FLOATING_POINT", +#endif +#ifdef SQLITE_OMIT_FOREIGN_KEY + "OMIT_FOREIGN_KEY", +#endif +#ifdef SQLITE_OMIT_GET_TABLE + "OMIT_GET_TABLE", +#endif +#ifdef SQLITE_OMIT_HEX_INTEGER + "OMIT_HEX_INTEGER", +#endif +#ifdef SQLITE_OMIT_INCRBLOB + "OMIT_INCRBLOB", +#endif +#ifdef SQLITE_OMIT_INTEGRITY_CHECK + "OMIT_INTEGRITY_CHECK", +#endif +#ifdef SQLITE_OMIT_INTROSPECTION_PRAGMAS + "OMIT_INTROSPECTION_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_JSON + "OMIT_JSON", +#endif +#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION + "OMIT_LIKE_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_LOAD_EXTENSION + "OMIT_LOAD_EXTENSION", +#endif +#ifdef SQLITE_OMIT_LOCALTIME + "OMIT_LOCALTIME", +#endif +#ifdef SQLITE_OMIT_LOOKASIDE + "OMIT_LOOKASIDE", +#endif +#ifdef SQLITE_OMIT_MEMORYDB + "OMIT_MEMORYDB", +#endif +#ifdef SQLITE_OMIT_OR_OPTIMIZATION + "OMIT_OR_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_PAGER_PRAGMAS + "OMIT_PAGER_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_PARSER_TRACE + "OMIT_PARSER_TRACE", +#endif +#ifdef SQLITE_OMIT_POPEN + "OMIT_POPEN", +#endif +#ifdef SQLITE_OMIT_PRAGMA + "OMIT_PRAGMA", +#endif +#ifdef SQLITE_OMIT_PROGRESS_CALLBACK + "OMIT_PROGRESS_CALLBACK", +#endif +#ifdef SQLITE_OMIT_QUICKBALANCE + "OMIT_QUICKBALANCE", +#endif +#ifdef SQLITE_OMIT_REINDEX + "OMIT_REINDEX", +#endif +#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS + "OMIT_SCHEMA_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS + "OMIT_SCHEMA_VERSION_PRAGMAS", +#endif +#ifdef SQLITE_OMIT_SHARED_CACHE + "OMIT_SHARED_CACHE", +#endif +#ifdef SQLITE_OMIT_SHUTDOWN_DIRECTORIES + "OMIT_SHUTDOWN_DIRECTORIES", +#endif +#ifdef SQLITE_OMIT_SUBQUERY + "OMIT_SUBQUERY", +#endif +#ifdef SQLITE_OMIT_TCL_VARIABLE + "OMIT_TCL_VARIABLE", +#endif +#ifdef SQLITE_OMIT_TEMPDB + "OMIT_TEMPDB", +#endif +#ifdef SQLITE_OMIT_TEST_CONTROL + "OMIT_TEST_CONTROL", +#endif +#ifdef SQLITE_OMIT_TRACE +# if SQLITE_OMIT_TRACE != 1 + "OMIT_TRACE=" CTIMEOPT_VAL(SQLITE_OMIT_TRACE), +# endif +#endif +#ifdef SQLITE_OMIT_TRIGGER + "OMIT_TRIGGER", +#endif +#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION + "OMIT_TRUNCATE_OPTIMIZATION", +#endif +#ifdef SQLITE_OMIT_UTF16 + "OMIT_UTF16", +#endif +#ifdef SQLITE_OMIT_VACUUM + "OMIT_VACUUM", +#endif +#ifdef SQLITE_OMIT_VIEW + "OMIT_VIEW", +#endif +#ifdef SQLITE_OMIT_VIRTUALTABLE + "OMIT_VIRTUALTABLE", +#endif +#ifdef SQLITE_OMIT_WAL + "OMIT_WAL", +#endif +#ifdef SQLITE_OMIT_WSD + "OMIT_WSD", +#endif +#ifdef SQLITE_OMIT_XFER_OPT + "OMIT_XFER_OPT", +#endif +#ifdef SQLITE_PCACHE_SEPARATE_HEADER + "PCACHE_SEPARATE_HEADER", +#endif +#ifdef SQLITE_PERFORMANCE_TRACE + "PERFORMANCE_TRACE", +#endif +#ifdef SQLITE_POWERSAFE_OVERWRITE +# if SQLITE_POWERSAFE_OVERWRITE != 1 + "POWERSAFE_OVERWRITE=" CTIMEOPT_VAL(SQLITE_POWERSAFE_OVERWRITE), +# endif +#endif +#ifdef SQLITE_PREFER_PROXY_LOCKING + "PREFER_PROXY_LOCKING", +#endif +#ifdef SQLITE_PROXY_DEBUG + "PROXY_DEBUG", +#endif +#ifdef SQLITE_REVERSE_UNORDERED_SELECTS + "REVERSE_UNORDERED_SELECTS", +#endif +#ifdef SQLITE_RTREE_INT_ONLY + "RTREE_INT_ONLY", +#endif +#ifdef SQLITE_SECURE_DELETE + "SECURE_DELETE", +#endif +#ifdef SQLITE_SMALL_STACK + "SMALL_STACK", +#endif +#ifdef SQLITE_SORTER_PMASZ + "SORTER_PMASZ=" CTIMEOPT_VAL(SQLITE_SORTER_PMASZ), +#endif +#ifdef SQLITE_SOUNDEX + "SOUNDEX", +#endif +#ifdef SQLITE_STAT4_SAMPLES + "STAT4_SAMPLES=" CTIMEOPT_VAL(SQLITE_STAT4_SAMPLES), +#endif +#ifdef SQLITE_STMTJRNL_SPILL + "STMTJRNL_SPILL=" CTIMEOPT_VAL(SQLITE_STMTJRNL_SPILL), +#endif +#ifdef SQLITE_SUBSTR_COMPATIBILITY + "SUBSTR_COMPATIBILITY", +#endif +#if (!defined(SQLITE_WIN32_MALLOC) \ + && !defined(SQLITE_ZERO_MALLOC) \ + && !defined(SQLITE_MEMDEBUG) \ + ) || defined(SQLITE_SYSTEM_MALLOC) + "SYSTEM_MALLOC", +#endif +#ifdef SQLITE_TCL + "TCL", +#endif +#ifdef SQLITE_TEMP_STORE + "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE), +#endif +#ifdef SQLITE_TEST + "TEST", +#endif +#if defined(SQLITE_THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE), +#elif defined(THREADSAFE) + "THREADSAFE=" CTIMEOPT_VAL(THREADSAFE), +#else + "THREADSAFE=1", +#endif +#ifdef SQLITE_UNLINK_AFTER_CLOSE + "UNLINK_AFTER_CLOSE", +#endif +#ifdef SQLITE_UNTESTABLE + "UNTESTABLE", +#endif +#ifdef SQLITE_USER_AUTHENTICATION + "USER_AUTHENTICATION", +#endif +#ifdef SQLITE_USE_ALLOCA + "USE_ALLOCA", +#endif +#ifdef SQLITE_USE_FCNTL_TRACE + "USE_FCNTL_TRACE", +#endif +#ifdef SQLITE_USE_URI + "USE_URI", +#endif +#ifdef SQLITE_VDBE_COVERAGE + "VDBE_COVERAGE", +#endif +#ifdef SQLITE_WIN32_MALLOC + "WIN32_MALLOC", +#endif +#ifdef SQLITE_ZERO_MALLOC + "ZERO_MALLOC", +#endif + +} ; + +SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ + *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]); + return (const char**)sqlite3azCompileOpt; +} + +#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ + +/************** End of ctime.c ***********************************************/ /************** Begin file global.c ******************************************/ /* ** 2008 June 13 @@ -21080,6 +21890,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* xTestCallback */ #endif 0, /* bLocaltimeFault */ + 0, /* xAltLocaltime */ 0x7ffffffe, /* iOnceResetThreshold */ SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */ 0, /* iPrngSeed */ @@ -21092,6 +21903,18 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { */ SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +/* +** Counter used for coverage testing. Does not come into play for +** release builds. +** +** Access to this global variable is not mutex protected. This might +** result in TSAN warnings. But as the variable does not exist in +** release builds, that should not be a concern. +*/ +SQLITE_PRIVATE unsigned int sqlite3CoverageCounter; +#endif /* SQLITE_COVERAGE_TEST || SQLITE_DEBUG */ + #ifdef VDBE_PROFILE /* ** The following performance counter can be used in place of @@ -21142,6 +21965,48 @@ SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; */ SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY"; +/* +** Standard typenames. These names must match the COLTYPE_* definitions. +** Adjust the SQLITE_N_STDTYPE value if adding or removing entries. +** +** sqlite3StdType[] The actual names of the datatypes. +** +** sqlite3StdTypeLen[] The length (in bytes) of each entry +** in sqlite3StdType[]. +** +** sqlite3StdTypeAffinity[] The affinity associated with each entry +** in sqlite3StdType[]. +** +** sqlite3StdTypeMap[] The type value (as returned from +** sqlite3_column_type() or sqlite3_value_type()) +** for each entry in sqlite3StdType[]. +*/ +SQLITE_PRIVATE const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 }; +SQLITE_PRIVATE const char sqlite3StdTypeAffinity[] = { + SQLITE_AFF_NUMERIC, + SQLITE_AFF_BLOB, + SQLITE_AFF_INTEGER, + SQLITE_AFF_INTEGER, + SQLITE_AFF_REAL, + SQLITE_AFF_TEXT +}; +SQLITE_PRIVATE const char sqlite3StdTypeMap[] = { + 0, + SQLITE_BLOB, + SQLITE_INTEGER, + SQLITE_INTEGER, + SQLITE_FLOAT, + SQLITE_TEXT +}; +SQLITE_PRIVATE const char *sqlite3StdType[] = { + "ANY", + "BLOB", + "INT", + "INTEGER", + "REAL", + "TEXT" +}; + /************** End of global.c **********************************************/ /************** Begin file status.c ******************************************/ /* @@ -21239,7 +22104,7 @@ typedef struct AuxData AuxData; typedef struct VdbeCursor VdbeCursor; struct VdbeCursor { u8 eCurType; /* One of the CURTYPE_* values above */ - i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ + i8 iDb; /* Index of cursor database in db->aDb[] */ u8 nullRow; /* True if pointing to a row with no data */ u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ u8 isTable; /* True for rowid tables. False for indexes */ @@ -21252,9 +22117,11 @@ struct VdbeCursor { Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ - Btree *pBtx; /* Separate file holding temporary table */ + union { /* pBtx for isEphermeral. pAltMap otherwise */ + Btree *pBtx; /* Separate file holding temporary table */ + u32 *aAltMap; /* Mapping from table to index column numbers */ + } ub; i64 seqCount; /* Sequence counter */ - u32 *aAltMap; /* Mapping from table to index column numbers */ /* Cached OP_Column parse information is only valid if cacheStatus matches ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of @@ -21344,8 +22211,8 @@ struct VdbeFrame { int nMem; /* Number of entries in aMem */ int nChildMem; /* Number of memory cells for child frame */ int nChildCsr; /* Number of cursors for child frame */ - int nChange; /* Statement changes (Vdbe.nChange) */ - int nDbChange; /* Value of db->nChange */ + i64 nChange; /* Statement changes (Vdbe.nChange) */ + i64 nDbChange; /* Value of db->nChange */ }; /* Magic number for sanity checking on VdbeFrame objects */ @@ -21552,7 +22419,7 @@ struct Vdbe { u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ - int nChange; /* Number of db changes made since last reset */ + i64 nChange; /* Number of db changes made since last reset */ int iStatement; /* Statement number (or 0 if has no opened stmt) */ i64 iCurrentTime; /* Value of julianday('now') for this statement */ i64 nFkConstraint; /* Number of imm. FK constraints this VM */ @@ -21594,7 +22461,7 @@ struct Vdbe { bft bIsReader:1; /* True for statements that read */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ - u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */ + u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_ENABLE_NORMALIZE char *zNormSql; /* Normalization of the associated SQL statement */ @@ -21644,6 +22511,24 @@ struct PreUpdate { Index *pPk; /* PK index if pTab is WITHOUT ROWID */ }; +/* +** An instance of this object is used to pass an vector of values into +** OP_VFilter, the xFilter method of a virtual table. The vector is the +** set of values on the right-hand side of an IN constraint. +** +** The value as passed into xFilter is an sqlite3_value with a "pointer" +** type, such as is generated by sqlite3_result_pointer() and read by +** sqlite3_value_pointer. Such values have MEM_Term|MEM_Subtype|MEM_Null +** and a subtype of 'p'. The sqlite3_vtab_in_first() and _next() interfaces +** know how to use this object to step through all the values in the +** right operand of the IN constraint. +*/ +typedef struct ValueList ValueList; +struct ValueList { + BtCursor *pCsr; /* An ephemeral table holding all values */ + sqlite3_value *pOut; /* Register to hold each decoded output value */ +}; + /* ** Function prototypes */ @@ -21656,7 +22541,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); +SQLITE_PRIVATE void sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); @@ -21690,14 +22575,19 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); +#ifndef SQLITE_OMIT_INCRBLOB SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); +#else +SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int); +#endif #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); #endif SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); +SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double); +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*); SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); @@ -22675,8 +23565,10 @@ static void clearYMD_HMS_TZ(DateTime *p){ ** is available. This routine returns 0 on success and ** non-zero on any kind of error. ** -** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this -** routine will always fail. +** If the sqlite3GlobalConfig.bLocaltimeFault variable is non-zero then this +** routine will always fail. If bLocaltimeFault is nonzero and +** sqlite3GlobalConfig.xAltLocaltime is not NULL, then xAltLocaltime() is +** invoked in place of the OS-defined localtime() function. ** ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C ** library function localtime_r() is used to assist in the calculation of @@ -22692,14 +23584,30 @@ static int osLocaltime(time_t *t, struct tm *pTm){ sqlite3_mutex_enter(mutex); pX = localtime(t); #ifndef SQLITE_UNTESTABLE - if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 + && 0==sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm) + ){ + pX = pTm; + }else{ + pX = 0; + } + } #endif if( pX ) *pTm = *pX; +#if SQLITE_THREADSAFE>0 sqlite3_mutex_leave(mutex); +#endif rc = pX==0; #else #ifndef SQLITE_UNTESTABLE - if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; + if( sqlite3GlobalConfig.bLocaltimeFault ){ + if( sqlite3GlobalConfig.xAltLocaltime!=0 ){ + return sqlite3GlobalConfig.xAltLocaltime((const void*)t,(void*)pTm); + }else{ + return 1; + } + } #endif #if HAVE_LOCALTIME_R rc = localtime_r(t, pTm)==0; @@ -22714,67 +23622,56 @@ static int osLocaltime(time_t *t, struct tm *pTm){ #ifndef SQLITE_OMIT_LOCALTIME /* -** Compute the difference (in milliseconds) between localtime and UTC -** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs, -** return this value and set *pRc to SQLITE_OK. -** -** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value -** is undefined in this case. +** Assuming the input DateTime is UTC, move it to its localtime equivalent. */ -static sqlite3_int64 localtimeOffset( - DateTime *p, /* Date at which to calculate offset */ - sqlite3_context *pCtx, /* Write error here if one occurs */ - int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ +static int toLocaltime( + DateTime *p, /* Date at which to calculate offset */ + sqlite3_context *pCtx /* Write error here if one occurs */ ){ - DateTime x, y; time_t t; struct tm sLocal; + int iYearDiff; /* Initialize the contents of sLocal to avoid a compiler warning. */ memset(&sLocal, 0, sizeof(sLocal)); - x = *p; - computeYMD_HMS(&x); - if( x.Y<1971 || x.Y>=2038 ){ + computeJD(p); + if( p->iJD<2108667600*(i64)100000 /* 1970-01-01 */ + || p->iJD>2130141456*(i64)100000 /* 2038-01-18 */ + ){ /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only ** works for years between 1970 and 2037. For dates outside this range, ** SQLite attempts to map the year into an equivalent year within this ** range, do the calculation, then map the year back. */ - x.Y = 2000; - x.M = 1; - x.D = 1; - x.h = 0; - x.m = 0; - x.s = 0.0; - } else { - int s = (int)(x.s + 0.5); - x.s = s; + DateTime x = *p; + computeYMD_HMS(&x); + iYearDiff = (2000 + x.Y%4) - x.Y; + x.Y += iYearDiff; + x.validJD = 0; + computeJD(&x); + t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); + }else{ + iYearDiff = 0; + t = (time_t)(p->iJD/1000 - 21086676*(i64)10000); } - x.tz = 0; - x.validJD = 0; - computeJD(&x); - t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); if( osLocaltime(&t, &sLocal) ){ sqlite3_result_error(pCtx, "local time unavailable", -1); - *pRc = SQLITE_ERROR; - return 0; + return SQLITE_ERROR; } - y.Y = sLocal.tm_year + 1900; - y.M = sLocal.tm_mon + 1; - y.D = sLocal.tm_mday; - y.h = sLocal.tm_hour; - y.m = sLocal.tm_min; - y.s = sLocal.tm_sec; - y.validYMD = 1; - y.validHMS = 1; - y.validJD = 0; - y.rawS = 0; - y.validTZ = 0; - y.isError = 0; - computeJD(&y); - *pRc = SQLITE_OK; - return y.iJD - x.iJD; + p->Y = sLocal.tm_year + 1900 - iYearDiff; + p->M = sLocal.tm_mon + 1; + p->D = sLocal.tm_mday; + p->h = sLocal.tm_hour; + p->m = sLocal.tm_min; + p->s = sLocal.tm_sec + (p->iJD%1000)*0.001; + p->validYMD = 1; + p->validHMS = 1; + p->validJD = 0; + p->rawS = 0; + p->validTZ = 0; + p->isError = 0; + return SQLITE_OK; } #endif /* SQLITE_OMIT_LOCALTIME */ @@ -22787,18 +23684,17 @@ static sqlite3_int64 localtimeOffset( ** of several units of time. */ static const struct { - u8 eType; /* Transformation type code */ - u8 nName; /* Length of th name */ - char *zName; /* Name of the transformation */ - double rLimit; /* Maximum NNN value for this transform */ - double rXform; /* Constant used for this transform */ + u8 nName; /* Length of the name */ + char zName[7]; /* Name of the transformation */ + float rLimit; /* Maximum NNN value for this transform */ + float rXform; /* Constant used for this transform */ } aXformType[] = { - { 0, 6, "second", 464269060800.0, 1000.0 }, - { 0, 6, "minute", 7737817680.0, 60000.0 }, - { 0, 4, "hour", 128963628.0, 3600000.0 }, - { 0, 3, "day", 5373485.0, 86400000.0 }, - { 1, 5, "month", 176546.0, 2592000000.0 }, - { 2, 4, "year", 14713.0, 31536000000.0 }, + { 6, "second", 4.6427e+14, 1.0 }, + { 6, "minute", 7.7379e+12, 60.0 }, + { 4, "hour", 1.2897e+11, 3600.0 }, + { 3, "day", 5373485.0, 86400.0 }, + { 5, "month", 176546.0, 2592000.0 }, + { 4, "year", 14713.0, 31536000.0 }, }; /* @@ -22829,11 +23725,55 @@ static int parseModifier( sqlite3_context *pCtx, /* Function context */ const char *z, /* The text of the modifier */ int n, /* Length of zMod in bytes */ - DateTime *p /* The date/time value to be modified */ + DateTime *p, /* The date/time value to be modified */ + int idx /* Parameter index of the modifier */ ){ int rc = 1; double r; switch(sqlite3UpperToLower[(u8)z[0]] ){ + case 'a': { + /* + ** auto + ** + ** If rawS is available, then interpret as a julian day number, or + ** a unix timestamp, depending on its magnitude. + */ + if( sqlite3_stricmp(z, "auto")==0 ){ + if( idx>1 ) return 1; /* IMP: R-33611-57934 */ + if( !p->rawS || p->validJD ){ + rc = 0; + p->rawS = 0; + }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ + && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ + ){ + r = p->s*1000.0 + 210866760000000.0; + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + rc = 0; + } + } + break; + } + case 'j': { + /* + ** julianday + ** + ** Always interpret the prior number as a julian-day value. If this + ** is not the first modifier, or if the prior argument is not a numeric + ** value in the allowed range of julian day numbers understood by + ** SQLite (0..5373484.5) then the result will be NULL. + */ + if( sqlite3_stricmp(z, "julianday")==0 ){ + if( idx>1 ) return 1; /* IMP: R-31176-64601 */ + if( p->validJD && p->rawS ){ + rc = 0; + p->rawS = 0; + } + } + break; + } #ifndef SQLITE_OMIT_LOCALTIME case 'l': { /* localtime @@ -22842,9 +23782,7 @@ static int parseModifier( ** show local time. */ if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ - computeJD(p); - p->iJD += localtimeOffset(p, pCtx, &rc); - clearYMD_HMS_TZ(p); + rc = toLocaltime(p, pCtx); } break; } @@ -22857,6 +23795,7 @@ static int parseModifier( ** seconds since 1970. Convert to a real julian day number. */ if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ + if( idx>1 ) return 1; /* IMP: R-49255-55373 */ r = p->s*1000.0 + 210866760000000.0; if( r>=0.0 && r<464269060800000.0 ){ clearYMD_HMS_TZ(p); @@ -22869,18 +23808,31 @@ static int parseModifier( #ifndef SQLITE_OMIT_LOCALTIME else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ if( p->tzSet==0 ){ - sqlite3_int64 c1; + i64 iOrigJD; /* Original localtime */ + i64 iGuess; /* Guess at the corresponding utc time */ + int cnt = 0; /* Safety to prevent infinite loop */ + int iErr; /* Guess is off by this much */ + computeJD(p); - c1 = localtimeOffset(p, pCtx, &rc); - if( rc==SQLITE_OK ){ - p->iJD -= c1; - clearYMD_HMS_TZ(p); - p->iJD += c1 - localtimeOffset(p, pCtx, &rc); - } + iGuess = iOrigJD = p->iJD; + iErr = 0; + do{ + DateTime new; + memset(&new, 0, sizeof(new)); + iGuess -= iErr; + new.iJD = iGuess; + new.validJD = 1; + rc = toLocaltime(&new, pCtx); + if( rc ) return rc; + computeJD(&new); + iErr = new.iJD - iOrigJD; + }while( iErr && cnt++<3 ); + memset(p, 0, sizeof(*p)); + p->iJD = iGuess; + p->validJD = 1; p->tzSet = 1; - }else{ - rc = SQLITE_OK; } + rc = SQLITE_OK; } #endif break; @@ -22996,9 +23948,10 @@ static int parseModifier( && sqlite3_strnicmp(aXformType[i].zName, z, n)==0 && r>-aXformType[i].rLimit && rM += (int)r; x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; @@ -23008,8 +23961,9 @@ static int parseModifier( r -= (int)r; break; } - case 2: { /* Special processing to add years */ + case 5: { /* Special processing to add years */ int y = (int)r; + assert( strcmp(aXformType[i].zName,"year")==0 ); computeYMD_HMS(p); p->Y += y; p->validJD = 0; @@ -23018,7 +23972,7 @@ static int parseModifier( } } computeJD(p); - p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder); + p->iJD += (sqlite3_int64)(r*1000.0*aXformType[i].rXform + rRounder); rc = 0; break; } @@ -23068,7 +24022,7 @@ static int isDate( for(i=1; iisError || !validJulianDay(p->iJD) ) return 1; @@ -23098,6 +24052,24 @@ static void juliandayFunc( } } +/* +** unixepoch( TIMESTRING, MOD, MOD, ...) +** +** Return the number of seconds (including fractional seconds) since +** the unix epoch of 1970-01-01 00:00:00 GMT. +*/ +static void unixepochFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + DateTime x; + if( isDate(context, argc, argv, &x)==0 ){ + computeJD(&x); + sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000); + } +} + /* ** datetime( TIMESTRING, MOD, MOD, ...) ** @@ -23110,11 +24082,38 @@ static void datetimeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - char zBuf[100]; + int Y, s; + char zBuf[24]; computeYMD_HMS(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d", - x.Y, x.M, x.D, x.h, x.m, (int)(x.s)); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + Y = x.Y; + if( Y<0 ) Y = -Y; + zBuf[1] = '0' + (Y/1000)%10; + zBuf[2] = '0' + (Y/100)%10; + zBuf[3] = '0' + (Y/10)%10; + zBuf[4] = '0' + (Y)%10; + zBuf[5] = '-'; + zBuf[6] = '0' + (x.M/10)%10; + zBuf[7] = '0' + (x.M)%10; + zBuf[8] = '-'; + zBuf[9] = '0' + (x.D/10)%10; + zBuf[10] = '0' + (x.D)%10; + zBuf[11] = ' '; + zBuf[12] = '0' + (x.h/10)%10; + zBuf[13] = '0' + (x.h)%10; + zBuf[14] = ':'; + zBuf[15] = '0' + (x.m/10)%10; + zBuf[16] = '0' + (x.m)%10; + zBuf[17] = ':'; + s = (int)x.s; + zBuf[18] = '0' + (s/10)%10; + zBuf[19] = '0' + (s)%10; + zBuf[20] = 0; + if( x.Y<0 ){ + zBuf[0] = '-'; + sqlite3_result_text(context, zBuf, 20, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(context, &zBuf[1], 19, SQLITE_TRANSIENT); + } } } @@ -23130,10 +24129,20 @@ static void timeFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - char zBuf[100]; + int s; + char zBuf[16]; computeHMS(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + zBuf[0] = '0' + (x.h/10)%10; + zBuf[1] = '0' + (x.h)%10; + zBuf[2] = ':'; + zBuf[3] = '0' + (x.m/10)%10; + zBuf[4] = '0' + (x.m)%10; + zBuf[5] = ':'; + s = (int)x.s; + zBuf[6] = '0' + (s/10)%10; + zBuf[7] = '0' + (s)%10; + zBuf[8] = 0; + sqlite3_result_text(context, zBuf, 8, SQLITE_TRANSIENT); } } @@ -23149,10 +24158,28 @@ static void dateFunc( ){ DateTime x; if( isDate(context, argc, argv, &x)==0 ){ - char zBuf[100]; + int Y; + char zBuf[16]; computeYMD(&x); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D); - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + Y = x.Y; + if( Y<0 ) Y = -Y; + zBuf[1] = '0' + (Y/1000)%10; + zBuf[2] = '0' + (Y/100)%10; + zBuf[3] = '0' + (Y/10)%10; + zBuf[4] = '0' + (Y)%10; + zBuf[5] = '-'; + zBuf[6] = '0' + (x.M/10)%10; + zBuf[7] = '0' + (x.M)%10; + zBuf[8] = '-'; + zBuf[9] = '0' + (x.D/10)%10; + zBuf[10] = '0' + (x.D)%10; + zBuf[11] = 0; + if( x.Y<0 ){ + zBuf[0] = '-'; + sqlite3_result_text(context, zBuf, 11, SQLITE_TRANSIENT); + }else{ + sqlite3_result_text(context, &zBuf[1], 10, SQLITE_TRANSIENT); + } } } @@ -23181,131 +24208,100 @@ static void strftimeFunc( sqlite3_value **argv ){ DateTime x; - u64 n; size_t i,j; - char *z; sqlite3 *db; const char *zFmt; - char zBuf[100]; + sqlite3_str sRes; + + if( argc==0 ) return; zFmt = (const char*)sqlite3_value_text(argv[0]); if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return; db = sqlite3_context_db_handle(context); - for(i=0, n=1; zFmt[i]; i++, n++){ - if( zFmt[i]=='%' ){ - switch( zFmt[i+1] ){ - case 'd': - case 'H': - case 'm': - case 'M': - case 'S': - case 'W': - n++; - /* fall thru */ - case 'w': - case '%': - break; - case 'f': - n += 8; - break; - case 'j': - n += 3; - break; - case 'Y': - n += 8; - break; - case 's': - case 'J': - n += 50; - break; - default: - return; /* ERROR. return a NULL */ - } - i++; - } - } - testcase( n==sizeof(zBuf)-1 ); - testcase( n==sizeof(zBuf) ); - testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); - testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ); - if( n(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - sqlite3_result_error_toobig(context); - return; - }else{ - z = sqlite3DbMallocRawNN(db, (int)n); - if( z==0 ){ - sqlite3_result_error_nomem(context); - return; - } - } + sqlite3StrAccumInit(&sRes, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ - if( zFmt[i]!='%' ){ - z[j++] = zFmt[i]; - }else{ - i++; - switch( zFmt[i] ){ - case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; - case 'f': { - double s = x.s; - if( s>59.999 ) s = 59.999; - sqlite3_snprintf(7, &z[j],"%06.3f", s); - j += sqlite3Strlen30(&z[j]); - break; + if( zFmt[i]!='%' ) continue; + if( j59.999 ) s = 59.999; + sqlite3_str_appendf(&sRes, "%06.3f", s); + break; + } + case 'H': { + sqlite3_str_appendf(&sRes, "%02d", x.h); + break; + } + case 'W': /* Fall thru */ + case 'j': { + int nDay; /* Number of days since 1st day of year */ + DateTime y = x; + y.validJD = 0; + y.M = 1; + y.D = 1; + computeJD(&y); + nDay = (int)((x.iJD-y.iJD+43200000)/86400000); + if( zFmt[i]=='W' ){ + int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ + wd = (int)(((x.iJD+43200000)/86400000)%7); + sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); + }else{ + sqlite3_str_appendf(&sRes,"%03d",nDay+1); } - case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; - case 'W': /* Fall thru */ - case 'j': { - int nDay; /* Number of days since 1st day of year */ - DateTime y = x; - y.validJD = 0; - y.M = 1; - y.D = 1; - computeJD(&y); - nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( zFmt[i]=='W' ){ - int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ - wd = (int)(((x.iJD+43200000)/86400000)%7); - sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); - j += 2; - }else{ - sqlite3_snprintf(4, &z[j],"%03d",nDay+1); - j += 3; - } - break; - } - case 'J': { - sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); - j+=sqlite3Strlen30(&z[j]); - break; - } - case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; - case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; - case 's': { - i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); - sqlite3Int64ToText(iS, &z[j]); - j += sqlite3Strlen30(&z[j]); - break; - } - case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; - case 'w': { - z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; - break; - } - case 'Y': { - sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]); - break; - } - default: z[j++] = '%'; break; + break; + } + case 'J': { + sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0); + break; + } + case 'm': { + sqlite3_str_appendf(&sRes,"%02d",x.M); + break; + } + case 'M': { + sqlite3_str_appendf(&sRes,"%02d",x.m); + break; + } + case 's': { + i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000); + sqlite3_str_appendf(&sRes,"%lld",iS); + break; + } + case 'S': { + sqlite3_str_appendf(&sRes,"%02d",(int)x.s); + break; + } + case 'w': { + sqlite3_str_appendchar(&sRes, 1, + (char)(((x.iJD+129600000)/86400000) % 7) + '0'); + break; + } + case 'Y': { + sqlite3_str_appendf(&sRes,"%04d",x.Y); + break; + } + case '%': { + sqlite3_str_appendchar(&sRes, 1, '%'); + break; + } + default: { + sqlite3_str_reset(&sRes); + return; } } } - z[j] = 0; - sqlite3_result_text(context, z, -1, - z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); + if( jpMethods==0) ) return 0; return id->pMethods->xDeviceCharacteristics(id); } #ifndef SQLITE_OMIT_WAL @@ -23740,12 +24738,15 @@ SQLITE_PRIVATE int sqlite3OsOpenMalloc( rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ sqlite3_free(pFile); + *ppFile = 0; }else{ *ppFile = pFile; } }else{ + *ppFile = 0; rc = SQLITE_NOMEM_BKPT; } + assert( *ppFile!=0 || rc!=SQLITE_OK ); return rc; } SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){ @@ -24463,7 +25464,7 @@ static void adjustStats(int iSize, int increment){ ** This routine checks the guards at either end of the allocation and ** if they are incorrect it asserts. */ -static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ +static struct MemBlockHdr *sqlite3MemsysGetHeader(const void *pAllocation){ struct MemBlockHdr *p; int *pInt; u8 *pU8; @@ -24710,7 +25711,7 @@ SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){ ** ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); */ -SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ +SQLITE_PRIVATE int sqlite3MemdebugHasType(const void *p, u8 eType){ int rc = 1; if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){ struct MemBlockHdr *pHdr; @@ -24732,7 +25733,7 @@ SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ ** ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); */ -SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ +SQLITE_PRIVATE int sqlite3MemdebugNoType(const void *p, u8 eType){ int rc = 1; if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){ struct MemBlockHdr *pHdr; @@ -27110,205 +28111,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ /* ** Include code that is common to all os_*.c files */ -/************** Include os_common.h in the middle of mutex_w32.c *************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_io_error_hit; -SQLITE_API extern int sqlite3_io_error_hardhit; -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_persist; -SQLITE_API extern int sqlite3_io_error_benign; -SQLITE_API extern int sqlite3_diskfull_pending; -SQLITE_API extern int sqlite3_diskfull; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_open_file_count; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif /* defined(SQLITE_TEST) */ - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in mutex_w32.c ******************/ +/* #include "os_common.h" */ /* ** Include the header file for the Windows VFS. @@ -28101,7 +28904,7 @@ SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ ** TRUE if p is a lookaside memory allocation from db */ #ifndef SQLITE_OMIT_LOOKASIDE -static int isLookaside(sqlite3 *db, void *p){ +static int isLookaside(sqlite3 *db, const void *p){ return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); } #else @@ -28112,18 +28915,18 @@ static int isLookaside(sqlite3 *db, void *p){ ** Return the size of a memory allocation previously obtained from ** sqlite3Malloc() or sqlite3_malloc(). */ -SQLITE_PRIVATE int sqlite3MallocSize(void *p){ +SQLITE_PRIVATE int sqlite3MallocSize(const void *p){ assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - return sqlite3GlobalConfig.m.xSize(p); + return sqlite3GlobalConfig.m.xSize((void*)p); } -static int lookasideMallocSize(sqlite3 *db, void *p){ +static int lookasideMallocSize(sqlite3 *db, const void *p){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE return plookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL; #else return db->lookaside.szTrue; #endif } -SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, const void *p){ assert( p!=0 ); #ifdef SQLITE_DEBUG if( db==0 || !isLookaside(db,p) ){ @@ -28150,7 +28953,7 @@ SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ } } } - return sqlite3GlobalConfig.m.xSize(p); + return sqlite3GlobalConfig.m.xSize((void*)p); } SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); @@ -28535,8 +29338,9 @@ SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const cha ** Free any prior content in *pz and replace it with a copy of zNew. */ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ + char *z = sqlite3DbStrDup(db, zNew); sqlite3DbFree(db, *pz); - *pz = sqlite3DbStrDup(db, zNew); + *pz = z; } /* @@ -28544,8 +29348,15 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ ** has happened. This routine will set db->mallocFailed, and also ** temporarily disable the lookaside memory allocator and interrupt ** any running VDBEs. +** +** Always return a NULL pointer so that this routine can be invoked using +** +** return sqlite3OomFault(db); +** +** and thereby avoid unnecessary stack frame allocations for the overwhelmingly +** common case where no OOM occurs. */ -SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ +SQLITE_PRIVATE void *sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ @@ -28553,9 +29364,11 @@ SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ } DisableLookaside; if( db->pParse ){ + sqlite3ErrorMsg(db->pParse, "out of memory"); db->pParse->rc = SQLITE_NOMEM_BKPT; } } + return 0; } /* @@ -28760,7 +29573,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ /* ** Set the StrAccum object to an error mode. */ -static void setStrAccumError(StrAccum *p, u8 eError){ +SQLITE_PRIVATE void sqlite3StrAccumSetError(StrAccum *p, u8 eError){ assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); p->accError = eError; if( p->mxAlloc ) sqlite3_str_reset(p); @@ -28796,12 +29609,12 @@ static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ char *z; if( pAccum->accError ) return 0; if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){ - setStrAccumError(pAccum, SQLITE_TOOBIG); + sqlite3StrAccumSetError(pAccum, SQLITE_TOOBIG); return 0; } z = sqlite3DbMallocRaw(pAccum->db, n); if( z==0 ){ - setStrAccumError(pAccum, SQLITE_NOMEM); + sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM); } return z; } @@ -29464,12 +30277,22 @@ SQLITE_API void sqlite3_str_vappendf( goto adjust_width_for_utf8; } case etTOKEN: { - Token *pToken; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; - pToken = va_arg(ap, Token*); - assert( bArgList==0 ); - if( pToken && pToken->n ){ - sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + if( flag_alternateform ){ + /* %#T means an Expr pointer that uses Expr.u.zToken */ + Expr *pExpr = va_arg(ap,Expr*); + if( ALWAYS(pExpr) && ALWAYS(!ExprHasProperty(pExpr,EP_IntValue)) ){ + sqlite3_str_appendall(pAccum, (const char*)pExpr->u.zToken); + sqlite3RecordErrorOffsetOfExpr(pAccum->db, pExpr); + } + }else{ + /* %T means a Token pointer */ + Token *pToken = va_arg(ap, Token*); + assert( bArgList==0 ); + if( pToken && pToken->n ){ + sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + sqlite3RecordErrorByteOffset(pAccum->db, pToken->z); + } } length = width = 0; break; @@ -29524,6 +30347,42 @@ SQLITE_API void sqlite3_str_vappendf( }/* End for loop over the format string */ } /* End of function */ + +/* +** The z string points to the first character of a token that is +** associated with an error. If db does not already have an error +** byte offset recorded, try to compute the error byte offset for +** z and set the error byte offset in db. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorByteOffset(sqlite3 *db, const char *z){ + const Parse *pParse; + const char *zText; + const char *zEnd; + assert( z!=0 ); + if( NEVER(db==0) ) return; + if( db->errByteOffset!=(-2) ) return; + pParse = db->pParse; + if( NEVER(pParse==0) ) return; + zText =pParse->zTail; + if( NEVER(zText==0) ) return; + zEnd = &zText[strlen(zText)]; + if( SQLITE_WITHIN(z,zText,zEnd) ){ + db->errByteOffset = (int)(z-zText); + } +} + +/* +** If pExpr has a byte offset for the start of a token, record that as +** as the error offset. +*/ +SQLITE_PRIVATE void sqlite3RecordErrorOffsetOfExpr(sqlite3 *db, const Expr *pExpr){ + while( pExpr && (ExprHasProperty(pExpr,EP_FromJoin) || pExpr->w.iOfst<=0) ){ + pExpr = pExpr->pLeft; + } + if( pExpr==0 ) return; + db->errByteOffset = pExpr->w.iOfst; +} + /* ** Enlarge the memory allocation on a StrAccum object so that it is ** able to accept at least N more bytes of text. @@ -29531,7 +30390,7 @@ SQLITE_API void sqlite3_str_vappendf( ** Return the number of bytes of text that StrAccum is able to accept ** after the attempted enlargement. The value returned might be zero. */ -static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ +SQLITE_PRIVATE int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ @@ -29540,7 +30399,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ return 0; } if( p->mxAlloc==0 ){ - setStrAccumError(p, SQLITE_TOOBIG); + sqlite3StrAccumSetError(p, SQLITE_TOOBIG); return p->nAlloc - p->nChar - 1; }else{ char *zOld = isMalloced(p) ? p->zText : 0; @@ -29553,7 +30412,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ } if( szNew > p->mxAlloc ){ sqlite3_str_reset(p); - setStrAccumError(p, SQLITE_TOOBIG); + sqlite3StrAccumSetError(p, SQLITE_TOOBIG); return 0; }else{ p->nAlloc = (int)szNew; @@ -29571,7 +30430,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ sqlite3_str_reset(p); - setStrAccumError(p, SQLITE_NOMEM); + sqlite3StrAccumSetError(p, SQLITE_NOMEM); return 0; } } @@ -29644,7 +30503,7 @@ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ memcpy(zText, p->zText, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ - setStrAccumError(p, SQLITE_NOMEM); + sqlite3StrAccumSetError(p, SQLITE_NOMEM); } p->zText = zText; return zText; @@ -29659,6 +30518,22 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ return p->zText; } +/* +** Use the content of the StrAccum passed as the second argument +** as the result of an SQL function. +*/ +SQLITE_PRIVATE void sqlite3ResultStrAccum(sqlite3_context *pCtx, StrAccum *p){ + if( p->accError ){ + sqlite3_result_error_code(pCtx, p->accError); + sqlite3_str_reset(p); + }else if( isMalloced(p) ){ + sqlite3_result_text(pCtx, p->zText, p->nChar, SQLITE_DYNAMIC); + }else{ + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + sqlite3_str_reset(p); + } +} + /* ** This singleton is an sqlite3_str object that is returned if ** sqlite3_malloc() fails to provide space for a real one. This @@ -30079,6 +30954,8 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) } if( pItem->fg.jointype & JT_LEFT ){ sqlite3_str_appendf(&x, " LEFT-JOIN"); + }else if( pItem->fg.jointype & JT_CROSS ){ + sqlite3_str_appendf(&x, " CROSS-JOIN"); } if( pItem->fg.fromDDL ){ sqlite3_str_appendf(&x, " DDL"); @@ -30347,7 +31224,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3_str_appendf(&x, " fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable); + sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable); } if( ExprHasProperty(pExpr, EP_FromDDL) ){ sqlite3_str_appendf(&x, " DDL"); @@ -30377,6 +31254,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", pExpr->iColumn, zFlgs, zOp2); }else{ + assert( ExprUseYTab(pExpr) ); sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", pExpr->iTable, pExpr->iColumn, pExpr->y.pTab, zFlgs); @@ -30396,11 +31274,13 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m } #ifndef SQLITE_OMIT_FLOATING_POINT case TK_FLOAT: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); break; } #endif case TK_STRING: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); break; } @@ -30409,17 +31289,19 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m break; } case TK_TRUEFALSE: { - sqlite3TreeViewLine(pView, - sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE"); + sqlite3TreeViewLine(pView,"%s%s", + sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs); break; } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); break; } #endif case TK_VARIABLE: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", pExpr->u.zToken, pExpr->iColumn); break; @@ -30429,12 +31311,14 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m break; } case TK_ID: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); break; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; @@ -30484,6 +31368,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m } case TK_SPAN: { + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; @@ -30495,6 +31380,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE ** operators that appear in the original SQL always have the ** EP_Collate bit set and appear in treeview output as just "COLLATE" */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", pExpr->u.zToken, zFlgs); @@ -30510,6 +31396,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m pFarg = 0; pWin = 0; }else{ + assert( ExprUseXList(pExpr) ); pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; @@ -30517,6 +31404,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m pWin = 0; #endif } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->op==TK_AGG_FUNCTION ){ sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p", pExpr->op2, pExpr->u.zToken, zFlgs, @@ -30548,11 +31436,13 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { + assert( ExprUseXSelect(pExpr) ); sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags); sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; } case TK_SELECT: { + assert( ExprUseXSelect(pExpr) ); sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags); sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; @@ -30560,7 +31450,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case TK_IN: { sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); }else{ sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); @@ -30581,9 +31471,12 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m ** Z is stored in pExpr->pList->a[1].pExpr. */ case TK_BETWEEN: { - Expr *pX = pExpr->pLeft; - Expr *pY = pExpr->x.pList->a[0].pExpr; - Expr *pZ = pExpr->x.pList->a[1].pExpr; + const Expr *pX, *pY, *pZ; + pX = pExpr->pLeft; + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr==2 ); + pY = pExpr->x.pList->a[0].pExpr; + pZ = pExpr->x.pList->a[1].pExpr; sqlite3TreeViewLine(pView, "BETWEEN"); sqlite3TreeViewExpr(pView, pX, 1); sqlite3TreeViewExpr(pView, pY, 1); @@ -30605,6 +31498,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case TK_CASE: { sqlite3TreeViewLine(pView, "CASE"); sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + assert( ExprUseXList(pExpr) ); sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); break; } @@ -30617,6 +31511,7 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m case OE_Fail: zType = "fail"; break; case OE_Ignore: zType = "ignore"; break; } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); break; } @@ -30629,12 +31524,16 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m } case TK_VECTOR: { char *z = sqlite3_mprintf("VECTOR%s",zFlgs); + assert( ExprUseXList(pExpr) ); sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z); sqlite3_free(z); break; } case TK_SELECT_COLUMN: { - sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn); + sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s", + pExpr->iColumn, pExpr->iTable-1, + pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : ""); + assert( ExprUseXSelect(pExpr->pLeft) ); sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); break; } @@ -30651,6 +31550,15 @@ SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 m sqlite3TreeViewExpr(pView, &tmp, 0); break; } + case TK_ROW: { + if( pExpr->iColumn<=0 ){ + sqlite3TreeViewLine(pView, "First FROM table rowid"); + }else{ + sqlite3TreeViewLine(pView, "First FROM table column %d", + pExpr->iColumn-1); + } + break; + } default: { sqlite3TreeViewLine(pView, "op=%d", pExpr->op); break; @@ -31702,16 +32610,6 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ #include #endif -/* -** Routine needed to support the testcase() macro. -*/ -#ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE void sqlite3Coverage(int x){ - static unsigned dummy = 0; - dummy += (unsigned)x; -} -#endif - /* ** Calls to sqlite3FaultSim() are used to simulate a failure during testing, ** or to bypass normal error detection during testing in order to let @@ -31741,11 +32639,21 @@ SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ #ifndef SQLITE_OMIT_FLOATING_POINT /* ** Return true if the floating point value is Not a Number (NaN). +** +** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN. +** Otherwise, we have our own implementation that works on most systems. */ SQLITE_PRIVATE int sqlite3IsNaN(double x){ + int rc; /* The value return */ +#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN u64 y; memcpy(&y,&x,sizeof(y)); - return IsNaN(y); + rc = IsNaN(y); +#else + rc = isnan(x); +#endif /* HAVE_ISNAN */ + testcase( rc ); + return rc; } #endif /* SQLITE_OMIT_FLOATING_POINT */ @@ -31770,8 +32678,14 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ ** the column name if and only if the COLFLAG_HASTYPE flag is set. */ SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){ - if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt; - return pCol->zName + strlen(pCol->zName) + 1; + if( pCol->colFlags & COLFLAG_HASTYPE ){ + return pCol->zCnName + strlen(pCol->zCnName) + 1; + }else if( pCol->eCType ){ + assert( pCol->eCType<=SQLITE_N_STDTYPE ); + return (char*)sqlite3StdType[pCol->eCType-1]; + }else{ + return zDflt; + } } /* @@ -31792,7 +32706,11 @@ static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ assert( db!=0 ); db->errCode = err_code; - if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); + if( err_code || db->pErr ){ + sqlite3ErrorFinish(db, err_code); + }else{ + db->errByteOffset = -1; + } } /* @@ -31802,6 +32720,7 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ assert( db!=0 ); db->errCode = SQLITE_OK; + db->errByteOffset = -1; if( db->pErr ) sqlite3ValueSetNull(db->pErr); } @@ -31822,17 +32741,8 @@ SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ ** handle "db". The error code is set to "err_code". ** ** If it is not NULL, string zFormat specifies the format of the -** error string in the style of the printf functions: The following -** format characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList -** -** zFormat and any string tokens that follow it are assumed to be -** encoded in UTF-8. +** error string. zFormat and any string tokens that follow it are +** assumed to be encoded in UTF-8. ** ** To clear the most recent error for sqlite handle "db", sqlite3Error ** should be called with err_code set to SQLITE_OK and zFormat set @@ -31856,13 +32766,6 @@ SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *z /* ** Add an error message to pParse->zErrMsg and increment pParse->nErr. -** The following formatting characters are allowed: -** -** %s Insert a string -** %z A string that should be freed after use -** %d Insert an integer -** %T Insert a token -** %S Insert the first element of a SrcList ** ** This function should be used to report any error that occurs while ** compiling an SQL statement (i.e. within sqlite3_prepare()). The @@ -31875,11 +32778,19 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ char *zMsg; va_list ap; sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse ); + db->errByteOffset = -2; va_start(ap, zFormat); zMsg = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); + if( db->errByteOffset<-1 ) db->errByteOffset = -1; if( db->suppressErr ){ sqlite3DbFree(db, zMsg); + if( db->mallocFailed ){ + pParse->nErr++; + pParse->rc = SQLITE_NOMEM; + } }else{ pParse->nErr++; sqlite3DbFree(db, pParse->zErrMsg); @@ -31942,11 +32853,34 @@ SQLITE_PRIVATE void sqlite3Dequote(char *z){ z[j] = 0; } SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ + assert( !ExprHasProperty(p, EP_IntValue) ); assert( sqlite3Isquote(p->u.zToken[0]) ); p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted; sqlite3Dequote(p->u.zToken); } +/* +** If the input token p is quoted, try to adjust the token to remove +** the quotes. This is not always possible: +** +** "abc" -> abc +** "ab""cd" -> (not possible because of the interior "") +** +** Remove the quotes if possible. This is a optimization. The overall +** system should still return the correct answer even if this routine +** is always a no-op. +*/ +SQLITE_PRIVATE void sqlite3DequoteToken(Token *p){ + unsigned int i; + if( p->n<2 ) return; + if( !sqlite3Isquote(p->z[0]) ) return; + for(i=1; in-1; i++){ + if( sqlite3Isquote(p->z[i]) ) return; + } + p->n -= 2; + p->z++; +} + /* ** Generate a Token object from a string */ @@ -33052,13 +33986,13 @@ static void logBadConnection(const char *zType){ ** used as an argument to sqlite3_errmsg() or sqlite3_close(). */ SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3 *db){ - u32 magic; + u8 eOpenState; if( db==0 ){ logBadConnection("NULL"); return 0; } - magic = db->magic; - if( magic!=SQLITE_MAGIC_OPEN ){ + eOpenState = db->eOpenState; + if( eOpenState!=SQLITE_STATE_OPEN ){ if( sqlite3SafetyCheckSickOrOk(db) ){ testcase( sqlite3GlobalConfig.xLog!=0 ); logBadConnection("unopened"); @@ -33069,11 +34003,11 @@ SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3 *db){ } } SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ - u32 magic; - magic = db->magic; - if( magic!=SQLITE_MAGIC_SICK && - magic!=SQLITE_MAGIC_OPEN && - magic!=SQLITE_MAGIC_BUSY ){ + u8 eOpenState; + eOpenState = db->eOpenState; + if( eOpenState!=SQLITE_STATE_SICK && + eOpenState!=SQLITE_STATE_OPEN && + eOpenState!=SQLITE_STATE_BUSY ){ testcase( sqlite3GlobalConfig.xLog!=0 ); logBadConnection("invalid"); return 0; @@ -33238,7 +34172,6 @@ SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ return a[x&7] + y - 10; } -#ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Convert a double into a LogEst ** In other words, compute an approximation for 10*log2(x). @@ -33253,16 +34186,9 @@ SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ e = (a>>52) - 1022; return e*10; } -#endif /* SQLITE_OMIT_VIRTUALTABLE */ -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_ENABLE_STAT4) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) /* ** Convert a LogEst into an integer. -** -** Note that this routine is only used when one or more of various -** non-standard compile-time options is enabled. */ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ u64 n; @@ -33270,17 +34196,9 @@ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ x /= 10; if( n>=5 ) n -= 2; else if( n>=1 ) n -= 1; -#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ - defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) if( x>60 ) return (u64)LARGEST_INT64; -#else - /* If only SQLITE_ENABLE_STAT4 is on, then the largest input - ** possible to this routine is 310, resulting in a maximum x of 31 */ - assert( x<=60 ); -#endif return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x); } -#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */ /* ** Add a new name/number pair to a VList. This might require that the @@ -33692,35 +34610,35 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 18 */ "If" OpHelp(""), /* 19 */ "Not" OpHelp("r[P2]= !r[P1]"), /* 20 */ "IfNot" OpHelp(""), - /* 21 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), - /* 22 */ "SeekLT" OpHelp("key=r[P3@P4]"), - /* 23 */ "SeekLE" OpHelp("key=r[P3@P4]"), - /* 24 */ "SeekGE" OpHelp("key=r[P3@P4]"), - /* 25 */ "SeekGT" OpHelp("key=r[P3@P4]"), - /* 26 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), - /* 27 */ "IfNoHope" OpHelp("key=r[P3@P4]"), - /* 28 */ "NoConflict" OpHelp("key=r[P3@P4]"), - /* 29 */ "NotFound" OpHelp("key=r[P3@P4]"), - /* 30 */ "Found" OpHelp("key=r[P3@P4]"), - /* 31 */ "SeekRowid" OpHelp("intkey=r[P3]"), - /* 32 */ "NotExists" OpHelp("intkey=r[P3]"), - /* 33 */ "Last" OpHelp(""), - /* 34 */ "IfSmaller" OpHelp(""), - /* 35 */ "SorterSort" OpHelp(""), - /* 36 */ "Sort" OpHelp(""), - /* 37 */ "Rewind" OpHelp(""), - /* 38 */ "IdxLE" OpHelp("key=r[P3@P4]"), - /* 39 */ "IdxGT" OpHelp("key=r[P3@P4]"), - /* 40 */ "IdxLT" OpHelp("key=r[P3@P4]"), - /* 41 */ "IdxGE" OpHelp("key=r[P3@P4]"), - /* 42 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 21 */ "IsNullOrType" OpHelp("if typeof(r[P1]) IN (P3,5) goto P2"), + /* 22 */ "IfNullRow" OpHelp("if P1.nullRow then r[P3]=NULL, goto P2"), + /* 23 */ "SeekLT" OpHelp("key=r[P3@P4]"), + /* 24 */ "SeekLE" OpHelp("key=r[P3@P4]"), + /* 25 */ "SeekGE" OpHelp("key=r[P3@P4]"), + /* 26 */ "SeekGT" OpHelp("key=r[P3@P4]"), + /* 27 */ "IfNotOpen" OpHelp("if( !csr[P1] ) goto P2"), + /* 28 */ "IfNoHope" OpHelp("key=r[P3@P4]"), + /* 29 */ "NoConflict" OpHelp("key=r[P3@P4]"), + /* 30 */ "NotFound" OpHelp("key=r[P3@P4]"), + /* 31 */ "Found" OpHelp("key=r[P3@P4]"), + /* 32 */ "SeekRowid" OpHelp("intkey=r[P3]"), + /* 33 */ "NotExists" OpHelp("intkey=r[P3]"), + /* 34 */ "Last" OpHelp(""), + /* 35 */ "IfSmaller" OpHelp(""), + /* 36 */ "SorterSort" OpHelp(""), + /* 37 */ "Sort" OpHelp(""), + /* 38 */ "Rewind" OpHelp(""), + /* 39 */ "IdxLE" OpHelp("key=r[P3@P4]"), + /* 40 */ "IdxGT" OpHelp("key=r[P3@P4]"), + /* 41 */ "IdxLT" OpHelp("key=r[P3@P4]"), + /* 42 */ "IdxGE" OpHelp("key=r[P3@P4]"), /* 43 */ "Or" OpHelp("r[P3]=(r[P1] || r[P2])"), /* 44 */ "And" OpHelp("r[P3]=(r[P1] && r[P2])"), - /* 45 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), - /* 46 */ "Program" OpHelp(""), - /* 47 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), - /* 48 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), - /* 49 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 45 */ "RowSetRead" OpHelp("r[P3]=rowset(P1)"), + /* 46 */ "RowSetTest" OpHelp("if r[P3] in rowset(P1) goto P2"), + /* 47 */ "Program" OpHelp(""), + /* 48 */ "FkIfZero" OpHelp("if fkctr[P1]==0 goto P2"), + /* 49 */ "IfPos" OpHelp("if r[P1]>0 then r[P1]-=P3, goto P2"), /* 50 */ "IsNull" OpHelp("if r[P1]==NULL goto P2"), /* 51 */ "NotNull" OpHelp("if r[P1]!=NULL goto P2"), /* 52 */ "Ne" OpHelp("IF r[P3]!=r[P1]"), @@ -33730,49 +34648,49 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 56 */ "Lt" OpHelp("IF r[P3]=r[P1]"), /* 58 */ "ElseEq" OpHelp(""), - /* 59 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), - /* 60 */ "IncrVacuum" OpHelp(""), - /* 61 */ "VNext" OpHelp(""), - /* 62 */ "Init" OpHelp("Start at P2"), - /* 63 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), - /* 64 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), - /* 65 */ "Return" OpHelp(""), - /* 66 */ "EndCoroutine" OpHelp(""), - /* 67 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), - /* 68 */ "Halt" OpHelp(""), - /* 69 */ "Integer" OpHelp("r[P2]=P1"), - /* 70 */ "Int64" OpHelp("r[P2]=P4"), - /* 71 */ "String" OpHelp("r[P2]='P4' (len=P1)"), - /* 72 */ "Null" OpHelp("r[P2..P3]=NULL"), - /* 73 */ "SoftNull" OpHelp("r[P1]=NULL"), - /* 74 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), - /* 75 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), - /* 76 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), - /* 77 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), - /* 78 */ "SCopy" OpHelp("r[P2]=r[P1]"), - /* 79 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 80 */ "ChngCntRow" OpHelp("output=r[P1]"), - /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 82 */ "CollSeq" OpHelp(""), - /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 84 */ "RealAffinity" OpHelp(""), - /* 85 */ "Cast" OpHelp("affinity(r[P1])"), - /* 86 */ "Permutation" OpHelp(""), - /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), - /* 89 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), - /* 90 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), - /* 91 */ "Column" OpHelp("r[P3]=PX"), - /* 92 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 93 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 94 */ "Count" OpHelp("r[P2]=count()"), - /* 95 */ "ReadCookie" OpHelp(""), - /* 96 */ "SetCookie" OpHelp(""), - /* 97 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 98 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 99 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 100 */ "OpenDup" OpHelp(""), - /* 101 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"), + /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"), + /* 61 */ "IncrVacuum" OpHelp(""), + /* 62 */ "VNext" OpHelp(""), + /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"), + /* 64 */ "Init" OpHelp("Start at P2"), + /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"), + /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"), + /* 67 */ "Return" OpHelp(""), + /* 68 */ "EndCoroutine" OpHelp(""), + /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"), + /* 70 */ "Halt" OpHelp(""), + /* 71 */ "Integer" OpHelp("r[P2]=P1"), + /* 72 */ "Int64" OpHelp("r[P2]=P4"), + /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"), + /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"), + /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"), + /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"), + /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"), + /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"), + /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), + /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"), + /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"), + /* 82 */ "FkCheck" OpHelp(""), + /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 84 */ "CollSeq" OpHelp(""), + /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 86 */ "RealAffinity" OpHelp(""), + /* 87 */ "Cast" OpHelp("affinity(r[P1])"), + /* 88 */ "Permutation" OpHelp(""), + /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"), + /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 93 */ "Column" OpHelp("r[P3]=PX"), + /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"), + /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 97 */ "Count" OpHelp("r[P2]=count()"), + /* 98 */ "ReadCookie" OpHelp(""), + /* 99 */ "SetCookie" OpHelp(""), + /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"), /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 157 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 158 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 159 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 160 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 161 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 162 */ "Expire" OpHelp(""), - /* 163 */ "CursorLock" OpHelp(""), - /* 164 */ "CursorUnlock" OpHelp(""), - /* 165 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 166 */ "VBegin" OpHelp(""), - /* 167 */ "VCreate" OpHelp(""), - /* 168 */ "VDestroy" OpHelp(""), - /* 169 */ "VOpen" OpHelp(""), - /* 170 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 171 */ "VRename" OpHelp(""), - /* 172 */ "Pagecount" OpHelp(""), - /* 173 */ "MaxPgcnt" OpHelp(""), - /* 174 */ "Trace" OpHelp(""), - /* 175 */ "CursorHint" OpHelp(""), - /* 176 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 177 */ "Noop" OpHelp(""), - /* 178 */ "Explain" OpHelp(""), - /* 179 */ "Abortable" OpHelp(""), + /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 113 */ "OpenDup" OpHelp(""), + /* 114 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 116 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 117 */ "String8" OpHelp("r[P2]='P4'"), + /* 118 */ "SorterOpen" OpHelp(""), + /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 121 */ "Close" OpHelp(""), + /* 122 */ "ColumnsUsed" OpHelp(""), + /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 128 */ "RowCell" OpHelp(""), + /* 129 */ "Delete" OpHelp(""), + /* 130 */ "ResetCount" OpHelp(""), + /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 132 */ "SorterData" OpHelp("r[P2]=data"), + /* 133 */ "RowData" OpHelp("r[P2]=data"), + /* 134 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 135 */ "NullRow" OpHelp(""), + /* 136 */ "SeekEnd" OpHelp(""), + /* 137 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 138 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 142 */ "FinishSeek" OpHelp(""), + /* 143 */ "Destroy" OpHelp(""), + /* 144 */ "Clear" OpHelp(""), + /* 145 */ "ResetSorter" OpHelp(""), + /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 147 */ "SqlExec" OpHelp(""), + /* 148 */ "ParseSchema" OpHelp(""), + /* 149 */ "LoadAnalysis" OpHelp(""), + /* 150 */ "DropTable" OpHelp(""), + /* 151 */ "DropIndex" OpHelp(""), + /* 152 */ "DropTrigger" OpHelp(""), + /* 153 */ "Real" OpHelp("r[P2]=P4"), + /* 154 */ "IntegrityCk" OpHelp(""), + /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 156 */ "Param" OpHelp(""), + /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 165 */ "Expire" OpHelp(""), + /* 166 */ "CursorLock" OpHelp(""), + /* 167 */ "CursorUnlock" OpHelp(""), + /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 169 */ "VBegin" OpHelp(""), + /* 170 */ "VCreate" OpHelp(""), + /* 171 */ "VDestroy" OpHelp(""), + /* 172 */ "VOpen" OpHelp(""), + /* 173 */ "VInitIn" OpHelp("r[P2]=ValueList(P1,P3)"), + /* 174 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 175 */ "VRename" OpHelp(""), + /* 176 */ "Pagecount" OpHelp(""), + /* 177 */ "MaxPgcnt" OpHelp(""), + /* 178 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"), + /* 179 */ "Trace" OpHelp(""), + /* 180 */ "CursorHint" OpHelp(""), + /* 181 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 182 */ "Noop" OpHelp(""), + /* 183 */ "Explain" OpHelp(""), + /* 184 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -34157,205 +35080,7 @@ static pid_t randomnessPid = 0; /* ** Include code that is common to all os_*.c files */ -/************** Include os_common.h in the middle of os_unix.c ***************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_io_error_hit; -SQLITE_API extern int sqlite3_io_error_hardhit; -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_persist; -SQLITE_API extern int sqlite3_io_error_benign; -SQLITE_API extern int sqlite3_diskfull_pending; -SQLITE_API extern int sqlite3_diskfull; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_open_file_count; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif /* defined(SQLITE_TEST) */ - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in os_unix.c ********************/ +/* #include "os_common.h" */ /* ** Define various macros that are missing from some systems. @@ -38009,7 +38734,9 @@ static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){ /* Forward declaration */ static int unixGetTempname(int nBuf, char *zBuf); -static int unixFcntlExternalReader(unixFile*, int*); +#ifndef SQLITE_OMIT_WAL + static int unixFcntlExternalReader(unixFile*, int*); +#endif /* ** Information and control of an open file handle. @@ -38128,7 +38855,12 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){ #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */ case SQLITE_FCNTL_EXTERNAL_READER: { +#ifndef SQLITE_OMIT_WAL return unixFcntlExternalReader((unixFile*)id, (int*)pArg); +#else + *(int*)pArg = 0; + return SQLITE_OK; +#endif } } return SQLITE_NOTFOUND; @@ -38961,11 +39693,17 @@ static int unixShmLock( int flags /* What to do with the lock */ ){ unixFile *pDbFd = (unixFile*)fd; /* Connection holding shared memory */ - unixShm *p = pDbFd->pShm; /* The shared memory being locked */ - unixShmNode *pShmNode = p->pShmNode; /* The underlying file iNode */ + unixShm *p; /* The shared memory being locked */ + unixShmNode *pShmNode; /* The underlying file iNode */ int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ - int *aLock = pShmNode->aLock; + int *aLock; + + p = pDbFd->pShm; + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + aLock = pShmNode->aLock; assert( pShmNode==pDbFd->pInode->pShmNode ); assert( pShmNode->pInode==pDbFd->pInode ); @@ -39849,25 +40587,35 @@ static int fillInUnixFile( return rc; } +/* +** Directories to consider for temp files. +*/ +static const char *azTempDirs[] = { + 0, + 0, + "/var/tmp", + "/usr/tmp", + "/tmp", + "." +}; + +/* +** Initialize first two members of azTempDirs[] array. +*/ +static void unixTempFileInit(void){ + azTempDirs[0] = getenv("SQLITE_TMPDIR"); + azTempDirs[1] = getenv("TMPDIR"); +} + /* ** Return the name of a directory in which to put temporary files. ** If no suitable temporary file directory can be found, return NULL. */ static const char *unixTempFileDir(void){ - static const char *azDirs[] = { - 0, - 0, - "/var/tmp", - "/usr/tmp", - "/tmp", - "." - }; unsigned int i = 0; struct stat buf; const char *zDir = sqlite3_temp_directory; - if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); - if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); while(1){ if( zDir!=0 && osStat(zDir, &buf)==0 @@ -39876,8 +40624,8 @@ static const char *unixTempFileDir(void){ ){ return zDir; } - if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break; - zDir = azDirs[i++]; + if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break; + zDir = azTempDirs[i++]; } return 0; } @@ -40183,6 +40931,11 @@ static int unixOpen( } memset(p, 0, sizeof(unixFile)); +#ifdef SQLITE_ASSERT_NO_FILES + /* Applications that never read or write a persistent disk files */ + assert( zName==0 ); +#endif + if( eType==SQLITE_OPEN_MAIN_DB ){ UnixUnusedFd *pUnused; pUnused = findReusableFd(zName, flags); @@ -42144,6 +42897,9 @@ SQLITE_API int sqlite3_os_init(void){ assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */ #endif + /* Initialize temp file dir array. */ + unixTempFileInit(); + return SQLITE_OK; } @@ -42183,205 +42939,7 @@ SQLITE_API int sqlite3_os_end(void){ /* ** Include code that is common to all os_*.c files */ -/************** Include os_common.h in the middle of os_win.c ****************/ -/************** Begin file os_common.h ***************************************/ -/* -** 2004 May 22 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains macros and a little bit of code that is common to -** all of the platform-specific files (os_*.c) and is #included into those -** files. -** -** This file should be #included by the os_*.c files only. It is not a -** general purpose header file. -*/ -#ifndef _OS_COMMON_H_ -#define _OS_COMMON_H_ - -/* -** At least two bugs have slipped in because we changed the MEMORY_DEBUG -** macro to SQLITE_DEBUG and some older makefiles have not yet made the -** switch. The following code should catch this problem at compile-time. -*/ -#ifdef MEMORY_DEBUG -# error "The MEMORY_DEBUG macro is obsolete. Use SQLITE_DEBUG instead." -#endif - -/* -** Macros for performance tracing. Normally turned off. Only works -** on i486 hardware. -*/ -#ifdef SQLITE_PERFORMANCE_TRACE - -/* -** hwtime.h contains inline assembler code for implementing -** high-performance timing routines. -*/ -/************** Include hwtime.h in the middle of os_common.h ****************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in os_common.h ******************/ - -static sqlite_uint64 g_start; -static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=sqlite3Hwtime() -#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start -#define TIMER_ELAPSED g_elapsed -#else -#define TIMER_START -#define TIMER_END -#define TIMER_ELAPSED ((sqlite_uint64)0) -#endif - -/* -** If we compile with the SQLITE_TEST macro set, then the following block -** of code will give us the ability to simulate a disk I/O error. This -** is used for testing the I/O recovery logic. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_io_error_hit; -SQLITE_API extern int sqlite3_io_error_hardhit; -SQLITE_API extern int sqlite3_io_error_pending; -SQLITE_API extern int sqlite3_io_error_persist; -SQLITE_API extern int sqlite3_io_error_benign; -SQLITE_API extern int sqlite3_diskfull_pending; -SQLITE_API extern int sqlite3_diskfull; -#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) -#define SimulateIOError(CODE) \ - if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ - || sqlite3_io_error_pending-- == 1 ) \ - { local_ioerr(); CODE; } -static void local_ioerr(){ - IOTRACE(("IOERR\n")); - sqlite3_io_error_hit++; - if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; -} -#define SimulateDiskfullError(CODE) \ - if( sqlite3_diskfull_pending ){ \ - if( sqlite3_diskfull_pending == 1 ){ \ - local_ioerr(); \ - sqlite3_diskfull = 1; \ - sqlite3_io_error_hit = 1; \ - CODE; \ - }else{ \ - sqlite3_diskfull_pending--; \ - } \ - } -#else -#define SimulateIOErrorBenign(X) -#define SimulateIOError(A) -#define SimulateDiskfullError(A) -#endif /* defined(SQLITE_TEST) */ - -/* -** When testing, keep a count of the number of open files. -*/ -#if defined(SQLITE_TEST) -SQLITE_API extern int sqlite3_open_file_count; -#define OpenCounter(X) sqlite3_open_file_count+=(X) -#else -#define OpenCounter(X) -#endif /* defined(SQLITE_TEST) */ - -#endif /* !defined(_OS_COMMON_H_) */ - -/************** End of os_common.h *******************************************/ -/************** Continuing where we left off in os_win.c *********************/ +/* #include "os_common.h" */ /* ** Include the header file for the Windows VFS. @@ -46433,10 +46991,14 @@ static int winShmLock( winFile *pDbFd = (winFile*)fd; /* Connection holding shared memory */ winShm *p = pDbFd->pShm; /* The shared memory being locked */ winShm *pX; /* For looping over all siblings */ - winShmNode *pShmNode = p->pShmNode; + winShmNode *pShmNode; int rc = SQLITE_OK; /* Result code */ u16 mask; /* Mask of locks to take or release */ + if( p==0 ) return SQLITE_IOERR_SHMLOCK; + pShmNode = p->pShmNode; + if( NEVER(pShmNode==0) ) return SQLITE_IOERR_SHMLOCK; + assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK ); assert( n>=1 ); assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED) @@ -48792,7 +49354,7 @@ static int memdbRead( */ static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){ unsigned char *pNew; - if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){ + if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){ return SQLITE_FULL; } if( newSz>p->szMax ){ @@ -48851,8 +49413,9 @@ static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ MemStore *p = ((MemFile*)pFile)->pStore; int rc = SQLITE_OK; memdbEnter(p); - if( NEVER(size>p->sz) ){ - rc = SQLITE_FULL; + if( size>p->sz ){ + /* This can only happen with a corrupt wal mode db */ + rc = SQLITE_CORRUPT; }else{ p->sz = size; } @@ -48991,7 +49554,7 @@ static int memdbFetch( ){ MemStore *p = ((MemFile*)pFile)->pStore; memdbEnter(p); - if( iOfst+iAmt>p->sz ){ + if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){ *pp = 0; }else{ p->nMmap++; @@ -49025,10 +49588,9 @@ static int memdbOpen( MemFile *pFile = (MemFile*)pFd; MemStore *p = 0; int szName; - if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){ - return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags); - } - memset(pFile, 0, sizeof(*p)); + UNUSED_PARAMETER(pVfs); + + memset(pFile, 0, sizeof(*pFile)); szName = sqlite3Strlen30(zName); if( szName>1 && zName[0]=='/' ){ int i; @@ -49087,8 +49649,9 @@ static int memdbOpen( p->szMax = sqlite3GlobalConfig.mxMemdbSize; } pFile->pStore = p; - assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */ - *pOutFlags = flags | SQLITE_OPEN_MEMORY; + if( pOutFlags!=0 ){ + *pOutFlags = flags | SQLITE_OPEN_MEMORY; + } pFd->pMethods = &memdb_io_methods; memdbLeave(p); return SQLITE_OK; @@ -49329,7 +49892,8 @@ SQLITE_API int sqlite3_deserialize( sqlite3_mutex_enter(db->mutex); if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; iDb = sqlite3FindDbName(db, zSchema); - if( iDb<0 ){ + testcase( iDb==1 ); + if( iDb<2 && iDb!=0 ){ rc = SQLITE_ERROR; goto end_deserialize; } @@ -49752,7 +50316,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ sqlite3BitvecClear(0, 1, pTmpSpace); /* Run the program */ - pc = 0; + pc = i = 0; while( (op = aOp[pc])!=0 ){ switch( op ){ case 1: @@ -50056,11 +50620,14 @@ static int numberOfCachePages(PCache *p){ ** suggested cache size is set to N. */ return p->szCache; }else{ + i64 n; /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the ** number of cache pages is adjusted to be a number of pages that would ** use approximately abs(N*1024) bytes of memory based on the current ** page size. */ - return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + n = ((-1024*(i64)p->szCache)/(p->szPage+p->szExtra)); + if( n>1000000000 ) n = 1000000000; + return (int)n; } } @@ -50361,7 +50928,8 @@ SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ ** make it so. */ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ - assert( p->nRef>0 ); + assert( p->nRef>0 || p->pCache->bPurgeable==0 ); + testcase( p->nRef==0 ); assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; @@ -51515,12 +52083,18 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ */ static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ PCache1 *pCache = (PCache1 *)p; + u32 n; + assert( nMax>=0 ); if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; pcache1EnterMutex(pGroup); - pGroup->nMaxPage += (nMax - pCache->nMax); + n = (u32)nMax; + if( n > 0x7fff0000 - pGroup->nMaxPage + pCache->nMax ){ + n = 0x7fff0000 - pGroup->nMaxPage + pCache->nMax; + } + pGroup->nMaxPage += (n - pCache->nMax); pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; - pCache->nMax = nMax; + pCache->nMax = n; pCache->n90pct = pCache->nMax*9/10; pcache1EnforceMaxPage(pCache); pcache1LeaveMutex(pGroup); @@ -51536,7 +52110,7 @@ static void pcache1Shrink(sqlite3_pcache *p){ PCache1 *pCache = (PCache1*)p; if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; - int savedMaxPage; + unsigned int savedMaxPage; pcache1EnterMutex(pGroup); savedMaxPage = pGroup->nMaxPage; pGroup->nMaxPage = 0; @@ -53273,6 +53847,7 @@ struct Pager { u8 noLock; /* Do not lock (except in WAL mode) */ u8 readOnly; /* True for a read-only database */ u8 memDb; /* True to inhibit all file I/O */ + u8 memVfs; /* VFS-implemented memory database */ /************************************************************************** ** The following block contains those class members that change during @@ -53322,8 +53897,8 @@ struct Pager { i16 nReserve; /* Number of unused bytes at end of each page */ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ u32 sectorSize; /* Assumed sector size during rollback */ - int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ + i64 pageSize; /* Number of bytes in a page */ i64 journalSizeLimit; /* Size limit for persistent journal files */ char *zFilename; /* Name of the database file */ char *zJournal; /* Name of the journal file */ @@ -55486,6 +56061,9 @@ static int pager_playback(Pager *pPager, int isHot){ goto end_playback; } pPager->dbSize = mxPg; + if( pPager->mxPgnomxPgno = mxPg; + } } /* Copy original pages out of the journal and back into the @@ -55667,6 +56245,7 @@ static int readDbPage(PgHdr *pPg){ */ static void pager_write_changecounter(PgHdr *pPg){ u32 change_counter; + if( NEVER(pPg==0) ) return; /* Increment the value just read and write it back to byte 24. */ change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; @@ -56541,8 +57120,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ ** current database image, in pages, OR ** ** b) if the page content were written at this time, it would not -** be necessary to write the current content out to the sub-journal -** (as determined by function subjRequiresPage()). +** be necessary to write the current content out to the sub-journal. ** ** If the condition asserted by this function were not true, and the ** dirty page were to be discarded from the cache via the pagerStress() @@ -56557,8 +57135,16 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ */ #if defined(SQLITE_DEBUG) static void assertTruncateConstraintCb(PgHdr *pPg){ + Pager *pPager = pPg->pPager; assert( pPg->flags&PGHDR_DIRTY ); - assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); + if( pPg->pgno>pPager->dbSize ){ /* if (a) is false */ + Pgno pgno = pPg->pgno; + int i; + for(i=0; ipPager->nSavepoint; i++){ + PagerSavepoint *p = &pPager->aSavepoint[i]; + assert( p->nOrigpInSavepoint,pgno) ); + } + } } static void assertTruncateConstraint(Pager *pPager){ sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); @@ -56580,7 +57166,6 @@ static void assertTruncateConstraint(Pager *pPager){ */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ assert( pPager->dbSize>=nPage || CORRUPT_DB ); - testcase( pPager->dbSizeeState>=PAGER_WRITER_CACHEMOD ); pPager->dbSize = nPage; @@ -57501,6 +58086,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( pPager->zWal = 0; } #endif + (void)pPtr; /* Suppress warning about unused pPtr value */ if( nPathname ) sqlite3DbFree(0, zPathname); pPager->pVfs = pVfs; @@ -57513,7 +58099,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); #ifndef SQLITE_OMIT_DESERIALIZE - memJM = (fout&SQLITE_OPEN_MEMORY)!=0; + pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; #endif readOnly = (fout&SQLITE_OPEN_READONLY)!=0; @@ -57898,7 +58484,7 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ ** may mean that the pager was in the error-state when this ** function was called and the journal file does not exist. */ - if( !isOpen(pPager->jfd) ){ + if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ sqlite3_vfs * const pVfs = pPager->pVfs; int bExists; /* True if journal file exists */ rc = sqlite3OsAccess( @@ -58300,6 +58886,7 @@ SQLITE_PRIVATE int sqlite3PagerGet( DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ + /* printf("PAGE %u\n", pgno); fflush(stdout); */ return pPager->xGet(pPager, pgno, ppPage, flags); } @@ -59380,8 +59967,8 @@ SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ ** used by the pager and its associated cache. */ SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ - int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) - + 5*sizeof(void*); + int perPageSize = pPager->pageSize + pPager->nExtra + + (int)(sizeof(PgHdr) + 5*sizeof(void*)); return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + sqlite3MallocSize(pPager) + pPager->pageSize; @@ -59450,7 +60037,7 @@ SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, i ** Return true if this is an in-memory or temp-file backed pager. */ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ - return pPager->tempFile; + return pPager->tempFile || pPager->memVfs; } /* @@ -59575,14 +60162,14 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ } pPager->nSavepoint = nNew; - /* If this is a release of the outermost savepoint, truncate - ** the sub-journal to zero bytes in size. */ + /* Truncate the sub-journal so that it only includes the parts + ** that are still in use. */ if( op==SAVEPOINT_RELEASE ){ PagerSavepoint *pRel = &pPager->aSavepoint[nNew]; if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){ /* Only truncate if it is an in-memory sub-journal. */ if( sqlite3JournalIsInMemory(pPager->sjfd) ){ - i64 sz = (pPager->pageSize+4)*pRel->iSubRec; + i64 sz = (pPager->pageSize+4)*(i64)pRel->iSubRec; rc = sqlite3OsTruncate(pPager->sjfd, sz); assert( rc==SQLITE_OK ); } @@ -59770,7 +60357,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i pPgOld = sqlite3PagerLookup(pPager, pgno); assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); if( pPgOld ){ - if( pPgOld->nRef>1 ){ + if( NEVER(pPgOld->nRef>1) ){ sqlite3PagerUnrefNotNull(pPgOld); return SQLITE_CORRUPT_BKPT; } @@ -59905,12 +60492,12 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ u8 eOld = pPager->journalMode; /* Prior journalmode */ /* The eMode parameter is always valid */ - assert( eMode==PAGER_JOURNALMODE_DELETE - || eMode==PAGER_JOURNALMODE_TRUNCATE - || eMode==PAGER_JOURNALMODE_PERSIST - || eMode==PAGER_JOURNALMODE_OFF - || eMode==PAGER_JOURNALMODE_WAL - || eMode==PAGER_JOURNALMODE_MEMORY ); + assert( eMode==PAGER_JOURNALMODE_DELETE /* 0 */ + || eMode==PAGER_JOURNALMODE_PERSIST /* 1 */ + || eMode==PAGER_JOURNALMODE_OFF /* 2 */ + || eMode==PAGER_JOURNALMODE_TRUNCATE /* 3 */ + || eMode==PAGER_JOURNALMODE_MEMORY /* 4 */ + || eMode==PAGER_JOURNALMODE_WAL /* 5 */ ); /* This routine is only called from the OP_JournalMode opcode, and ** the logic there will never allow a temporary file to be changed @@ -59947,7 +60534,6 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ assert( isOpen(pPager->fd) || pPager->exclusiveMode ); if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ - /* In this case we would like to delete the journal file. If it is ** not possible, then that is not a problem. Deleting the journal file ** here is an optimization only. @@ -60059,6 +60645,18 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint( int *pnCkpt /* OUT: Final number of checkpointed frames */ ){ int rc = SQLITE_OK; + if( pPager->pWal==0 && pPager->journalMode==PAGER_JOURNALMODE_WAL ){ + /* This only happens when a database file is zero bytes in size opened and + ** then "PRAGMA journal_mode=WAL" is run and then sqlite3_wal_checkpoint() + ** is invoked without any intervening transactions. We need to start + ** a transaction to initialize pWal. The PRAGMA table_list statement is + ** used for this since it starts transactions on every database file, + ** including all ATTACHed databases. This seems expensive for a single + ** sqlite3_wal_checkpoint() call, but it happens very rarely. + ** https://sqlite.org/forum/forumpost/fd0f19d229156939 + */ + sqlite3_exec(db, "PRAGMA table_list",0,0,0); + } if( pPager->pWal ){ rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), @@ -60516,7 +61114,10 @@ SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ ** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and ** HASHTABLE_NPAGE are selected so that together the wal-index header and ** first index block are the same size as all other index blocks in the -** wal-index. +** wal-index. The values are: +** +** HASHTABLE_NPAGE 4096 +** HASHTABLE_NPAGE_ONE 4062 ** ** Each index block contains two sections, a page-mapping that contains the ** database page number associated with each wal frame, and a hash-table @@ -60752,6 +61353,70 @@ struct WalCkptInfo { }; #define READMARK_NOT_USED 0xffffffff +/* +** This is a schematic view of the complete 136-byte header of the +** wal-index file (also known as the -shm file): +** +** +-----------------------------+ +** 0: | iVersion | \ +** +-----------------------------+ | +** 4: | (unused padding) | | +** +-----------------------------+ | +** 8: | iChange | | +** +-------+-------+-------------+ | +** 12: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | +** 16: | mxFrame | | First copy of the +** +-----------------------------+ | WalIndexHdr object +** 20: | nPage | | +** +-----------------------------+ | +** 24: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 32: | aSalt | | +** | | | +** +-----------------------------+ | +** 40: | aCksum | | +** | | / +** +-----------------------------+ +** 48: | iVersion | \ +** +-----------------------------+ | +** 52: | (unused padding) | | +** +-----------------------------+ | +** 56: | iChange | | +** +-------+-------+-------------+ | +** 60: | bInit | bBig | szPage | | +** +-------+-------+-------------+ | Second copy of the +** 64: | mxFrame | | WalIndexHdr +** +-----------------------------+ | +** 68: | nPage | | +** +-----------------------------+ | +** 72: | aFrameCksum | | +** | | | +** +-----------------------------+ | +** 80: | aSalt | | +** | | | +** +-----------------------------+ | +** 88: | aCksum | | +** | | / +** +-----------------------------+ +** 96: | nBackfill | +** +-----------------------------+ +** 100: | 5 read marks | +** | | +** | | +** | | +** | | +** +-------+-------+------+------+ +** 120: | Write | Ckpt | Rcvr | Rd0 | \ +** +-------+-------+------+------+ ) 8 lock bytes +** | Read1 | Read2 | Rd3 | Rd4 | / +** +-------+-------+------+------+ +** 128: | nBackfillAttempted | +** +-----------------------------+ +** 132: | (unused padding) | +** +-----------------------------+ +*/ /* A block of WALINDEX_LOCK_RESERVED bytes beginning at ** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems @@ -60908,9 +61573,13 @@ struct WalIterator { ** so. It is safe to enlarge the wal-index if pWal->writeLock is true ** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE. ** -** If this call is successful, *ppPage is set to point to the wal-index -** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs, -** then an SQLite error code is returned and *ppPage is set to 0. +** Three possible result scenarios: +** +** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page +** (2) rc>=SQLITE_ERROR and *ppPage==NULL +** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0 +** +** Scenario (3) can only occur when pWal->writeLock is false and iPage==0 */ static SQLITE_NOINLINE int walIndexPageRealloc( Wal *pWal, /* The WAL context */ @@ -60943,7 +61612,9 @@ static SQLITE_NOINLINE int walIndexPageRealloc( rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); - assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 ); + assert( pWal->apWiData[iPage]!=0 + || rc!=SQLITE_OK + || (pWal->writeLock==0 && iPage==0) ); testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK ); if( rc==SQLITE_OK ){ if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM; @@ -61282,8 +61953,8 @@ struct WalHashLoc { ** slot in the hash table is set to N, it refers to frame number ** (pLoc->iZero+N) in the log. ** -** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the -** first frame indexed by the hash table, frame (pLoc->iZero+1). +** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the +** first frame indexed by the hash table, frame (pLoc->iZero). */ static int walHashGet( Wal *pWal, /* WAL handle */ @@ -61295,7 +61966,7 @@ static int walHashGet( rc = walIndexPage(pWal, iHash, &pLoc->aPgno); assert( rc==SQLITE_OK || iHash>0 ); - if( rc==SQLITE_OK ){ + if( pLoc->aPgno ){ pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE]; if( iHash==0 ){ pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)]; @@ -61303,7 +61974,8 @@ static int walHashGet( }else{ pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE; } - pLoc->aPgno = &pLoc->aPgno[-1]; + }else if( NEVER(rc==SQLITE_OK) ){ + rc = SQLITE_ERROR; } return rc; } @@ -61385,8 +62057,9 @@ static void walCleanupHash(Wal *pWal){ /* Zero the entries in the aPgno array that correspond to frames with ** frame numbers greater than pWal->hdr.mxFrame. */ - nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]); - memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte); + nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]); + assert( nByte>=0 ); + memset((void *)&sLoc.aPgno[iLimit], 0, nByte); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT /* Verify that the every entry in the mapping region is still reachable @@ -61395,11 +62068,11 @@ static void walCleanupHash(Wal *pWal){ if( iLimit ){ int j; /* Loop counter */ int iKey; /* Hash key */ - for(j=1; j<=iLimit; j++){ + for(j=0; j=0 ); + memset((void*)sLoc.aPgno, 0, nByte); } /* If the entry in aPgno[] is already set, then the previous writer @@ -61442,9 +62115,9 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ ** Remove the remnants of that writers uncommitted transaction from ** the hash-table before writing any new entries. */ - if( sLoc.aPgno[idx] ){ + if( sLoc.aPgno[idx-1] ){ walCleanupHash(pWal); - assert( !sLoc.aPgno[idx] ); + assert( !sLoc.aPgno[idx-1] ); } /* Write the aPgno[] array entry and the hash-table slot. */ @@ -61452,7 +62125,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){ if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT; } - sLoc.aPgno[idx] = iPage; + sLoc.aPgno[idx-1] = iPage; AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx); #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT @@ -61473,19 +62146,18 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ */ if( (idx&0x3ff)==0 ){ int i; /* Loop counter */ - for(i=1; i<=idx; i++){ + for(i=0; iapWiData[iPg] = aPrivate; for(iFrame=iFirst; iFrame<=iLast; iFrame++){ @@ -61765,14 +62438,43 @@ SQLITE_PRIVATE int sqlite3WalOpen( assert( zWalName && zWalName[0] ); assert( pDbFd ); + /* Verify the values of various constants. Any changes to the values + ** of these constants would result in an incompatible on-disk format + ** for the -shm file. Any change that causes one of these asserts to + ** fail is a backward compatibility problem, even if the change otherwise + ** works. + ** + ** This table also serves as a helpful cross-reference when trying to + ** interpret hex dumps of the -shm file. + */ + assert( 48 == sizeof(WalIndexHdr) ); + assert( 40 == sizeof(WalCkptInfo) ); + assert( 120 == WALINDEX_LOCK_OFFSET ); + assert( 136 == WALINDEX_HDR_SIZE ); + assert( 4096 == HASHTABLE_NPAGE ); + assert( 4062 == HASHTABLE_NPAGE_ONE ); + assert( 8192 == HASHTABLE_NSLOT ); + assert( 383 == HASHTABLE_HASH_1 ); + assert( 32768 == WALINDEX_PGSZ ); + assert( 8 == SQLITE_SHM_NLOCK ); + assert( 5 == WAL_NREADER ); + assert( 24 == WAL_FRAME_HDRSIZE ); + assert( 32 == WAL_HDRSIZE ); + assert( 120 == WALINDEX_LOCK_OFFSET + WAL_WRITE_LOCK ); + assert( 121 == WALINDEX_LOCK_OFFSET + WAL_CKPT_LOCK ); + assert( 122 == WALINDEX_LOCK_OFFSET + WAL_RECOVER_LOCK ); + assert( 123 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(0) ); + assert( 124 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(1) ); + assert( 125 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(2) ); + assert( 126 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(3) ); + assert( 127 == WALINDEX_LOCK_OFFSET + WAL_READ_LOCK(4) ); + /* In the amalgamation, the os_unix.c and os_win.c source files come before ** this source file. Verify that the #defines of the locking byte offsets ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. ** For that matter, if the lock offset ever changes from its initial design ** value of 120, we need to know that so there is an assert() to check it. */ - assert( 120==WALINDEX_LOCK_OFFSET ); - assert( 136==WALINDEX_HDR_SIZE ); #ifdef WIN_SHM_BASE assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET ); #endif @@ -62074,7 +62776,6 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ int nEntry; /* Number of entries in this segment */ ht_slot *aIndex; /* Sorted index for this segment */ - sLoc.aPgno++; if( (i+1)==nSegment ){ nEntry = (int)(iLast - sLoc.iZero); }else{ @@ -62855,7 +63556,9 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ } /* Allocate a buffer to read frames into */ - szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE; + assert( (pWal->szPage & (pWal->szPage-1))==0 ); + assert( pWal->szPage>=512 && pWal->szPage<=65536 ); + szFrame = pWal->szPage + WAL_FRAME_HDRSIZE; aFrame = (u8 *)sqlite3_malloc64(szFrame); if( aFrame==0 ){ rc = SQLITE_NOMEM_BKPT; @@ -62869,7 +63572,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** the caller. */ aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; - for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->hdr.szPage); + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage); iOffset+szFrame<=szWal; iOffset+=szFrame ){ @@ -63213,7 +63916,8 @@ SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ rc = walHashGet(pWal, walFramePage(i), &sLoc); if( rc!=SQLITE_OK ) break; - pgno = sLoc.aPgno[i-sLoc.iZero]; + assert( i - sLoc.iZero - 1 >=0 ); + pgno = sLoc.aPgno[i-sLoc.iZero-1]; iDbOff = (i64)(pgno-1) * szPage; if( iDbOff+szPage<=szDb ){ @@ -63446,7 +64150,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame( iKey = walHash(pgno); while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ u32 iFrame = iH + sLoc.iZero; - if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){ + if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ assert( iFrame>iRead || CORRUPT_DB ); iRead = iFrame; } @@ -64698,7 +65402,6 @@ typedef struct CellInfo CellInfo; */ struct MemPage { u8 isInit; /* True if previously initialized. MUST BE FIRST! */ - u8 bBusy; /* Prevent endless loops on corrupt database files */ u8 intKey; /* True if table b-trees. False for index b-trees */ u8 intKeyLeaf; /* True if the leaf of an intKey table */ Pgno pgno; /* Page number for this page */ @@ -64720,7 +65423,9 @@ struct MemPage { u8 *apOvfl[4]; /* Pointers to the body of overflow cells */ BtShared *pBt; /* Pointer to BtShared that this page is part of */ u8 *aData; /* Pointer to disk image of the page data */ - u8 *aDataEnd; /* One byte past the end of usable data */ + u8 *aDataEnd; /* One byte past the end of the entire page - not just + ** the usable space, the entire page. Used to prevent + ** corruption-induced of buffer overflow. */ u8 *aCellIdx; /* The cell index area */ u8 *aDataOfst; /* Same as aData for leaves. aData+4 for interior */ DbPage *pDbPage; /* Pager page handle */ @@ -66279,15 +66984,13 @@ static int btreeMoveto( sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ rc = SQLITE_CORRUPT_BKPT; - goto moveto_done; + }else{ + rc = sqlite3BtreeIndexMoveto(pCur, pIdxKey, pRes); } + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); }else{ pIdxKey = 0; - } - rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); -moveto_done: - if( pIdxKey ){ - sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); + rc = sqlite3BtreeTableMoveto(pCur, nKey, bias, pRes); } return rc; } @@ -66679,18 +67382,32 @@ static void btreeParseCellPtr( ** ** pIter += getVarint(pIter, (u64*)&pInfo->nKey); ** - ** The code is inlined to avoid a function call. + ** The code is inlined and the loop is unrolled for performance. + ** This routine is a high-runner. */ iKey = *pIter; if( iKey>=0x80 ){ - u8 *pEnd = &pIter[7]; - iKey &= 0x7f; - while(1){ - iKey = (iKey<<7) | (*++pIter & 0x7f); - if( (*pIter)<0x80 ) break; - if( pIter>=pEnd ){ - iKey = (iKey<<8) | *++pIter; - break; + u8 x; + iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x =*++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); + if( x>=0x80 ){ + iKey = (iKey<<8) | (*++pIter); + } + } + } + } + } } } } @@ -66700,7 +67417,7 @@ static void btreeParseCellPtr( pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==pPage->maxLocal+1 ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. @@ -66737,7 +67454,7 @@ static void btreeParseCellPtrIndex( pInfo->nPayload = nPayload; pInfo->pPayload = pIter; testcase( nPayload==pPage->maxLocal ); - testcase( nPayload==pPage->maxLocal+1 ); + testcase( nPayload==(u32)pPage->maxLocal+1 ); if( nPayload<=pPage->maxLocal ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. @@ -66800,7 +67517,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ while( (*pIter++)&0x80 && pItermaxLocal ); - testcase( nSize==pPage->maxLocal+1 ); + testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize<=pPage->maxLocal ){ nSize += (u32)(pIter - pCell); if( nSize<4 ) nSize = 4; @@ -66808,7 +67525,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ int minLocal = pPage->minLocal; nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); testcase( nSize==pPage->maxLocal ); - testcase( nSize==pPage->maxLocal+1 ); + testcase( nSize==(u32)pPage->maxLocal+1 ); if( nSize>pPage->maxLocal ){ nSize = minLocal; } @@ -66942,7 +67659,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; - }else if( iFree+sz>usableSize ){ + }else if( NEVER(iFree+sz>usableSize) ){ return SQLITE_CORRUPT_PAGE(pPage); } @@ -67049,6 +67766,8 @@ static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc){ ** fragmented bytes within the page. */ memcpy(&aData[iAddr], &aData[pc], 2); aData[hdr+7] += (u8)x; + testcase( pc+x>maxPC ); + return &aData[pc]; }else if( x+pc > maxPC ){ /* This slot extends off the end of the usable part of the page */ *pRc = SQLITE_CORRUPT_PAGE(pPg); @@ -67136,7 +67855,7 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ int g2; assert( pSpace+nByte<=data+pPage->pBt->usableSize ); *pIdx = g2 = (int)(pSpace-data); - if( NEVER(g2<=gap) ){ + if( g2<=gap ){ return SQLITE_CORRUPT_PAGE(pPage); }else{ return SQLITE_OK; @@ -67222,7 +67941,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ if( iFreeBlk>pPage->pBt->usableSize-4 ){ /* TH3: corrupt081.100 */ return SQLITE_CORRUPT_PAGE(pPage); } - assert( iFreeBlk>iPtr || iFreeBlk==0 ); + assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); /* At this point: ** iFreeBlk: First freeblock after iStart, or zero if none @@ -67493,7 +68212,7 @@ static int btreeInitPage(MemPage *pPage){ pPage->nOverflow = 0; pPage->cellOffset = pPage->hdrOffset + 8 + pPage->childPtrSize; pPage->aCellIdx = data + pPage->childPtrSize + 8; - pPage->aDataEnd = pPage->aData + pBt->usableSize; + pPage->aDataEnd = pPage->aData + pBt->pageSize; pPage->aDataOfst = pPage->aData + pPage->childPtrSize; /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the ** number of cells on the page. */ @@ -67528,7 +68247,7 @@ static void zeroPage(MemPage *pPage, int flags){ u8 hdr = pPage->hdrOffset; u16 first; - assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno || CORRUPT_DB ); assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); assert( sqlite3PagerGetData(pPage->pDbPage) == data ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); @@ -67544,7 +68263,7 @@ static void zeroPage(MemPage *pPage, int flags){ pPage->nFree = (u16)(pBt->usableSize - first); decodeFlags(pPage, flags); pPage->cellOffset = first; - pPage->aDataEnd = &data[pBt->usableSize]; + pPage->aDataEnd = &data[pBt->pageSize]; pPage->aCellIdx = &data[first]; pPage->aDataOfst = &data[pPage->childPtrSize]; pPage->nOverflow = 0; @@ -67670,7 +68389,7 @@ static int getAndInitPage( goto getAndInitPage_error2; } } - assert( (*ppPage)->pgno==pgno ); + assert( (*ppPage)->pgno==pgno || CORRUPT_DB ); assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); /* If obtaining a child page for a cursor, we must verify that the page is @@ -68147,30 +68866,38 @@ static int removeFromSharingList(BtShared *pBt){ ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child ** pointer. */ -static void allocateTempSpace(BtShared *pBt){ - if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); - - /* One of the uses of pBt->pTmpSpace is to format cells before - ** inserting them into a leaf page (function fillInCell()). If - ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes - ** by the various routines that manipulate binary cells. Which - ** can mean that fillInCell() only initializes the first 2 or 3 - ** bytes of pTmpSpace, but that the first 4 bytes are copied from - ** it into a database page. This is not actually a problem, but it - ** does cause a valgrind error when the 1 or 2 bytes of unitialized - ** data is passed to system call write(). So to avoid this error, - ** zero the first 4 bytes of temp space here. - ** - ** Also: Provide four bytes of initialized space before the - ** beginning of pTmpSpace as an area available to prepend the - ** left-child pointer to the beginning of a cell. - */ - if( pBt->pTmpSpace ){ - memset(pBt->pTmpSpace, 0, 8); - pBt->pTmpSpace += 4; - } +static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){ + assert( pBt!=0 ); + assert( pBt->pTmpSpace==0 ); + /* This routine is called only by btreeCursor() when allocating the + ** first write cursor for the BtShared object */ + assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 ); + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); + if( pBt->pTmpSpace==0 ){ + BtCursor *pCur = pBt->pCursor; + pBt->pCursor = pCur->pNext; /* Unlink the cursor */ + memset(pCur, 0, sizeof(*pCur)); + return SQLITE_NOMEM_BKPT; } + + /* One of the uses of pBt->pTmpSpace is to format cells before + ** inserting them into a leaf page (function fillInCell()). If + ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes + ** by the various routines that manipulate binary cells. Which + ** can mean that fillInCell() only initializes the first 2 or 3 + ** bytes of pTmpSpace, but that the first 4 bytes are copied from + ** it into a database page. This is not actually a problem, but it + ** does cause a valgrind error when the 1 or 2 bytes of unitialized + ** data is passed to system call write(). So to avoid this error, + ** zero the first 4 bytes of temp space here. + ** + ** Also: Provide four bytes of initialized space before the + ** beginning of pTmpSpace as an area available to prepend the + ** left-child pointer to the beginning of a cell. + */ + memset(pBt->pTmpSpace, 0, 8); + pBt->pTmpSpace += 4; + return SQLITE_OK; } /* @@ -68549,7 +69276,6 @@ static int lockBtree(BtShared *pBt){ MemPage *pPage1; /* Page 1 of the database file */ u32 nPage; /* Number of pages in the database */ u32 nPageFile = 0; /* Number of pages in the database file */ - u32 nPageHeader; /* Number of pages in the database according to hdr */ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pBt->pPage1==0 ); @@ -68561,7 +69287,7 @@ static int lockBtree(BtShared *pBt){ /* Do some checking to help insure the file we opened really is ** a valid database file. */ - nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); + nPage = get4byte(28+(u8*)pPage1->aData); sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ nPage = nPageFile; @@ -68596,7 +69322,7 @@ static int lockBtree(BtShared *pBt){ goto page1_init_failed; } - /* If the write version is set to 2, this database should be accessed + /* If the read version is set to 2, this database should be accessed ** in WAL mode. If the log is not already open, open it now. Then ** return SQLITE_OK and return without populating BtShared.pPage1. ** The caller detects this and calls this function again. This is @@ -68668,9 +69394,13 @@ static int lockBtree(BtShared *pBt){ pageSize-usableSize); return rc; } - if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ - rc = SQLITE_CORRUPT_BKPT; - goto page1_init_failed; + if( nPage>nPageFile ){ + if( sqlite3WritableSchema(pBt->db)==0 ){ + rc = SQLITE_CORRUPT_BKPT; + goto page1_init_failed; + }else{ + nPage = nPageFile; + } } /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to ** be less than 480. In other words, if the page size is 512, then the @@ -69394,16 +70124,18 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){ /* ** This routine is called prior to sqlite3PagerCommit when a transaction ** is committed for an auto-vacuum database. -** -** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages -** the database file should be truncated to during the commit process. -** i.e. the database has been reorganized so that only the first *pnTrunc -** pages are in use. */ -static int autoVacuumCommit(BtShared *pBt){ +static int autoVacuumCommit(Btree *p){ int rc = SQLITE_OK; - Pager *pPager = pBt->pPager; - VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); ) + Pager *pPager; + BtShared *pBt; + sqlite3 *db; + VVA_ONLY( int nRef ); + + assert( p!=0 ); + pBt = p->pBt; + pPager = pBt->pPager; + VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); ) assert( sqlite3_mutex_held(pBt->mutex) ); invalidateAllOverflowCache(pBt); @@ -69411,6 +70143,7 @@ static int autoVacuumCommit(BtShared *pBt){ if( !pBt->incrVacuum ){ Pgno nFin; /* Number of pages in database after autovacuuming */ Pgno nFree; /* Number of pages on the freelist initially */ + Pgno nVac; /* Number of pages to vacuum */ Pgno iFree; /* The next page to be freed */ Pgno nOrig; /* Database size before freeing */ @@ -69424,18 +70157,42 @@ static int autoVacuumCommit(BtShared *pBt){ } nFree = get4byte(&pBt->pPage1->aData[36]); - nFin = finalDbSize(pBt, nOrig, nFree); + db = p->db; + if( db->xAutovacPages ){ + int iDb; + for(iDb=0; ALWAYS(iDbnDb); iDb++){ + if( db->aDb[iDb].pBt==p ) break; + } + nVac = db->xAutovacPages( + db->pAutovacPagesArg, + db->aDb[iDb].zDbSName, + nOrig, + nFree, + pBt->pageSize + ); + if( nVac>nFree ){ + nVac = nFree; + } + if( nVac==0 ){ + return SQLITE_OK; + } + }else{ + nVac = nFree; + } + nFin = finalDbSize(pBt, nOrig, nVac); if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT; if( nFinnFin && rc==SQLITE_OK; iFree--){ - rc = incrVacuumStep(pBt, nFin, iFree, 1); + rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree); } if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); - put4byte(&pBt->pPage1->aData[32], 0); - put4byte(&pBt->pPage1->aData[36], 0); + if( nVac==nFree ){ + put4byte(&pBt->pPage1->aData[32], 0); + put4byte(&pBt->pPage1->aData[36], 0); + } put4byte(&pBt->pPage1->aData[28], nFin); pBt->bDoTruncate = 1; pBt->nPage = nFin; @@ -69486,7 +70243,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zSuperJrnl){ sqlite3BtreeEnter(p); #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ - rc = autoVacuumCommit(pBt); + rc = autoVacuumCommit(p); if( rc!=SQLITE_OK ){ sqlite3BtreeLeave(p); return rc; @@ -69673,7 +70430,7 @@ static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ int nPage = get4byte(&pPage1->aData[28]); testcase( nPage==0 ); if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); - testcase( pBt->nPage!=nPage ); + testcase( pBt->nPage!=(u32)nPage ); pBt->nPage = nPage; } @@ -69885,10 +70642,6 @@ static int btreeCursor( assert( pBt->pPage1 && pBt->pPage1->aData ); assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 ); - if( wrFlag ){ - allocateTempSpace(pBt); - if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT; - } if( iTable<=1 ){ if( iTable<1 ){ return SQLITE_CORRUPT_BKPT; @@ -69905,19 +70658,25 @@ static int btreeCursor( pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; - pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0; - pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY; + pCur->curFlags = 0; /* If there are two or more cursors on the same btree, then all such ** cursors *must* have the BTCF_Multiple flag set. */ for(pX=pBt->pCursor; pX; pX=pX->pNext){ if( pX->pgnoRoot==iTable ){ pX->curFlags |= BTCF_Multiple; - pCur->curFlags |= BTCF_Multiple; + pCur->curFlags = BTCF_Multiple; } } + pCur->eState = CURSOR_INVALID; pCur->pNext = pBt->pCursor; pBt->pCursor = pCur; - pCur->eState = CURSOR_INVALID; + if( wrFlag ){ + pCur->curFlags |= BTCF_WriteFlag; + pCur->curPagerFlags = 0; + if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt); + }else{ + pCur->curPagerFlags = PAGER_GET_READONLY; + } return SQLITE_OK; } static int btreeCursorWithLock( @@ -70291,7 +71050,9 @@ static int accessPayload( assert( pPage ); assert( eOp==0 || eOp==1 ); assert( pCur->eState==CURSOR_VALID ); - assert( pCur->ixnCell ); + if( pCur->ix>=pPage->nCell ){ + return SQLITE_CORRUPT_PAGE(pPage); + } assert( cursorHoldsMutex(pCur) ); getCellInfo(pCur); @@ -70478,7 +71239,6 @@ SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>=0 && pCur->pPage ); - assert( pCur->ixpPage->nCell ); return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } @@ -70540,7 +71300,7 @@ static const void *fetchPayload( assert( pCur->eState==CURSOR_VALID ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorOwnsBtShared(pCur) ); - assert( pCur->ixpPage->nCell ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); assert( pCur->info.nSize>0 ); assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB ); assert( pCur->info.pPayloadpPage->aDataEnd ||CORRUPT_DB); @@ -70691,7 +71451,7 @@ static int moveToRoot(BtCursor *pCur){ while( --pCur->iPage ){ releasePageNotNull(pCur->apPage[pCur->iPage]); } - pCur->pPage = pCur->apPage[0]; + pRoot = pCur->pPage = pCur->apPage[0]; goto skip_init; } }else if( pCur->pgnoRoot==0 ){ @@ -70716,7 +71476,7 @@ static int moveToRoot(BtCursor *pCur){ pCur->curIntKey = pCur->pPage->intKey; } pRoot = pCur->pPage; - assert( pRoot->pgno==pCur->pgnoRoot ); + assert( pRoot->pgno==pCur->pgnoRoot || CORRUPT_DB ); /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is @@ -70738,7 +71498,6 @@ skip_init: pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); - pRoot = pCur->pPage; if( pRoot->nCell>0 ){ pCur->eState = CURSOR_VALID; }else if( !pRoot->leaf ){ @@ -70873,12 +71632,8 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ return rc; } -/* Move the cursor so that it points to an entry near the key -** specified by pIdxKey or intKey. Return a success code. -** -** For INTKEY tables, the intKey parameter is used. pIdxKey -** must be NULL. For index tables, pIdxKey is used and intKey -** is ignored. +/* Move the cursor so that it points to an entry in a table (a.k.a INTKEY) +** table near the key intKey. Return a success code. ** ** If an exact match is not found, then the cursor is always ** left pointing at a leaf page which would hold the entry if it @@ -70891,39 +71646,32 @@ SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ ** *pRes is as follows: ** ** *pRes<0 The cursor is left pointing at an entry that -** is smaller than intKey/pIdxKey or if the table is empty +** is smaller than intKey or if the table is empty ** and the cursor is therefore left point to nothing. ** ** *pRes==0 The cursor is left pointing at an entry that -** exactly matches intKey/pIdxKey. +** exactly matches intKey. ** ** *pRes>0 The cursor is left pointing at an entry that -** is larger than intKey/pIdxKey. -** -** For index tables, the pIdxKey->eqSeen field is set to 1 if there -** exists an entry in the table that exactly matches pIdxKey. +** is larger than intKey. */ -SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( +SQLITE_PRIVATE int sqlite3BtreeTableMoveto( BtCursor *pCur, /* The cursor to be moved */ - UnpackedRecord *pIdxKey, /* Unpacked index key */ i64 intKey, /* The table key */ int biasRight, /* If true, bias the search to the high end */ int *pRes /* Write search results here */ ){ int rc; - RecordCompare xRecordCompare; assert( cursorOwnsBtShared(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( pRes ); - assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); - assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) ); + assert( pCur->pKeyInfo==0 ); + assert( pCur->eState!=CURSOR_VALID || pCur->curIntKey!=0 ); /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ - if( pIdxKey==0 - && pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 - ){ + if( pCur->eState==CURSOR_VALID && (pCur->curFlags & BTCF_ValidNKey)!=0 ){ if( pCur->info.nKey==intKey ){ *pRes = 0; return SQLITE_OK; @@ -70945,9 +71693,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( if( pCur->info.nKey==intKey ){ return SQLITE_OK; } - }else if( rc==SQLITE_DONE ){ - rc = SQLITE_OK; - }else{ + }else if( rc!=SQLITE_DONE ){ return rc; } } @@ -70958,16 +71704,148 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( pCur->pBtree->nSeek++; /* Performance measurement during testing */ #endif - if( pIdxKey ){ - xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); - pIdxKey->errCode = 0; - assert( pIdxKey->default_rc==1 - || pIdxKey->default_rc==0 - || pIdxKey->default_rc==-1 - ); - }else{ - xRecordCompare = 0; /* All keys are integers */ + rc = moveToRoot(pCur); + if( rc ){ + if( rc==SQLITE_EMPTY ){ + assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + *pRes = -1; + return SQLITE_OK; + } + return rc; } + assert( pCur->pPage ); + assert( pCur->pPage->isInit ); + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->pPage->nCell > 0 ); + assert( pCur->iPage==0 || pCur->apPage[0]->intKey==pCur->curIntKey ); + assert( pCur->curIntKey ); + + for(;;){ + int lwr, upr, idx, c; + Pgno chldPg; + MemPage *pPage = pCur->pPage; + u8 *pCell; /* Pointer to current cell in pPage */ + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey ); + lwr = 0; + upr = pPage->nCell-1; + assert( biasRight==0 || biasRight==1 ); + idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ + for(;;){ + i64 nCellKey; + pCell = findCellPastPtr(pPage, idx); + if( pPage->intKeyLeaf ){ + while( 0x80 <= *(pCell++) ){ + if( pCell>=pPage->aDataEnd ){ + return SQLITE_CORRUPT_PAGE(pPage); + } + } + } + getVarint(pCell, (u64*)&nCellKey); + if( nCellKeyupr ){ c = -1; break; } + }else if( nCellKey>intKey ){ + upr = idx-1; + if( lwr>upr ){ c = +1; break; } + }else{ + assert( nCellKey==intKey ); + pCur->ix = (u16)idx; + if( !pPage->leaf ){ + lwr = idx; + goto moveto_table_next_layer; + }else{ + pCur->curFlags |= BTCF_ValidNKey; + pCur->info.nKey = nCellKey; + pCur->info.nSize = 0; + *pRes = 0; + return SQLITE_OK; + } + } + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ + } + assert( lwr==upr+1 || !pPage->leaf ); + assert( pPage->isInit ); + if( pPage->leaf ){ + assert( pCur->ixpPage->nCell ); + pCur->ix = (u16)idx; + *pRes = c; + rc = SQLITE_OK; + goto moveto_table_finish; + } +moveto_table_next_layer: + if( lwr>=pPage->nCell ){ + chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); + }else{ + chldPg = get4byte(findCell(pPage, lwr)); + } + pCur->ix = (u16)lwr; + rc = moveToChild(pCur, chldPg); + if( rc ) break; + } +moveto_table_finish: + pCur->info.nSize = 0; + assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); + return rc; +} + +/* Move the cursor so that it points to an entry in an index table +** near the key pIdxKey. Return a success code. +** +** If an exact match is not found, then the cursor is always +** left pointing at a leaf page which would hold the entry if it +** were present. The cursor might point to an entry that comes +** before or after the key. +** +** An integer is written into *pRes which is the result of +** comparing the key with the entry to which the cursor is +** pointing. The meaning of the integer written into +** *pRes is as follows: +** +** *pRes<0 The cursor is left pointing at an entry that +** is smaller than pIdxKey or if the table is empty +** and the cursor is therefore left point to nothing. +** +** *pRes==0 The cursor is left pointing at an entry that +** exactly matches pIdxKey. +** +** *pRes>0 The cursor is left pointing at an entry that +** is larger than pIdxKey. +** +** The pIdxKey->eqSeen field is set to 1 if there +** exists an entry in the table that exactly matches pIdxKey. +*/ +SQLITE_PRIVATE int sqlite3BtreeIndexMoveto( + BtCursor *pCur, /* The cursor to be moved */ + UnpackedRecord *pIdxKey, /* Unpacked index key */ + int *pRes /* Write search results here */ +){ + int rc; + RecordCompare xRecordCompare; + + assert( cursorOwnsBtShared(pCur) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( pCur->pKeyInfo!=0 ); + +#ifdef SQLITE_DEBUG + pCur->pBtree->nSeek++; /* Performance measurement during testing */ +#endif + + xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); + pIdxKey->errCode = 0; + assert( pIdxKey->default_rc==1 + || pIdxKey->default_rc==0 + || pIdxKey->default_rc==-1 + ); rc = moveToRoot(pCur); if( rc ){ @@ -71000,141 +71878,101 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; - assert( biasRight==0 || biasRight==1 ); - idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ - pCur->ix = (u16)idx; - if( xRecordCompare==0 ){ - for(;;){ - i64 nCellKey; - pCell = findCellPastPtr(pPage, idx); - if( pPage->intKeyLeaf ){ - while( 0x80 <= *(pCell++) ){ - if( pCell>=pPage->aDataEnd ){ - return SQLITE_CORRUPT_PAGE(pPage); - } - } - } - getVarint(pCell, (u64*)&nCellKey); - if( nCellKeyupr ){ c = -1; break; } - }else if( nCellKey>intKey ){ - upr = idx-1; - if( lwr>upr ){ c = +1; break; } - }else{ - assert( nCellKey==intKey ); - pCur->ix = (u16)idx; - if( !pPage->leaf ){ - lwr = idx; - goto moveto_next_layer; - }else{ - pCur->curFlags |= BTCF_ValidNKey; - pCur->info.nKey = nCellKey; - pCur->info.nSize = 0; - *pRes = 0; - return SQLITE_OK; - } - } - assert( lwr+upr>=0 ); - idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */ - } - }else{ - for(;;){ - int nCell; /* Size of the pCell cell in bytes */ - pCell = findCellPastPtr(pPage, idx); + idx = upr>>1; /* idx = (lwr+upr)/2; */ + for(;;){ + int nCell; /* Size of the pCell cell in bytes */ + pCell = findCellPastPtr(pPage, idx); - /* The maximum supported page-size is 65536 bytes. This means that - ** the maximum number of record bytes stored on an index B-Tree - ** page is less than 16384 bytes and may be stored as a 2-byte - ** varint. This information is used to attempt to avoid parsing - ** the entire cell by checking for the cases where the record is - ** stored entirely within the b-tree page by inspecting the first - ** 2 bytes of the cell. - */ - nCell = pCell[0]; - if( nCell<=pPage->max1bytePayload ){ - /* This branch runs if the record-size field of the cell is a - ** single byte varint and the record fits entirely on the main - ** b-tree page. */ - testcase( pCell+nCell+1==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); - }else if( !(pCell[1] & 0x80) - && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal - ){ - /* The record-size field is a 2 byte varint and the record - ** fits entirely on the main b-tree page. */ - testcase( pCell+nCell+2==pPage->aDataEnd ); - c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); - }else{ - /* The record flows over onto one or more overflow pages. In - ** this case the whole cell needs to be parsed, a buffer allocated - ** and accessPayload() used to retrieve the record into the - ** buffer before VdbeRecordCompare() can be called. - ** - ** If the record is corrupt, the xRecordCompare routine may read - ** up to two varints past the end of the buffer. An extra 18 - ** bytes of padding is allocated at the end of the buffer in - ** case this happens. */ - void *pCellKey; - u8 * const pCellBody = pCell - pPage->childPtrSize; - const int nOverrun = 18; /* Size of the overrun padding */ - pPage->xParseCell(pPage, pCellBody, &pCur->info); - nCell = (int)pCur->info.nKey; - testcase( nCell<0 ); /* True if key size is 2^32 or more */ - testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */ - testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ - testcase( nCell==2 ); /* Minimum legal index key size */ - if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){ - rc = SQLITE_CORRUPT_PAGE(pPage); - goto moveto_finish; - } - pCellKey = sqlite3Malloc( nCell+nOverrun ); - if( pCellKey==0 ){ - rc = SQLITE_NOMEM_BKPT; - goto moveto_finish; - } - pCur->ix = (u16)idx; - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); - memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */ - pCur->curFlags &= ~BTCF_ValidOvfl; - if( rc ){ - sqlite3_free(pCellKey); - goto moveto_finish; - } - c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + /* The maximum supported page-size is 65536 bytes. This means that + ** the maximum number of record bytes stored on an index B-Tree + ** page is less than 16384 bytes and may be stored as a 2-byte + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first + ** 2 bytes of the cell. + */ + nCell = pCell[0]; + if( nCell<=pPage->max1bytePayload ){ + /* This branch runs if the record-size field of the cell is a + ** single byte varint and the record fits entirely on the main + ** b-tree page. */ + testcase( pCell+nCell+1==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); + }else if( !(pCell[1] & 0x80) + && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal + ){ + /* The record-size field is a 2 byte varint and the record + ** fits entirely on the main b-tree page. */ + testcase( pCell+nCell+2==pPage->aDataEnd ); + c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); + }else{ + /* The record flows over onto one or more overflow pages. In + ** this case the whole cell needs to be parsed, a buffer allocated + ** and accessPayload() used to retrieve the record into the + ** buffer before VdbeRecordCompare() can be called. + ** + ** If the record is corrupt, the xRecordCompare routine may read + ** up to two varints past the end of the buffer. An extra 18 + ** bytes of padding is allocated at the end of the buffer in + ** case this happens. */ + void *pCellKey; + u8 * const pCellBody = pCell - pPage->childPtrSize; + const int nOverrun = 18; /* Size of the overrun padding */ + pPage->xParseCell(pPage, pCellBody, &pCur->info); + nCell = (int)pCur->info.nKey; + testcase( nCell<0 ); /* True if key size is 2^32 or more */ + testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */ + testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */ + testcase( nCell==2 ); /* Minimum legal index key size */ + if( nCell<2 || nCell/pCur->pBt->usableSize>pCur->pBt->nPage ){ + rc = SQLITE_CORRUPT_PAGE(pPage); + goto moveto_index_finish; + } + pCellKey = sqlite3Malloc( nCell+nOverrun ); + if( pCellKey==0 ){ + rc = SQLITE_NOMEM_BKPT; + goto moveto_index_finish; + } + pCur->ix = (u16)idx; + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */ + pCur->curFlags &= ~BTCF_ValidOvfl; + if( rc ){ sqlite3_free(pCellKey); + goto moveto_index_finish; } - assert( - (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) - && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) - ); - if( c<0 ){ - lwr = idx+1; - }else if( c>0 ){ - upr = idx-1; - }else{ - assert( c==0 ); - *pRes = 0; - rc = SQLITE_OK; - pCur->ix = (u16)idx; - if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT; - goto moveto_finish; - } - if( lwr>upr ) break; - assert( lwr+upr>=0 ); - idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ + c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); } + assert( + (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) + && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) + ); + if( c<0 ){ + lwr = idx+1; + }else if( c>0 ){ + upr = idx-1; + }else{ + assert( c==0 ); + *pRes = 0; + rc = SQLITE_OK; + pCur->ix = (u16)idx; + if( pIdxKey->errCode ) rc = SQLITE_CORRUPT_BKPT; + goto moveto_index_finish; + } + if( lwr>upr ) break; + assert( lwr+upr>=0 ); + idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */ } assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) ); assert( pPage->isInit ); if( pPage->leaf ){ - assert( pCur->ixpPage->nCell ); + assert( pCur->ixpPage->nCell || CORRUPT_DB ); pCur->ix = (u16)idx; *pRes = c; rc = SQLITE_OK; - goto moveto_finish; + goto moveto_index_finish; } -moveto_next_layer: if( lwr>=pPage->nCell ){ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]); }else{ @@ -71144,7 +71982,7 @@ moveto_next_layer: rc = moveToChild(pCur, chldPg); if( rc ) break; } -moveto_finish: +moveto_index_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); return rc; @@ -71245,16 +72083,6 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ return SQLITE_CORRUPT_BKPT; } - /* If the database file is corrupt, it is possible for the value of idx - ** to be invalid here. This can only occur if a second cursor modifies - ** the page while cursor pCur is holding a reference to it. Which can - ** only happen if the database is corrupt in such a way as to link the - ** page into more than one b-tree structure. - ** - ** Update 2019-12-23: appears to long longer be possible after the - ** addition of anotherValidCursor() condition on balance_deeper(). */ - harmless( idx>pPage->nCell ); - if( idx>=pPage->nCell ){ if( !pPage->leaf ){ rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8])); @@ -72166,16 +72994,24 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ if( *pRC ) return; - assert( idx>=0 && idxnCell ); + assert( idx>=0 ); + assert( idxnCell ); assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->nFree>=0 ); data = pPage->aData; ptr = &pPage->aCellIdx[2*idx]; + assert( pPage->pBt->usableSize > (u32)(ptr-data) ); pc = get2byte(ptr); hdr = pPage->hdrOffset; - testcase( pc==get2byte(&data[hdr+5]) ); +#if 0 /* Not required. Omit for efficiency */ + if( pcnCell*2 ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; + } +#endif + testcase( pc==(u32)get2byte(&data[hdr+5]) ); testcase( pc+sz==pPage->pBt->usableSize ); if( pc+sz > pPage->pBt->usableSize ){ *pRC = SQLITE_CORRUPT_BKPT; @@ -72467,7 +73303,7 @@ static int rebuildPage( assert( i(u32)usableSize) ){ j = 0; } + if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kpPg->aDataEnd ) goto editpage_fail; /* Add cells to the start of the page */ if( iNewpBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); @@ -73128,6 +73964,7 @@ static int balance_nonroot( goto balance_cleanup; } } + nMaxCells += apOld[i]->nCell + ArraySize(pParent->apOvfl); if( (i--)==0 ) break; if( pParent->nOverflow && i+nxDiv==pParent->aiOvfl[0] ){ @@ -73169,7 +74006,6 @@ static int balance_nonroot( /* Make nMaxCells a multiple of 4 in order to preserve 8-byte ** alignment */ - nMaxCells = nOld*(MX_CELL(pBt) + ArraySize(pParent->apOvfl)); nMaxCells = (nMaxCells + 3)&~3; /* @@ -73452,7 +74288,9 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; - if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){ + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) + && rc==SQLITE_OK + ){ rc = SQLITE_CORRUPT_BKPT; } if( rc ) goto balance_cleanup; @@ -73653,7 +74491,7 @@ static int balance_nonroot( iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; b.ixNx[k]<=i && ALWAYS(kpDbPage)!=1 ){ + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){ rc = SQLITE_CORRUPT_BKPT; }else{ if( iOffset+ovflPageSize<(u32)nTotal ){ @@ -74169,24 +75007,6 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); - if( pCur->eState==CURSOR_FAULT ){ - assert( pCur->skipNext!=SQLITE_OK ); - return pCur->skipNext; - } - - assert( cursorOwnsBtShared(pCur) ); - assert( (pCur->curFlags & BTCF_WriteFlag)!=0 - && pBt->inTransaction==TRANS_WRITE - && (pBt->btsFlags & BTS_READ_ONLY)==0 ); - assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); - - /* Assert that the caller has been consistent. If this cursor was opened - ** expecting an index b-tree, then the caller should be inserting blob - ** keys with no associated data. If the cursor was opened expecting an - ** intkey table, the caller should be inserting integer keys with a - ** blob of associated data. */ - assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); - /* Save the positions of any other cursors open on this table. ** ** In some cases, the call to btreeMoveto() below is a no-op. For @@ -74211,6 +75031,24 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( } } + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = moveToRoot(pCur); + if( rc && rc!=SQLITE_EMPTY ) return rc; + } + + assert( cursorOwnsBtShared(pCur) ); + assert( (pCur->curFlags & BTCF_WriteFlag)!=0 + && pBt->inTransaction==TRANS_WRITE + && (pBt->btsFlags & BTS_READ_ONLY)==0 ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); + if( pCur->pKeyInfo==0 ){ assert( pX->pKey==0 ); /* If this is an insert into a table b-tree, invalidate any incrblob @@ -74250,7 +75088,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** to an adjacent cell. Move the cursor so that it is pointing either ** to the cell to be overwritten or an adjacent cell. */ - rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); + rc = sqlite3BtreeTableMoveto(pCur, pX->nKey, + (flags & BTREE_APPEND)!=0, &loc); if( rc ) return rc; } }else{ @@ -74273,13 +75112,11 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( r.aMem = pX->aMem; r.nField = pX->nMem; r.default_rc = 0; - r.errCode = 0; - r.r1 = 0; - r.r2 = 0; r.eqSeen = 0; - rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); + rc = sqlite3BtreeIndexMoveto(pCur, &r, &loc); }else{ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, + (flags & BTREE_APPEND)!=0, &loc); } if( rc ) return rc; } @@ -74300,14 +75137,13 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( } } assert( pCur->eState==CURSOR_VALID - || (pCur->eState==CURSOR_INVALID && loc) - || CORRUPT_DB ); + || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->pPage; assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ - if( NEVER(pCur->eState>CURSOR_INVALID) ){ + if( pCur->eState>CURSOR_INVALID ){ rc = SQLITE_CORRUPT_BKPT; }else{ rc = btreeComputeFreeSpace(pPage); @@ -74342,7 +75178,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( idx = pCur->ix; if( loc==0 ){ CellInfo info; - assert( idxnCell ); + assert( idx>=0 ); + if( idx>=pPage->nCell ){ + return SQLITE_CORRUPT_BKPT; + } rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ goto end_insert; @@ -74524,7 +75363,7 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 } }while( rc==SQLITE_OK && nOut>0 ); - if( rc==SQLITE_OK && nRem>0 ){ + if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ Pgno pgnoNew; MemPage *pNew = 0; rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); @@ -74570,14 +75409,13 @@ SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; - int rc; /* Return code */ - MemPage *pPage; /* Page to delete cell from */ - unsigned char *pCell; /* Pointer to cell to delete */ - int iCellIdx; /* Index of cell to delete */ - int iCellDepth; /* Depth of node containing pCell */ - CellInfo info; /* Size of the cell being deleted */ - int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ - u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ + CellInfo info; /* Size of the cell being deleted */ + u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */ assert( cursorOwnsBtShared(pCur) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -74586,28 +75424,45 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); assert( !hasReadConflicts(p, pCur->pgnoRoot) ); assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 ); - if( pCur->eState==CURSOR_REQUIRESEEK ){ - rc = btreeRestoreCursorPosition(pCur); - assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); - if( rc || pCur->eState!=CURSOR_VALID ) return rc; + if( pCur->eState!=CURSOR_VALID ){ + if( pCur->eState>=CURSOR_REQUIRESEEK ){ + rc = btreeRestoreCursorPosition(pCur); + assert( rc!=SQLITE_OK || CORRUPT_DB || pCur->eState==CURSOR_VALID ); + if( rc || pCur->eState!=CURSOR_VALID ) return rc; + }else{ + return SQLITE_CORRUPT_BKPT; + } } - assert( CORRUPT_DB || pCur->eState==CURSOR_VALID ); + assert( pCur->eState==CURSOR_VALID ); iCellDepth = pCur->iPage; iCellIdx = pCur->ix; pPage = pCur->pPage; + if( pPage->nCell<=iCellIdx ){ + return SQLITE_CORRUPT_BKPT; + } pCell = findCell(pPage, iCellIdx); - if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT; + if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ + return SQLITE_CORRUPT_BKPT; + } - /* If the bPreserve flag is set to true, then the cursor position must + /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must ** be preserved following this delete operation. If the current delete ** will cause a b-tree rebalance, then this is done by saving the cursor ** key and leaving the cursor in CURSOR_REQUIRESEEK state before ** returning. ** - ** Or, if the current delete will not cause a rebalance, then the cursor + ** If the current delete will not cause a rebalance, then the cursor ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately - ** before or after the deleted entry. In this case set bSkipnext to true. */ + ** before or after the deleted entry. + ** + ** The bPreserve value records which path is required: + ** + ** bPreserve==0 Not necessary to save the cursor position + ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position + ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. + */ + bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ if( !pPage->leaf || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) @@ -74618,7 +75473,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ rc = saveCursorKey(pCur); if( rc ) return rc; }else{ - bSkipnext = 1; + bPreserve = 2; } } @@ -74718,8 +75573,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ } if( rc==SQLITE_OK ){ - if( bSkipnext ){ - assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); + if( bPreserve>1 ){ + assert( (pCur->iPage==iCellDepth || CORRUPT_DB) ); assert( pPage==pCur->pPage || CORRUPT_DB ); assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); pCur->eState = CURSOR_SKIPNEXT; @@ -74913,7 +75768,7 @@ static int clearDatabasePage( BtShared *pBt, /* The BTree that contains the table */ Pgno pgno, /* Page number to clear */ int freePageFlag, /* Deallocate page if true */ - int *pnChange /* Add number of Cells freed to this counter */ + i64 *pnChange /* Add number of Cells freed to this counter */ ){ MemPage *pPage; int rc; @@ -74928,11 +75783,12 @@ static int clearDatabasePage( } rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); if( rc ) return rc; - if( pPage->bBusy ){ + if( (pBt->openFlags & BTREE_SINGLE)==0 + && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) + ){ rc = SQLITE_CORRUPT_BKPT; goto cleardatabasepage_out; } - pPage->bBusy = 1; hdr = pPage->hdrOffset; for(i=0; inCell; i++){ pCell = findCell(pPage, i); @@ -74946,6 +75802,7 @@ static int clearDatabasePage( if( !pPage->leaf ){ rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange); if( rc ) goto cleardatabasepage_out; + if( pPage->intKey ) pnChange = 0; } if( pnChange ){ testcase( !pPage->intKey ); @@ -74958,7 +75815,6 @@ static int clearDatabasePage( } cleardatabasepage_out: - pPage->bBusy = 0; releasePage(pPage); return rc; } @@ -74975,7 +75831,7 @@ cleardatabasepage_out: ** If pnChange is not NULL, then the integer value pointed to by pnChange ** is incremented by the number of entries in the table. */ -SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, i64 *pnChange){ int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); @@ -75037,10 +75893,10 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ return SQLITE_CORRUPT_BKPT; } - rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); - if( rc ) return rc; rc = sqlite3BtreeClearTable(p, iTable, 0); - if( rc ){ + if( rc ) return rc; + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + if( NEVER(rc) ){ releasePage(pPage); return rc; } @@ -76308,14 +77164,13 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ if( i==1 ){ Parse sParse; int rc = 0; - memset(&sParse, 0, sizeof(sParse)); - sParse.db = pDb; + sqlite3ParseObjectInit(&sParse,pDb); if( sqlite3OpenTempDatabase(&sParse) ){ sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); rc = SQLITE_ERROR; } sqlite3DbFree(pErrorDb, sParse.zErrMsg); - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); if( rc ){ return 0; } @@ -77197,10 +78052,15 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ #ifndef SQLITE_OMIT_UTF16 int rc; #endif + assert( pMem!=0 ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); - if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ + if( !(pMem->flags&MEM_Str) ){ + pMem->enc = desiredEnc; + return SQLITE_OK; + } + if( pMem->enc==desiredEnc ){ return SQLITE_OK; } assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -77329,6 +78189,7 @@ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ @@ -77353,6 +78214,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ #ifndef SQLITE_OMIT_INCRBLOB SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ int nByte; + assert( pMem!=0 ); assert( pMem->flags & MEM_Zero ); assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) ); testcase( sqlite3_value_nochange(pMem) ); @@ -77368,6 +78230,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ return SQLITE_NOMEM_BKPT; } + assert( pMem->z!=0 ); + assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte ); memset(&pMem->z[pMem->n], 0, pMem->u.nZero); pMem->n += pMem->u.nZero; @@ -77380,6 +78244,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ ** Make sure the given Mem is \u0000 terminated. */ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); @@ -77407,6 +78272,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ const int nByte = 32; + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !(pMem->flags&MEM_Zero) ); assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); @@ -77442,6 +78308,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ sqlite3_context ctx; Mem t; assert( pFunc!=0 ); + assert( pMem!=0 ); assert( pFunc->xFinalize!=0 ); assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -77585,13 +78452,14 @@ static SQLITE_NOINLINE i64 doubleToInt64(double r){ ** ** If pMem represents a string value, its encoding might be changed. */ -static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){ +static SQLITE_NOINLINE i64 memIntValue(const Mem *pMem){ i64 value = 0; sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); return value; } -SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){ int flags; + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); flags = pMem->flags; @@ -77620,6 +78488,7 @@ static SQLITE_NOINLINE double memRealValue(Mem *pMem){ return val; } SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ @@ -77652,6 +78521,7 @@ SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ */ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ i64 ix; + assert( pMem!=0 ); assert( pMem->flags & MEM_Real ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -77679,6 +78549,7 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ ** Convert pMem to type integer. Invalidate any prior representations. */ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -77693,6 +78564,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ ** Invalidate any prior representations. */ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); @@ -77726,6 +78598,7 @@ SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ ** as much of the string as we can and ignore the rest. */ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ + assert( pMem!=0 ); testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_Real ); testcase( pMem->flags & MEM_IntReal ); @@ -77835,6 +78708,7 @@ SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){ ** Delete any previous value and set the value to be a BLOB of length ** n containing all zeros. */ +#ifndef SQLITE_OMIT_INCRBLOB SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Blob|MEM_Zero; @@ -77844,6 +78718,21 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ pMem->enc = SQLITE_UTF8; pMem->z = 0; } +#else +SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + int nByte = n>0?n:1; + if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){ + return SQLITE_NOMEM_BKPT; + } + assert( pMem->z!=0 ); + assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte ); + memset(pMem->z, 0, nByte); + pMem->n = n>0?n:0; + pMem->flags = MEM_Blob; + pMem->enc = SQLITE_UTF8; + return SQLITE_OK; +} +#endif /* ** The pMem is known to contain content that needs to be destroyed prior @@ -77883,6 +78772,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( void (*xDestructor)(void*) ){ assert( pMem->flags==MEM_Null ); + vdbeMemClear(pMem); pMem->u.zPType = zPType ? zPType : ""; pMem->z = pPtr; pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; @@ -78077,6 +78967,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( int iLimit; /* Maximum allowed string or blob size */ u16 flags = 0; /* New value for pMem->flags */ + assert( pMem!=0 ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !sqlite3VdbeMemIsRowSet(pMem) ); @@ -78385,7 +79276,7 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ #ifdef SQLITE_ENABLE_STAT4 static int valueFromFunction( sqlite3 *db, /* The database connection */ - Expr *p, /* The expression to evaluate */ + const Expr *p, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 aff, /* Affinity to use */ sqlite3_value **ppVal, /* Write the new value here */ @@ -78402,8 +79293,10 @@ static int valueFromFunction( assert( pCtx!=0 ); assert( (p->flags & EP_TokenOnly)==0 ); + assert( ExprUseXList(p) ); pList = p->x.pList; if( pList ) nVal = pList->nExpr; + assert( !ExprHasProperty(p, EP_IntValue) ); pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 @@ -78479,7 +79372,7 @@ static int valueFromFunction( */ static int valueFromExpr( sqlite3 *db, /* The database connection */ - Expr *pExpr, /* The expression to evaluate */ + const Expr *pExpr, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal, /* Write the new value here */ @@ -78494,11 +79387,7 @@ static int valueFromExpr( assert( pExpr!=0 ); while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft; -#if defined(SQLITE_ENABLE_STAT4) if( op==TK_REGISTER ) op = pExpr->op2; -#else - if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; -#endif /* Compressed expressions only appear when parsing the DEFAULT clause ** on a table column definition, and hence only when pCtx==0. This @@ -78507,7 +79396,9 @@ static int valueFromExpr( assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 ); if( op==TK_CAST ){ - u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); + u8 aff; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + aff = sqlite3AffinityType(pExpr->u.zToken,0); rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); testcase( rc!=SQLITE_OK ); if( *ppVal ){ @@ -78580,6 +79471,7 @@ static int valueFromExpr( #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ int nVal; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); assert( pExpr->u.zToken[1]=='\'' ); pVal = valueNew(db, pCtx); @@ -78597,6 +79489,7 @@ static int valueFromExpr( } #endif else if( op==TK_TRUEFALSE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); pVal = valueNew(db, pCtx); if( pVal ){ pVal->flags = MEM_Int; @@ -78609,7 +79502,7 @@ static int valueFromExpr( no_mem: #ifdef SQLITE_ENABLE_STAT4 - if( pCtx==0 || pCtx->pParse->nErr==0 ) + if( pCtx==0 || NEVER(pCtx->pParse->nErr==0) ) #endif sqlite3OomFault(db); sqlite3DbFree(db, zVal); @@ -78634,7 +79527,7 @@ no_mem: */ SQLITE_PRIVATE int sqlite3ValueFromExpr( sqlite3 *db, /* The database connection */ - Expr *pExpr, /* The expression to evaluate */ + const Expr *pExpr, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ sqlite3_value **ppVal /* Write the new value here */ @@ -79150,8 +80043,10 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); } + assert( p->aOp!=0 ); p->nOp++; pOp = &p->aOp[i]; + assert( pOp!=0 ); pOp->opcode = (u8)op; pOp->p5 = 0; pOp->p1 = p1; @@ -80285,8 +81180,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ */ static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ assert( p->nOp>0 || p->aOp==0 ); - assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed - || p->pParse->nErr>0 ); + assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->pParse->nErr>0 ); if( p->nOp ){ assert( p->aOp ); sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); @@ -80394,7 +81288,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayComment( if( zOpName[nOpName+1] ){ int seenCom = 0; char c; - zSynopsis = zOpName += nOpName + 1; + zSynopsis = zOpName + nOpName + 1; if( strncmp(zSynopsis,"IF ",3)==0 ){ sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); zSynopsis = zAlt; @@ -80467,6 +81361,7 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){ const char *zOp = 0; switch( pExpr->op ){ case TK_STRING: + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3_str_appendf(p, "%Q", pExpr->u.zToken); break; case TK_INTEGER: @@ -80569,7 +81464,7 @@ SQLITE_PRIVATE char *sqlite3VdbeDisplayP4(sqlite3 *db, Op *pOp){ case P4_COLLSEQ: { static const char *const encnames[] = {"?", "8", "16LE", "16BE"}; CollSeq *pColl = pOp->p4.pColl; - assert( pColl->enc>=0 && pColl->enc<4 ); + assert( pColl->enc<4 ); sqlite3_str_appendf(&x, "%.18s-%s", pColl->zName, encnames[pColl->enc]); break; @@ -80813,8 +81708,8 @@ static void releaseMemArray(Mem *p, int N){ */ testcase( p->flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); - testcase( p->xDel==sqlite3VdbeFrameMemDel ); if( p->flags&(MEM_Agg|MEM_Dyn) ){ + testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel ); sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ sqlite3DbFreeNN(db, p->zMalloc); @@ -81376,8 +82271,6 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } - assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); - assert( pCx->pBtx==0 || pCx->isEphemeral ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); @@ -81914,9 +82807,9 @@ SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ ** has made changes and is in autocommit mode, then commit those ** changes. If a rollback is needed, then do the rollback. ** -** This routine is the only way to move the state of a VM from -** SQLITE_MAGIC_RUN to SQLITE_MAGIC_HALT. It is harmless to -** call this on a VM that is in the SQLITE_MAGIC_HALT state. +** This routine is the only way to move the sqlite3eOpenState of a VM from +** SQLITE_STATE_RUN to SQLITE_STATE_HALT. It is harmless to +** call this on a VM that is in the SQLITE_STATE_HALT state. ** ** Return an error code. If the commit could not complete because of ** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it @@ -81962,9 +82855,15 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ sqlite3VdbeEnter(p); /* Check for one of the special errors */ - mrc = p->rc & 0xff; - isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR - || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; + if( p->rc ){ + mrc = p->rc & 0xff; + isSpecialError = mrc==SQLITE_NOMEM + || mrc==SQLITE_IOERR + || mrc==SQLITE_INTERRUPT + || mrc==SQLITE_FULL; + }else{ + mrc = isSpecialError = 0; + } if( isSpecialError ){ /* If the query was read-only and the error code is SQLITE_INTERRUPT, ** no rollback is necessary. Otherwise, at least a savepoint @@ -82016,6 +82915,9 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ return SQLITE_ERROR; } rc = SQLITE_CONSTRAINT_FOREIGNKEY; + }else if( db->flags & SQLITE_CorruptRdOnly ){ + rc = SQLITE_CORRUPT; + db->flags &= ~SQLITE_CorruptRdOnly; }else{ /* The auto-commit flag is true, the vdbe program was successful ** or hit an 'OR FAIL' constraint and there are no deferred foreign @@ -82149,6 +83051,7 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ sqlite3ValueSetNull(db->pErr); } db->errCode = rc; + db->errByteOffset = -1; return rc; } @@ -82410,7 +83313,7 @@ SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){ assert( p->deferredMoveto ); assert( p->isTable ); assert( p->eCurType==CURTYPE_BTREE ); - rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res); + rc = sqlite3BtreeTableMoveto(p->uc.pCursor, p->movetoTarget, 0, &res); if( rc ) return rc; if( res!=0 ) return SQLITE_CORRUPT_BKPT; #ifdef SQLITE_TEST @@ -82470,7 +83373,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ if( p->deferredMoveto ){ u32 iMap; assert( !p->isEphemeral ); - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ + if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; return SQLITE_OK; @@ -82748,14 +83651,14 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ /* ** Deserialize the data blob pointed to by buf as serial type serial_type -** and store the result in pMem. Return the number of bytes read. +** and store the result in pMem. ** ** This function is implemented as two separate routines for performance. ** The few cases that require local variables are broken out into a separate ** routine so that in most cases the overhead of moving the stack pointer ** is avoided. */ -static u32 serialGet( +static void serialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ @@ -82789,9 +83692,8 @@ static u32 serialGet( memcpy(&pMem->u.r, &x, sizeof(x)); pMem->flags = IsNaN(x) ? MEM_Null : MEM_Real; } - return 8; } -SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( +SQLITE_PRIVATE void sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ @@ -82802,13 +83704,13 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->flags = MEM_Null|MEM_Zero; pMem->n = 0; pMem->u.nZero = 0; - break; + return; } case 11: /* Reserved for future use */ case 0: { /* Null */ /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */ pMem->flags = MEM_Null; - break; + return; } case 1: { /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement @@ -82816,7 +83718,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = ONE_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 1; + return; } case 2: { /* 2-byte signed integer */ /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit @@ -82824,7 +83726,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = TWO_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 2; + return; } case 3: { /* 3-byte signed integer */ /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit @@ -82832,7 +83734,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = THREE_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 3; + return; } case 4: { /* 4-byte signed integer */ /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit @@ -82844,7 +83746,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( #endif pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 4; + return; } case 5: { /* 6-byte signed integer */ /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit @@ -82852,13 +83754,14 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf); pMem->flags = MEM_Int; testcase( pMem->u.i<0 ); - return 6; + return; } case 6: /* 8-byte signed integer */ case 7: { /* IEEE floating point */ /* These use local variables, so do them in a separate routine ** to avoid having to move the frame pointer in the common case */ - return serialGet(buf,serial_type,pMem); + serialGet(buf,serial_type,pMem); + return; } case 8: /* Integer 0 */ case 9: { /* Integer 1 */ @@ -82866,7 +83769,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */ pMem->u.i = serial_type-8; pMem->flags = MEM_Int; - return 0; + return; } default: { /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in @@ -82877,10 +83780,10 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( pMem->z = (char *)buf; pMem->n = (serial_type-12)/2; pMem->flags = aFlag[serial_type&1]; - return pMem->n; + return; } } - return 0; + return; } /* ** This routine is used to allocate sufficient space for an UnpackedRecord @@ -82943,7 +83846,8 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->szMalloc = 0; pMem->z = 0; - d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + d += sqlite3VdbeSerialTypeLen(serial_type); pMem++; if( (++u)>=p->nField ) break; } @@ -83027,7 +83931,8 @@ static int vdbeRecordCompareDebug( /* Extract the values to be compared. */ - d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + d1 += sqlite3VdbeSerialTypeLen(serial_type1); /* Do the comparison */ @@ -83194,7 +84099,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem ** number. Return negative, zero, or positive if the first (i64) is less than, ** equal to, or greater than the second (double). */ -static int sqlite3IntFloatCompare(i64 i, double r){ +SQLITE_PRIVATE int sqlite3IntFloatCompare(i64 i, double r){ if( sizeof(LONGDOUBLE_TYPE)>8 ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; testcase( x0x7fffffff ); assert( m.n>=0 ); if( unlikely(szHdr<3 || szHdr>(unsigned)m.n) ){ @@ -83918,7 +84823,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare( ** This routine sets the value to be returned by subsequent calls to ** sqlite3_changes() on the database handle 'db'. */ -SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, i64 nChange){ assert( sqlite3_mutex_held(db->mutex) ); db->nChange = nChange; db->nTotalChange += nChange; @@ -84120,6 +85025,8 @@ SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( } } + assert( pCsr!=0 ); + assert( pCsr->eCurType==CURTYPE_BTREE ); assert( pCsr->nField==pTab->nCol || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1) ); @@ -84519,8 +85426,8 @@ SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ ** the function result. ** ** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the -** result as a string or blob but if the string or blob is too large, it -** then sets the error code to SQLITE_TOOBIG +** result as a string or blob. Appropriate errors are set if the string/blob +** is too big or if an OOM occurs. ** ** The invokeValueDestructor(P,X) routine invokes destructor function X() ** on value P is not going to be used and need to be destroyed. @@ -84532,8 +85439,16 @@ static void setResultStrOrError( u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ - if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){ - sqlite3_result_error_toobig(pCtx); + int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel); + if( rc ){ + if( rc==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); + }else{ + /* The only errors possible from sqlite3VdbeMemSetStr are + ** SQLITE_TOOBIG and SQLITE_NOMEM */ + assert( rc==SQLITE_NOMEM ); + sqlite3_result_error_nomem(pCtx); + } } } static int invokeValueDestructor( @@ -84690,8 +85605,12 @@ SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ return SQLITE_TOOBIG; } +#ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); return SQLITE_OK; +#else + return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); +#endif } SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ pCtx->isError = errCode ? errCode : -1; @@ -84991,6 +85910,70 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ return sqlite3_value_nochange(p->pOut); } +/* +** Implementation of sqlite3_vtab_in_first() (if bNext==0) and +** sqlite3_vtab_in_next() (if bNext!=0). +*/ +static int valueFromValueList( + sqlite3_value *pVal, /* Pointer to the ValueList object */ + sqlite3_value **ppOut, /* Store the next value from the list here */ + int bNext /* 1 for _next(). 0 for _first() */ +){ + int rc; + ValueList *pRhs; + + *ppOut = 0; + if( pVal==0 ) return SQLITE_MISUSE; + pRhs = (ValueList*)sqlite3_value_pointer(pVal, "ValueList"); + if( pRhs==0 ) return SQLITE_MISUSE; + if( bNext ){ + rc = sqlite3BtreeNext(pRhs->pCsr, 0); + }else{ + int dummy = 0; + rc = sqlite3BtreeFirst(pRhs->pCsr, &dummy); + assert( rc==SQLITE_OK || sqlite3BtreeEof(pRhs->pCsr) ); + if( sqlite3BtreeEof(pRhs->pCsr) ) rc = SQLITE_DONE; + } + if( rc==SQLITE_OK ){ + u32 sz; /* Size of current row in bytes */ + Mem sMem; /* Raw content of current row */ + memset(&sMem, 0, sizeof(sMem)); + sz = sqlite3BtreePayloadSize(pRhs->pCsr); + rc = sqlite3VdbeMemFromBtreeZeroOffset(pRhs->pCsr,(int)sz,&sMem); + if( rc==SQLITE_OK ){ + u8 *zBuf = (u8*)sMem.z; + u32 iSerial; + sqlite3_value *pOut = pRhs->pOut; + int iOff = 1 + getVarint32(&zBuf[1], iSerial); + sqlite3VdbeSerialGet(&zBuf[iOff], iSerial, pOut); + pOut->enc = ENC(pOut->db); + if( (pOut->flags & MEM_Ephem)!=0 && sqlite3VdbeMemMakeWriteable(pOut) ){ + rc = SQLITE_NOMEM; + }else{ + *ppOut = pOut; + } + } + sqlite3VdbeMemRelease(&sMem); + } + return rc; +} + +/* +** Set the iterator value pVal to point to the first value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 0); +} + +/* +** Set the iterator value pVal to point to the next value in the set. +** Set (*ppOut) to point to this value before returning. +*/ +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut){ + return valueFromValueList(pVal, ppOut, 1); +} + /* ** Return the current time for a statement. If the current time ** is requested more than once within the same run of a single prepared @@ -85675,7 +86658,10 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu break; } case SQLITE_FLOAT: { - rc = sqlite3_bind_double(pStmt, i, pValue->u.r); + assert( pValue->flags & (MEM_Real|MEM_IntReal) ); + rc = sqlite3_bind_double(pStmt, i, + (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i + ); break; } case SQLITE_BLOB: { @@ -85703,7 +86689,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ +#ifndef SQLITE_OMIT_INCRBLOB sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); +#else + rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); +#endif sqlite3_mutex_leave(p->db->mutex); } return rc; @@ -85991,6 +86981,7 @@ SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppVa u32 nRec; u8 *aRec; + assert( p->pCsr->eCurType==CURTYPE_BTREE ); nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); aRec = sqlite3DbMallocRaw(db, nRec); if( !aRec ) goto preupdate_old_out; @@ -86298,11 +87289,9 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( #ifndef SQLITE_OMIT_UTF16 Mem utf8; /* Used to convert UTF16 into UTF8 for display */ #endif - char zBase[100]; /* Initial working space */ db = p->db; - sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), - db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3StrAccumInit(&out, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); if( db->nVdbeExec>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; @@ -86652,7 +87641,6 @@ static VdbeCursor *allocateCursor( Vdbe *p, /* The virtual machine */ int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ - int iDb, /* Database the cursor belongs to, or -1 */ u8 eCurType /* Type of the new cursor */ ){ /* Find the memory cell that will be used to store the blob of memory @@ -86709,7 +87697,6 @@ static VdbeCursor *allocateCursor( p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); pCx->eCurType = eCurType; - pCx->iDb = iDb; pCx->nField = nField; pCx->aOffset = &pCx->aType[nField]; if( eCurType==CURTYPE_BTREE ){ @@ -87035,96 +88022,7 @@ SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){ ** hwtime.h contains inline assembler code for implementing ** high-performance timing routines. */ -/************** Include hwtime.h in the middle of vdbe.c *********************/ -/************** Begin file hwtime.h ******************************************/ -/* -** 2008 May 27 -** -** The author disclaims copyright to this source code. In place of -** a legal notice, here is a blessing: -** -** May you do good and not evil. -** May you find forgiveness for yourself and forgive others. -** May you share freely, never taking more than you give. -** -****************************************************************************** -** -** This file contains inline asm code for retrieving "high-performance" -** counters for x86 and x86_64 class CPUs. -*/ -#ifndef SQLITE_HWTIME_H -#define SQLITE_HWTIME_H - -/* -** The following routine only works on pentium-class (or newer) processors. -** It uses the RDTSC opcode to read the cycle count value out of the -** processor and returns that value. This can be used for high-res -** profiling. -*/ -#if !defined(__STRICT_ANSI__) && \ - (defined(__GNUC__) || defined(_MSC_VER)) && \ - (defined(i386) || defined(__i386__) || defined(_M_IX86)) - - #if defined(__GNUC__) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned int lo, hi; - __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); - return (sqlite_uint64)hi << 32 | lo; - } - - #elif defined(_MSC_VER) - - __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ - __asm { - rdtsc - ret ; return value at EDX:EAX - } - } - - #endif - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long val; - __asm__ __volatile__ ("rdtsc" : "=A" (val)); - return val; - } - -#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - - __inline__ sqlite_uint64 sqlite3Hwtime(void){ - unsigned long long retval; - unsigned long junk; - __asm__ __volatile__ ("\n\ - 1: mftbu %1\n\ - mftb %L0\n\ - mftbu %0\n\ - cmpw %0,%1\n\ - bne 1b" - : "=r" (retval), "=r" (junk)); - return retval; - } - -#else - - /* - ** asm() is needed for hardware timing support. Without asm(), - ** disable the sqlite3Hwtime() routine. - ** - ** sqlite3Hwtime() is only used for some obscure debugging - ** and analysis configurations, not in any deliverable, so this - ** should not be a great loss. - */ -SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } - -#endif - -#endif /* !defined(SQLITE_HWTIME_H) */ - -/************** End of hwtime.h **********************************************/ -/************** Continuing where we left off in vdbe.c ***********************/ +/* #include "hwtime.h" */ #endif @@ -87171,6 +88069,42 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ } } +/* +** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning +** with pOp->p3. Return the hash. +*/ +static u64 filterHash(const Mem *aMem, const Op *pOp){ + int i, mx; + u64 h = 0; + + assert( pOp->p4type==P4_INT32 ); + for(i=pOp->p3, mx=i+pOp->p4.i; iflags & (MEM_Int|MEM_IntReal) ){ + h += p->u.i; + }else if( p->flags & MEM_Real ){ + h += sqlite3VdbeIntValue(p); + }else if( p->flags & (MEM_Str|MEM_Blob) ){ + h += p->n; + if( p->flags & MEM_Zero ) h += p->u.nZero; + } + } + return h; +} + +/* +** Return the symbolic name for the data type of a pMem +*/ +static const char *vdbeMemTypeName(Mem *pMem){ + static const char *azTypes[] = { + /* SQLITE_INTEGER */ "INT", + /* SQLITE_FLOAT */ "REAL", + /* SQLITE_TEXT */ "TEXT", + /* SQLITE_BLOB */ "BLOB", + /* SQLITE_NULL */ "NULL" + }; + return azTypes[sqlite3_value_type(pMem)-1]; +} /* ** Execute as much of a VDBE program as we can. @@ -87453,6 +88387,8 @@ case OP_Gosub: { /* jump */ /* Most jump operations do a goto to this spot in order to update ** the pOp pointer. */ jump_to_p2: + assert( pOp->p2>0 ); /* There are never any jumps to instruction 0 */ + assert( pOp->p2nOp ); /* Jumps must be in range */ pOp = &aOp[pOp->p2 - 1]; break; } @@ -87812,12 +88748,18 @@ case OP_SoftNull: { ** Synopsis: r[P2]=P4 (len=P1) ** ** P4 points to a blob of data P1 bytes long. Store this -** blob in register P2. +** blob in register P2. If P4 is a NULL pointer, then construct +** a zero-filled blob that is P1 bytes long in P2. */ case OP_Blob: { /* out2 */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); pOut = out2Prerelease(p, pOp); - sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + if( pOp->p4.z==0 ){ + sqlite3VdbeMemSetZeroBlob(pOut, pOp->p1); + if( sqlite3VdbeMemExpandBlob(pOut) ) goto no_mem; + }else{ + sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + } pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; @@ -87966,24 +88908,22 @@ case OP_IntCopy: { /* out2 */ break; } -/* Opcode: ChngCntRow P1 P2 * * * -** Synopsis: output=r[P1] +/* Opcode: FkCheck * * * * * ** -** Output value in register P1 as the chance count for a DML statement, -** due to the "PRAGMA count_changes=ON" setting. Or, if there was a -** foreign key error in the statement, trigger the error now. +** Halt with an SQLITE_CONSTRAINT error if there are any unresolved +** foreign key constraint violations. If there are no foreign key +** constraint violations, this is a no-op. ** -** This opcode is a variant of OP_ResultRow that checks the foreign key -** immediate constraint count and throws an error if the count is -** non-zero. The P2 opcode must be 1. +** FK constraint violations are also checked when the prepared statement +** exits. This opcode is used to raise foreign key constraint errors prior +** to returning results such as a row change count or the result of a +** RETURNING clause. */ -case OP_ChngCntRow: { - assert( pOp->p2==1 ); +case OP_FkCheck: { if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ goto abort_due_to_error; } - /* Fall through to the next case, OP_ResultRow */ - /* no break */ deliberate_fall_through + break; } /* Opcode: ResultRow P1 P2 * * * @@ -88621,7 +89561,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); - if( NEVER(pIn1==pIn3) ) flags3 = flags1 | MEM_Str; + if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; } if( (flags3 & MEM_Str)==0 && (flags3&(MEM_Int|MEM_Real|MEM_IntReal))!=0 ){ testcase( pIn3->flags & MEM_Int ); @@ -89002,6 +89942,22 @@ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ break; } +/* Opcode: IsNullOrType P1 P2 P3 * * +** Synopsis: if typeof(r[P1]) IN (P3,5) goto P2 +** +** Jump to P2 if the value in register P1 is NULL or has a datatype P3. +** P3 is an integer which should be one of SQLITE_INTEGER, SQLITE_FLOAT, +** SQLITE_BLOB, SQLITE_NULL, or SQLITE_TEXT. +*/ +case OP_IsNullOrType: { /* jump, in1 */ + int doTheJump; + pIn1 = &aMem[pOp->p1]; + doTheJump = (pIn1->flags & MEM_Null)!=0 || sqlite3_value_type(pIn1)==pOp->p3; + VdbeBranchTaken( doTheJump, 2); + if( doTheJump ) goto jump_to_p2; + break; +} + /* Opcode: ZeroOrNull P1 P2 P3 * * ** Synopsis: r[P2] = 0 OR NULL ** @@ -89073,10 +90029,18 @@ case OP_Offset: { /* out3 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; pOut = &p->aMem[pOp->p3]; - if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){ + if( pC==0 || pC->eCurType!=CURTYPE_BTREE ){ sqlite3VdbeMemSetNull(pOut); }else{ - sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + if( pC->deferredMoveto ){ + rc = sqlite3VdbeFinishMoveto(pC); + if( rc ) goto abort_due_to_error; + } + if( sqlite3BtreeEof(pC->uc.pCursor) ){ + sqlite3VdbeMemSetNull(pOut); + }else{ + sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); + } } break; } @@ -89135,6 +90099,7 @@ case OP_Column: { assert( pC!=0 ); assert( p2<(u32)pC->nField ); aOffset = pC->aOffset; + assert( aOffset==pC->aType+pC->nField ); assert( pC->eCurType!=CURTYPE_VTAB ); assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); assert( pC->eCurType!=CURTYPE_SORTER ); @@ -89370,6 +90335,110 @@ op_column_corrupt: } } +/* Opcode: TypeCheck P1 P2 P3 P4 * +** Synopsis: typecheck(r[P1@P2]) +** +** Apply affinities to the range of P2 registers beginning with P1. +** Take the affinities from the Table object in P4. If any value +** cannot be coerced into the correct type, then raise an error. +** +** This opcode is similar to OP_Affinity except that this opcode +** forces the register type to the Table column type. This is used +** to implement "strict affinity". +** +** GENERATED ALWAYS AS ... STATIC columns are only checked if P3 +** is zero. When P3 is non-zero, no type checking occurs for +** static generated columns. Virtual columns are computed at query time +** and so they are never checked. +** +** Preconditions: +** +**
    +**
  • P2 should be the number of non-virtual columns in the +** table of P4. +**
  • Table P4 should be a STRICT table. +**
+** +** If any precondition is false, an assertion fault occurs. +*/ +case OP_TypeCheck: { + Table *pTab; + Column *aCol; + int i; + + assert( pOp->p4type==P4_TABLE ); + pTab = pOp->p4.pTab; + assert( pTab->tabFlags & TF_Strict ); + assert( pTab->nNVCol==pOp->p2 ); + aCol = pTab->aCol; + pIn1 = &aMem[pOp->p1]; + for(i=0; inCol; i++){ + if( aCol[i].colFlags & COLFLAG_GENERATED ){ + if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue; + if( pOp->p3 ){ pIn1++; continue; } + } + assert( pIn1 < &aMem[pOp->p1+pOp->p2] ); + applyAffinity(pIn1, aCol[i].affinity, encoding); + if( (pIn1->flags & MEM_Null)==0 ){ + switch( aCol[i].eCType ){ + case COLTYPE_BLOB: { + if( (pIn1->flags & MEM_Blob)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_INTEGER: + case COLTYPE_INT: { + if( (pIn1->flags & MEM_Int)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_TEXT: { + if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error; + break; + } + case COLTYPE_REAL: { + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_Real ); + testcase( (pIn1->flags & (MEM_Real|MEM_IntReal))==MEM_IntReal ); + if( pIn1->flags & MEM_Int ){ + /* When applying REAL affinity, if the result is still an MEM_Int + ** that will fit in 6 bytes, then change the type to MEM_IntReal + ** so that we keep the high-resolution integer value but know that + ** the type really wants to be REAL. */ + testcase( pIn1->u.i==140737488355328LL ); + testcase( pIn1->u.i==140737488355327LL ); + testcase( pIn1->u.i==-140737488355328LL ); + testcase( pIn1->u.i==-140737488355329LL ); + if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL){ + pIn1->flags |= MEM_IntReal; + pIn1->flags &= ~MEM_Int; + }else{ + pIn1->u.r = (double)pIn1->u.i; + pIn1->flags |= MEM_Real; + pIn1->flags &= ~MEM_Int; + } + }else if( (pIn1->flags & (MEM_Real|MEM_IntReal))==0 ){ + goto vdbe_type_error; + } + break; + } + default: { + /* COLTYPE_ANY. Accept anything. */ + break; + } + } + } + REGISTER_TRACE((int)(pIn1-aMem), pIn1); + pIn1++; + } + assert( pIn1 == &aMem[pOp->p1+pOp->p2] ); + break; + +vdbe_type_error: + sqlite3VdbeError(p, "cannot store %s value in %s column %s.%s", + vdbeMemTypeName(pIn1), sqlite3StdType[aCol[i].eCType-1], + pTab->zName, aCol[i].zCnName); + rc = SQLITE_CONSTRAINT_DATATYPE; + goto abort_due_to_error; +} + /* Opcode: Affinity P1 P2 * P4 * ** Synopsis: affinity(r[P1@P2]) ** @@ -89584,7 +90653,7 @@ case OP_MakeRecord: { testcase( uu==127 ); testcase( uu==128 ); testcase( uu==32767 ); testcase( uu==32768 ); testcase( uu==8388607 ); testcase( uu==8388608 ); - testcase( uu==2147483647 ); testcase( uu==2147483648 ); + testcase( uu==2147483647 ); testcase( uu==2147483648LL ); testcase( uu==140737488355327LL ); testcase( uu==140737488355328LL ); if( uu<=127 ){ if( (i&1)==i && file_format>=4 ){ @@ -89712,7 +90781,7 @@ case OP_MakeRecord: { break; } -/* Opcode: Count P1 P2 p3 * * +/* Opcode: Count P1 P2 P3 * * ** Synopsis: r[P2]=count() ** ** Store the number of entries (an integer value) in the table or index @@ -90033,8 +91102,16 @@ case OP_Transaction: { assert( pOp->p2>=0 && pOp->p2<=2 ); assert( pOp->p1>=0 && pOp->p1nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); - if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ - rc = SQLITE_READONLY; + assert( rc==SQLITE_OK ); + if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){ + if( db->flags & SQLITE_QueryOnly ){ + /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */ + rc = SQLITE_READONLY; + }else{ + /* Writes prohibited due to a prior SQLITE_CORRUPT in the current + ** transaction */ + rc = SQLITE_CORRUPT; + } goto abort_due_to_error; } pBt = db->aDb[pOp->p1].pBt; @@ -90076,7 +91153,8 @@ case OP_Transaction: { } } assert( pOp->p5==0 || pOp->p4type==P4_INT32 ); - if( pOp->p5 + if( rc==SQLITE_OK + && pOp->p5 && (iMeta!=pOp->p3 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i) ){ @@ -90173,6 +91251,7 @@ case OP_SetCookie: { /* When the schema cookie changes, record the new cookie internally */ pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5; db->mDbFlags |= DBFLAG_SchemaChange; + sqlite3FkClearTriggerCache(db, pOp->p1); }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ pDb->pSchema->file_format = pOp->p3; @@ -90286,6 +91365,8 @@ case OP_ReopenIdx: { pCur = p->apCsr[pOp->p1]; if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){ assert( pCur->iDb==pOp->p3 ); /* Guaranteed by the code generator */ + assert( pCur->eCurType==CURTYPE_BTREE ); + sqlite3BtreeClearCursor(pCur->uc.pCursor); goto open_cursor_set_hints; } /* If the cursor is not currently open or is open on a different @@ -90348,8 +91429,9 @@ case OP_OpenWrite: assert( pOp->p1>=0 ); assert( nField>=0 ); testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ - pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); + pCur = allocateCursor(p, pOp->p1, nField, CURTYPE_BTREE); if( pCur==0 ) goto no_mem; + pCur->iDb = iDb; pCur->nullRow = 1; pCur->isOrdered = 1; pCur->pgnoRoot = p2; @@ -90391,7 +91473,7 @@ case OP_OpenDup: { assert( pOrig ); assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */ - pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE); + pCx = allocateCursor(p, pOp->p1, pOrig->nField, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->isEphemeral = 1; @@ -90399,10 +91481,10 @@ case OP_OpenDup: { pCx->isTable = pOrig->isTable; pCx->pgnoRoot = pOrig->pgnoRoot; pCx->isOrdered = pOrig->isOrdered; - pCx->pBtx = pOrig->pBtx; + pCx->ub.pBtx = pOrig->ub.pBtx; pCx->hasBeenDuped = 1; pOrig->hasBeenDuped = 1; - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this @@ -90468,23 +91550,23 @@ case OP_OpenEphemeral: { aMem[pOp->p3].z = ""; } pCx = p->apCsr[pOp->p1]; - if( pCx && !pCx->hasBeenDuped ){ + if( pCx && !pCx->hasBeenDuped && ALWAYS(pOp->p2<=pCx->nField) ){ /* If the ephermeral table is already open and has no duplicates from ** OP_OpenDup, then erase all existing content so that the table is ** empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); pCx->seqCount = 0; pCx->cacheStatus = CACHE_STALE; - rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + rc = sqlite3BtreeClearTable(pCx->ub.pBtx, pCx->pgnoRoot, 0); }else{ - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); + rc = sqlite3BtreeBeginTrans(pCx->ub.pBtx, 1, 0); if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before @@ -90493,26 +91575,26 @@ case OP_OpenEphemeral: { */ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBtx, &pCx->pgnoRoot, + rc = sqlite3BtreeCreateTable(pCx->ub.pBtx, &pCx->pgnoRoot, BTREE_BLOBKEY | pOp->p5); if( rc==SQLITE_OK ){ assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, pKeyInfo, pCx->uc.pCursor); } pCx->isTable = 0; }else{ pCx->pgnoRoot = SCHEMA_ROOT; - rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, SCHEMA_ROOT, BTREE_WRCSR, 0, pCx->uc.pCursor); pCx->isTable = 1; } } pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); if( rc ){ - sqlite3BtreeClose(pCx->pBtx); + sqlite3BtreeClose(pCx->ub.pBtx); } } } @@ -90536,7 +91618,7 @@ case OP_SorterOpen: { assert( pOp->p1>=0 ); assert( pOp->p2>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER); + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER); if( pCx==0 ) goto no_mem; pCx->pKeyInfo = pOp->p4.pKeyInfo; assert( pCx->pKeyInfo->db==db ); @@ -90585,7 +91667,7 @@ case OP_OpenPseudo: { assert( pOp->p1>=0 ); assert( pOp->p3>=0 ); - pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); + pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO); if( pCx==0 ) goto no_mem; pCx->nullRow = 1; pCx->seekResult = pOp->p2; @@ -90773,6 +91855,7 @@ case OP_SeekGT: { /* jump, in3, group */ /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ if( (newType & (MEM_Int|MEM_IntReal))==0 ){ + int c; if( (newType & MEM_Real)==0 ){ if( (newType & MEM_Null) || oc>=OP_SeekGE ){ VdbeBranchTaken(1,2); @@ -90782,7 +91865,8 @@ case OP_SeekGT: { /* jump, in3, group */ if( rc!=SQLITE_OK ) goto abort_due_to_error; goto seek_not_found; } - }else + } + c = sqlite3IntFloatCompare(iKey, pIn3->u.r); /* If the approximation iKey is larger than the actual real search ** term, substitute >= for > and < for <=. e.g. if the search term @@ -90791,7 +91875,7 @@ case OP_SeekGT: { /* jump, in3, group */ ** (x > 4.9) -> (x >= 5) ** (x <= 4.9) -> (x < 5) */ - if( pIn3->u.r<(double)iKey ){ + if( c>0 ){ assert( OP_SeekGE==(OP_SeekGT-1) ); assert( OP_SeekLT==(OP_SeekLE-1) ); assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) ); @@ -90800,14 +91884,14 @@ case OP_SeekGT: { /* jump, in3, group */ /* If the approximation iKey is smaller than the actual real search ** term, substitute <= for < and > for >=. */ - else if( pIn3->u.r>(double)iKey ){ + else if( c<0 ){ assert( OP_SeekLE==(OP_SeekLT+1) ); assert( OP_SeekGT==(OP_SeekGE+1) ); assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) ); if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; } } - rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); + rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)iKey, 0, &res); pC->movetoTarget = iKey; /* Used by OP_Delete */ if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -90854,7 +91938,7 @@ case OP_SeekGT: { /* jump, in3, group */ { int i; for(i=0; iuc.pCursor, &r, 0, 0, &res); + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, &r, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -91273,7 +92357,7 @@ case OP_Found: { /* jump, in3 */ } } } - rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); + rc = sqlite3BtreeIndexMoveto(pC->uc.pCursor, pIdxKey, &res); if( pFree ) sqlite3DbFreeNN(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -91382,7 +92466,7 @@ notExistsWithKey: pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); res = 0; - rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); + rc = sqlite3BtreeTableMoveto(pCrsr, iKey, 0, &res); assert( rc==SQLITE_OK || res==0 ); pC->movetoTarget = iKey; /* Used by OP_Delete */ pC->nullRow = 0; @@ -91539,7 +92623,7 @@ case OP_NewRowid: { /* out2 */ do{ sqlite3_randomness(sizeof(v), &v); v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ - }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v, + }while( ((rc = sqlite3BtreeTableMoveto(pC->uc.pCursor, (u64)v, 0, &res))==SQLITE_OK) && (res==0) && (++cnt<100)); @@ -91629,7 +92713,7 @@ case OP_Insert: { assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) ); }else{ pTab = 0; - zDb = 0; /* Not needed. Silence a compiler warning. */ + zDb = 0; } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -91782,13 +92866,14 @@ case OP_Delete: { pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); } }else{ - zDb = 0; /* Not needed. Silence a compiler warning. */ - pTab = 0; /* Not needed. Silence a compiler warning. */ + zDb = 0; + pTab = 0; } #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* Invoke the pre-update-hook if required. */ - if( db->xPreUpdateCallback && pOp->p4.pTab ){ + assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab ); + if( db->xPreUpdateCallback && pTab ){ assert( !(opflags & OPFLAG_ISUPDATE) || HasRowid(pTab)==0 || (aMem[pOp->p3].flags & MEM_Int) @@ -91829,7 +92914,7 @@ case OP_Delete: { /* Invoke the update-hook if required. */ if( opflags & OPFLAG_NCHANGE ){ p->nChange++; - if( db->xUpdateCallback && HasRowid(pTab) ){ + if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){ db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName, pC->movetoTarget); assert( pC->iDb>=0 ); @@ -92034,6 +93119,10 @@ case OP_Rowid: { /* out2 */ ** Move the cursor P1 to a null row. Any OP_Column operations ** that occur while the cursor is on the null row will always ** write a NULL. +** +** Or, if P1 is a Pseudo-Cursor (a cursor opened using OP_OpenPseudo) +** just reset the cache for that cursor. This causes the row of +** content held by the pseudo-cursor to be reparsed. */ case OP_NullRow: { VdbeCursor *pC; @@ -92416,7 +93505,8 @@ case OP_SorterInsert: { /* in2 */ ** an UPDATE or DELETE statement and the index entry to be updated ** or deleted is not found. For some uses of IdxDelete ** (example: the EXCEPT operator) it does not matter that no matching -** entry is found. For those cases, P5 is zero. +** entry is found. For those cases, P5 is zero. Also, do not raise +** this (self-correcting and non-critical) error if in writable_schema mode. */ case OP_IdxDelete: { VdbeCursor *pC; @@ -92437,12 +93527,12 @@ case OP_IdxDelete: { r.nField = (u16)pOp->p3; r.default_rc = 0; r.aMem = &aMem[pOp->p2]; - rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); + rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res); if( rc ) goto abort_due_to_error; if( res==0 ){ rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; - }else if( pOp->p5 ){ + }else if( pOp->p5 && !sqlite3WritableSchema(db) ){ rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } @@ -92521,9 +93611,9 @@ case OP_IdxRowid: { /* out2 */ pTabCur->movetoTarget = rowid; pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); - pTabCur->aAltMap = pOp->p4.ai; - assert( !pC->isEphemeral ); assert( !pTabCur->isEphemeral ); + pTabCur->ub.aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -92750,7 +93840,7 @@ case OP_Destroy: { /* out2 */ ** See also: Destroy */ case OP_Clear: { - int nChange; + i64 nChange; sqlite3VdbeIncrWriteCounter(p, 0); nChange = 0; @@ -92876,7 +93966,7 @@ case OP_ParseSchema: { }else #endif { - zSchema = DFLT_SCHEMA_TABLE; + zSchema = LEGACY_SCHEMA_TABLE; initData.db = db; initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; @@ -94045,7 +95135,7 @@ case OP_VOpen: { pVCur->pVtab = pVtab; /* Initialize vdbe cursor object */ - pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB); + pCur = allocateCursor(p, pOp->p1, 0, CURTYPE_VTAB); if( pCur ){ pCur->uc.pVCur = pVCur; pVtab->nRef++; @@ -94058,6 +95148,34 @@ case OP_VOpen: { } #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VInitIn P1 P2 P3 * * +** Synopsis: r[P2]=ValueList(P1,P3) +** +** Set register P2 to be a pointer to a ValueList object for cursor P1 +** with cache register P3 and output register P3+1. This ValueList object +** can be used as the first argument to sqlite3_vtab_in_first() and +** sqlite3_vtab_in_next() to extract all of the values stored in the P1 +** cursor. Register P3 is used to hold the values returned by +** sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). +*/ +case OP_VInitIn: { /* out2 */ + VdbeCursor *pC; /* The cursor containing the RHS values */ + ValueList *pRhs; /* New ValueList object to put in reg[P2] */ + + pC = p->apCsr[pOp->p1]; + pRhs = sqlite3_malloc64( sizeof(*pRhs) ); + if( pRhs==0 ) goto no_mem; + pRhs->pCsr = pC->uc.pCursor; + pRhs->pOut = &aMem[pOp->p3]; + pOut = out2Prerelease(p, pOp); + pOut->flags = MEM_Null; + sqlite3VdbeMemSetPointer(pOut, pRhs, "ValueList", sqlite3_free); + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + + #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VFilter P1 P2 P3 P4 * ** Synopsis: iplan=r[P3] zplan='P4' @@ -94096,6 +95214,7 @@ case OP_VFilter: { /* jump */ pCur = p->apCsr[pOp->p1]; assert( memIsValid(pQuery) ); REGISTER_TRACE(pOp->p3, pQuery); + assert( pCur!=0 ); assert( pCur->eCurType==CURTYPE_VTAB ); pVCur = pCur->uc.pVCur; pVtab = pVCur->pVtab; @@ -94107,7 +95226,6 @@ case OP_VFilter: { /* jump */ iQuery = (int)pQuery->u.i; /* Invoke the xFilter method */ - res = 0; apArg = p->apArg; for(i = 0; iapCsr[pOp->p1]; + assert( pCur!=0 ); assert( pCur->eCurType==CURTYPE_VTAB ); assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); pDest = &aMem[pOp->p3]; @@ -94197,8 +95316,8 @@ case OP_VNext: { /* jump */ int res; VdbeCursor *pCur; - res = 0; pCur = p->apCsr[pOp->p1]; + assert( pCur!=0 ); assert( pCur->eCurType==CURTYPE_VTAB ); if( pCur->nullRow ){ break; @@ -94294,7 +95413,7 @@ case OP_VUpdate: { const sqlite3_module *pModule; int nArg; int i; - sqlite_int64 rowid; + sqlite_int64 rowid = 0; Mem **apArg; Mem *pX; @@ -94482,6 +95601,77 @@ case OP_Function: { /* group */ break; } +/* Opcode: FilterAdd P1 * P3 P4 * +** Synopsis: filter(P1) += key(P3@P4) +** +** Compute a hash on the P4 registers starting with r[P3] and +** add that hash to the bloom filter contained in r[P1]. +*/ +case OP_FilterAdd: { + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( pIn1->flags & MEM_Blob ); + assert( pIn1->n>0 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= pIn1->n; + pIn1->z[h/8] |= 1<<(h&7); + break; +} + +/* Opcode: Filter P1 P2 P3 P4 * +** Synopsis: if key(P3@P4) not in filter(P1) goto P2 +** +** Compute a hash on the key contained in the P4 registers starting +** with r[P3]. Check to see if that hash is found in the +** bloom filter hosted by register P1. If it is not present then +** maybe jump to P2. Otherwise fall through. +** +** False negatives are harmless. It is always safe to fall through, +** even if the value is in the bloom filter. A false negative causes +** more CPU cycles to be used, but it should still yield the correct +** answer. However, an incorrect answer may well arise from a +** false positive - if the jump is taken when it should fall through. +*/ +case OP_Filter: { /* jump */ + u64 h; + + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); + pIn1 = &aMem[pOp->p1]; + assert( (pIn1->flags & MEM_Blob)!=0 ); + assert( pIn1->n >= 1 ); + h = filterHash(aMem, pOp); +#ifdef SQLITE_DEBUG + if( db->flags&SQLITE_VdbeTrace ){ + int ii; + for(ii=pOp->p3; iip3+pOp->p4.i; ii++){ + registerTrace(ii, &aMem[ii]); + } + printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); + } +#endif + h %= pIn1->n; + if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ + VdbeBranchTaken(1, 2); + p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; + goto jump_to_p2; + }else{ + p->aCounter[SQLITE_STMTSTATUS_FILTER_MISS]++; + VdbeBranchTaken(0, 2); + } + break; +} + /* Opcode: Trace P1 P2 * P4 * ** ** Write P4 on the statement trace output if statement tracing is @@ -94739,6 +95929,18 @@ abort_due_to_error: rc = SQLITE_CORRUPT_BKPT; } assert( rc ); +#ifdef SQLITE_DEBUG + if( db->flags & SQLITE_VdbeTrace ){ + const char *zTrace = p->zSql; + if( zTrace==0 ){ + if( aOp[0].opcode==OP_Trace ){ + zTrace = aOp[0].p4.z; + } + if( zTrace==0 ) zTrace = "???"; + } + printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace); + } +#endif if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); } @@ -94749,6 +95951,9 @@ abort_due_to_error: (int)(pOp - aOp), p->zSql, p->zErrMsg); sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); + if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){ + db->flags |= SQLITE_CorruptRdOnly; + } rc = SQLITE_ERROR; if( resetSchemaOnFault>0 ){ sqlite3ResetOneSchema(db, resetSchemaOnFault-1); @@ -94880,7 +96085,10 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ } if( rc==SQLITE_ROW ){ VdbeCursor *pC = v->apCsr[0]; - u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0; + u32 type; + assert( pC!=0 ); + assert( pC->eCurType==CURTYPE_BTREE ); + type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0; testcase( pC->nHdrParsed==p->iCol ); testcase( pC->nHdrParsed==p->iCol+1 ); if( type<12 ){ @@ -94954,10 +96162,9 @@ SQLITE_API int sqlite3_blob_open( sqlite3_mutex_enter(db->mutex); pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); - do { - memset(&sParse, 0, sizeof(Parse)); + while(1){ + sqlite3ParseObjectInit(&sParse,db); if( !pBlob ) goto blob_open_out; - sParse.db = db; sqlite3DbFree(db, zErr); zErr = 0; @@ -94972,7 +96179,7 @@ SQLITE_API int sqlite3_blob_open( sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } #ifndef SQLITE_OMIT_VIEW - if( pTab && pTab->pSelect ){ + if( pTab && IsView(pTab) ){ pTab = 0; sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } @@ -94992,7 +96199,7 @@ SQLITE_API int sqlite3_blob_open( /* Now search pTab for the exact column. */ for(iCol=0; iColnCol; iCol++) { - if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ + if( sqlite3StrICmp(pTab->aCol[iCol].zCnName, zColumn)==0 ){ break; } } @@ -95017,7 +96224,8 @@ SQLITE_API int sqlite3_blob_open( ** key columns must be indexed. The check below will pick up this ** case. */ FKey *pFKey; - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ int j; for(j=0; jnCol; j++){ if( pFKey->aCol[j].iFrom==iCol ){ @@ -95133,7 +96341,9 @@ SQLITE_API int sqlite3_blob_open( goto blob_open_out; } rc = blobSeekToRow(pBlob, iRow, &zErr); - } while( (++nAttempt)=SQLITE_MAX_SCHEMA_RETRY || rc!=SQLITE_SCHEMA ) break; + sqlite3ParseObjectReset(&sParse); + } blob_open_out: if( rc==SQLITE_OK && db->mallocFailed==0 ){ @@ -95144,7 +96354,7 @@ blob_open_out: } sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); sqlite3DbFree(db, zErr); - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -95224,6 +96434,8 @@ static int blobReadWrite( */ sqlite3_int64 iKey; iKey = sqlite3BtreeIntegerKey(p->pCsr); + assert( v->apCsr[0]!=0 ); + assert( v->apCsr[0]->eCurType==CURTYPE_BTREE ); sqlite3VdbePreUpdateHook( v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol ); @@ -96277,7 +97489,8 @@ SQLITE_PRIVATE int sqlite3VdbeSorterInit( } #endif - assert( pCsr->pKeyInfo && pCsr->pBtx==0 ); + assert( pCsr->pKeyInfo ); + assert( !pCsr->isEphemeral ); assert( pCsr->eCurType==CURTYPE_SORTER ); szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); @@ -96606,7 +97819,7 @@ static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); sqlite3OsFetch(pFd, 0, (int)nByte, &p); - sqlite3OsUnfetch(pFd, 0, p); + if( p ) sqlite3OsUnfetch(pFd, 0, p); } } #else @@ -97324,6 +98537,7 @@ static int vdbeIncrMergerNew( vdbeMergeEngineFree(pMerger); rc = SQLITE_NOMEM_BKPT; } + assert( *ppOut!=0 || rc!=SQLITE_OK ); return rc; } @@ -98689,6 +99903,9 @@ static int memjrnlCreateFile(MemJournal *p){ } +/* Forward reference */ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size); + /* ** Write data to the file. */ @@ -98719,22 +99936,20 @@ static int memjrnlWrite( ** the in-memory journal is being used by a connection using the ** atomic-write optimization. In this case the first 28 bytes of the ** journal file may be written as part of committing the transaction. */ - assert( iOfst==p->endpoint.iOffset || iOfst==0 ); -#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ - || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) + assert( iOfst<=p->endpoint.iOffset ); + if( iOfst>0 && iOfst!=p->endpoint.iOffset ){ + memjrnlTruncate(pJfd, iOfst); + } if( iOfst==0 && p->pFirst ){ assert( p->nChunkSize>iAmt ); memcpy((u8*)p->pFirst->zChunk, zBuf, iAmt); - }else -#else - assert( iOfst>0 || p->pFirst==0 ); -#endif - { + }else{ while( nWrite>0 ){ FileChunk *pChunk = p->endpoint.pChunk; int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize); int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset); + assert( pChunk!=0 || iChunkOffset==0 ); if( iChunkOffset==0 ){ /* New chunk is required to extend the file. */ FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize)); @@ -98749,10 +99964,11 @@ static int memjrnlWrite( assert( !p->pFirst ); p->pFirst = pNew; } - p->endpoint.pChunk = pNew; + pChunk = p->endpoint.pChunk = pNew; } - memcpy((u8*)p->endpoint.pChunk->zChunk + iChunkOffset, zWrite, iSpace); + assert( pChunk!=0 ); + memcpy((u8*)pChunk->zChunk + iChunkOffset, zWrite, iSpace); zWrite += iSpace; nWrite -= iSpace; p->endpoint.iOffset += iSpace; @@ -98776,7 +99992,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ p->pFirst = 0; }else{ i64 iOff = p->nChunkSize; - for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + for(pIter=p->pFirst; ALWAYS(pIter) && iOffpNext){ iOff += p->nChunkSize; } if( ALWAYS(pIter) ){ @@ -99025,7 +100241,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); pExpr = pExpr->pRight; continue; - }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + }else if( ExprUseXSelect(pExpr) ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; }else{ @@ -99297,6 +100513,7 @@ static void resolveAlias( }else{ incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -99400,6 +100617,7 @@ SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){ Table *pExTab; n = pExpr->iColumn; + assert( ExprUseYTab(pExpr) ); pExTab = pExpr->y.pTab; assert( pExTab!=0 ); if( (pExTab->tabFlags & TF_HasGenerated)!=0 @@ -99513,7 +100731,7 @@ static int lookupName( u8 hCol; pTab = pItem->pTab; assert( pTab!=0 && pTab->zName!=0 ); - assert( pTab->nCol>0 ); + assert( pTab->nCol>0 || pParse->nErr ); if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){ int hit = 0; pEList = pItem->pSelect->pEList; @@ -99528,8 +100746,9 @@ static int lookupName( } if( hit || zTab==0 ) continue; } - if( zDb && pTab->pSchema!=pSchema ){ - continue; + if( zDb ){ + if( pTab->pSchema!=pSchema ) continue; + if( pSchema==0 && strcmp(zDb,"*")!=0 ) continue; } if( zTab ){ const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; @@ -99537,16 +100756,16 @@ static int lookupName( if( sqlite3StrICmp(zTabName, zTab)!=0 ){ continue; } + assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT && pItem->zAlias ){ sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } } - if( 0==(cntTab++) ){ - pMatch = pItem; - } hCol = sqlite3StrIHash(zCol); for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ /* If there has been exactly one prior match and this match ** is for the right-hand table of a NATURAL JOIN or is in a ** USING clause, then skip this match. @@ -99562,9 +100781,14 @@ static int lookupName( break; } } + if( 0==cnt && VisibleRowid(pTab) ){ + cntTab++; + pMatch = pItem; + } } if( pMatch ){ pExpr->iTable = pMatch->iCursor; + assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pMatch->pTab; /* RIGHT JOIN not (yet) supported */ assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); @@ -99619,7 +100843,9 @@ static int lookupName( pSchema = pTab->pSchema; cntTab++; for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ - if( pCol->hName==hCol && sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( pCol->hName==hCol + && sqlite3StrICmp(pCol->zCnName, zCol)==0 + ){ if( iCol==pTab->iPKey ){ iCol = -1; } @@ -99636,6 +100862,7 @@ static int lookupName( #ifndef SQLITE_OMIT_UPSERT if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ testcase( iCol==(-1) ); + assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT ){ pExpr->iColumn = iCol; pExpr->y.pTab = pTab; @@ -99648,9 +100875,11 @@ static int lookupName( }else #endif /* SQLITE_OMIT_UPSERT */ { + assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pTab; if( pParse->bReturning ){ eNewExprOp = TK_REGISTER; + pExpr->op2 = TK_COLUMN; pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + sqlite3TableColumnToStorage(pTab, iCol) + 1; }else{ @@ -99684,7 +100913,7 @@ static int lookupName( && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && VisibleRowid(pMatch->pTab) + && ALWAYS(VisibleRowid(pMatch->pTab)) ){ cnt = 1; pExpr->iColumn = -1; @@ -99722,8 +100951,8 @@ static int lookupName( ){ Expr *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); - assert( pExpr->x.pList==0 ); - assert( pExpr->x.pSelect==0 ); + assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 ); + assert( ExprUseXSelect(pExpr)==0 || pExpr->x.pSelect==0 ); pOrig = pEList->a[j].pExpr; if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); @@ -99795,7 +101024,7 @@ static int lookupName( sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); #endif pExpr->op = TK_STRING; - pExpr->y.pTab = 0; + memset(&pExpr->y, 0, sizeof(pExpr->y)); return WRC_Prune; } if( sqlite3ExprIdToTrueFalse(pExpr) ){ @@ -99817,6 +101046,7 @@ static int lookupName( }else{ sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); pParse->checkSchema = 1; pTopNC->nNcErr++; } @@ -99881,7 +101111,9 @@ SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSr Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ SrcItem *pItem = &pSrc->a[iSrc]; - Table *pTab = p->y.pTab = pItem->pTab; + Table *pTab; + assert( ExprUseYTab(p) ); + pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ p->iColumn = -1; @@ -99923,7 +101155,8 @@ static void notValidImpl( Parse *pParse, /* Leave error message here */ NameContext *pNC, /* The name context */ const char *zMsg, /* Type of error */ - Expr *pExpr /* Invalidate this expression on error */ + Expr *pExpr, /* Invalidate this expression on error */ + Expr *pError /* Associate error with this expression */ ){ const char *zIn = "partial index WHERE clauses"; if( pNC->ncFlags & NC_IdxExpr ) zIn = "index expressions"; @@ -99935,10 +101168,11 @@ static void notValidImpl( #endif sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); if( pExpr ) pExpr->op = TK_NULL; + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); } -#define sqlite3ResolveNotValid(P,N,M,X,E) \ +#define sqlite3ResolveNotValid(P,N,M,X,E,R) \ assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ - if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E); + if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E,R); /* ** Expression p should encode a floating point value between 1.0 and 0.0. @@ -99948,6 +101182,7 @@ static void notValidImpl( static int exprProbability(Expr *p){ double r = -1.0; if( p->op!=TK_FLOAT ) return -1; + assert( !ExprHasProperty(p, EP_IntValue) ); sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); assert( r>=0.0 ); if( r>1.0 ) return -1; @@ -99996,6 +101231,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pSrcList && pSrcList->nSrc>=1 ); pItem = pSrcList->a; pExpr->op = TK_COLUMN; + assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pItem->pTab; pExpr->iTable = pItem->iCursor; pExpr->iColumn--; @@ -100027,6 +101263,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } sqlite3WalkExpr(pWalker, pExpr->pLeft); if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ + testcase( ExprHasProperty(pExpr, EP_FromJoin) ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->op==TK_NOTNULL ){ pExpr->u.zToken = "true"; ExprSetProperty(pExpr, EP_IsTrue); @@ -100062,24 +101300,28 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_ID ){ zDb = 0; zTable = 0; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); zColumn = pExpr->u.zToken; }else{ Expr *pLeft = pExpr->pLeft; testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", - NC_IdxExpr|NC_GenCol, 0); + NC_IdxExpr|NC_GenCol, 0, pExpr); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ zDb = 0; }else{ assert( pRight->op==TK_DOT ); + assert( !ExprHasProperty(pRight, EP_IntValue) ); zDb = pLeft->u.zToken; pLeft = pRight->pLeft; pRight = pRight->pRight; } + assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) ); zTable = pLeft->u.zToken; zColumn = pRight->u.zToken; + assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); @@ -100096,7 +101338,6 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ int no_such_func = 0; /* True if no such function exists */ int wrong_num_args = 0; /* True if wrong number of arguments */ int is_agg = 0; /* True if is an aggregate function */ - int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ @@ -100104,9 +101345,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #ifndef SQLITE_OMIT_WINDOWFUNC Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); zId = pExpr->u.zToken; - nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); @@ -100123,8 +101363,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->iTable = exprProbability(pList->a[1].pExpr); if( pExpr->iTable<0 ){ sqlite3ErrorMsg(pParse, - "second argument to likelihood() must be a " - "constant between 0.0 and 1.0"); + "second argument to %#T() must be a " + "constant between 0.0 and 1.0", pExpr); pNC->nNcErr++; } }else{ @@ -100145,8 +101385,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); if( auth!=SQLITE_OK ){ if( auth==SQLITE_DENY ){ - sqlite3ErrorMsg(pParse, "not authorized to use function: %s", - pDef->zName); + sqlite3ErrorMsg(pParse, "not authorized to use function: %#T", + pExpr); pNC->nNcErr++; } pExpr->op = TK_NULL; @@ -100169,7 +101409,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all ** all this. */ sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", - NC_IdxExpr|NC_PartIdx|NC_GenCol, 0); + NC_IdxExpr|NC_PartIdx|NC_GenCol, 0, pExpr); }else{ assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ pExpr->op2 = pNC->ncFlags & NC_SelfRef; @@ -100182,7 +101422,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* Internal-use-only functions are disallowed unless the ** SQL is being compiled using sqlite3NestedParse() or ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be - ** used to activate internal functionsn for testing purposes */ + ** used to activate internal functions for testing purposes */ no_such_func = 1; pDef = 0; }else @@ -100201,7 +101441,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ); if( pDef && pDef->xValue==0 && pWin ){ sqlite3ErrorMsg(pParse, - "%.*s() may not be used as a window function", nId, zId + "%#T() may not be used as a window function", pExpr ); pNC->nNcErr++; }else if( @@ -100215,13 +101455,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ }else{ zType = "aggregate"; } - sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); + sqlite3ErrorMsg(pParse, "misuse of %s function %#T()",zType,pExpr); pNC->nNcErr++; is_agg = 0; } #else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ - sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); + sqlite3ErrorMsg(pParse,"misuse of aggregate function %#T()",pExpr); pNC->nNcErr++; is_agg = 0; } @@ -100231,18 +101471,18 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && pParse->explain==0 #endif ){ - sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + sqlite3ErrorMsg(pParse, "no such function: %#T", pExpr); pNC->nNcErr++; }else if( wrong_num_args ){ - sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", - nId, zId); + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %#T()", + pExpr); pNC->nNcErr++; } #ifndef SQLITE_OMIT_WINDOWFUNC else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3ErrorMsg(pParse, - "FILTER may not be used with non-aggregate %.*s()", - nId, zId + "FILTER may not be used with non-aggregate %#T()", + pExpr ); pNC->nNcErr++; } @@ -100268,7 +101508,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; - assert( pWin==pExpr->y.pWin ); + assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); if( pParse->db->mallocFailed ) break; @@ -100281,7 +101521,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ }else #endif /* SQLITE_OMIT_WINDOWFUNC */ { - NameContext *pNC2 = pNC; + NameContext *pNC2; /* For looping up thru outer contexts */ pExpr->op = TK_AGG_FUNCTION; pExpr->op2 = 0; #ifndef SQLITE_OMIT_WINDOWFUNC @@ -100289,16 +101529,22 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); } #endif - while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ + pNC2 = pNC; + while( pNC2 + && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 + ){ pExpr->op2++; pNC2 = pNC2->pNext; } assert( pDef!=0 || IN_RENAME_OBJECT ); if( pNC2 && pDef ){ assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg ); + assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); - pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX); - + testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 ); + pNC2->ncFlags |= NC_HasAgg + | ((pDef->funcFlags^SQLITE_FUNC_ANYORDER) + & (SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER)); } } pNC->ncFlags |= savedAllowFlags; @@ -100314,15 +101560,17 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif case TK_IN: { testcase( pExpr->op==TK_IN ); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ int nRef = pNC->nRef; testcase( pNC->ncFlags & NC_IsCheck ); testcase( pNC->ncFlags & NC_PartIdx ); testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); - sqlite3ResolveNotValid(pParse, pNC, "subqueries", - NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); - sqlite3WalkSelect(pWalker, pExpr->x.pSelect); + if( pNC->ncFlags & NC_SelfRef ){ + notValidImpl(pParse, pNC, "subqueries", pExpr, pExpr); + }else{ + sqlite3WalkSelect(pWalker, pExpr->x.pSelect); + } assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); @@ -100337,7 +101585,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); sqlite3ResolveNotValid(pParse, pNC, "parameters", - NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); + NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr, pExpr); break; } case TK_IS: @@ -100369,6 +101617,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pExpr->pLeft!=0 ); nLeft = sqlite3ExprVectorSize(pExpr->pLeft); if( pExpr->op==TK_BETWEEN ){ + assert( ExprUseXList(pExpr) ); nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr); if( nRight==nLeft ){ nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr); @@ -100388,11 +101637,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_BETWEEN ); sqlite3ErrorMsg(pParse, "row value misused"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); } break; } } - return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue; + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + return pParse->nErr ? WRC_Abort : WRC_Continue; } /* @@ -100417,7 +101668,9 @@ static int resolveAsName( UNUSED_PARAMETER(pParse); if( pE->op==TK_ID ){ - char *zCol = pE->u.zToken; + const char *zCol; + assert( !ExprHasProperty(pE, EP_IntValue) ); + zCol = pE->u.zToken; for(i=0; inExpr; i++){ if( pEList->a[i].eEName==ENAME_NAME && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 @@ -100498,11 +101751,13 @@ static void resolveOutOfRangeError( Parse *pParse, /* The error context into which to write the error */ const char *zType, /* "ORDER" or "GROUP" */ int i, /* The index (1-based) of the term out of range */ - int mx /* Largest permissible value of i */ + int mx, /* Largest permissible value of i */ + Expr *pError /* Associate the error with the expression */ ){ sqlite3ErrorMsg(pParse, "%r %s BY term out of range - should be " "between 1 and %d", i, zType, mx); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); } /* @@ -100558,7 +101813,7 @@ static int resolveCompoundOrderBy( if( NEVER(pE==0) ) continue; if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ - resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); + resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr, pE); return 1; } }else{ @@ -100654,7 +101909,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ if( pItem->u.x.iOrderByCol ){ if( pItem->u.x.iOrderByCol>pEList->nExpr ){ - resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); + resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr, 0); return 1; } resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); @@ -100746,7 +102001,7 @@ static int resolveOrderGroupBy( ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ if( iCol<1 || iCol>0xffff ){ - resolveOutOfRangeError(pParse, zType, i+1, nResult); + resolveOutOfRangeError(pParse, zType, i+1, nResult, pE2); return 1; } pItem->u.x.iOrderByCol = (u16)iCol; @@ -100804,7 +102059,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ */ if( (p->selFlags & SF_Expanded)==0 ){ sqlite3SelectPrep(pParse, p, pOuterNC); - return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune; + return pParse->nErr ? WRC_Abort : WRC_Prune; } isCompound = p->pPrior!=0; @@ -100841,7 +102096,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ p->pOrderBy = 0; } - /* Recursively resolve names in all subqueries + /* Recursively resolve names in all subqueries in the FROM clause */ for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; @@ -100852,7 +102107,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( pItem->zName ) pParse->zAuthContext = pItem->zName; sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; - if( pParse->nErr || db->mallocFailed ) return WRC_Abort; + if( pParse->nErr ) return WRC_Abort; + assert( db->mallocFailed==0 ); /* If the number of references to the outer context changed when ** expressions in the sub-select were resolved, the sub-select @@ -100885,7 +102141,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ pGroupBy = p->pGroupBy; if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){ assert( NC_MinMaxAgg==SF_MinMaxAgg ); - p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg); + assert( NC_OrderAgg==SF_OrderByReqd ); + p->selFlags |= SF_Aggregate | (sNC.ncFlags&(NC_MinMaxAgg|NC_OrderAgg)); }else{ sNC.ncFlags &= ~NC_AllowAgg; } @@ -101068,8 +102325,8 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( Walker w; if( pExpr==0 ) return SQLITE_OK; - savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = (pNC->ncFlags & NC_NoSelect) ? 0 : resolveSelectStep; @@ -101112,8 +102369,8 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( w.xSelectCallback = resolveSelectStep; w.xSelectCallback2 = 0; w.u.pNC = pNC; - savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); for(i=0; inExpr; i++){ Expr *pExpr = pList->a[i].pExpr; if( pExpr==0 ) continue; @@ -101131,10 +102388,11 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( assert( EP_Win==NC_HasWin ); testcase( pNC->ncFlags & NC_HasAgg ); testcase( pNC->ncFlags & NC_HasWin ); - if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin) ){ + if( pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg) ){ ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) ); - savedHasAgg |= pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin); - pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin); + savedHasAgg |= pNC->ncFlags & + (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); + pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); } if( w.pParse->nErr>0 ) return WRC_Abort; } @@ -101248,9 +102506,9 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); /* ** Return the affinity character for a single column of a table. */ -SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){ - assert( iColnCol ); - return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER; +SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){ + if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER; + return pTab->aCol[iCol].affinity; } /* @@ -101280,11 +102538,14 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ } op = pExpr->op; if( op==TK_REGISTER ) op = pExpr->op2; - if( (op==TK_COLUMN || op==TK_AGG_COLUMN) && pExpr->y.pTab ){ - return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + if( op==TK_COLUMN || op==TK_AGG_COLUMN ){ + assert( ExprUseYTab(pExpr) ); + if( pExpr->y.pTab ){ + return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + } } if( op==TK_SELECT ){ - assert( pExpr->flags&EP_xIsSelect ); + assert( ExprUseXSelect(pExpr) ); assert( pExpr->x.pSelect!=0 ); assert( pExpr->x.pSelect->pEList!=0 ); assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 ); @@ -101297,12 +102558,15 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ } #endif if( op==TK_SELECT_COLUMN ){ - assert( pExpr->pLeft->flags&EP_xIsSelect ); + assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); + assert( pExpr->iColumn < pExpr->iTable ); + assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); return sqlite3ExprAffinity( pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); } return pExpr->affExpr; @@ -101317,7 +102581,7 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(const Expr *pExpr){ ** and the pExpr parameter is returned unchanged. */ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( - Parse *pParse, /* Parsing context */ + const Parse *pParse, /* Parsing context */ Expr *pExpr, /* Add the "COLLATE" clause to this expression */ const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ @@ -101332,7 +102596,11 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( } return pExpr; } -SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString( + const Parse *pParse, /* Parsing context */ + Expr *pExpr, /* Add the "COLLATE" clause to this expression */ + const char *zC /* The collating sequence name */ +){ Token s; assert( zC!=0 ); sqlite3TokenInit(&s, (char*)zC); @@ -101358,7 +102626,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){ if( ExprHasProperty(pExpr, EP_Unlikely) ){ - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( ExprUseXList(pExpr) ); assert( pExpr->x.pList->nExpr>0 ); assert( pExpr->op==TK_FUNCTION ); pExpr = pExpr->x.pList->a[0].pExpr; @@ -101391,27 +102659,30 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ while( p ){ int op = p->op; if( op==TK_REGISTER ) op = p->op2; - if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER) - && p->y.pTab!=0 - ){ - /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally - ** a TK_COLUMN but was previously evaluated and cached in a register */ - int j = p->iColumn; - if( j>=0 ){ - const char *zColl = p->y.pTab->aCol[j].zColl; - pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){ + assert( ExprUseYTab(p) ); + if( p->y.pTab!=0 ){ + /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally + ** a TK_COLUMN but was previously evaluated and cached in a register */ + int j = p->iColumn; + if( j>=0 ){ + const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); + } + break; } - break; } if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; } if( op==TK_VECTOR ){ + assert( ExprUseXList(p) ); p = p->x.pList->a[0].pExpr; continue; } if( op==TK_COLLATE ){ + assert( !ExprHasProperty(p, EP_IntValue) ); pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } @@ -101421,11 +102692,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){ }else{ Expr *pNext = p->pRight; /* The Expr.x union is never used at the same time as Expr.pRight */ + assert( ExprUseXList(p) ); assert( p->x.pList==0 || p->pRight==0 ); - if( p->x.pList!=0 - && !db->mallocFailed - && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) - ){ + if( p->x.pList!=0 && !db->mallocFailed ){ int i; for(i=0; ALWAYS(ix.pList->nExpr); i++){ if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){ @@ -101508,7 +102777,7 @@ static char comparisonAffinity(const Expr *pExpr){ aff = sqlite3ExprAffinity(pExpr->pLeft); if( pExpr->pRight ){ aff = sqlite3CompareAffinity(pExpr->pRight, aff); - }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + }else if( ExprUseXSelect(pExpr) ){ aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); }else if( aff==0 ){ aff = SQLITE_AFF_BLOB; @@ -101634,7 +102903,7 @@ static int codeCompare( ** But a TK_SELECT might be either a vector or a scalar. It is only ** considered a vector if it has two or more result columns. */ -SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr){ +SQLITE_PRIVATE int sqlite3ExprIsVector(const Expr *pExpr){ return sqlite3ExprVectorSize(pExpr)>1; } @@ -101644,12 +102913,14 @@ SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr){ ** is a sub-select, return the number of columns in the sub-select. For ** any other type of expression, return 1. */ -SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){ +SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){ u8 op = pExpr->op; if( op==TK_REGISTER ) op = pExpr->op2; if( op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); return pExpr->x.pList->nExpr; }else if( op==TK_SELECT ){ + assert( ExprUseXSelect(pExpr) ); return pExpr->x.pSelect->pEList->nExpr; }else{ return 1; @@ -101676,8 +102947,10 @@ SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ if( sqlite3ExprIsVector(pVector) ){ assert( pVector->op2==0 || pVector->op==TK_REGISTER ); if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); return pVector->x.pSelect->pEList->a[i].pExpr; }else{ + assert( ExprUseXList(pVector) ); return pVector->x.pList->a[i].pExpr; } } @@ -101708,11 +102981,12 @@ SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( Parse *pParse, /* Parsing context */ Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ - int iField /* Which column of the vector to return */ + int iField, /* Which column of the vector to return */ + int nField /* Total number of columns in the vector */ ){ Expr *pRet; if( pVector->op==TK_SELECT ){ - assert( pVector->flags & EP_xIsSelect ); + assert( ExprUseXSelect(pVector) ); /* The TK_SELECT_COLUMN Expr node: ** ** pLeft: pVector containing TK_SELECT. Not deleted. @@ -101731,14 +103005,23 @@ SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( */ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ + pRet->iTable = nField; pRet->iColumn = iField; pRet->pLeft = pVector; } - assert( pRet==0 || pRet->iTable==0 ); }else{ - if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; + if( pVector->op==TK_VECTOR ){ + Expr **ppVector; + assert( ExprUseXList(pVector) ); + ppVector = &pVector->x.pList->a[iField].pExpr; + pVector = *ppVector; + if( IN_RENAME_OBJECT ){ + /* This must be a vector UPDATE inside a trigger */ + *ppVector = 0; + return pVector; + } + } pRet = sqlite3ExprDup(pParse->db, pVector, 0); - sqlite3RenameTokenRemap(pParse, pRet, pVector); } return pRet; } @@ -101794,10 +103077,12 @@ static int exprVectorRegister( return pVector->iTable+iField; } if( op==TK_SELECT ){ + assert( ExprUseXSelect(pVector) ); *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr; return regSelect+iField; } if( op==TK_VECTOR ){ + assert( ExprUseXList(pVector) ); *ppExpr = pVector->x.pList->a[iField].pExpr; return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); } @@ -101931,14 +103216,14 @@ SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ ** to by pnHeight, the second parameter, then set *pnHeight to that ** value. */ -static void heightOfExpr(Expr *p, int *pnHeight){ +static void heightOfExpr(const Expr *p, int *pnHeight){ if( p ){ if( p->nHeight>*pnHeight ){ *pnHeight = p->nHeight; } } } -static void heightOfExprList(ExprList *p, int *pnHeight){ +static void heightOfExprList(const ExprList *p, int *pnHeight){ if( p ){ int i; for(i=0; inExpr; i++){ @@ -101946,8 +103231,8 @@ static void heightOfExprList(ExprList *p, int *pnHeight){ } } } -static void heightOfSelect(Select *pSelect, int *pnHeight){ - Select *p; +static void heightOfSelect(const Select *pSelect, int *pnHeight){ + const Select *p; for(p=pSelect; p; p=p->pPrior){ heightOfExpr(p->pWhere, pnHeight); heightOfExpr(p->pHaving, pnHeight); @@ -101969,10 +103254,9 @@ static void heightOfSelect(Select *pSelect, int *pnHeight){ ** if appropriate. */ static void exprSetHeight(Expr *p){ - int nHeight = 0; - heightOfExpr(p->pLeft, &nHeight); - heightOfExpr(p->pRight, &nHeight); - if( ExprHasProperty(p, EP_xIsSelect) ){ + int nHeight = p->pLeft ? p->pLeft->nHeight : 0; + if( p->pRight && p->pRight->nHeight>nHeight ) nHeight = p->pRight->nHeight; + if( ExprUseXSelect(p) ){ heightOfSelect(p->x.pSelect, &nHeight); }else if( p->x.pList ){ heightOfExprList(p->x.pList, &nHeight); @@ -101999,7 +103283,7 @@ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ ** Return the maximum height of any expression tree referenced ** by the select statement passed as an argument. */ -SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ +SQLITE_PRIVATE int sqlite3SelectExprHeight(const Select *p){ int nHeight = 0; heightOfSelect(p, &nHeight); return nHeight; @@ -102011,7 +103295,7 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ */ SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ if( pParse->nErr ) return; - if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ + if( p && ExprUseXList(p) && p->x.pList ){ p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); } } @@ -102169,6 +103453,63 @@ SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pS } } +/* +** Expression list pEList is a list of vector values. This function +** converts the contents of pEList to a VALUES(...) Select statement +** returning 1 row for each element of the list. For example, the +** expression list: +** +** ( (1,2), (3,4) (5,6) ) +** +** is translated to the equivalent of: +** +** VALUES(1,2), (3,4), (5,6) +** +** Each of the vector values in pEList must contain exactly nElem terms. +** If a list element that is not a vector or does not contain nElem terms, +** an error message is left in pParse. +** +** This is used as part of processing IN(...) expressions with a list +** of vectors on the RHS. e.g. "... IN ((1,2), (3,4), (5,6))". +*/ +SQLITE_PRIVATE Select *sqlite3ExprListToValues(Parse *pParse, int nElem, ExprList *pEList){ + int ii; + Select *pRet = 0; + assert( nElem>1 ); + for(ii=0; iinExpr; ii++){ + Select *pSel; + Expr *pExpr = pEList->a[ii].pExpr; + int nExprElem; + if( pExpr->op==TK_VECTOR ){ + assert( ExprUseXList(pExpr) ); + nExprElem = pExpr->x.pList->nExpr; + }else{ + nExprElem = 1; + } + if( nExprElem!=nElem ){ + sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d", + nExprElem, nExprElem>1?"s":"", nElem + ); + break; + } + assert( ExprUseXList(pExpr) ); + pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0); + pExpr->x.pList = 0; + if( pSel ){ + if( pRet ){ + pSel->op = TK_ALL; + pSel->pPrior = pRet; + } + pRet = pSel; + } + } + + if( pRet && pRet->pPrior ){ + pRet->selFlags |= SF_MultiValue; + } + sqlite3ExprListDelete(pParse->db, pEList); + return pRet; +} /* ** Join two expressions using an AND operator. If either expression is @@ -102202,7 +103543,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ SQLITE_PRIVATE Expr *sqlite3ExprFunction( Parse *pParse, /* Parsing context */ ExprList *pList, /* Argument list */ - Token *pToken, /* Name of the function */ + const Token *pToken, /* Name of the function */ int eDistinct /* SF_Distinct or SF_ALL or 0 */ ){ Expr *pNew; @@ -102213,12 +103554,16 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction( sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } - if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + pNew->w.iOfst = (int)(pToken->z - pParse->zTail); + if( pList + && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] + && !pParse->nested + ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); } pNew->x.pList = pList; ExprSetProperty(pNew, EP_HasFunc); - assert( !ExprHasProperty(pNew, EP_xIsSelect) ); + assert( ExprUseXList(pNew) ); sqlite3ExprSetHeightAndFlags(pParse, pNew); if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); return pNew; @@ -102237,8 +103582,8 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction( */ SQLITE_PRIVATE void sqlite3ExprFunctionUsable( Parse *pParse, /* Parsing and code generating context */ - Expr *pExpr, /* The function invocation */ - FuncDef *pDef /* The function being invoked */ + const Expr *pExpr, /* The function invocation */ + const FuncDef *pDef /* The function being invoked */ ){ assert( !IN_RENAME_OBJECT ); assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 ); @@ -102253,7 +103598,7 @@ SQLITE_PRIVATE void sqlite3ExprFunctionUsable( ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning ** that the schema is possibly tainted). */ - sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName); + sqlite3ErrorMsg(pParse, "unsafe use of %#T()", pExpr); } } } @@ -102309,6 +103654,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); return; } x = (ynVar)i; @@ -102336,6 +103682,7 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n pExpr->iColumn = x; if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); + sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); } } @@ -102344,27 +103691,26 @@ SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n */ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); - /* Sanity check: Assert that the IntValue is non-negative if it exists */ - assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); - - assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed ); - assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced) - || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) ); + assert( !ExprUseUValue(p) || p->u.iValue>=0 ); + assert( !ExprUseYWin(p) || !ExprUseYSub(p) ); + assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed ); + assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) ); #ifdef SQLITE_DEBUG if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ assert( p->pLeft==0 ); assert( p->pRight==0 ); - assert( p->x.pSelect==0 ); + assert( !ExprUseXSelect(p) || p->x.pSelect==0 ); + assert( !ExprUseXList(p) || p->x.pList==0 ); } #endif if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ - assert( p->x.pList==0 || p->pRight==0 ); + assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 ); if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ assert( !ExprHasProperty(p, EP_WinFunc) ); sqlite3ExprDeleteNN(db, p->pRight); - }else if( ExprHasProperty(p, EP_xIsSelect) ){ + }else if( ExprUseXSelect(p) ){ assert( !ExprHasProperty(p, EP_WinFunc) ); sqlite3SelectDelete(db, p->x.pSelect); }else{ @@ -102376,7 +103722,10 @@ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ #endif } } - if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); + if( ExprHasProperty(p, EP_MemToken) ){ + assert( !ExprHasProperty(p, EP_IntValue) ); + sqlite3DbFree(db, p->u.zToken); + } if( !ExprHasProperty(p, EP_Static) ){ sqlite3DbFreeNN(db, p); } @@ -102418,7 +103767,7 @@ SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){ ** passed as the first argument. This is always one of EXPR_FULLSIZE, ** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. */ -static int exprStructSize(Expr *p){ +static int exprStructSize(const Expr *p){ if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE; if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE; return EXPR_FULLSIZE; @@ -102458,7 +103807,7 @@ static int exprStructSize(Expr *p){ ** of dupedExprStructSize() contain multiple assert() statements that attempt ** to enforce this constraint. */ -static int dupedExprStructSize(Expr *p, int flags){ +static int dupedExprStructSize(const Expr *p, int flags){ int nSize; assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); @@ -102489,7 +103838,7 @@ static int dupedExprStructSize(Expr *p, int flags){ ** of the Expr structure and a copy of the Expr.u.zToken string (if that ** string is defined.) */ -static int dupedExprNodeSize(Expr *p, int flags){ +static int dupedExprNodeSize(const Expr *p, int flags){ int nByte = dupedExprStructSize(p, flags) & 0xfff; if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ nByte += sqlite3Strlen30NN(p->u.zToken)+1; @@ -102510,7 +103859,7 @@ static int dupedExprNodeSize(Expr *p, int flags){ ** and Expr.pRight variables (but not for any structures pointed to or ** descended from the Expr.x.pList or Expr.x.pSelect variables). */ -static int dupedExprSize(Expr *p, int flags){ +static int dupedExprSize(const Expr *p, int flags){ int nByte = 0; if( p ){ nByte = dupedExprNodeSize(p, flags); @@ -102529,7 +103878,7 @@ static int dupedExprSize(Expr *p, int flags){ ** if any. Before returning, *pzBuffer is set to the first byte past the ** portion of the buffer copied into by this function. */ -static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ +static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ Expr *pNew; /* Value to return */ u8 *zAlloc; /* Memory space from which to build Expr object */ u32 staticFlag; /* EP_Static if space not obtained from malloc */ @@ -102592,7 +103941,7 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ - if( ExprHasProperty(p, EP_xIsSelect) ){ + if( ExprUseXSelect(p) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); @@ -102621,7 +103970,6 @@ static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ if( pNew->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; - assert( p->iColumn==0 || p->pRight==0 ); assert( p->pRight==0 || p->pRight==p->pLeft || ExprHasProperty(p->pLeft, EP_Subquery) ); }else{ @@ -102711,15 +104059,17 @@ static void gatherSelectWindows(Select *p){ ** truncated version of the usual Expr structure that will be stored as ** part of the in-memory representation of the database schema. */ -SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, const Expr *p, int flags){ assert( flags==0 || flags==EXPRDUP_REDUCE ); return p ? exprDup(db, p, flags, 0) : 0; } -SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){ ExprList *pNew; - struct ExprList_item *pItem, *pOldItem; + struct ExprList_item *pItem; + const struct ExprList_item *pOldItem; int i; - Expr *pPriorSelectCol = 0; + Expr *pPriorSelectColOld = 0; + Expr *pPriorSelectColNew = 0; assert( db!=0 ); if( p==0 ) return 0; pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); @@ -102736,17 +104086,17 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags) && pOldExpr->op==TK_SELECT_COLUMN && (pNewExpr = pItem->pExpr)!=0 ){ - assert( pNewExpr->iColumn==0 || i>0 ); - if( pNewExpr->iColumn==0 ){ - assert( pOldExpr->pLeft==pOldExpr->pRight - || ExprHasProperty(pOldExpr->pLeft, EP_Subquery) ); - pPriorSelectCol = pNewExpr->pLeft = pNewExpr->pRight; + if( pNewExpr->pRight ){ + pPriorSelectColOld = pOldExpr->pRight; + pPriorSelectColNew = pNewExpr->pRight; + pNewExpr->pLeft = pNewExpr->pRight; }else{ - assert( i>0 ); - assert( pItem[-1].pExpr!=0 ); - assert( pNewExpr->iColumn==pItem[-1].pExpr->iColumn+1 ); - assert( pPriorSelectCol==pItem[-1].pExpr->pLeft ); - pNewExpr->pLeft = pPriorSelectCol; + if( pOldExpr->pLeft!=pPriorSelectColOld ){ + pPriorSelectColOld = pOldExpr->pLeft; + pPriorSelectColNew = sqlite3ExprDup(db, pPriorSelectColOld, flags); + pNewExpr->pRight = pPriorSelectColNew; + } + pNewExpr->pLeft = pPriorSelectColNew; } } pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); @@ -102768,7 +104118,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags) */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) -SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){ SrcList *pNew; int i; int nByte; @@ -102780,7 +104130,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ SrcItem *pNewItem = &pNew->a[i]; - SrcItem *pOldItem = &p->a[i]; + const SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -102812,7 +104162,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ } return pNew; } -SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){ IdList *pNew; int i; assert( db!=0 ); @@ -102836,11 +104186,11 @@ SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ } return pNew; } -SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){ Select *pRet = 0; Select *pNext = 0; Select **pp = &pRet; - Select *p; + const Select *p; assert( db!=0 ); for(p=pDup; p; p=p->pPrior){ @@ -102885,7 +104235,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ return pRet; } #else -SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){ assert( p==0 ); return 0; } @@ -103005,11 +104355,9 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector( } for(i=0; inId; i++){ - Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); + Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i, pColumns->nId); assert( pSubExpr!=0 || db->mallocFailed ); - assert( pSubExpr==0 || pSubExpr->iTable==0 ); if( pSubExpr==0 ) continue; - pSubExpr->iTable = pColumns->nId; pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ assert( pList->nExpr==iFirst+i+1 ); @@ -103083,7 +104431,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int SQLITE_PRIVATE void sqlite3ExprListSetName( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to add the span. */ - Token *pName, /* Name to be added */ + const Token *pName, /* Name to be added */ int dequote /* True to cause the name to be dequoted */ ){ assert( pList!=0 || pParse->db->mallocFailed!=0 ); @@ -103101,7 +104449,7 @@ SQLITE_PRIVATE void sqlite3ExprListSetName( ** to the token-map. */ sqlite3Dequote(pItem->zEName); if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName); + sqlite3RenameTokenMap(pParse, (const void*)pItem->zEName, pName); } } } @@ -103220,7 +104568,7 @@ SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char *zIn){ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ u32 v; assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); - if( !ExprHasProperty(pExpr, EP_Quoted) + if( !ExprHasProperty(pExpr, EP_Quoted|EP_IntValue) && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 ){ pExpr->op = TK_TRUEFALSE; @@ -103237,6 +104585,7 @@ SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ pExpr = sqlite3ExprSkipCollate((Expr*)pExpr); assert( pExpr->op==TK_TRUEFALSE ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); return pExpr->u.zToken[4]==0; @@ -103420,6 +104769,38 @@ SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } +/* +** Check pExpr to see if it is an invariant constraint on data source pSrc. +** This is an optimization. False negatives will perhaps cause slower +** queries, but false positives will yield incorrect answers. So when in +** double, return 0. +** +** To be an invariant constraint, the following must be true: +** +** (1) pExpr cannot refer to any table other than pSrc->iCursor. +** +** (2) pExpr cannot use subqueries or non-deterministic functions. +** +** (*) ** Not applicable to this branch ** +** +** (4) If pSrc is the right operand of a LEFT JOIN, then... +** (4a) pExpr must come from an ON clause.. +** (4b) and specifically the ON clause associated with the LEFT JOIN. +** +** (5) If pSrc is not the right operand of a LEFT JOIN or the left +** operand of a RIGHT JOIN, then pExpr must be from the WHERE +** clause, not an ON clause. +*/ +SQLITE_PRIVATE int sqlite3ExprIsTableConstraint(Expr *pExpr, const SrcItem *pSrc){ + if( pSrc->fg.jointype & JT_LEFT ){ + if( !ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (4a) */ + if( pExpr->w.iRightJoinTable!=pSrc->iCursor ) return 0; /* rule (4b) */ + }else{ + if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; /* rule (5) */ + } + return sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor); /* rules (1), (2) */ +} + /* ** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). @@ -103441,7 +104822,7 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ } /* Check if pExpr is a sub-select. If so, consider it variable. */ - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ pWalker->eCode = 0; return WRC_Abort; } @@ -103529,7 +104910,7 @@ SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. */ -SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ +SQLITE_PRIVATE int sqlite3ExprIsInteger(const Expr *p, int *pValue){ int rc = 0; if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ @@ -103548,9 +104929,9 @@ SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ break; } case TK_UMINUS: { - int v; + int v = 0; if( sqlite3ExprIsInteger(p->pLeft, &v) ){ - assert( v!=(-2147483647-1) ); + assert( ((unsigned int)v)!=0x80000000 ); *pValue = -v; rc = 1; } @@ -103591,10 +104972,11 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ case TK_BLOB: return 0; case TK_COLUMN: + assert( ExprUseYTab(p) ); return ExprHasProperty(p, EP_CanBeNull) || p->y.pTab==0 || /* Reference to column of index on expression */ (p->iColumn>=0 - && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */ + && p->y.pTab->aCol!=0 /* Possible due to prior error */ && p->y.pTab->aCol[p->iColumn].notNull==0); default: return 1; @@ -103662,13 +105044,13 @@ SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ ** table, then return NULL. */ #ifndef SQLITE_OMIT_SUBQUERY -static Select *isCandidateForInOpt(Expr *pX){ +static Select *isCandidateForInOpt(const Expr *pX){ Select *p; SrcList *pSrc; ExprList *pEList; Table *pTab; int i; - if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */ + if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */ if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */ p = pX->x.pSelect; if( p->pPrior ) return 0; /* Not a compound SELECT */ @@ -103686,7 +105068,7 @@ static Select *isCandidateForInOpt(Expr *pX){ if( pSrc->a[0].pSelect ) return 0; /* FROM is not a subquery or view */ pTab = pSrc->a[0].pTab; assert( pTab!=0 ); - assert( pTab->pSelect==0 ); /* FROM clause is not a view */ + assert( !IsView(pTab) ); /* FROM clause is not a view */ if( IsVirtual(pTab) ) return 0; /* FROM clause not a virtual table */ pEList = p->pEList; assert( pEList!=0 ); @@ -103839,7 +105221,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( ** or not NULL is actually possible (it may not be, for example, due ** to NOT NULL constraints in the schema). If no NULL values are possible, ** set prRhsHasNull to 0 before continuing. */ - if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){ + if( prRhsHasNull && ExprUseXSelect(pX) ){ int i; ExprList *pEList = pX->x.pSelect->pEList; for(i=0; inExpr; i++){ @@ -103995,7 +105377,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( */ if( eType==0 && (inFlags & IN_INDEX_NOOP_OK) - && !ExprHasProperty(pX, EP_xIsSelect) + && ExprUseXList(pX) && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) ){ eType = IN_INDEX_NOOP; @@ -104040,10 +105422,10 @@ SQLITE_PRIVATE int sqlite3FindInIndex( ** It is the responsibility of the caller to ensure that the returned ** string is eventually freed using sqlite3DbFree(). */ -static char *exprINAffinity(Parse *pParse, Expr *pExpr){ +static char *exprINAffinity(Parse *pParse, const Expr *pExpr){ Expr *pLeft = pExpr->pLeft; int nVal = sqlite3ExprVectorSize(pLeft); - Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0; + Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0; char *zRet; assert( pExpr->op==TK_IN ); @@ -104093,7 +105475,7 @@ SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpec */ SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ #ifndef SQLITE_OMIT_SUBQUERY - if( pExpr->flags & EP_xIsSelect ){ + if( ExprUseXSelect(pExpr) ){ sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1); }else #endif @@ -104157,10 +105539,11 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", pExpr->x.pSelect->selId)); } + assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); @@ -104169,6 +105552,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( } /* Begin coding the subroutine */ + assert( !ExprUseYWin(pExpr) ); ExprSetProperty(pExpr, EP_Subrtn); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); pExpr->y.sub.regReturn = ++pParse->nMem; @@ -104189,7 +105573,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( pExpr->iTable = iTab; addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId)); }else{ VdbeComment((v, "RHS of IN operator")); @@ -104197,7 +105581,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( #endif pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ /* Case 1: expr IN (SELECT ...) ** ** Generate code to write the results of the select into the temporary @@ -104295,6 +105679,7 @@ SQLITE_PRIVATE void sqlite3CodeRhsOfIN( if( addrOnce ){ sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ + assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); @@ -104331,19 +105716,22 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ testcase( pExpr->op==TK_EXISTS ); testcase( pExpr->op==TK_SELECT ); assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT ); - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( ExprUseXSelect(pExpr) ); pSel = pExpr->x.pSelect; /* If this routine has already been coded, then invoke it as a ** subroutine. */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId)); + assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); return pExpr->iTable; } /* Begin coding the subroutine */ + assert( !ExprUseYWin(pExpr) ); + assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) ); ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = @@ -104410,10 +105798,8 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } pSel->iLimit = 0; if( sqlite3Select(pParse, pSel, &dest) ){ - if( pParse->nErr ){ - pExpr->op2 = pExpr->op; - pExpr->op = TK_ERROR; - } + pExpr->op2 = pExpr->op; + pExpr->op = TK_ERROR; return 0; } pExpr->iTable = rReg = dest.iSDParm; @@ -104423,6 +105809,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ } /* Subroutine return */ + assert( ExprUseYSub(pExpr) ); sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3ClearTempRegCache(pParse); @@ -104439,7 +105826,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ */ SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ int nVector = sqlite3ExprVectorSize(pIn->pLeft); - if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){ + if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){ if( nVector!=pIn->x.pSelect->pEList->nExpr ){ sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); return 1; @@ -104573,13 +105960,15 @@ static void sqlite3ExprCodeIN( ** This is step (1) in the in-operator.md optimized algorithm. */ if( eType==IN_INDEX_NOOP ){ - ExprList *pList = pExpr->x.pList; - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + ExprList *pList; + CollSeq *pColl; int labelOk = sqlite3VdbeMakeLabel(pParse); int r2, regToFree; int regCkNull = 0; int ii; - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; + pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); if( destIfNull!=destIfFalse ){ regCkNull = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); @@ -104627,10 +106016,9 @@ static void sqlite3ExprCodeIN( }else{ destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); } - if( pParse->nErr ) goto sqlite3ExprCodeIN_finished; for(i=0; ipLeft, i); - if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; + if( pParse->nErr ) goto sqlite3ExprCodeIN_oom_error; if( sqlite3ExprCanBeNull(p) ){ sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); VdbeCoverage(v); @@ -104768,11 +106156,12 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ c = sqlite3DecOrHexToI64(z, &value); if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ #ifdef SQLITE_OMIT_FLOATING_POINT - sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); + sqlite3ErrorMsg(pParse, "oversized integer: %s%#T", negFlag?"-":"",pExpr); #else #ifndef SQLITE_OMIT_HEX_INTEGER if( sqlite3_strnicmp(z,"0x",2)==0 ){ - sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z); + sqlite3ErrorMsg(pParse, "hex literal too big: %s%#T", + negFlag?"-":"",pExpr); }else #endif { @@ -104816,9 +106205,10 @@ SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn( ** and store the result in register regOut */ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( - Parse *pParse, - Column *pCol, - int regOut + Parse *pParse, /* Parsing context */ + Table *pTab, /* Table containing the generated column */ + Column *pCol, /* The generated column */ + int regOut /* Put the result in this register */ ){ int iAddr; Vdbe *v = pParse->pVdbe; @@ -104829,7 +106219,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( }else{ iAddr = 0; } - sqlite3ExprCodeCopy(pParse, pCol->pDflt, regOut); + sqlite3ExprCodeCopy(pParse, sqlite3ColumnExpr(pTab,pCol), regOut); if( pCol->affinity>=SQLITE_AFF_TEXT ){ sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); } @@ -104865,12 +106255,13 @@ SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ Parse *pParse = sqlite3VdbeParser(v); if( pCol->colFlags & COLFLAG_BUSY ){ - sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + pCol->zCnName); }else{ int savedSelfTab = pParse->iSelfTab; pCol->colFlags |= COLFLAG_BUSY; pParse->iSelfTab = iTabCur+1; - sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut); + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, regOut); pParse->iSelfTab = savedSelfTab; pCol->colFlags &= ~COLFLAG_BUSY; } @@ -104963,6 +106354,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ int i; iResult = pParse->nMem+1; pParse->nMem += nResult; + assert( ExprUseXList(p) ); for(i=0; ix.pList->a[i].pExpr, i+iResult); } @@ -105037,6 +106429,7 @@ static int exprCodeInlineFunction( ** Test-only SQL functions that are only usable if enabled ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS */ +#if !defined(SQLITE_UNTESTABLE) case INLINEFUNC_expr_compare: { /* Compare two expressions using sqlite3ExprCompare() */ assert( nFarg==2 ); @@ -105070,7 +106463,6 @@ static int exprCodeInlineFunction( break; } -#ifdef SQLITE_DEBUG case INLINEFUNC_affinity: { /* The AFFINITY() function evaluates to a string that describes ** the type affinity of the argument. This is used for testing of @@ -105084,7 +106476,7 @@ static int exprCodeInlineFunction( (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); break; } -#endif +#endif /* !defined(SQLITE_UNTESTABLE) */ } return target; } @@ -105138,7 +106530,8 @@ expr_code_doover: if( pCol->iColumn<0 ){ VdbeComment((v,"%s.rowid",pTab->zName)); }else{ - VdbeComment((v,"%s.%s",pTab->zName,pTab->aCol[pCol->iColumn].zName)); + VdbeComment((v,"%s.%s", + pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } @@ -105160,6 +106553,7 @@ expr_code_doover: */ int aff; iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + assert( ExprUseYTab(pExpr) ); if( pExpr->y.pTab ){ aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); }else{ @@ -105183,9 +106577,11 @@ expr_code_doover: ** immediately prior to the first column. */ Column *pCol; - Table *pTab = pExpr->y.pTab; + Table *pTab; int iSrc; int iCol = pExpr->iColumn; + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; assert( pTab!=0 ); assert( iCol>=XN_ROWID ); assert( iColnCol ); @@ -105199,12 +106595,12 @@ expr_code_doover: if( pCol->colFlags & COLFLAG_GENERATED ){ if( pCol->colFlags & COLFLAG_BUSY ){ sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", - pCol->zName); + pCol->zCnName); return 0; } pCol->colFlags |= COLFLAG_BUSY; if( pCol->colFlags & COLFLAG_NOTAVAIL ){ - sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc); + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, iSrc); } pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); return iSrc; @@ -105223,6 +106619,7 @@ expr_code_doover: iTab = pParse->iSelfTab - 1; } } + assert( ExprUseYTab(pExpr) ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); @@ -105300,6 +106697,7 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); inReg = target; } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); sqlite3VdbeAddOp2(v, OP_Cast, target, sqlite3AffinityType(pExpr->u.zToken, 0)); return inReg; @@ -105439,7 +106837,7 @@ expr_code_doover: || NEVER(pExpr->iAgg>=pInfo->nFunc) ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %#T()", pExpr); }else{ return pInfo->aFunc[pExpr->iAgg].iMem; } @@ -105467,8 +106865,8 @@ expr_code_doover: ** multiple times if we know they always give the same result */ return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1); } - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); assert( !ExprHasProperty(pExpr, EP_TokenOnly) ); + assert( ExprUseXList(pExpr) ); pFarg = pExpr->x.pList; nFarg = pFarg ? pFarg->nExpr : 0; assert( !ExprHasProperty(pExpr, EP_IntValue) ); @@ -105480,7 +106878,7 @@ expr_code_doover: } #endif if( pDef==0 || pDef->xFinalize!=0 ){ - sqlite3ErrorMsg(pParse, "unknown function: %s()", zId); + sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); break; } if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ @@ -105557,7 +106955,7 @@ expr_code_doover: sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){ + if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){ Expr *pArg = pFarg->a[0].pExpr; if( pArg->op==TK_COLUMN ){ sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); @@ -105587,7 +106985,10 @@ expr_code_doover: testcase( op==TK_SELECT ); if( pParse->db->mallocFailed ){ return 0; - }else if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){ + }else if( op==TK_SELECT + && ALWAYS( ExprUseXSelect(pExpr) ) + && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 + ){ sqlite3SubselectError(pParse, nCol, 1); }else{ return sqlite3CodeSubselect(pParse, pExpr); @@ -105599,11 +107000,9 @@ expr_code_doover: if( pExpr->pLeft->iTable==0 ){ pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } - assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT - || pExpr->pLeft->op==TK_ERROR ); - if( pExpr->iTable!=0 - && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) - ){ + assert( pExpr->pLeft->op==TK_SELECT || pExpr->pLeft->op==TK_ERROR ); + n = sqlite3ExprVectorSize(pExpr->pLeft); + if( pExpr->iTable!=n ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); } @@ -105671,9 +107070,14 @@ expr_code_doover: ** p1==1 -> old.a p1==4 -> new.a ** p1==2 -> old.b p1==5 -> new.b */ - Table *pTab = pExpr->y.pTab; - int iCol = pExpr->iColumn; - int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + Table *pTab; + int iCol; + int p1; + + assert( ExprUseYTab(pExpr) ); + pTab = pExpr->y.pTab; + iCol = pExpr->iColumn; + p1 = pExpr->iTable * (pTab->nCol+1) + 1 + sqlite3TableColumnToStorage(pTab, iCol); assert( pExpr->iTable==0 || pExpr->iTable==1 ); @@ -105684,7 +107088,7 @@ expr_code_doover: sqlite3VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "r[%d]=%s.%s", target, (pExpr->iTable ? "new" : "old"), - (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName) + (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zCnName) )); #ifndef SQLITE_OMIT_FLOATING_POINT @@ -105761,7 +107165,7 @@ expr_code_doover: Expr *pDel = 0; sqlite3 *db = pParse->db; - assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); + assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 ); assert(pExpr->x.pList->nExpr > 0); pEList = pExpr->x.pList; aListelem = pEList->a; @@ -105958,7 +107362,7 @@ SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); if( inReg!=target ){ u8 op; - if( ExprHasProperty(pExpr,EP_Subquery) ){ + if( ALWAYS(pExpr) && ExprHasProperty(pExpr,EP_Subquery) ){ op = OP_Copy; }else{ op = OP_SCopy; @@ -106106,7 +107510,7 @@ static void exprCodeBetween( memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( ExprUseXList(pExpr) ); pDel = sqlite3ExprDup(db, pExpr->pLeft, 0); if( db->mallocFailed==0 ){ exprAnd.op = TK_AND; @@ -106496,7 +107900,11 @@ SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,i ** Otherwise, if the values are not the same or if pExpr is not a simple ** SQL value, zero is returned. */ -static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){ +static int exprCompareVariable( + const Parse *pParse, + const Expr *pVar, + const Expr *pExpr +){ int res = 0; int iVar; sqlite3_value *pL, *pR = 0; @@ -106548,7 +107956,12 @@ static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){ ** Argument pParse should normally be NULL. If it is not NULL and pA or ** pB causes a return value of 2. */ -SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ +SQLITE_PRIVATE int sqlite3ExprCompare( + const Parse *pParse, + const Expr *pA, + const Expr *pB, + int iTab +){ u32 combinedFlags; if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; @@ -106572,7 +107985,9 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa } return 2; } - if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ + assert( !ExprHasProperty(pA, EP_IntValue) ); + assert( !ExprHasProperty(pB, EP_IntValue) ); + if( pA->u.zToken ){ if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; #ifndef SQLITE_OMIT_WINDOWFUNC @@ -106590,7 +108005,12 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa return 0; }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; - }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ + }else + if( pB->u.zToken!=0 + && pA->op!=TK_COLUMN + && pA->op!=TK_AGG_COLUMN + && strcmp(pA->u.zToken,pB->u.zToken)!=0 + ){ return 2; } } @@ -106632,7 +108052,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTa ** Two NULL pointers are considered to be the same. But a NULL pointer ** always differs from a non-NULL pointer. */ -SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ +SQLITE_PRIVATE int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){ int i; if( pA==0 && pB==0 ) return 0; if( pA==0 || pB==0 ) return 1; @@ -106651,7 +108071,7 @@ SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ ** Like sqlite3ExprCompare() except COLLATE operators at the top-level ** are ignored. */ -SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){ return sqlite3ExprCompare(0, sqlite3ExprSkipCollateAndLikely(pA), sqlite3ExprSkipCollateAndLikely(pB), @@ -106665,9 +108085,9 @@ SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ ** non-NULL if pNN is not NULL */ static int exprImpliesNotNull( - Parse *pParse, /* Parsing context */ - Expr *p, /* The expression to be checked */ - Expr *pNN, /* The expression that is NOT NULL */ + const Parse *pParse,/* Parsing context */ + const Expr *p, /* The expression to be checked */ + const Expr *pNN, /* The expression that is NOT NULL */ int iTab, /* Table being evaluated */ int seenNot /* Return true only if p can be any non-NULL value */ ){ @@ -106679,12 +108099,13 @@ static int exprImpliesNotNull( switch( p->op ){ case TK_IN: { if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0; - assert( ExprHasProperty(p,EP_xIsSelect) - || (p->x.pList!=0 && p->x.pList->nExpr>0) ); + assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) ); return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_BETWEEN: { - ExprList *pList = p->x.pList; + ExprList *pList; + assert( ExprUseXList(p) ); + pList = p->x.pList; assert( pList!=0 ); assert( pList->nExpr==2 ); if( seenNot ) return 0; @@ -106760,7 +108181,12 @@ static int exprImpliesNotNull( ** improvement. Returning false might cause a performance reduction, but ** it will always give the correct answer and is hence always safe. */ -SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ +SQLITE_PRIVATE int sqlite3ExprImpliesExpr( + const Parse *pParse, + const Expr *pE1, + const Expr *pE2, + int iTab +){ if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){ return 1; } @@ -106856,10 +108282,14 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_GE ); /* The y.pTab=0 assignment in wherecode.c always happens after the ** impliesNotNullRow() test */ - if( (pLeft->op==TK_COLUMN && ALWAYS(pLeft->y.pTab!=0) - && IsVirtual(pLeft->y.pTab)) - || (pRight->op==TK_COLUMN && ALWAYS(pRight->y.pTab!=0) - && IsVirtual(pRight->y.pTab)) + assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); + assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); + if( (pLeft->op==TK_COLUMN + && pLeft->y.pTab!=0 + && IsVirtual(pLeft->y.pTab)) + || (pRight->op==TK_COLUMN + && pRight->y.pTab!=0 + && IsVirtual(pRight->y.pTab)) ){ return WRC_Prune; } @@ -106968,88 +108398,125 @@ SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( } -/* -** An instance of the following structure is used by the tree walker -** to count references to table columns in the arguments of an -** aggregate function, in order to implement the -** sqlite3FunctionThisSrc() routine. +/* Structure used to pass information throught the Walker in order to +** implement sqlite3ReferencesSrcList(). */ -struct SrcCount { - SrcList *pSrc; /* One particular FROM clause in a nested query */ - int iSrcInner; /* Smallest cursor number in this context */ - int nThis; /* Number of references to columns in pSrcList */ - int nOther; /* Number of references to columns in other FROM clauses */ +struct RefSrcList { + sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */ + SrcList *pRef; /* Looking for references to these tables */ + i64 nExclude; /* Number of tables to exclude from the search */ + int *aiExclude; /* Cursor IDs for tables to exclude from the search */ }; /* -** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first -** SELECT with a FROM clause encountered during this iteration, set -** SrcCount.iSrcInner to the cursor number of the leftmost object in -** the FROM cause. +** Walker SELECT callbacks for sqlite3ReferencesSrcList(). +** +** When entering a new subquery on the pExpr argument, add all FROM clause +** entries for that subquery to the exclude list. +** +** When leaving the subquery, remove those entries from the exclude list. */ -static int selectSrcCount(Walker *pWalker, Select *pSel){ - struct SrcCount *p = pWalker->u.pSrcCount; - if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){ - pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor; +static int selectRefEnter(Walker *pWalker, Select *pSelect){ + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = pSelect->pSrc; + i64 i, j; + int *piNew; + if( pSrc->nSrc==0 ) return WRC_Continue; + j = p->nExclude; + p->nExclude += pSrc->nSrc; + piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int)); + if( piNew==0 ){ + p->nExclude = 0; + return WRC_Abort; + }else{ + p->aiExclude = piNew; + } + for(i=0; inSrc; i++, j++){ + p->aiExclude[j] = pSrc->a[i].iCursor; } return WRC_Continue; } +static void selectRefLeave(Walker *pWalker, Select *pSelect){ + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = pSelect->pSrc; + if( p->nExclude ){ + assert( p->nExclude>=pSrc->nSrc ); + p->nExclude -= pSrc->nSrc; + } +} -/* -** Count the number of references to columns. +/* This is the Walker EXPR callback for sqlite3ReferencesSrcList(). +** +** Set the 0x01 bit of pWalker->eCode if there is a reference to any +** of the tables shown in RefSrcList.pRef. +** +** Set the 0x02 bit of pWalker->eCode if there is a reference to a +** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude. */ -static int exprSrcCount(Walker *pWalker, Expr *pExpr){ - /* There was once a NEVER() on the second term on the grounds that - ** sqlite3FunctionUsesThisSrc() was always called before - ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet - ** been converted into TK_AGG_COLUMN. But this is no longer true due - ** to window functions - sqlite3WindowRewrite() may now indirectly call - ** FunctionUsesThisSrc() when creating a new sub-select. */ - if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){ +static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){ + if( pExpr->op==TK_COLUMN + || pExpr->op==TK_AGG_COLUMN + ){ int i; - struct SrcCount *p = pWalker->u.pSrcCount; - SrcList *pSrc = p->pSrc; + struct RefSrcList *p = pWalker->u.pRefSrcList; + SrcList *pSrc = p->pRef; int nSrc = pSrc ? pSrc->nSrc : 0; for(i=0; iiTable==pSrc->a[i].iCursor ) break; + if( pExpr->iTable==pSrc->a[i].iCursor ){ + pWalker->eCode |= 1; + return WRC_Continue; + } } - if( inThis++; - }else if( pExpr->iTableiSrcInner ){ - /* In a well-formed parse tree (no name resolution errors), - ** TK_COLUMN nodes with smaller Expr.iTable values are in an - ** outer context. Those are the only ones to count as "other" */ - p->nOther++; + for(i=0; inExclude && p->aiExclude[i]!=pExpr->iTable; i++){} + if( i>=p->nExclude ){ + pWalker->eCode |= 2; } } return WRC_Continue; } /* -** Determine if any of the arguments to the pExpr Function reference -** pSrcList. Return true if they do. Also return true if the function -** has no arguments or has only constant arguments. Return false if pExpr -** references columns but not columns of tables found in pSrcList. +** Check to see if pExpr references any tables in pSrcList. +** Possible return values: +** +** 1 pExpr does references a table in pSrcList. +** +** 0 pExpr references some table that is not defined in either +** pSrcList or in subqueries of pExpr itself. +** +** -1 pExpr only references no tables at all, or it only +** references tables defined in subqueries of pExpr itself. +** +** As currently used, pExpr is always an aggregate function call. That +** fact is exploited for efficiency. */ -SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ +SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){ Walker w; - struct SrcCount cnt; - assert( pExpr->op==TK_AGG_FUNCTION ); + struct RefSrcList x; memset(&w, 0, sizeof(w)); - w.xExprCallback = exprSrcCount; - w.xSelectCallback = selectSrcCount; - w.u.pSrcCount = &cnt; - cnt.pSrc = pSrcList; - cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF; - cnt.nThis = 0; - cnt.nOther = 0; + memset(&x, 0, sizeof(x)); + w.xExprCallback = exprRefToSrcList; + w.xSelectCallback = selectRefEnter; + w.xSelectCallback2 = selectRefLeave; + w.u.pRefSrcList = &x; + x.db = pParse->db; + x.pRef = pSrcList; + assert( pExpr->op==TK_AGG_FUNCTION ); + assert( ExprUseXList(pExpr) ); sqlite3WalkExprList(&w, pExpr->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); } #endif - return cnt.nThis>0 || cnt.nOther==0; + sqlite3DbFree(pParse->db, x.aiExclude); + if( w.eCode & 0x01 ){ + return 1; + }else if( w.eCode ){ + return 0; + }else{ + return -1; + } } /* @@ -107184,6 +108651,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 ){ pCol = &pAggInfo->aCol[k]; + assert( ExprUseYTab(pExpr) ); pCol->pTab = pExpr->y.pTab; pCol->iTable = pExpr->iTable; pCol->iColumn = pExpr->iColumn; @@ -107247,7 +108715,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; pItem->iMem = ++pParse->nMem; - assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( ExprUseUToken(pExpr) ); pItem->pFunc = sqlite3FindFunction(pParse->db, pExpr->u.zToken, pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); @@ -107462,7 +108930,7 @@ static void renameTestSchema( pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " - "FROM \"%w\"." DFLT_SCHEMA_TABLE " " + "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ", @@ -107473,7 +108941,7 @@ static void renameTestSchema( if( bTemp==0 ){ sqlite3NestedParse(pParse, "SELECT 1 " - "FROM temp." DFLT_SCHEMA_TABLE " " + "FROM temp." LEGACY_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ", @@ -107491,14 +108959,14 @@ static void renameTestSchema( */ static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){ sqlite3NestedParse(pParse, - "UPDATE \"%w\"." DFLT_SCHEMA_TABLE + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET sql = sqlite_rename_quotefix(%Q, sql)" "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb ); if( bTemp==0 ){ sqlite3NestedParse(pParse, - "UPDATE temp." DFLT_SCHEMA_TABLE + "UPDATE temp." LEGACY_SCHEMA_TABLE " SET sql = sqlite_rename_quotefix('temp', sql)" "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" @@ -107537,9 +109005,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( const char *zTabName; /* Original name of the table */ Vdbe *v; VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ - u32 savedDbFlags; /* Saved value of db->mDbFlags */ - savedDbFlags = db->mDbFlags; if( NEVER(db->mallocFailed) ) goto exit_rename_table; assert( pSrc->nSrc==1 ); assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); @@ -107548,7 +109014,6 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( if( !pTab ) goto exit_rename_table; iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; - db->mDbFlags |= DBFLAG_PreferBuiltin; /* Get a NULL terminated version of the new table name. */ zName = sqlite3NameFromToken(db, pName); @@ -107577,7 +109042,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( } #ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); goto exit_rename_table; } @@ -107619,7 +109084,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in ** the schema to use the new table name. */ sqlite3NestedParse(pParse, - "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" @@ -107629,7 +109094,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( /* Update the tbl_name and name columns of the sqlite_schema table ** as required. */ sqlite3NestedParse(pParse, - "UPDATE %Q." DFLT_SCHEMA_TABLE " SET " + "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET " "tbl_name = %Q, " "name = CASE " "WHEN type='table' THEN %Q " @@ -107689,7 +109154,6 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( exit_rename_table: sqlite3SrcListDelete(db, pSrc); sqlite3DbFree(db, zName); - db->mDbFlags = savedDbFlags; } /* @@ -107730,7 +109194,9 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ int r1; /* Temporary registers */ db = pParse->db; - if( pParse->nErr || db->mallocFailed ) return; + assert( db->pParse==pParse ); + if( pParse->nErr ) return; + assert( db->mallocFailed==0 ); pNew = pParse->pNewTable; assert( pNew ); @@ -107739,7 +109205,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ zDb = db->aDb[iDb].zDbSName; zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = &pNew->aCol[pNew->nCol-1]; - pDflt = pCol->pDflt; + pDflt = sqlite3ColumnExpr(pNew, pCol); pTab = sqlite3FindTable(db, zTab, zDb); assert( pTab ); @@ -107773,7 +109239,8 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ if( pDflt && pDflt->pLeft->op==TK_NULL ){ pDflt = 0; } - if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ + assert( IsOrdinaryTable(pNew) ); + if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){ sqlite3ErrorIfNotEmpty(pParse, zDb, zTab, "Cannot add a REFERENCES column with non-NULL default value"); } @@ -107810,31 +109277,30 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); if( zCol ){ char *zEnd = &zCol[pColDef->n-1]; - u32 savedDbFlags = db->mDbFlags; while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ *zEnd-- = '\0'; } - db->mDbFlags |= DBFLAG_PreferBuiltin; /* substr() operations on characters, but addColOffset is in bytes. So we ** have to use printf() to translate between these units: */ + assert( IsOrdinaryTable(pTab) ); + assert( IsOrdinaryTable(pNew) ); sqlite3NestedParse(pParse, - "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = printf('%%.%ds, ',sql) || %Q" " || substr(sql,1+length(printf('%%.%ds',sql))) " "WHERE type = 'table' AND name = %Q", - zDb, pNew->addColOffset, zCol, pNew->addColOffset, + zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset, zTab ); sqlite3DbFree(db, zCol); - db->mDbFlags = savedDbFlags; } - /* Make sure the schema version is at least 3. But do not upgrade - ** from less than 3 to 4, as that will corrupt any preexisting DESC - ** index. - */ v = sqlite3GetVdbe(pParse); if( v ){ + /* Make sure the schema version is at least 3. But do not upgrade + ** from less than 3 to 4, as that will corrupt any preexisting DESC + ** index. + */ r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); sqlite3VdbeUsesBtree(v, iDb); @@ -107843,10 +109309,25 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); sqlite3ReleaseTempReg(pParse, r1); - } - /* Reload the table definition */ - renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + /* Reload the table definition */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd); + + /* Verify that constraints are still satisfied */ + if( pNew->pCheck!=0 + || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + ){ + sqlite3NestedParse(pParse, + "SELECT CASE WHEN quick_check GLOB 'CHECK*'" + " THEN raise(ABORT,'CHECK constraint failed')" + " ELSE raise(ABORT,'NOT NULL constraint failed')" + " END" + " FROM pragma_quick_check(%Q,%Q)" + " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", + zTab, zDb + ); + } + } } /* @@ -107887,7 +109368,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ #endif /* Make sure this is not an attempt to ALTER a view. */ - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } @@ -107896,7 +109377,8 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ } sqlite3MayAbort(pParse); - assert( pTab->addColOffset>0 ); + assert( IsOrdinaryTable(pTab) ); + assert( pTab->u.tab.addColOffset>0 ); iDb = sqlite3SchemaToIndex(db, pTab->pSchema); /* Put a copy of the Table struct in Parse.pNewTable for the @@ -107923,13 +109405,13 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); for(i=0; inCol; i++){ Column *pCol = &pNew->aCol[i]; - pCol->zName = sqlite3DbStrDup(db, pCol->zName); - pCol->hName = sqlite3StrIHash(pCol->zName); - pCol->zColl = 0; - pCol->pDflt = 0; + pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName); + pCol->hName = sqlite3StrIHash(pCol->zCnName); } + assert( IsOrdinaryTable(pNew) ); + pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); pNew->pSchema = db->aDb[iDb].pSchema; - pNew->addColOffset = pTab->addColOffset; + pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; pNew->nTabRef = 1; exit_begin_add_column: @@ -107949,7 +109431,7 @@ exit_begin_add_column: static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ const char *zType = 0; #ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ + if( IsView(pTab) ){ zType = "view"; } #endif @@ -108016,10 +109498,10 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( zOld = sqlite3NameFromToken(db, pOld); if( !zOld ) goto exit_rename_column; for(iCol=0; iColnCol; iCol++){ - if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zCnName, zOld) ) break; } if( iCol==pTab->nCol ){ - sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pOld); goto exit_rename_column; } @@ -108037,18 +109519,17 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( assert( pNew->n>0 ); bQuote = sqlite3Isquote(pNew->z[0]); sqlite3NestedParse(pParse, - "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " - " AND (type != 'index' OR tbl_name = %Q)" - " AND sql NOT LIKE 'create virtual%%'", + " AND (type != 'index' OR tbl_name = %Q)", zDb, zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1, pTab->zName ); sqlite3NestedParse(pParse, - "UPDATE temp." DFLT_SCHEMA_TABLE " SET " + "UPDATE temp." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " "WHERE type IN ('trigger', 'view')", zDb, pTab->zName, iCol, zNew, bQuote @@ -108083,7 +109564,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( ** the parse tree. */ struct RenameToken { - void *p; /* Parse tree element created by token t */ + const void *p; /* Parse tree element created by token t */ Token t; /* The token that created parse tree element p */ RenameToken *pNext; /* Next is a list of all RenameToken objects */ }; @@ -108125,9 +109606,11 @@ struct RenameCtx { ** Technically, as x no longer points into a valid object or to the byte ** following a valid object, it may not be used in comparison operations. */ -static void renameTokenCheckAll(Parse *pParse, void *pPtr){ - if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){ - RenameToken *p; +static void renameTokenCheckAll(Parse *pParse, const void *pPtr){ + assert( pParse==pParse->db->pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr==0 ){ + const RenameToken *p; u8 i = 0; for(p=pParse->pRename; p; p=p->pNext){ if( p->p ){ @@ -108153,7 +109636,11 @@ static void renameTokenCheckAll(Parse *pParse, void *pPtr){ ** with tail recursion in tokenExpr() routine, for a small performance ** improvement. */ -SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ +SQLITE_PRIVATE const void *sqlite3RenameTokenMap( + Parse *pParse, + const void *pPtr, + const Token *pToken +){ RenameToken *pNew; assert( pPtr || pParse->db->mallocFailed ); renameTokenCheckAll(pParse, pPtr); @@ -108175,7 +109662,7 @@ SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pTo ** with parse tree element pFrom. This function remaps the associated token ** to parse tree element pTo. */ -SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){ +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom){ RenameToken *p; renameTokenCheckAll(pParse, pTo); for(p=pParse->pRename; p; p=p->pNext){ @@ -108191,7 +109678,10 @@ SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFro */ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ Parse *pParse = pWalker->pParse; - sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr); + if( ExprUseYTab(pExpr) ){ + sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab); + } return WRC_Continue; } @@ -108221,6 +109711,7 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC); + if( sNC.pParse->db->mallocFailed ) return; sqlite3WalkSelect(pWalker, p); sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols); } @@ -108235,12 +109726,12 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ */ static void unmapColumnIdlistNames( Parse *pParse, - IdList *pIdList + const IdList *pIdList ){ if( pIdList ){ int ii; for(ii=0; iinId; ii++){ - sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName); + sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName); } } } @@ -108252,9 +109743,9 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; int i; if( pParse->nErr ) return WRC_Abort; + testcase( p->selFlags & SF_View ); + testcase( p->selFlags & SF_CopyCte ); if( p->selFlags & (SF_View|SF_CopyCte) ){ - testcase( p->selFlags & SF_View ); - testcase( p->selFlags & SF_CopyCte ); return WRC_Prune; } if( ALWAYS(p->pEList) ){ @@ -108269,7 +109760,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ SrcList *pSrc = p->pSrc; for(i=0; inSrc; i++){ sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); - if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort; + sqlite3WalkExpr(pWalker, pSrc->a[i].pOn); unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing); } } @@ -108337,7 +109828,7 @@ static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ static RenameToken *renameTokenFind( Parse *pParse, struct RenameCtx *pCtx, - void *pPtr + const void *pPtr ){ RenameToken **pp; if( NEVER(pPtr==0) ){ @@ -108391,6 +109882,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ renameTokenFind(pWalker->pParse, p, (void*)pExpr); }else if( pExpr->op==TK_COLUMN && pExpr->iColumn==p->iCol + && ALWAYS(ExprUseYTab(pExpr)) && p->pTab==pExpr->y.pTab ){ renameTokenFind(pWalker->pParse, p, (void*)pExpr); @@ -108439,12 +109931,12 @@ static void renameColumnParseError( const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3_mprintf("error in %s %s%s%s: %s", + zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s", zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); - sqlite3_free(zErr); + sqlite3DbFree(pParse->db, zErr); } /* @@ -108456,18 +109948,18 @@ static void renameColumnParseError( static void renameColumnElistNames( Parse *pParse, RenameCtx *pCtx, - ExprList *pEList, + const ExprList *pEList, const char *zOld ){ if( pEList ){ int i; for(i=0; inExpr; i++){ - char *zName = pEList->a[i].zEName; + const char *zName = pEList->a[i].zEName; if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) && ALWAYS(zName!=0) && 0==sqlite3_stricmp(zName, zOld) ){ - renameTokenFind(pParse, pCtx, (void*)zName); + renameTokenFind(pParse, pCtx, (const void*)zName); } } } @@ -108481,15 +109973,15 @@ static void renameColumnElistNames( static void renameColumnIdlistNames( Parse *pParse, RenameCtx *pCtx, - IdList *pIdList, + const IdList *pIdList, const char *zOld ){ if( pIdList ){ int i; for(i=0; inId; i++){ - char *zName = pIdList->a[i].zName; + const char *zName = pIdList->a[i].zName; if( 0==sqlite3_stricmp(zName, zOld) ){ - renameTokenFind(pParse, pCtx, (void*)zName); + renameTokenFind(pParse, pCtx, (const void*)zName); } } } @@ -108508,24 +110000,22 @@ static int renameParseSql( int bTemp /* True if SQL is from temp schema */ ){ int rc; - char *zErr = 0; + sqlite3ParseObjectInit(p, db); + if( zSql==0 ){ + return SQLITE_NOMEM; + } + if( sqlite3StrNICmp(zSql,"CREATE ",7)!=0 ){ + return SQLITE_CORRUPT_BKPT; + } db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); - - /* Parse the SQL statement passed as the first argument. If no error - ** occurs and the parse does not result in a new table, index or - ** trigger object, the database must be corrupt. */ - memset(p, 0, sizeof(Parse)); p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; - assert( p->zErrMsg==0 ); - assert( rc!=SQLITE_OK || zErr==0 ); - p->zErrMsg = zErr; + rc = sqlite3RunParser(p, zSql); if( db->mallocFailed ) rc = SQLITE_NOMEM; if( rc==SQLITE_OK - && p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0 + && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) ){ rc = SQLITE_CORRUPT_BKPT; } @@ -108715,6 +110205,9 @@ static int renameResolveTrigger(Parse *pParse){ } } } + if( rc==SQLITE_OK && db->mallocFailed ){ + rc = SQLITE_NOMEM; + } sNC.pSrcList = pSrc; if( rc==SQLITE_OK && pStep->pWhere ){ rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); @@ -108800,13 +110293,13 @@ static void renameParseCleanup(Parse *pParse){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->zErrMsg); renameTokenFree(db, pParse->pRename); - sqlite3ParserReset(pParse); + sqlite3ParseObjectReset(pParse); } /* ** SQL function: ** -** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld) +** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP) ** ** 0. zSql: SQL statement to rewrite ** 1. type: Type of object ("table", "view" etc.) @@ -108824,7 +110317,8 @@ static void renameParseCleanup(Parse *pParse){ ** ** This function is used internally by the ALTER TABLE RENAME COLUMN command. ** It is only accessible to SQL created using sqlite3NestedParse(). It is -** not reachable from ordinary SQL passed into sqlite3_prepare(). +** not reachable from ordinary SQL passed into sqlite3_prepare() unless the +** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled. */ static void renameColumnFunc( sqlite3_context *context, @@ -108862,7 +110356,7 @@ static void renameColumnFunc( sqlite3BtreeLeaveAll(db); return; } - zOld = pTab->aCol[iCol].zName; + zOld = pTab->aCol[iCol].zCnName; memset(&sCtx, 0, sizeof(sCtx)); sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol); @@ -108881,8 +110375,8 @@ static void renameColumnFunc( sCtx.pTab = pTab; if( rc!=SQLITE_OK ) goto renameColumnFunc_done; if( sParse.pNewTable ){ - Select *pSelect = sParse.pNewTable->pSelect; - if( pSelect ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); @@ -108891,16 +110385,15 @@ static void renameColumnFunc( sqlite3WalkSelect(&sWalker, pSelect); } if( rc!=SQLITE_OK ) goto renameColumnFunc_done; - }else{ + }else if( IsOrdinaryTable(sParse.pNewTable) ){ /* A regular table */ int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); FKey *pFKey; - assert( sParse.pNewTable->pSelect==0 ); sCtx.pTab = sParse.pNewTable; if( bFKOnly==0 ){ if( iColnCol ){ renameTokenFind( - &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zName + &sParse, &sCtx, (void*)sParse.pNewTable->aCol[iCol].zCnName ); } if( sCtx.iCol<0 ){ @@ -108915,12 +110408,15 @@ static void renameColumnFunc( } #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + Expr *pExpr = sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i]); + sqlite3WalkExpr(&sWalker, pExpr); } #endif } - for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( IsOrdinaryTable(sParse.pNewTable) ); + for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; inCol; i++){ if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); @@ -108971,7 +110467,9 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ - if( sParse.zErrMsg ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[0]); + }else if( sParse.zErrMsg ){ renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); @@ -108991,7 +110489,10 @@ renameColumnFunc_done: */ static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ RenameCtx *p = pWalker->u.pRename; - if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){ + if( pExpr->op==TK_COLUMN + && ALWAYS(ExprUseYTab(pExpr)) + && p->pTab==pExpr->y.pTab + ){ renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); } return WRC_Continue; @@ -109086,28 +110587,31 @@ static void renameTableFunc( if( sParse.pNewTable ){ Table *pTab = sParse.pNewTable; - if( pTab->pSelect ){ + if( IsView(pTab) ){ if( isLegacy==0 ){ - Select *pSelect = pTab->pSelect; + Select *pSelect = pTab->u.view.pSelect; NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; assert( pSelect->selFlags & SF_View ); pSelect->selFlags &= ~SF_View; - sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); + sqlite3SelectPrep(&sParse, pTab->u.view.pSelect, &sNC); if( sParse.nErr ){ rc = sParse.rc; }else{ - sqlite3WalkSelect(&sWalker, pTab->pSelect); + sqlite3WalkSelect(&sWalker, pTab->u.view.pSelect); } } }else{ /* Modify any FK definitions to point to the new table. */ #ifndef SQLITE_OMIT_FOREIGN_KEY - if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){ + if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys)) + && !IsVirtual(pTab) + ){ FKey *pFKey; - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); } @@ -109164,7 +110668,9 @@ static void renameTableFunc( rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote); } if( rc!=SQLITE_OK ){ - if( sParse.zErrMsg ){ + if( rc==SQLITE_ERROR && sqlite3WritableSchema(db) ){ + sqlite3_result_value(context, argv[3]); + }else if( sParse.zErrMsg ){ renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); @@ -109184,15 +110690,15 @@ static void renameTableFunc( static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_STRING && (pExpr->flags & EP_DblQuoted) ){ - renameTokenFind(pWalker->pParse, pWalker->u.pRename, (void*)pExpr); + renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr); } return WRC_Continue; } -/* -** The implementation of an SQL scalar function that rewrites DDL statements -** so that any string literals that use double-quotes are modified so that -** they use single quotes. +/* SQL function: sqlite_rename_quotefix(DB,SQL) +** +** Rewrite the DDL statement "SQL" so that any string literals that use +** double-quotes use single quotes instead. ** ** Two arguments must be passed: ** @@ -109211,6 +110717,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){ ** returns the string: ** ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1 +** +** If there is a error in the input SQL, then raise an error, except +** if PRAGMA writable_schema=ON, then just return the input string +** unmodified following an error. */ static void renameQuotefixFunc( sqlite3_context *context, @@ -109247,8 +110757,8 @@ static void renameQuotefixFunc( sWalker.u.pRename = &sCtx; if( sParse.pNewTable ){ - Select *pSelect = sParse.pNewTable->pSelect; - if( pSelect ){ + if( IsView(sParse.pNewTable) ){ + Select *pSelect = sParse.pNewTable->u.view.pSelect; pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; sqlite3SelectPrep(&sParse, pSelect, 0); @@ -109261,7 +110771,9 @@ static void renameQuotefixFunc( sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + sqlite3WalkExpr(&sWalker, + sqlite3ColumnExpr(sParse.pNewTable, + &sParse.pNewTable->aCol[i])); } #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ } @@ -109283,7 +110795,11 @@ static void renameQuotefixFunc( renameTokenFree(db, sCtx.pList); } if( rc!=SQLITE_OK ){ - sqlite3_result_error_code(context, rc); + if( sqlite3WritableSchema(db) && rc==SQLITE_ERROR ){ + sqlite3_result_value(context, argv[1]); + }else{ + sqlite3_result_error_code(context, rc); + } } renameParseCleanup(&sParse); } @@ -109295,7 +110811,8 @@ static void renameQuotefixFunc( sqlite3BtreeLeaveAll(db); } -/* +/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS) +** ** An SQL user function that checks that there are no parse or symbol ** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement. ** After an ALTER TABLE .. RENAME operation is performed and the schema @@ -109310,11 +110827,13 @@ static void renameQuotefixFunc( ** 5: "when" part of error message. ** 6: True to disable the DQS quirk when parsing SQL. ** -** Unless it finds an error, this function normally returns NULL. However, it -** returns integer value 1 if: +** The return value is computed as follows: ** -** * the SQL argument creates a trigger, and -** * the table that the trigger is attached to is in database zDb. +** A. If an error is seen and not in PRAGMA writable_schema=ON mode, +** then raise the error. +** B. Else if a trigger is created and the the table that the trigger is +** attached to is in database zDb, then return 1. +** C. Otherwise return NULL. */ static void renameTableTest( sqlite3_context *context, @@ -109344,11 +110863,11 @@ static void renameTableTest( rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); db->flags |= (flags & (SQLITE_DqsDML|SQLITE_DqsDDL)); if( rc==SQLITE_OK ){ - if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ + if( isLegacy==0 && sParse.pNewTable && IsView(sParse.pNewTable) ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; - sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); + sqlite3SelectPrep(&sParse, sParse.pNewTable->u.view.pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; } @@ -109359,12 +110878,16 @@ static void renameTableTest( if( rc==SQLITE_OK ){ int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); int i2 = sqlite3FindDbName(db, zDb); - if( i1==i2 ) sqlite3_result_int(context, 1); + if( i1==i2 ){ + /* Handle output case B */ + sqlite3_result_int(context, 1); + } } } } - if( rc!=SQLITE_OK && zWhen ){ + if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){ + /* Output case A */ renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); @@ -109419,13 +110942,14 @@ static void dropColumnFunc( goto drop_column_done; } - pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName); + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zCnName); if( iColnCol-1 ){ RenameToken *pEnd; - pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName); zEnd = (const char*)pEnd->t.z; }else{ - zEnd = (const char*)&zSql[pTab->addColOffset]; + assert( IsOrdinaryTable(pTab) ); + zEnd = (const char*)&zSql[pTab->u.tab.addColOffset]; while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; } @@ -109451,7 +110975,7 @@ drop_column_done: ** statement. Argument pSrc contains the possibly qualified name of the ** table being edited, and token pName the name of the column to drop. */ -SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const Token *pName){ sqlite3 *db = pParse->db; /* Database handle */ Table *pTab; /* Table to modify */ int iDb; /* Index of db containing pTab in aDb[] */ @@ -109479,7 +111003,7 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token * } iCol = sqlite3ColumnIndex(pTab, zCol); if( iCol<0 ){ - sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol); + sqlite3ErrorMsg(pParse, "no such column: \"%T\"", pName); goto exit_drop_column; } @@ -109503,10 +111027,16 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token * iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); zDb = db->aDb[iDb].zDbSName; +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Invoke the authorization callback. */ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){ + goto exit_drop_column; + } +#endif renameTestSchema(pParse, zDb, iDb==1, "", 0); renameFixQuotes(pParse, zDb, iDb==1); sqlite3NestedParse(pParse, - "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_drop_column(%d, sql, %d) " "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" , zDb, iDb, iCol, pTab->zName @@ -109561,6 +111091,12 @@ SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token * nField++; } } + if( nField==0 ){ + /* dbsqlfuzz 5f09e7bcc78b4954d06bf9f2400d7715f48d1fef */ + pParse->nMem++; + sqlite3VdbeAddOp2(v, OP_Null, 0, reg+1); + nField = 1; + } sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec); if( pPk ){ sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); @@ -110030,7 +111566,6 @@ static void statInit( + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample); } #endif - db = sqlite3_context_db_handle(context); p = sqlite3DbMallocZero(db, n); if( p==0 ){ sqlite3_result_error_nomem(context); @@ -110449,28 +111984,19 @@ static void statGet( ** ** I = (K+D-1)/D */ - char *z; - int i; + sqlite3_str sStat; /* Text of the constructed "stat" line */ + int i; /* Loop counter */ - char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 ); - if( zRet==0 ){ - sqlite3_result_error_nomem(context); - return; - } - - sqlite3_snprintf(24, zRet, "%llu", + sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100); + sqlite3_str_appendf(&sStat, "%llu", p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow); - z = zRet + sqlite3Strlen30(zRet); for(i=0; inKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; - sqlite3_snprintf(24, z, " %llu", iVal); - z += sqlite3Strlen30(z); + sqlite3_str_appendf(&sStat, " %llu", iVal); assert( p->current.anEq[i] ); } - assert( z[0]=='\0' && z>zRet ); - - sqlite3_result_text(context, zRet, -1, sqlite3_free); + sqlite3ResultStrAccum(context, &sStat); } #ifdef SQLITE_ENABLE_STAT4 else if( eCall==STAT_GET_ROWID ){ @@ -110489,6 +112015,8 @@ static void statGet( } }else{ tRowcnt *aCnt = 0; + sqlite3_str sStat; + int i; assert( p->iGetnSample ); switch( eCall ){ @@ -110500,23 +112028,12 @@ static void statGet( break; } } - - { - char *zRet = sqlite3MallocZero(p->nCol * 25); - if( zRet==0 ){ - sqlite3_result_error_nomem(context); - }else{ - int i; - char *z = zRet; - for(i=0; inCol; i++){ - sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); - z += sqlite3Strlen30(z); - } - assert( z[0]=='\0' && z>zRet ); - z[-1] = '\0'; - sqlite3_result_text(context, zRet, -1, sqlite3_free); - } + sqlite3StrAccumInit(&sStat, 0, 0, 0, p->nCol*100); + for(i=0; inCol; i++){ + sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]); } + if( sStat.nChar ) sStat.nChar--; + sqlite3ResultStrAccum(context, &sStat); } #endif /* SQLITE_ENABLE_STAT4 */ #ifndef SQLITE_DEBUG @@ -110565,7 +112082,7 @@ static void analyzeVdbeCommentIndexWithColumnName( }else if( i==XN_EXPR ){ VdbeComment((v,"%s.expr(%d)",pIdx->zName, k)); }else{ - VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zName)); + VdbeComment((v,"%s.%s", pIdx->zName, pIdx->pTable->aCol[i].zCnName)); } } #else @@ -110612,7 +112129,7 @@ static void analyzeOneTable( if( v==0 || NEVER(pTab==0) ){ return; } - if( pTab->tnum==0 ){ + if( !IsOrdinaryTable(pTab) ){ /* Do not gather statistics on views or virtual tables */ return; } @@ -111437,9 +112954,12 @@ static int loadStatTbl( */ static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ + const Table *pStat4; assert( db->lookaside.bDisable ); - if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ + if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0 + && IsOrdinaryTable(pStat4) + ){ rc = loadStatTbl(db, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", @@ -111476,6 +112996,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ char *zSql; int rc = SQLITE_OK; Schema *pSchema = db->aDb[iDb].pSchema; + const Table *pStat1; assert( iDb>=0 && iDbnDb ); assert( db->aDb[iDb].pBt!=0 ); @@ -111498,7 +113019,9 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zDbSName; - if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ + if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)) + && IsOrdinaryTable(pStat1) + ){ zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ @@ -111889,17 +113412,18 @@ static void codeAttach( sName.pParse = pParse; if( - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) || - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) || - SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey)) + SQLITE_OK!=resolveAttachExpr(&sName, pFilename) || + SQLITE_OK!=resolveAttachExpr(&sName, pDbname) || + SQLITE_OK!=resolveAttachExpr(&sName, pKey) ){ goto attach_end; } #ifndef SQLITE_OMIT_AUTHORIZATION - if( pAuthArg ){ + if( ALWAYS(pAuthArg) ){ char *zAuthArg; if( pAuthArg->op==TK_STRING ){ + assert( !ExprHasProperty(pAuthArg, EP_IntValue) ); zAuthArg = pAuthArg->u.zToken; }else{ zAuthArg = 0; @@ -112318,10 +113842,10 @@ SQLITE_PRIVATE void sqlite3AuthRead( if( iCol>=0 ){ assert( iColnCol ); - zCol = pTab->aCol[iCol].zName; + zCol = pTab->aCol[iCol].zCnName; }else if( pTab->iPKey>=0 ){ assert( pTab->iPKeynCol ); - zCol = pTab->aCol[pTab->iPKey].zName; + zCol = pTab->aCol[pTab->iPKey].zCnName; }else{ zCol = "ROWID"; } @@ -112557,11 +114081,13 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ assert( pParse->pToplevel==0 ); db = pParse->db; + assert( db->pParse==pParse ); if( pParse->nested ) return; - if( db->mallocFailed || pParse->nErr ){ - if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR; + if( pParse->nErr ){ + if( db->mallocFailed ) pParse->rc = SQLITE_NOMEM; return; } + assert( db->mallocFailed==0 ); /* Begin by generating some termination code at the end of the ** vdbe program @@ -112584,17 +114110,22 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ int i; int reg; - addrRewind = - sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); - VdbeCoverage(v); - reg = pReturning->iRetReg; - for(i=0; inRetCol; i++){ - sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); + if( NEVER(pReturning->nRetCol==0) ){ + assert( CORRUPT_DB ); + }else{ + sqlite3VdbeAddOp0(v, OP_FkCheck); + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; inRetCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); + sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrRewind); } - sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); - sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); - VdbeCoverage(v); - sqlite3VdbeJumpHere(v, addrRewind); } sqlite3VdbeAddOp0(v, OP_Halt); @@ -112675,7 +114206,11 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ if( pParse->bReturning ){ Returning *pRet = pParse->u1.pReturning; - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + if( NEVER(pRet->nRetCol==0) ){ + assert( CORRUPT_DB ); + }else{ + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } } /* Finally, jump back to the beginning of the executable code. */ @@ -112685,7 +114220,9 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* Get the VDBE program ready for execution */ - if( v && pParse->nErr==0 && !db->mallocFailed ){ + assert( v!=0 || pParse->nErr ); + assert( db->mallocFailed==0 || pParse->nErr ); + if( pParse->nErr==0 ){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ assert( pParse->pAinc==0 || pParse->nTab>0 ); @@ -112699,20 +114236,21 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* ** Run the parser and code generator recursively in order to generate ** code for the SQL statement given onto the end of the pParse context -** currently under construction. When the parser is run recursively -** this way, the final OP_Halt is not appended and other initialization -** and finalization steps are omitted because those are handling by the -** outermost parser. +** currently under construction. Notes: ** -** Not everything is nestable. This facility is designed to permit -** INSERT, UPDATE, and DELETE operations against the schema table. Use -** care if you decide to try to use this routine for some other purposes. +** * The final OP_Halt is not appended and other initialization +** and finalization steps are omitted because those are handling by the +** outermost parser. +** +** * Built-in SQL functions always take precedence over application-defined +** SQL functions. In other words, it is not possible to override a +** built-in function. */ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ va_list ap; char *zSql; - char *zErrMsg = 0; sqlite3 *db = pParse->db; + u32 savedDbFlags = db->mDbFlags; char saveBuf[PARSE_TAIL_SZ]; if( pParse->nErr ) return; @@ -112731,8 +114269,11 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ pParse->nested++; memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); - sqlite3RunParser(pParse, zSql, &zErrMsg); - sqlite3DbFree(db, zErrMsg); + db->mDbFlags |= DBFLAG_PreferBuiltin; + sqlite3RunParser(pParse, zSql); + sqlite3DbFree(db, pParse->zErrMsg); + pParse->zErrMsg = 0; + db->mDbFlags = savedDbFlags; sqlite3DbFree(db, zSql); memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); pParse->nested--; @@ -112789,17 +114330,17 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName); if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ if( i==1 ){ - if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 - || sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 - || sqlite3StrICmp(zName+7, &DFLT_SCHEMA_TABLE[7])==0 + if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 + || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 + || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){ p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, - DFLT_TEMP_SCHEMA_TABLE); + LEGACY_TEMP_SCHEMA_TABLE); } }else{ - if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){ + if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, - DFLT_SCHEMA_TABLE); + LEGACY_SCHEMA_TABLE); } } } @@ -112817,11 +114358,11 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const cha if( p ) break; } if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ - if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){ - p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE); - }else if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 ){ + if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ + p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE); + }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, - DFLT_TEMP_SCHEMA_TABLE); + LEGACY_TEMP_SCHEMA_TABLE); } } } @@ -112867,6 +114408,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( pMod = sqlite3PragmaVtabRegister(db, zName); } if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ + testcase( pMod->pEpoTab==0 ); return pMod->pEpoTab; } } @@ -112916,6 +114458,22 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem( return sqlite3LocateTable(pParse, flags, p->zName, zDb); } +/* +** Return the preferred table name for system tables. Translate legacy +** names into the new preferred names, as appropriate. +*/ +SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){ + if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){ + if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){ + return PREFERRED_SCHEMA_TABLE; + } + if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){ + return PREFERRED_TEMP_SCHEMA_TABLE; + } + } + return zName; +} + /* ** Locate the in-memory structure that describes ** a particular index given the name of that index @@ -113080,6 +114638,84 @@ SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ db->mDbFlags &= ~DBFLAG_SchemaChange; } +/* +** Set the expression associated with a column. This is usually +** the DEFAULT value, but might also be the expression that computes +** the value for a generated column. +*/ +SQLITE_PRIVATE void sqlite3ColumnSetExpr( + Parse *pParse, /* Parsing context */ + Table *pTab, /* The table containing the column */ + Column *pCol, /* The column to receive the new DEFAULT expression */ + Expr *pExpr /* The new default expression */ +){ + ExprList *pList; + assert( IsOrdinaryTable(pTab) ); + pList = pTab->u.tab.pDfltList; + if( pCol->iDflt==0 + || NEVER(pList==0) + || NEVER(pList->nExpriDflt) + ){ + pCol->iDflt = pList==0 ? 1 : pList->nExpr+1; + pTab->u.tab.pDfltList = sqlite3ExprListAppend(pParse, pList, pExpr); + }else{ + sqlite3ExprDelete(pParse->db, pList->a[pCol->iDflt-1].pExpr); + pList->a[pCol->iDflt-1].pExpr = pExpr; + } +} + +/* +** Return the expression associated with a column. The expression might be +** the DEFAULT clause or the AS clause of a generated column. +** Return NULL if the column has no associated expression. +*/ +SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){ + if( pCol->iDflt==0 ) return 0; + if( NEVER(!IsOrdinaryTable(pTab)) ) return 0; + if( NEVER(pTab->u.tab.pDfltList==0) ) return 0; + if( NEVER(pTab->u.tab.pDfltList->nExpriDflt) ) return 0; + return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr; +} + +/* +** Set the collating sequence name for a column. +*/ +SQLITE_PRIVATE void sqlite3ColumnSetColl( + sqlite3 *db, + Column *pCol, + const char *zColl +){ + i64 nColl; + i64 n; + char *zNew; + assert( zColl!=0 ); + n = sqlite3Strlen30(pCol->zCnName) + 1; + if( pCol->colFlags & COLFLAG_HASTYPE ){ + n += sqlite3Strlen30(pCol->zCnName+n) + 1; + } + nColl = sqlite3Strlen30(zColl) + 1; + zNew = sqlite3DbRealloc(db, pCol->zCnName, nColl+n); + if( zNew ){ + pCol->zCnName = zNew; + memcpy(pCol->zCnName + n, zColl, nColl); + pCol->colFlags |= COLFLAG_HASCOLL; + } +} + +/* +** Return the collating squence name for a column +*/ +SQLITE_PRIVATE const char *sqlite3ColumnColl(Column *pCol){ + const char *z; + if( (pCol->colFlags & COLFLAG_HASCOLL)==0 ) return 0; + z = pCol->zCnName; + while( *z ){ z++; } + if( pCol->colFlags & COLFLAG_HASTYPE ){ + do{ z++; }while( *z ); + } + return z+1; +} + /* ** Delete memory allocated for the column names of a table or view (the ** Table.aCol[] array). @@ -113090,12 +114726,20 @@ SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; inCol; i++, pCol++){ - assert( pCol->zName==0 || pCol->hName==sqlite3StrIHash(pCol->zName) ); - sqlite3DbFree(db, pCol->zName); - sqlite3ExprDelete(db, pCol->pDflt); - sqlite3DbFree(db, pCol->zColl); + assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) ); + sqlite3DbFree(db, pCol->zCnName); } sqlite3DbFree(db, pTable->aCol); + if( IsOrdinaryTable(pTable) ){ + sqlite3ExprListDelete(db, pTable->u.tab.pDfltList); + } + if( db==0 || db->pnBytesFreed==0 ){ + pTable->aCol = 0; + pTable->nCol = 0; + if( IsOrdinaryTable(pTable) ){ + pTable->u.tab.pDfltList = 0; + } + } } } @@ -113147,19 +114791,25 @@ static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ sqlite3FreeIndex(db, pIndex); } - /* Delete any foreign keys attached to this table. */ - sqlite3FkDelete(db, pTable); + if( IsOrdinaryTable(pTable) ){ + sqlite3FkDelete(db, pTable); + } +#ifndef SQLITE_OMIT_VIRTUAL_TABLE + else if( IsVirtual(pTable) ){ + sqlite3VtabClear(db, pTable); + } +#endif + else{ + assert( IsView(pTable) ); + sqlite3SelectDelete(db, pTable->u.view.pSelect); + } /* Delete the Table structure itself. */ sqlite3DeleteColumnNames(db, pTable); sqlite3DbFree(db, pTable->zName); sqlite3DbFree(db, pTable->zColAff); - sqlite3SelectDelete(db, pTable->pSelect); sqlite3ExprListDelete(db, pTable->pCheck); -#ifndef SQLITE_OMIT_VIRTUALTABLE - sqlite3VtabClear(db, pTable); -#endif sqlite3DbFree(db, pTable); /* Verify that no lookaside memory was used by schema tables */ @@ -113205,10 +114855,10 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char ** are not \000 terminated and are not persistent. The returned string ** is \000 terminated and is persistent. */ -SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, const Token *pName){ char *zName; if( pName ){ - zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); + zName = sqlite3DbStrNDup(db, (const char*)pName->z, pName->n); sqlite3Dequote(zName); }else{ zName = 0; @@ -113222,7 +114872,7 @@ SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ */ SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){ Vdbe *v = sqlite3GetVdbe(p); - sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE); + sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE); sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5); if( p->nTab==0 ){ p->nTab = 1; @@ -113583,7 +115233,8 @@ SQLITE_PRIVATE void sqlite3StartTable( pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ - sqlite3ErrorMsg(pParse, "table %T already exists", pName); + sqlite3ErrorMsg(pParse, "%s %T already exists", + (IsView(pTable)? "view" : "table"), pName); }else{ assert( !db->init.busy || CORRUPT_DB ); sqlite3CodeVerifySchema(pParse, iDb); @@ -113685,6 +115336,7 @@ SQLITE_PRIVATE void sqlite3StartTable( /* If an error occurs, we jump here */ begin_table_error: + pParse->checkSchema = 1; sqlite3DbFree(db, zName); return; } @@ -113694,7 +115346,7 @@ begin_table_error: */ #if SQLITE_ENABLE_HIDDEN_COLUMNS SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ - if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ + if( sqlite3_strnicmp(pCol->zCnName, "__hidden__", 10)==0 ){ pCol->colFlags |= COLFLAG_HIDDEN; if( pTab ) pTab->tabFlags |= TF_HasHidden; }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ @@ -113785,7 +115437,7 @@ SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ ** first to get things going. Then this routine is called for each ** column. */ -SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ +SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token sName, Token sType){ Table *p; int i; char *z; @@ -113793,55 +115445,96 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ Column *pCol; sqlite3 *db = pParse->db; u8 hName; + Column *aNew; + u8 eType = COLTYPE_CUSTOM; + u8 szEst = 1; + char affinity = SQLITE_AFF_BLOB; if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } - z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); + if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); + + /* Because keywords GENERATE ALWAYS can be converted into indentifiers + ** by the parser, we can sometimes end up with a typename that ends + ** with "generated always". Check for this case and omit the surplus + ** text. */ + if( sType.n>=16 + && sqlite3_strnicmp(sType.z+(sType.n-6),"always",6)==0 + ){ + sType.n -= 6; + while( ALWAYS(sType.n>0) && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + if( sType.n>=9 + && sqlite3_strnicmp(sType.z+(sType.n-9),"generated",9)==0 + ){ + sType.n -= 9; + while( sType.n>0 && sqlite3Isspace(sType.z[sType.n-1]) ) sType.n--; + } + } + + /* Check for standard typenames. For standard typenames we will + ** set the Column.eType field rather than storing the typename after + ** the column name, in order to save space. */ + if( sType.n>=3 ){ + sqlite3DequoteToken(&sType); + for(i=0; i0) ); if( z==0 ) return; - if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName); - memcpy(z, pName->z, pName->n); - z[pName->n] = 0; + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName); + memcpy(z, sName.z, sName.n); + z[sName.n] = 0; sqlite3Dequote(z); hName = sqlite3StrIHash(z); for(i=0; inCol; i++){ - if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zCnName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; } } - if( (p->nCol & 0x7)==0 ){ - Column *aNew; - aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); - if( aNew==0 ){ - sqlite3DbFree(db, z); - return; - } - p->aCol = aNew; + aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0])); + if( aNew==0 ){ + sqlite3DbFree(db, z); + return; } + p->aCol = aNew; pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); - pCol->zName = z; + pCol->zCnName = z; pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); - if( pType->n==0 ){ + if( sType.n==0 ){ /* If there is no type specified, columns have the default affinity ** 'BLOB' with a default size of 4 bytes. */ - pCol->affinity = SQLITE_AFF_BLOB; - pCol->szEst = 1; + pCol->affinity = affinity; + pCol->eCType = eType; + pCol->szEst = szEst; #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( 4>=sqlite3GlobalConfig.szSorterRef ){ - pCol->colFlags |= COLFLAG_SORTERREF; + if( affinity==SQLITE_AFF_BLOB ){ + if( 4>=sqlite3GlobalConfig.szSorterRef ){ + pCol->colFlags |= COLFLAG_SORTERREF; + } } #endif }else{ zType = z + sqlite3Strlen30(z) + 1; - memcpy(zType, pType->z, pType->n); - zType[pType->n] = 0; + memcpy(zType, sType.z, sType.n); + zType[sType.n] = 0; sqlite3Dequote(zType); pCol->affinity = sqlite3AffinityType(zType, pCol); pCol->colFlags |= COLFLAG_HASTYPE; @@ -113996,7 +115689,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue( pCol = &(p->aCol[p->nCol-1]); if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", - pCol->zName); + pCol->zCnName); #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( pCol->colFlags & COLFLAG_GENERATED ){ testcase( pCol->colFlags & COLFLAG_VIRTUAL ); @@ -114007,15 +115700,15 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue( /* A copy of pExpr is used instead of the original, as pExpr contains ** tokens that point to volatile memory. */ - Expr x; - sqlite3ExprDelete(db, pCol->pDflt); + Expr x, *pDfltExpr; memset(&x, 0, sizeof(x)); x.op = TK_SPAN; x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); x.pLeft = pExpr; x.flags = EP_Skip; - pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); + pDfltExpr = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); sqlite3DbFree(db, x.u.zToken); + sqlite3ColumnSetExpr(pParse, p, pCol, pDfltExpr); } } if( IN_RENAME_OBJECT ){ @@ -114111,9 +115804,11 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( assert( pCExpr!=0 ); sqlite3StringToId(pCExpr); if( pCExpr->op==TK_ID ){ - const char *zCName = pCExpr->u.zToken; + const char *zCName; + assert( !ExprHasProperty(pCExpr, EP_IntValue) ); + zCName = pCExpr->u.zToken; for(iCol=0; iColnCol; iCol++){ - if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ + if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){ pCol = &pTab->aCol[iCol]; makeColumnPartOfPrimaryKey(pParse, pCol); break; @@ -114124,7 +115819,7 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( } if( nTerm==1 && pCol - && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 + && pCol->eCType==COLTYPE_INTEGER && sortOrder!=SQLITE_SO_DESC ){ if( IN_RENAME_OBJECT && pList ){ @@ -114204,8 +115899,7 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; - sqlite3DbFree(db, p->aCol[i].zColl); - p->aCol[i].zColl = zColl; + sqlite3ColumnSetColl(db, &p->aCol[i], zColl); /* If the column is declared as " PRIMARY KEY COLLATE ", ** then an index may have been created on this column before the @@ -114214,12 +115908,11 @@ SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ for(pIdx=p->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->nKeyCol==1 ); if( pIdx->aiColumn[0]==i ){ - pIdx->azColl[0] = p->aCol[i].zColl; + pIdx->azColl[0] = sqlite3ColumnColl(&p->aCol[i]); } } - }else{ - sqlite3DbFree(db, zColl); } + sqlite3DbFree(db, zColl); } /* Change the most recently parsed column to be a GENERATED ALWAYS AS @@ -114239,7 +115932,7 @@ SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); goto generated_done; } - if( pCol->pDflt ) goto generated_error; + if( pCol->iDflt>0 ) goto generated_error; if( pType ){ if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ /* no-op */ @@ -114257,13 +115950,13 @@ SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType if( pCol->colFlags & COLFLAG_PRIMKEY ){ makeColumnPartOfPrimaryKey(pParse, pCol); /* For the error message */ } - pCol->pDflt = pExpr; + sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr); pExpr = 0; goto generated_done; generated_error: sqlite3ErrorMsg(pParse, "error in generated column \"%s\"", - pCol->zName); + pCol->zCnName); generated_done: sqlite3ExprDelete(pParse->db, pExpr); #else @@ -114365,7 +116058,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ Column *pCol; n = 0; for(pCol = p->aCol, i=0; inCol; i++, pCol++){ - n += identLength(pCol->zName) + 5; + n += identLength(pCol->zCnName) + 5; } n += identLength(p->zName); if( n<50 ){ @@ -114401,7 +116094,7 @@ static char *createTableStmt(sqlite3 *db, Table *p){ sqlite3_snprintf(n-k, &zStmt[k], zSep); k += sqlite3Strlen30(&zStmt[k]); zSep = zSep2; - identPut(zStmt, &k, pCol->zName); + identPut(zStmt, &k, pCol->zCnName); assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 ); assert( pCol->affinity-SQLITE_AFF_BLOB < ArraySize(azType) ); testcase( pCol->affinity==SQLITE_AFF_BLOB ); @@ -114485,7 +116178,6 @@ static void estimateIndexWidth(Index *pIdx){ */ static int hasColumn(const i16 *aiCol, int nCol, int x){ while( nCol-- > 0 ){ - assert( aiCol[0]>=0 ); if( x==*(aiCol++) ){ return 1; } @@ -114598,7 +116290,9 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ */ if( !db->init.imposterTable ){ for(i=0; inCol; i++){ - if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){ + if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 + && (pTab->aCol[i].notNull==OE_None) + ){ pTab->aCol[i].notNull = OE_Abort; } } @@ -114620,7 +116314,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; - sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zCnName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ){ @@ -114635,10 +116329,11 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); - if( db->mallocFailed || pParse->nErr ){ + if( pParse->nErr ){ pTab->tabFlags &= ~TF_WithoutRowid; return; } + assert( db->mallocFailed==0 ); pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk->nKeyCol==1 ); }else{ @@ -114750,7 +116445,7 @@ SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char * nName = sqlite3Strlen30(pTab->zName); if( sqlite3_strnicmp(zName, pTab->zName, nName)!=0 ) return 0; if( zName[nName]!='_' ) return 0; - pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); if( pMod==0 ) return 0; if( pMod->pModule->iVersion<3 ) return 0; if( pMod->pModule->xShadowName==0 ) return 0; @@ -114758,6 +116453,41 @@ SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3 *db, Table *pTab, const char * } #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ +#ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Table pTab is a virtual table. If it the virtual table implementation +** exists and has an xShadowName method, then loop over all other ordinary +** tables within the same schema looking for shadow tables of pTab, and mark +** any shadow tables seen using the TF_Shadow flag. +*/ +SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){ + int nName; /* Length of pTab->zName */ + Module *pMod; /* Module for the virtual table */ + HashElem *k; /* For looping through the symbol table */ + + assert( IsVirtual(pTab) ); + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]); + if( pMod==0 ) return; + if( NEVER(pMod->pModule==0) ) return; + if( pMod->pModule->iVersion<3 ) return; + if( pMod->pModule->xShadowName==0 ) return; + assert( pTab->zName!=0 ); + nName = sqlite3Strlen30(pTab->zName); + for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){ + Table *pOther = sqliteHashData(k); + assert( pOther->zName!=0 ); + if( !IsOrdinaryTable(pOther) ) continue; + if( pOther->tabFlags & TF_Shadow ) continue; + if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0 + && pOther->zName[nName]=='_' + && pMod->pModule->xShadowName(pOther->zName+nName+1) + ){ + pOther->tabFlags |= TF_Shadow; + } + } +} +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */ + #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Return true if zName is a shadow table name in the current database @@ -114831,7 +116561,7 @@ SQLITE_PRIVATE void sqlite3EndTable( Parse *pParse, /* Parse context */ Token *pCons, /* The ',' token after the last column defn. */ Token *pEnd, /* The ')' before options in the CREATE TABLE */ - u8 tabOpts, /* Extra table options. Usually 0. */ + u32 tabOpts, /* Extra table options. Usually 0. */ Select *pSelect /* Select from a "CREATE ... AS SELECT" */ ){ Table *p; /* The new table */ @@ -114859,7 +116589,7 @@ SQLITE_PRIVATE void sqlite3EndTable( ** table itself. So mark it read-only. */ if( db->init.busy ){ - if( pSelect ){ + if( pSelect || (!IsOrdinaryTable(p) && db->init.newTnum) ){ sqlite3ErrorMsg(pParse, ""); return; } @@ -114867,6 +116597,44 @@ SQLITE_PRIVATE void sqlite3EndTable( if( p->tnum==1 ) p->tabFlags |= TF_Readonly; } + /* Special processing for tables that include the STRICT keyword: + ** + ** * Do not allow custom column datatypes. Every column must have + ** a datatype that is one of INT, INTEGER, REAL, TEXT, or BLOB. + ** + ** * If a PRIMARY KEY is defined, other than the INTEGER PRIMARY KEY, + ** then all columns of the PRIMARY KEY must have a NOT NULL + ** constraint. + */ + if( tabOpts & TF_Strict ){ + int ii; + p->tabFlags |= TF_Strict; + for(ii=0; iinCol; ii++){ + Column *pCol = &p->aCol[ii]; + if( pCol->eCType==COLTYPE_CUSTOM ){ + if( pCol->colFlags & COLFLAG_HASTYPE ){ + sqlite3ErrorMsg(pParse, + "unknown datatype for %s.%s: \"%s\"", + p->zName, pCol->zCnName, sqlite3ColumnType(pCol, "") + ); + }else{ + sqlite3ErrorMsg(pParse, "missing datatype for %s.%s", + p->zName, pCol->zCnName); + } + return; + }else if( pCol->eCType==COLTYPE_ANY ){ + pCol->affinity = SQLITE_AFF_BLOB; + } + if( (pCol->colFlags & COLFLAG_PRIMKEY)!=0 + && p->iPKey!=ii + && pCol->notNull == OE_None + ){ + pCol->notNull = OE_Abort; + p->tabFlags |= TF_HasNotNull; + } + } + } + assert( (p->tabFlags & TF_HasPrimaryKey)==0 || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 ); assert( (p->tabFlags & TF_HasPrimaryKey)!=0 @@ -114911,7 +116679,7 @@ SQLITE_PRIVATE void sqlite3EndTable( for(ii=0; iinCol; ii++){ u32 colFlags = p->aCol[ii].colFlags; if( (colFlags & COLFLAG_GENERATED)!=0 ){ - Expr *pX = p->aCol[ii].pDflt; + Expr *pX = sqlite3ColumnExpr(p, &p->aCol[ii]); testcase( colFlags & COLFLAG_VIRTUAL ); testcase( colFlags & COLFLAG_STORED ); if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ @@ -114921,8 +116689,8 @@ SQLITE_PRIVATE void sqlite3EndTable( ** tree that have been allocated from lookaside memory, which is ** illegal in a schema and will lead to errors or heap corruption ** when the database connection closes. */ - sqlite3ExprDelete(db, pX); - p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0); + sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); } }else{ nNG++; @@ -114962,7 +116730,7 @@ SQLITE_PRIVATE void sqlite3EndTable( /* ** Initialize zType for the new view or table. */ - if( p->pSelect==0 ){ + if( IsOrdinaryTable(p) ){ /* A regular table */ zType = "table"; zType2 = "TABLE"; @@ -114996,6 +116764,11 @@ SQLITE_PRIVATE void sqlite3EndTable( int addrInsLoop; /* Top of the loop for inserting rows */ Table *pSelTab; /* A table that describes the SELECT results */ + if( IN_SPECIAL_PARSE ){ + pParse->rc = SQLITE_ERROR; + pParse->nErr++; + return; + } regYield = ++pParse->nMem; regRec = ++pParse->nMem; regRowid = ++pParse->nMem; @@ -115048,7 +116821,7 @@ SQLITE_PRIVATE void sqlite3EndTable( ** the information we've collected. */ sqlite3NestedParse(pParse, - "UPDATE %Q." DFLT_SCHEMA_TABLE + "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q" " WHERE rowid=#%d", db->aDb[iDb].zDbSName, @@ -115112,12 +116885,12 @@ SQLITE_PRIVATE void sqlite3EndTable( } #ifndef SQLITE_OMIT_ALTERTABLE - if( !pSelect && !p->pSelect ){ + if( !pSelect && IsOrdinaryTable(p) ){ assert( pCons && pEnd ); if( pCons->z==0 ){ pCons = pEnd; } - p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); + p->u.tab.addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } #endif } @@ -115174,12 +116947,13 @@ SQLITE_PRIVATE void sqlite3CreateView( */ pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ - p->pSelect = pSelect; + p->u.view.pSelect = pSelect; pSelect = 0; }else{ - p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + p->u.view.pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); } p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); + p->eTabType = TABTYP_VIEW; if( db->mallocFailed ) goto create_view_fail; /* Locate the end of the CREATE VIEW statement. Make sEnd point to @@ -115233,13 +117007,12 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE - db->nSchemaLock++; - rc = sqlite3VtabCallConnect(pParse, pTable); - db->nSchemaLock--; - if( rc ){ - return 1; + if( IsVirtual(pTable) ){ + db->nSchemaLock++; + rc = sqlite3VtabCallConnect(pParse, pTable); + db->nSchemaLock--; + return rc; } - if( IsVirtual(pTable) ) return 0; #endif #ifndef SQLITE_OMIT_VIEW @@ -115276,8 +117049,8 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ - assert( pTable->pSelect ); - pSel = sqlite3SelectDup(db, pTable->pSelect, 0); + assert( IsView(pTable) ); + pSel = sqlite3SelectDup(db, pTable->u.view.pSelect, 0); if( pSel ){ u8 eParseMode = pParse->eParseMode; pParse->eParseMode = PARSE_MODE_NORMAL; @@ -115306,10 +117079,10 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ */ sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); - if( db->mallocFailed==0 - && pParse->nErr==0 + if( pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr ){ + assert( db->mallocFailed==0 ); sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, SQLITE_AFF_NONE); } @@ -115336,8 +117109,6 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->pSchema->schemaFlags |= DB_UnresetViews; if( db->mallocFailed ){ sqlite3DeleteColumnNames(db, pTable); - pTable->aCol = 0; - pTable->nCol = 0; } #endif /* SQLITE_OMIT_VIEW */ return nErr; @@ -115354,10 +117125,8 @@ static void sqliteViewResetAll(sqlite3 *db, int idx){ if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3DeleteColumnNames(db, pTab); - pTab->aCol = 0; - pTab->nCol = 0; } } DbClearProperty(db, idx, DB_UnresetViews); @@ -115431,7 +117200,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ ** token for additional information. */ sqlite3NestedParse(pParse, - "UPDATE %Q." DFLT_SCHEMA_TABLE + "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET rootpage=%d WHERE #%d AND rootpage=#%d", pParse->db->aDb[iDb].zDbSName, iTable, r1, r1); #endif @@ -115566,7 +117335,7 @@ SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, in ** database. */ sqlite3NestedParse(pParse, - "DELETE FROM %Q." DFLT_SCHEMA_TABLE + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE tbl_name=%Q and type!='trigger'", pDb->zDbSName, pTab->zName); if( !isView && !IsVirtual(pTab) ){ @@ -115594,6 +117363,7 @@ SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db){ if( (db->flags & SQLITE_Defensive)!=0 && db->pVtabCtx==0 && db->nVdbeExec==0 + && !sqlite3VtabInSync(db) ){ return 1; } @@ -115613,6 +117383,9 @@ static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ return 1; } + if( pTab->tabFlags & TF_Eponymous ){ + return 1; + } return 0; } @@ -115697,11 +117470,11 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, /* Ensure DROP TABLE is not used on a view, and DROP VIEW is not used ** on a table. */ - if( isView && pTab->pSelect==0 ){ + if( isView && !IsView(pTab) ){ sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); goto exit_drop_table; } - if( !isView && pTab->pSelect ){ + if( !isView && IsView(pTab) ){ sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); goto exit_drop_table; } @@ -115752,7 +117525,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( FKey *pFKey = 0; FKey *pNextTo; Table *p = pParse->pNewTable; - int nByte; + i64 nByte; int i; int nCol; char *z; @@ -115765,7 +117538,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( if( pToCol && pToCol->nExpr!=1 ){ sqlite3ErrorMsg(pParse, "foreign key on %s" " should reference only one column of table %T", - p->aCol[iCol].zName, pTo); + p->aCol[iCol].zCnName, pTo); goto fk_end; } nCol = 1; @@ -115788,7 +117561,8 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( goto fk_end; } pFKey->pFrom = p; - pFKey->pNextFrom = p->pFKey; + assert( IsOrdinaryTable(p) ); + pFKey->pNextFrom = p->u.tab.pFKey; z = (char*)&pFKey->aCol[nCol]; pFKey->zTo = z; if( IN_RENAME_OBJECT ){ @@ -115805,7 +117579,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( for(i=0; inCol; j++){ - if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){ + if( sqlite3StrICmp(p->aCol[j].zCnName, pFromCol->a[i].zEName)==0 ){ pFKey->aCol[i].iFrom = j; break; } @@ -115853,7 +117627,8 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( /* Link the foreign key to the table as the last step. */ - p->pFKey = pFKey; + assert( IsOrdinaryTable(p) ); + p->u.tab.pFKey = pFKey; pFKey = 0; fk_end: @@ -115874,7 +117649,9 @@ SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ #ifndef SQLITE_OMIT_FOREIGN_KEY Table *pTab; FKey *pFKey; - if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; + if( (pTab = pParse->pNewTable)==0 ) return; + if( NEVER(!IsOrdinaryTable(pTab)) ) return; + if( (pFKey = pTab->u.tab.pFKey)==0 ) return; assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ pFKey->isDeferred = (u8)isDeferred; #endif @@ -115924,7 +117701,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ tnum = pIndex->tnum; } pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); - assert( pKey!=0 || db->mallocFailed || pParse->nErr ); + assert( pKey!=0 || pParse->nErr ); /* Open the sorter cursor if we are to use one. */ iSorter = pParse->nTab++; @@ -116088,9 +117865,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex( char *zExtra = 0; /* Extra space after the Index object */ Index *pPk = 0; /* PRIMARY KEY index for WITHOUT ROWID tables */ - if( db->mallocFailed || pParse->nErr>0 ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto exit_create_index; } + assert( db->mallocFailed==0 ); if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } @@ -116154,7 +117933,6 @@ SQLITE_PRIVATE void sqlite3CreateIndex( pDb = &db->aDb[iDb]; assert( pTab!=0 ); - assert( pParse->nErr==0 ); if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 @@ -116166,7 +117944,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( goto exit_create_index; } #ifndef SQLITE_OMIT_VIEW - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; } @@ -116257,7 +118035,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( Token prevCol; Column *pCol = &pTab->aCol[pTab->nCol-1]; pCol->colFlags |= COLFLAG_UNIQUE; - sqlite3TokenInit(&prevCol, pCol->zName); + sqlite3TokenInit(&prevCol, pCol->zCnName); pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; @@ -116275,6 +118053,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( Expr *pExpr = pList->a[i].pExpr; assert( pExpr!=0 ); if( pExpr->op==TK_COLLATE ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); } } @@ -116370,6 +118149,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( zColl = 0; if( pListItem->pExpr->op==TK_COLLATE ){ int nColl; + assert( !ExprHasProperty(pListItem->pExpr, EP_IntValue) ); zColl = pListItem->pExpr->u.zToken; nColl = sqlite3Strlen30(zColl) + 1; assert( nExtra>=nColl ); @@ -116378,7 +118158,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( zExtra += nColl; nExtra -= nColl; }else if( j>=0 ){ - zColl = pTab->aCol[j].zColl; + zColl = sqlite3ColumnColl(&pTab->aCol[j]); } if( !zColl ) zColl = sqlite3StrBINARY; if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ @@ -116576,13 +118356,13 @@ SQLITE_PRIVATE void sqlite3CreateIndex( /* Add an entry in sqlite_schema for this index */ sqlite3NestedParse(pParse, - "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", - db->aDb[iDb].zDbSName, - pIndex->zName, - pTab->zName, - iMem, - zStmt - ); + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", + db->aDb[iDb].zDbSName, + pIndex->zName, + pTab->zName, + iMem, + zStmt + ); sqlite3DbFree(db, zStmt); /* Fill the index with data and reparse the schema. Code an OP_Expire @@ -116618,7 +118398,7 @@ exit_create_index: ** The list was already ordered when this routine was entered, so at this ** point at most a single index (the newly added index) will be out of ** order. So we have to reorder at most one index. */ - Index **ppFrom = &pTab->pIndex; + Index **ppFrom; Index *pThis; for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ Index *pNext; @@ -116716,10 +118496,10 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists sqlite3 *db = pParse->db; int iDb; - assert( pParse->nErr==0 ); /* Never called with prior errors */ if( db->mallocFailed ){ goto exit_drop_index; } + assert( pParse->nErr==0 ); /* Never called with prior non-OOM errors */ assert( pName->nSrc==1 ); if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; @@ -116762,7 +118542,7 @@ SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists if( v ){ sqlite3BeginWriteOperation(pParse, 1, iDb); sqlite3NestedParse(pParse, - "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'", + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'", db->aDb[iDb].zDbSName, pIndex->zName ); sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); @@ -117130,7 +118910,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( pItem->pUsing = pUsing; return p; - append_from_error: +append_from_error: assert( p==0 ); sqlite3ExprDelete(db, pOn); sqlite3IdListDelete(db, pUsing); @@ -117158,6 +118938,7 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI }else{ pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); pItem->fg.isIndexedBy = 1; + assert( pItem->fg.isCte==0 ); /* No collision on union u2 */ } } } @@ -117470,7 +119251,7 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint( for(j=0; jnKeyCol; j++){ char *zCol; assert( pIdx->aiColumn[j]>=0 ); - zCol = pTab->aCol[pIdx->aiColumn[j]].zName; + zCol = pTab->aCol[pIdx->aiColumn[j]].zCnName; if( j ) sqlite3_str_append(&errMsg, ", ", 2); sqlite3_str_appendall(&errMsg, pTab->zName); sqlite3_str_append(&errMsg, ".", 1); @@ -117497,7 +119278,7 @@ SQLITE_PRIVATE void sqlite3RowidConstraint( int rc; if( pTab->iPKey>=0 ){ zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, - pTab->aCol[pTab->iPKey].zName); + pTab->aCol[pTab->iPKey].zCnName); rc = SQLITE_CONSTRAINT_PRIMARYKEY; }else{ zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); @@ -118138,6 +119919,7 @@ SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch( ){ FuncDef *p; for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); if( sqlite3StrICmp(p->zName, zFunc)==0 ){ return p; } @@ -118158,7 +119940,7 @@ SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( const char *zName = aDef[i].zName; int nName = sqlite3Strlen30(zName); int h = SQLITE_FUNC_HASH(zName[0], nName); - assert( zName[0]>='a' && zName[0]<='z' ); + assert( aDef[i].funcFlags & SQLITE_FUNC_BUILTIN ); pOther = sqlite3FunctionSearch(h, zName); if( pOther ){ assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] ); @@ -118384,6 +120166,16 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ return pTab; } +/* Generate byte-code that will report the number of rows modified +** by a DELETE, INSERT, or UPDATE statement. +*/ +SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ + sqlite3VdbeAddOp0(v, OP_FkCheck); + sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC); +} + /* Return true if table pTab is read-only. ** ** A table is read-only if any of the following are true: @@ -118424,7 +120216,7 @@ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ return 1; } #ifndef SQLITE_OMIT_VIEW - if( !viewOk && pTab->pSelect ){ + if( !viewOk && IsView(pTab) ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } @@ -118528,13 +120320,13 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); if( pPk->nKeyCol==1 ){ - const char *zName = pTab->aCol[pPk->aiColumn[0]].zName; + const char *zName = pTab->aCol[pPk->aiColumn[0]].zCnName; pLhs = sqlite3Expr(db, TK_ID, zName); pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); }else{ int i; for(i=0; inKeyCol; i++){ - Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName); + Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); pEList = sqlite3ExprListAppend(pParse, pEList, p); } pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); @@ -118550,6 +120342,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); pSrc->a[0].pTab = pTab; if( pSrc->a[0].fg.isIndexedBy ){ + assert( pSrc->a[0].fg.isCte==0 ); pSrc->a[0].u2.pIBIndex = 0; pSrc->a[0].fg.isIndexedBy = 0; sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy); @@ -118622,9 +120415,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( memset(&sContext, 0, sizeof(sContext)); db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto delete_from_cleanup; } + assert( db->mallocFailed==0 ); assert( pTabList->nSrc==1 ); @@ -118641,7 +120436,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - isView = pTab->pSelect!=0; + isView = IsView(pTab); #else # define pTrigger 0 # define isView 0 @@ -118805,7 +120600,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** ONEPASS_SINGLE: One-pass approach - at most one row deleted. ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted. */ - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0,0,wcf,iTabCur+1); if( pWInfo==0 ) goto delete_from_cleanup; eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); @@ -118891,7 +120686,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( eOnePass!=ONEPASS_OFF ){ assert( nKey==nPk ); /* OP_Found will use an unpacked key */ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){ - assert( pPk!=0 || pTab->pSelect!=0 ); + assert( pPk!=0 || IsView(pTab) ); sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); VdbeCoverage(v); } @@ -118958,9 +120753,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, memCnt, "rows deleted"); } delete_from_cleanup: @@ -119125,7 +120918,7 @@ SQLITE_PRIVATE void sqlite3GenerateRowDelete( ** the update-hook is not invoked for rows removed by REPLACE, but the ** pre-update-hook is. */ - if( pTab->pSelect==0 ){ + if( !IsView(pTab) ){ u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); @@ -119411,6 +121204,18 @@ static void typeofFunc( sqlite3_result_text(context, azType[i], -1, SQLITE_STATIC); } +/* subtype(X) +** +** Return the subtype of X +*/ +static void subtypeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + sqlite3_result_int(context, sqlite3_value_subtype(argv[0])); +} /* ** Implementation of the length() function @@ -119572,7 +121377,7 @@ endInstrOOM: } /* -** Implementation of the printf() function. +** Implementation of the printf() (a.k.a. format()) SQL function. */ static void printfFunc( sqlite3_context *context, @@ -119885,9 +121690,9 @@ static void last_insert_rowid( /* ** Implementation of the changes() SQL function. ** -** IMP: R-62073-11209 The changes() SQL function is a wrapper -** around the sqlite3_changes() C/C++ function and hence follows the same -** rules for counting changes. +** IMP: R-32760-32347 The changes() SQL function is a wrapper +** around the sqlite3_changes64() C/C++ function and hence follows the +** same rules for counting changes. */ static void changes( sqlite3_context *context, @@ -119896,12 +121701,12 @@ static void changes( ){ sqlite3 *db = sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); - sqlite3_result_int(context, sqlite3_changes(db)); + sqlite3_result_int64(context, sqlite3_changes64(db)); } /* ** Implementation of the total_changes() SQL function. The return value is -** the same as the sqlite3_total_changes() API function. +** the same as the sqlite3_total_changes64() API function. */ static void total_changes( sqlite3_context *context, @@ -119910,9 +121715,9 @@ static void total_changes( ){ sqlite3 *db = sqlite3_context_db_handle(context); UNUSED_PARAMETER2(NotUsed, NotUsed2); - /* IMP: R-52756-41993 This function is a wrapper around the - ** sqlite3_total_changes() C/C++ interface. */ - sqlite3_result_int(context, sqlite3_total_changes(db)); + /* IMP: R-11217-42568 This function is a wrapper around the + ** sqlite3_total_changes64() C/C++ interface. */ + sqlite3_result_int64(context, sqlite3_total_changes64(db)); } /* @@ -120341,39 +122146,42 @@ static const char hexdigits[] = { }; /* -** Implementation of the QUOTE() function. This function takes a single -** argument. If the argument is numeric, the return value is the same as -** the argument. If the argument is NULL, the return value is the string -** "NULL". Otherwise, the argument is enclosed in single quotes with -** single-quote escapes. +** Append to pStr text that is the SQL literal representation of the +** value contained in pValue. */ -static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ - assert( argc==1 ); - UNUSED_PARAMETER(argc); - switch( sqlite3_value_type(argv[0]) ){ +SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum *pStr, sqlite3_value *pValue){ + /* As currently implemented, the string must be initially empty. + ** we might relax this requirement in the future, but that will + ** require enhancements to the implementation. */ + assert( pStr!=0 && pStr->nChar==0 ); + + switch( sqlite3_value_type(pValue) ){ case SQLITE_FLOAT: { double r1, r2; - char zBuf[50]; - r1 = sqlite3_value_double(argv[0]); - sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); - sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); - if( r1!=r2 ){ - sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); + const char *zVal; + r1 = sqlite3_value_double(pValue); + sqlite3_str_appendf(pStr, "%!.15g", r1); + zVal = sqlite3_str_value(pStr); + if( zVal ){ + sqlite3AtoF(zVal, &r2, pStr->nChar, SQLITE_UTF8); + if( r1!=r2 ){ + sqlite3_str_reset(pStr); + sqlite3_str_appendf(pStr, "%!.20e", r1); + } } - sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); break; } case SQLITE_INTEGER: { - sqlite3_result_value(context, argv[0]); + sqlite3_str_appendf(pStr, "%lld", sqlite3_value_int64(pValue)); break; } case SQLITE_BLOB: { - char *zText = 0; - char const *zBlob = sqlite3_value_blob(argv[0]); - int nBlob = sqlite3_value_bytes(argv[0]); - assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ - zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); - if( zText ){ + char const *zBlob = sqlite3_value_blob(pValue); + int nBlob = sqlite3_value_bytes(pValue); + assert( zBlob==sqlite3_value_blob(pValue) ); /* No encoding change */ + sqlite3StrAccumEnlarge(pStr, nBlob*2 + 4); + if( pStr->accError==0 ){ + char *zText = pStr->zText; int i; for(i=0; i>4)&0x0F]; @@ -120383,42 +122191,48 @@ static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ zText[(nBlob*2)+3] = '\0'; zText[0] = 'X'; zText[1] = '\''; - sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); - sqlite3_free(zText); + pStr->nChar = nBlob*2 + 3; } break; } case SQLITE_TEXT: { - int i,j; - u64 n; - const unsigned char *zArg = sqlite3_value_text(argv[0]); - char *z; - - if( zArg==0 ) return; - for(i=0, n=0; zArg[i]; i++){ if( zArg[i]=='\'' ) n++; } - z = contextMalloc(context, ((i64)i)+((i64)n)+3); - if( z ){ - z[0] = '\''; - for(i=0, j=1; zArg[i]; i++){ - z[j++] = zArg[i]; - if( zArg[i]=='\'' ){ - z[j++] = '\''; - } - } - z[j++] = '\''; - z[j] = 0; - sqlite3_result_text(context, z, j, sqlite3_free); - } + const unsigned char *zArg = sqlite3_value_text(pValue); + sqlite3_str_appendf(pStr, "%Q", zArg); break; } default: { - assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); - sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); + assert( sqlite3_value_type(pValue)==SQLITE_NULL ); + sqlite3_str_append(pStr, "NULL", 4); break; } } } +/* +** Implementation of the QUOTE() function. +** +** The quote(X) function returns the text of an SQL literal which is the +** value of its argument suitable for inclusion into an SQL statement. +** Strings are surrounded by single-quotes with escapes on interior quotes +** as needed. BLOBs are encoded as hexadecimal literals. Strings with +** embedded NUL characters cannot be represented as string literals in SQL +** and hence the returned string literal is truncated prior to the first NUL. +*/ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ + sqlite3_str str; + sqlite3 *db = sqlite3_context_db_handle(context); + assert( argc==1 ); + UNUSED_PARAMETER(argc); + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3QuoteValue(&str,argv[0]); + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), str.nChar, + SQLITE_DYNAMIC); + if( str.accError!=SQLITE_OK ){ + sqlite3_result_null(context); + sqlite3_result_error_code(context, str.accError); + } +} + /* ** The unicode() function. Return the integer unicode code-point value ** for the first character of the input string. @@ -121029,97 +122843,167 @@ static void minMaxFinalize(sqlite3_context *context){ /* ** group_concat(EXPR, ?SEPARATOR?) +** +** The SEPARATOR goes before the EXPR string. This is tragic. The +** groupConcatInverse() implementation would have been easier if the +** SEPARATOR were appended after EXPR. And the order is undocumented, +** so we could change it, in theory. But the old behavior has been +** around for so long that we dare not, for fear of breaking something. */ +typedef struct { + StrAccum str; /* The accumulated concatenation */ +#ifndef SQLITE_OMIT_WINDOWFUNC + int nAccum; /* Number of strings presently concatenated */ + int nFirstSepLength; /* Used to detect separator length change */ + /* If pnSepLengths!=0, refs an array of inter-string separator lengths, + ** stored as actually incorporated into presently accumulated result. + ** (Hence, its slots in use number nAccum-1 between method calls.) + ** If pnSepLengths==0, nFirstSepLength is the length used throughout. + */ + int *pnSepLengths; +#endif +} GroupConcatCtx; + static void groupConcatStep( sqlite3_context *context, int argc, sqlite3_value **argv ){ const char *zVal; - StrAccum *pAccum; + GroupConcatCtx *pGCC; const char *zSep; int nVal, nSep; assert( argc==1 || argc==2 ); if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); - - if( pAccum ){ + pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); + if( pGCC ){ sqlite3 *db = sqlite3_context_db_handle(context); - int firstTerm = pAccum->mxAlloc==0; - pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; - if( !firstTerm ){ - if( argc==2 ){ - zSep = (char*)sqlite3_value_text(argv[1]); - nSep = sqlite3_value_bytes(argv[1]); - }else{ - zSep = ","; - nSep = 1; + int firstTerm = pGCC->str.mxAlloc==0; + pGCC->str.mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; + if( argc==1 ){ + if( !firstTerm ){ + sqlite3_str_appendchar(&pGCC->str, 1, ','); } - if( zSep ) sqlite3_str_append(pAccum, zSep, nSep); +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + pGCC->nFirstSepLength = 1; + } +#endif + }else if( !firstTerm ){ + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); + if( zSep ){ + sqlite3_str_append(&pGCC->str, zSep, nSep); + } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + nSep = 0; + } + if( nSep != pGCC->nFirstSepLength || pGCC->pnSepLengths != 0 ){ + int *pnsl = pGCC->pnSepLengths; + if( pnsl == 0 ){ + /* First separator length variation seen, start tracking them. */ + pnsl = (int*)sqlite3_malloc64((pGCC->nAccum+1) * sizeof(int)); + if( pnsl!=0 ){ + int i = 0, nA = pGCC->nAccum-1; + while( inFirstSepLength; + } + }else{ + pnsl = (int*)sqlite3_realloc64(pnsl, pGCC->nAccum * sizeof(int)); + } + if( pnsl!=0 ){ + if( ALWAYS(pGCC->nAccum>0) ){ + pnsl[pGCC->nAccum-1] = nSep; + } + pGCC->pnSepLengths = pnsl; + }else{ + sqlite3StrAccumSetError(&pGCC->str, SQLITE_NOMEM); + } + } +#endif } +#ifndef SQLITE_OMIT_WINDOWFUNC + else{ + pGCC->nFirstSepLength = sqlite3_value_bytes(argv[1]); + } + pGCC->nAccum += 1; +#endif zVal = (char*)sqlite3_value_text(argv[0]); nVal = sqlite3_value_bytes(argv[0]); - if( zVal ) sqlite3_str_append(pAccum, zVal, nVal); + if( zVal ) sqlite3_str_append(&pGCC->str, zVal, nVal); } } + #ifndef SQLITE_OMIT_WINDOWFUNC static void groupConcatInverse( sqlite3_context *context, int argc, sqlite3_value **argv ){ - int n; - StrAccum *pAccum; + GroupConcatCtx *pGCC; assert( argc==1 || argc==2 ); + (void)argc; /* Suppress unused parameter warning */ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); - /* pAccum is always non-NULL since groupConcatStep() will have always + pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); + /* pGCC is always non-NULL since groupConcatStep() will have always ** run frist to initialize it */ - if( ALWAYS(pAccum) ){ - n = sqlite3_value_bytes(argv[0]); - if( argc==2 ){ - n += sqlite3_value_bytes(argv[1]); + if( ALWAYS(pGCC) ){ + int nVS; + /* Must call sqlite3_value_text() to convert the argument into text prior + ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */ + (void)sqlite3_value_text(argv[0]); + nVS = sqlite3_value_bytes(argv[0]); + pGCC->nAccum -= 1; + if( pGCC->pnSepLengths!=0 ){ + assert(pGCC->nAccum >= 0); + if( pGCC->nAccum>0 ){ + nVS += *pGCC->pnSepLengths; + memmove(pGCC->pnSepLengths, pGCC->pnSepLengths+1, + (pGCC->nAccum-1)*sizeof(int)); + } }else{ - n++; + /* If removing single accumulated string, harmlessly over-do. */ + nVS += pGCC->nFirstSepLength; } - if( n>=(int)pAccum->nChar ){ - pAccum->nChar = 0; + if( nVS>=(int)pGCC->str.nChar ){ + pGCC->str.nChar = 0; }else{ - pAccum->nChar -= n; - memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar); + pGCC->str.nChar -= nVS; + memmove(pGCC->str.zText, &pGCC->str.zText[nVS], pGCC->str.nChar); + } + if( pGCC->str.nChar==0 ){ + pGCC->str.mxAlloc = 0; + sqlite3_free(pGCC->pnSepLengths); + pGCC->pnSepLengths = 0; } - if( pAccum->nChar==0 ) pAccum->mxAlloc = 0; } } #else # define groupConcatInverse 0 #endif /* SQLITE_OMIT_WINDOWFUNC */ static void groupConcatFinalize(sqlite3_context *context){ - StrAccum *pAccum; - pAccum = sqlite3_aggregate_context(context, 0); - if( pAccum ){ - if( pAccum->accError==SQLITE_TOOBIG ){ - sqlite3_result_error_toobig(context); - }else if( pAccum->accError==SQLITE_NOMEM ){ - sqlite3_result_error_nomem(context); - }else{ - sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, - sqlite3_free); - } + GroupConcatCtx *pGCC + = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); + if( pGCC ){ + sqlite3ResultStrAccum(context, &pGCC->str); +#ifndef SQLITE_OMIT_WINDOWFUNC + sqlite3_free(pGCC->pnSepLengths); +#endif } } #ifndef SQLITE_OMIT_WINDOWFUNC static void groupConcatValue(sqlite3_context *context){ - sqlite3_str *pAccum; - pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0); - if( pAccum ){ + GroupConcatCtx *pGCC + = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0); + if( pGCC ){ + StrAccum *pAccum = &pGCC->str; if( pAccum->accError==SQLITE_TOOBIG ){ sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); }else{ const char *zText = sqlite3_str_value(pAccum); - sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); } } } @@ -121183,11 +123067,12 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas int nExpr; assert( pExpr!=0 ); assert( pExpr->op==TK_FUNCTION ); + assert( ExprUseXList(pExpr) ); if( !pExpr->x.pList ){ return 0; } - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); nExpr = pExpr->x.pList->nExpr; + assert( !ExprHasProperty(pExpr, EP_IntValue) ); pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION if( pDef==0 ) return 0; @@ -121211,6 +123096,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas Expr *pEscape = pExpr->x.pList->a[2].pExpr; char *zEscape; if( pEscape->op!=TK_STRING ) return 0; + assert( !ExprHasProperty(pEscape, EP_IntValue) ); zEscape = pEscape->u.zToken; if( zEscape[0]==0 || zEscape[1]!=0 ) return 0; if( zEscape[0]==aWc[0] ) return 0; @@ -121437,12 +123323,12 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ */ static FuncDef aBuiltinFunc[] = { /***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/ +#if !defined(SQLITE_UNTESTABLE) TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0), TEST_FUNC(expr_compare, 2, INLINEFUNC_expr_compare, 0), TEST_FUNC(expr_implies_expr, 2, INLINEFUNC_expr_implies_expr, 0), -#ifdef SQLITE_DEBUG - TEST_FUNC(affinity, 1, INLINEFUNC_affinity, 0), -#endif + TEST_FUNC(affinity, 1, INLINEFUNC_affinity, 0), +#endif /* !defined(SQLITE_UNTESTABLE) */ /***** Regular functions *****/ #ifdef SQLITE_SOUNDEX FUNCTION(soundex, 1, 0, 0, soundexFunc ), @@ -121462,8 +123348,8 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY), #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - FUNCTION2(sqlite_offset, 1, 0, 0, noopFunc, SQLITE_FUNC_OFFSET| - SQLITE_FUNC_TYPEOF), + {1, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_OFFSET|SQLITE_FUNC_TYPEOF, + 0, 0, noopFunc, 0, 0, 0, "sqlite_offset", {0} }, #endif FUNCTION(ltrim, 1, 1, 0, trimFunc ), FUNCTION(ltrim, 2, 1, 0, trimFunc ), @@ -121474,15 +123360,17 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ FUNCTION(min, -1, 0, 1, minmaxFunc ), FUNCTION(min, 0, 0, 1, 0 ), WAGGREGATE(min, 1, 0, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, - SQLITE_FUNC_MINMAX ), + SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), FUNCTION(max, -1, 1, 1, minmaxFunc ), FUNCTION(max, 0, 1, 1, 0 ), WAGGREGATE(max, 1, 1, 1, minmaxStep, minMaxFinalize, minMaxValue, 0, - SQLITE_FUNC_MINMAX ), + SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER ), FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), + FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), FUNCTION(instr, 2, 0, 0, instrFunc ), FUNCTION(printf, -1, 0, 0, printfFunc ), + FUNCTION(format, -1, 0, 0, printfFunc ), FUNCTION(unicode, 1, 0, 0, unicodeFunc ), FUNCTION(char, -1, 0, 0, charFunc ), FUNCTION(abs, 1, 0, 0, absFunc ), @@ -121514,9 +123402,10 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), WAGGREGATE(count, 0,0,0, countStep, - countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT ), + countFinalize, countFinalize, countInverse, + SQLITE_FUNC_COUNT|SQLITE_FUNC_ANYORDER ), WAGGREGATE(count, 1,0,0, countStep, - countFinalize, countFinalize, countInverse, 0 ), + countFinalize, countFinalize, countInverse, SQLITE_FUNC_ANYORDER ), WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, @@ -121580,6 +123469,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif sqlite3WindowFunctions(); sqlite3RegisterDateTimeFunctions(); + sqlite3RegisterJsonFunctions(); sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); #if 0 /* Enable to print out how the built-in functions are hashed */ @@ -121591,6 +123481,7 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){ int n = sqlite3Strlen30(p->zName); int h = p->zName[0] + n; + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); printf(" %s(%d)", p->zName, h); } printf("\n"); @@ -121818,7 +123709,9 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex( */ if( pParent->iPKey>=0 ){ if( !zKey ) return 0; - if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zCnName, zKey) ){ + return 0; + } } }else if( paiCol ){ assert( nCol>1 ); @@ -121860,11 +123753,11 @@ SQLITE_PRIVATE int sqlite3FkLocateIndex( /* If the index uses a collation sequence that is different from ** the default collation sequence for the column, this index is ** unusable. Bail out early in this case. */ - zDfltColl = pParent->aCol[iCol].zColl; + zDfltColl = sqlite3ColumnColl(&pParent->aCol[iCol]); if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; - zIdxCol = pParent->aCol[iCol].zName; + zIdxCol = pParent->aCol[iCol].zCnName; for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; @@ -122088,7 +123981,7 @@ static Expr *exprTableRegister( pCol = &pTab->aCol[iCol]; pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; pExpr->affExpr = pCol->affinity; - zColl = pCol->zColl; + zColl = sqlite3ColumnColl(pCol); if( zColl==0 ) zColl = db->pDfltColl->zName; pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); }else{ @@ -122111,6 +124004,7 @@ static Expr *exprTableColumn( ){ Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); if( pExpr ){ + assert( ExprUseYTab(pExpr) ); pExpr->y.pTab = pTab; pExpr->iTable = iCursor; pExpr->iColumn = iCol; @@ -122197,7 +124091,7 @@ static void fkScanChildren( pLeft = exprTableRegister(pParse, pTab, regData, iCol); iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; assert( iCol>=0 ); - zCol = pFKey->pFrom->aCol[iCol].zName; + zCol = pFKey->pFrom->aCol[iCol].zCnName; pRight = sqlite3Expr(db, TK_ID, zCol); pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); @@ -122232,7 +124126,7 @@ static void fkScanChildren( i16 iCol = pIdx->aiColumn[i]; assert( iCol>=0 ); pLeft = exprTableRegister(pParse, pTab, regData, iCol); - pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName); + pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zCnName); pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); pAll = sqlite3ExprAnd(pParse, pAll, pEq); } @@ -122251,7 +124145,7 @@ static void fkScanChildren( ** clause. For each row found, increment either the deferred or immediate ** foreign key constraint counter. */ if( pParse->nErr==0 ){ - pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0, 0); sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); if( pWInfo ){ sqlite3WhereEnd(pWInfo); @@ -122302,6 +124196,25 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ } } +/* +** Clear the apTrigger[] cache of CASCADE triggers for all foreign keys +** in a particular database. This needs to happen when the schema +** changes. +*/ +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){ + HashElem *k; + Hash *pHash = &db->aDb[iDb].pSchema->tblHash; + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k)){ + Table *pTab = sqliteHashData(k); + FKey *pFKey; + if( !IsOrdinaryTable(pTab) ) continue; + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ + fkTriggerDelete(db, pFKey->apTrigger[0]); pFKey->apTrigger[0] = 0; + fkTriggerDelete(db, pFKey->apTrigger[1]); pFKey->apTrigger[1] = 0; + } + } +} + /* ** This function is called to generate code that runs when table pTab is ** being dropped from the database. The SrcList passed as the second argument @@ -122321,12 +124234,12 @@ static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ */ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ sqlite3 *db = pParse->db; - if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){ + if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){ int iSkip = 0; Vdbe *v = sqlite3GetVdbe(pParse); assert( v ); /* VDBE has already been allocated */ - assert( pTab->pSelect==0 ); /* Not a view */ + assert( IsOrdinaryTable(pTab) ); if( sqlite3FkReferences(pTab)==0 ){ /* Search for a deferred foreign key constraint for which this table ** is the child table. If one cannot be found, return without @@ -122334,7 +124247,7 @@ SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTa ** the entire DELETE if there are no outstanding deferred constraints ** when this statement is run. */ FKey *p; - for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; } if( !p ) return; @@ -122423,7 +124336,7 @@ static int fkParentIsModified( if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ Column *pCol = &pTab->aCol[iKey]; if( zKey ){ - if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1; + if( 0==sqlite3StrICmp(pCol->zCnName, zKey) ) return 1; }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ return 1; } @@ -122490,13 +124403,14 @@ SQLITE_PRIVATE void sqlite3FkCheck( /* If foreign-keys are disabled, this function is a no-op. */ if( (db->flags&SQLITE_ForeignKeys)==0 ) return; + if( !IsOrdinaryTable(pTab) ) return; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; /* Loop through all the foreign key constraints for which pTab is the ** child table (the table that the foreign key definition is part of). */ - for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ Table *pTo; /* Parent table of foreign key pFKey */ Index *pIdx = 0; /* Index on key columns in pTo */ int *aiFree = 0; @@ -122563,7 +124477,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( ** values read from the parent table are NULL. */ if( db->xAuth ){ int rcauth; - char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zCnName; rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); bIgnore = (rcauth==SQLITE_IGNORE); } @@ -122678,10 +124592,10 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask( Table *pTab /* Table being modified */ ){ u32 mask = 0; - if( pParse->db->flags&SQLITE_ForeignKeys ){ + if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){ FKey *p; int i; - for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); } for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ @@ -122731,19 +124645,19 @@ SQLITE_PRIVATE int sqlite3FkRequired( ){ int eRet = 1; /* Value to return if bHaveFK is true */ int bHaveFK = 0; /* If FK processing is required */ - if( pParse->db->flags&SQLITE_ForeignKeys ){ + if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){ if( !aChange ){ /* A DELETE operation. Foreign key processing is required if the ** table in question is either the child or parent table for any ** foreign key constraint. */ - bHaveFK = (sqlite3FkReferences(pTab) || pTab->pFKey); + bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ FKey *p; /* Check if any child key columns are being modified. */ - for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){ if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; bHaveFK = 1; @@ -122836,8 +124750,8 @@ static Trigger *fkActionTrigger( assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); sqlite3TokenInit(&tToCol, - pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); - sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); + pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zCnName); + sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zCnName); /* Create the expression "OLD.zToCol = zFromCol". It is important ** that the "OLD.zToCol" term is on the LHS of the = operator, so @@ -122882,7 +124796,7 @@ static Trigger *fkActionTrigger( testcase( pCol->colFlags & COLFLAG_STORED ); pDflt = 0; }else{ - pDflt = pCol->pDflt; + pDflt = sqlite3ColumnExpr(pFKey->pFrom, pCol); } if( pDflt ){ pNew = sqlite3ExprDup(db, pDflt, 0); @@ -123019,9 +124933,9 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ FKey *pFKey; /* Iterator variable */ FKey *pNext; /* Copy of pFKey->pNextFrom */ - assert( db==0 || IsVirtual(pTab) - || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); - for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ + assert( IsOrdinaryTable(pTab) ); + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){ + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); /* Remove the FK from the fkeyHash hash table. */ if( !db || db->pnBytesFreed==0 ){ @@ -123101,7 +125015,7 @@ SQLITE_PRIVATE void sqlite3OpenTable( }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); - assert( pPk->tnum==pTab->tnum ); + assert( pPk->tnum==pTab->tnum || CORRUPT_DB ); sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); sqlite3VdbeSetP4KeyInfo(pParse, pPk); VdbeComment((v, "%s", pTab->zName)); @@ -123168,28 +125082,68 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ } /* +** Make changes to the evolving bytecode to do affinity transformations +** of values that are about to be gathered into a row for table pTab. +** +** For ordinary (legacy, non-strict) tables: +** ----------------------------------------- +** ** Compute the affinity string for table pTab, if it has not already been ** computed. As an optimization, omit trailing SQLITE_AFF_BLOB affinities. ** -** If the affinity exists (if it is no entirely SQLITE_AFF_BLOB values) and -** if iReg>0 then code an OP_Affinity opcode that will set the affinities -** for register iReg and following. Or if affinities exists and iReg==0, +** If the affinity string is empty (because it was all SQLITE_AFF_BLOB entries +** which were then optimized out) then this routine becomes a no-op. +** +** Otherwise if iReg>0 then code an OP_Affinity opcode that will set the +** affinities for register iReg and following. Or if iReg==0, ** then just set the P4 operand of the previous opcode (which should be ** an OP_MakeRecord) to the affinity string. ** ** A column affinity string has one character per column: ** -** Character Column affinity -** ------------------------------ -** 'A' BLOB -** 'B' TEXT -** 'C' NUMERIC -** 'D' INTEGER -** 'E' REAL +** Character Column affinity +** --------- --------------- +** 'A' BLOB +** 'B' TEXT +** 'C' NUMERIC +** 'D' INTEGER +** 'E' REAL +** +** For STRICT tables: +** ------------------ +** +** Generate an appropropriate OP_TypeCheck opcode that will verify the +** datatypes against the column definitions in pTab. If iReg==0, that +** means an OP_MakeRecord opcode has already been generated and should be +** the last opcode generated. The new OP_TypeCheck needs to be inserted +** before the OP_MakeRecord. The new OP_TypeCheck should use the same +** register set as the OP_MakeRecord. If iReg>0 then register iReg is +** the first of a series of registers that will form the new record. +** Apply the type checking to that array of registers. */ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ int i, j; - char *zColAff = pTab->zColAff; + char *zColAff; + if( pTab->tabFlags & TF_Strict ){ + if( iReg==0 ){ + /* Move the previous opcode (which should be OP_MakeRecord) forward + ** by one slot and insert a new OP_TypeCheck where the current + ** OP_MakeRecord is found */ + VdbeOp *pPrev; + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + pPrev = sqlite3VdbeGetOp(v, -1); + assert( pPrev!=0 ); + assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed ); + pPrev->opcode = OP_TypeCheck; + sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3); + }else{ + /* Insert an isolated OP_Typecheck */ + sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + } + return; + } + zColAff = pTab->zColAff; if( zColAff==0 ){ sqlite3 *db = sqlite3VdbeDb(v); zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); @@ -123199,7 +125153,7 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ } for(i=j=0; inCol; i++){ - assert( pTab->aCol[i].affinity!=0 ); + assert( pTab->aCol[i].affinity!=0 || sqlite3VdbeParser(v)->nErr>0 ); if( (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ zColAff[j++] = pTab->aCol[i].affinity; } @@ -123215,6 +125169,8 @@ SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ if( iReg ){ sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); }else{ + assert( sqlite3VdbeGetOp(v, -1)->opcode==OP_MakeRecord + || sqlite3VdbeDb(v)->mallocFailed ); sqlite3VdbeChangeP4(v, -1, zColAff, i); } } @@ -123298,24 +125254,30 @@ SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( ** that appropriate affinity has been applied to the regular columns */ sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); - if( (pTab->tabFlags & TF_HasStored)!=0 - && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity - ){ - /* Change the OP_Affinity argument to '@' (NONE) for all stored - ** columns. '@' is the no-op affinity and those columns have not - ** yet been computed. */ - int ii, jj; - char *zP4 = pOp->p4.z; - assert( zP4!=0 ); - assert( pOp->p4type==P4_DYNAMIC ); - for(ii=jj=0; zP4[jj]; ii++){ - if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){ - continue; + if( (pTab->tabFlags & TF_HasStored)!=0 ){ + pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); + if( pOp->opcode==OP_Affinity ){ + /* Change the OP_Affinity argument to '@' (NONE) for all stored + ** columns. '@' is the no-op affinity and those columns have not + ** yet been computed. */ + int ii, jj; + char *zP4 = pOp->p4.z; + assert( zP4!=0 ); + assert( pOp->p4type==P4_DYNAMIC ); + for(ii=jj=0; zP4[jj]; ii++){ + if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){ + continue; + } + if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){ + zP4[jj] = SQLITE_AFF_NONE; + } + jj++; } - if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){ - zP4[jj] = SQLITE_AFF_NONE; - } - jj++; + }else if( pOp->opcode==OP_TypeCheck ){ + /* If an OP_TypeCheck was generated because the table is STRICT, + ** then set the P3 operand to indicate that generated columns should + ** not be checked */ + pOp->p3 = 1; } } @@ -123351,7 +125313,7 @@ SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( int x; pCol->colFlags |= COLFLAG_BUSY; w.eCode = 0; - sqlite3WalkExpr(&w, pCol->pDflt); + sqlite3WalkExpr(&w, sqlite3ColumnExpr(pTab, pCol)); pCol->colFlags &= ~COLFLAG_BUSY; if( w.eCode & COLFLAG_NOTAVAIL ){ pRedo = pCol; @@ -123360,13 +125322,13 @@ SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( eProgress = 1; assert( pCol->colFlags & COLFLAG_GENERATED ); x = sqlite3TableColumnToStorage(pTab, i) + iRegStore; - sqlite3ExprCodeGeneratedColumn(pParse, pCol, x); + sqlite3ExprCodeGeneratedColumn(pParse, pTab, pCol, x); pCol->colFlags &= ~COLFLAG_NOTAVAIL; } } }while( pRedo && eProgress ); if( pRedo ){ - sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName); + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zCnName); } pParse->iSelfTab = 0; } @@ -123725,9 +125687,11 @@ SQLITE_PRIVATE void sqlite3Insert( #endif db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto insert_cleanup; } + assert( db->mallocFailed==0 ); dest.iSDParm = 0; /* Suppress a harmless compiler warning */ /* If the Select object is really just a simple VALUES() list with a @@ -123761,7 +125725,7 @@ SQLITE_PRIVATE void sqlite3Insert( */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); - isView = pTab->pSelect!=0; + isView = IsView(pTab); #else # define pTrigger 0 # define tmask 0 @@ -123803,7 +125767,11 @@ SQLITE_PRIVATE void sqlite3Insert( ** ** This is the 2nd template. */ - if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ + if( pColumn==0 + && pSelect!=0 + && pTrigger==0 + && xferOptimization(pParse, pTab, pSelect, onError, iDb) + ){ assert( !pTrigger ); assert( pList==0 ); goto insert_end; @@ -123852,7 +125820,7 @@ SQLITE_PRIVATE void sqlite3Insert( } for(i=0; inId; i++){ for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zCnName)==0 ){ pColumn->a[i].idx = j; if( i!=j ) bIdListInOrder = 0; if( j==pTab->iPKey ){ @@ -123862,7 +125830,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ sqlite3ErrorMsg(pParse, "cannot INSERT into generated column \"%s\"", - pTab->aCol[j].zName); + pTab->aCol[j].zCnName); goto insert_cleanup; } #endif @@ -123903,7 +125871,9 @@ SQLITE_PRIVATE void sqlite3Insert( dest.nSdst = pTab->nCol; rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; - if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; + assert( db->pParse==pParse ); + if( rc || pParse->nErr ) goto insert_cleanup; + assert( db->mallocFailed==0 ); sqlite3VdbeEndCoroutine(v, regYield); sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); @@ -124047,7 +126017,7 @@ SQLITE_PRIVATE void sqlite3Insert( pTab->zName); goto insert_cleanup; } - if( pTab->pSelect ){ + if( IsView(pTab) ){ sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); goto insert_cleanup; } @@ -124146,7 +126116,9 @@ SQLITE_PRIVATE void sqlite3Insert( }else if( pColumn==0 ){ /* Hidden columns that are not explicitly named in the INSERT ** get there default value */ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); continue; } } @@ -124155,13 +126127,17 @@ SQLITE_PRIVATE void sqlite3Insert( if( j>=pColumn->nId ){ /* A column not named in the insert column list gets its ** default value */ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); continue; } k = j; }else if( nColumn==0 ){ /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ - sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + iRegStore); continue; }else{ k = i - nHidden; @@ -124386,9 +126362,7 @@ insert_end: ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows inserted"); } insert_cleanup: @@ -124676,7 +126650,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( db = pParse->db; v = pParse->pVdbe; assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + assert( !IsView(pTab) ); /* This table is not a VIEW */ nCol = pTab->nCol; /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for @@ -124727,7 +126701,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } if( onError==OE_Replace ){ if( b2ndPass /* REPLACE becomes ABORT on the 2nd pass */ - || pCol->pDflt==0 /* REPLACE is ABORT if no DEFAULT value */ + || pCol->iDflt==0 /* REPLACE is ABORT if no DEFAULT value */ ){ testcase( pCol->colFlags & COLFLAG_VIRTUAL ); testcase( pCol->colFlags & COLFLAG_STORED ); @@ -124749,7 +126723,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( VdbeCoverage(v); assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); nSeenReplace++; - sqlite3ExprCodeCopy(pParse, pCol->pDflt, iReg); + sqlite3ExprCodeCopy(pParse, + sqlite3ColumnExpr(pTab, pCol), iReg); sqlite3VdbeJumpHere(v, addr1); break; } @@ -124759,7 +126734,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( case OE_Rollback: case OE_Fail: { char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, - pCol->zName); + pCol->zCnName); sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, iReg); sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); @@ -125012,6 +126987,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( onError==OE_Replace /* IPK rule is REPLACE */ && onError!=overrideError /* Rules for other constraints are different */ && pTab->pIndex /* There exist other constraints */ + && !upsertIpkDelay /* IPK check already deferred by UPSERT */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; VdbeComment((v, "defer IPK REPLACE until last")); @@ -125177,7 +127153,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField ); x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); - VdbeComment((v, "%s", pTab->aCol[iField].zName)); + VdbeComment((v, "%s", pTab->aCol[iField].zCnName)); } } sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); @@ -125229,6 +127205,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row ** must be explicitly deleted in order to ensure any pre-update hook ** is invoked. */ + assert( IsOrdinaryTable(pTab) ); #ifndef SQLITE_ENABLE_PREUPDATE_HOOK if( (ix==0 && pIdx->pNext==0) /* Condition 3 */ && pPk==pIdx /* Condition 2 */ @@ -125236,7 +127213,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */ - (0==pTab->pFKey && 0==sqlite3FkReferences(pTab))) + (0==pTab->u.tab.pFKey && 0==sqlite3FkReferences(pTab))) ){ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; @@ -125271,7 +127248,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); VdbeComment((v, "%s.%s", pTab->zName, - pTab->aCol[pPk->aiColumn[i]].zName)); + pTab->aCol[pPk->aiColumn[i]].zCnName)); } } if( isUpdate ){ @@ -125335,7 +127312,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( assert( onError==OE_Replace ); nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; - assert( nConflictCk>0 ); + assert( nConflictCk>0 || db->mallocFailed ); + testcase( nConflictCk<=0 ); testcase( nConflictCk>1 ); if( regTrigCnt ){ sqlite3MultiWrite(pParse); @@ -125418,6 +127396,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( if( ipkTop ){ sqlite3VdbeGoto(v, ipkTop); VdbeComment((v, "Do IPK REPLACE")); + assert( ipkBottom>0 ); sqlite3VdbeJumpHere(v, ipkBottom); } @@ -125470,7 +127449,7 @@ SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ if( pTab->pSchema->file_format<2 ) return; for(i=pTab->nCol-1; i>0; i--){ - if( pTab->aCol[i].pDflt!=0 ) break; + if( pTab->aCol[i].iDflt!=0 ) break; if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break; } sqlite3VdbeChangeP5(v, i+1); @@ -125535,7 +127514,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( v = pParse->pVdbe; assert( v!=0 ); - assert( pTab->pSelect==0 ); /* This table is not a VIEW */ + assert( !IsView(pTab) ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ /* All REPLACE indexes are at the end of the list */ assert( pIdx->onError!=OE_Replace @@ -125548,7 +127527,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( } pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); if( update_flags==0 ){ @@ -125621,8 +127599,9 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices( assert( op==OP_OpenWrite || p5==0 ); if( IsVirtual(pTab) ){ /* This routine is a no-op for virtual tables. Leave the output - ** variables *piDataCur and *piIdxCur uninitialized so that valgrind - ** can detect if they are used by mistake in the caller. */ + ** variables *piDataCur and *piIdxCur set to illegal cursor numbers + ** for improved error detection. */ + *piDataCur = *piIdxCur = -999; return 0; } iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); @@ -125763,18 +127742,13 @@ static int xferOptimization( int destHasUniqueIdx = 0; /* True if pDest has a UNIQUE index */ int regData, regRowid; /* Registers holding data and rowid */ - if( pSelect==0 ){ - return 0; /* Must be of the form INSERT INTO ... SELECT ... */ - } + assert( pSelect!=0 ); if( pParse->pWith || pSelect->pWith ){ /* Do not attempt to process this query if there are an WITH clauses ** attached to it. Proceeding may generate a false "no such table: xxx" ** error if pSelect reads from a CTE named "xxx". */ return 0; } - if( sqlite3TriggerList(pParse, pDest) ){ - return 0; /* tab1 must not have triggers */ - } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pDest) ){ return 0; /* tab1 must not be a virtual table */ @@ -125837,13 +127811,8 @@ static int xferOptimization( if( HasRowid(pDest)!=HasRowid(pSrc) ){ return 0; /* source and destination must both be WITHOUT ROWID or not */ } -#ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pSrc) ){ - return 0; /* tab2 must not be a virtual table */ - } -#endif - if( pSrc->pSelect ){ - return 0; /* tab2 may not be a view */ + if( !IsOrdinaryTable(pSrc) ){ + return 0; /* tab2 may not be a view or virtual table */ } if( pDest->nCol!=pSrc->nCol ){ return 0; /* Number of columns must be the same in tab1 and tab2 */ @@ -125851,6 +127820,9 @@ static int xferOptimization( if( pDest->iPKey!=pSrc->iPKey ){ return 0; /* Both tables must have the same INTEGER PRIMARY KEY */ } + if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){ + return 0; /* Cannot feed from a non-strict into a strict table */ + } for(i=0; inCol; i++){ Column *pDestCol = &pDest->aCol[i]; Column *pSrcCol = &pSrc->aCol[i]; @@ -125887,7 +127859,9 @@ static int xferOptimization( ** This requirement could be relaxed for VIRTUAL columns, I suppose. */ if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ - if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){ + if( sqlite3ExprCompare(0, + sqlite3ColumnExpr(pSrc, pSrcCol), + sqlite3ColumnExpr(pDest, pDestCol), -1)!=0 ){ testcase( pDestCol->colFlags & COLFLAG_VIRTUAL ); testcase( pDestCol->colFlags & COLFLAG_STORED ); return 0; /* Different generator expressions */ @@ -125897,7 +127871,8 @@ static int xferOptimization( if( pDestCol->affinity!=pSrcCol->affinity ){ return 0; /* Affinity must be the same on all columns */ } - if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){ + if( sqlite3_stricmp(sqlite3ColumnColl(pDestCol), + sqlite3ColumnColl(pSrcCol))!=0 ){ return 0; /* Collating sequence must be the same on all columns */ } if( pDestCol->notNull && !pSrcCol->notNull ){ @@ -125905,11 +127880,15 @@ static int xferOptimization( } /* Default values for second and subsequent columns need to match. */ if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){ - assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN ); - assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN ); - if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) - || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken, - pSrcCol->pDflt->u.zToken)!=0) + Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol); + Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol); + assert( pDestExpr==0 || pDestExpr->op==TK_SPAN ); + assert( pDestExpr==0 || !ExprHasProperty(pDestExpr, EP_IntValue) ); + assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN ); + assert( pSrcExpr==0 || !ExprHasProperty(pSrcExpr, EP_IntValue) ); + if( (pDestExpr==0)!=(pSrcExpr==0) + || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken, + pSrcExpr->u.zToken)!=0) ){ return 0; /* Default values must be the same for all columns */ } @@ -125946,7 +127925,8 @@ static int xferOptimization( ** the extra complication to make this rule less restrictive is probably ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e] */ - if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){ + assert( IsOrdinaryTable(pDest) ); + if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){ return 0; } #endif @@ -126624,6 +128604,20 @@ struct sqlite3_api_routines { sqlite3_file *(*database_file_object)(const char*); /* Version 3.34.0 and later */ int (*txn_state)(sqlite3*,const char*); + /* Version 3.36.1 and later */ + sqlite3_int64 (*changes64)(sqlite3*); + sqlite3_int64 (*total_changes64)(sqlite3*); + /* Version 3.37.0 and later */ + int (*autovacuum_pages)(sqlite3*, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, void(*)(void*)); + /* Version 3.38.0 and later */ + int (*error_offset)(sqlite3*); + int (*vtab_rhs_value)(sqlite3_index_info*,int,sqlite3_value**); + int (*vtab_distinct)(sqlite3_index_info*); + int (*vtab_in)(sqlite3_index_info*,int,int); + int (*vtab_in_first)(sqlite3_value*,sqlite3_value**); + int (*vtab_in_next)(sqlite3_value*,sqlite3_value**); }; /* @@ -126930,6 +128924,18 @@ typedef int (*sqlite3_loadext_entry)( #define sqlite3_database_file_object sqlite3_api->database_file_object /* Version 3.34.0 and later */ #define sqlite3_txn_state sqlite3_api->txn_state +/* Version 3.36.1 and later */ +#define sqlite3_changes64 sqlite3_api->changes64 +#define sqlite3_total_changes64 sqlite3_api->total_changes64 +/* Version 3.37.0 and later */ +#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages +/* Version 3.38.0 and later */ +#define sqlite3_error_offset sqlite3_api->error_offset +#define sqlite3_vtab_rhs_value sqlite3_api->vtab_rhs_value +#define sqlite3_vtab_distinct sqlite3_api->vtab_distinct +#define sqlite3_vtab_in sqlite3_api->vtab_in +#define sqlite3_vtab_in_first sqlite3_api->vtab_in_first +#define sqlite3_vtab_in_next sqlite3_api->vtab_in_next #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) @@ -127414,6 +129420,18 @@ static const sqlite3_api_routines sqlite3Apis = { sqlite3_database_file_object, /* Version 3.34.0 and later */ sqlite3_txn_state, + /* Version 3.36.1 and later */ + sqlite3_changes64, + sqlite3_total_changes64, + /* Version 3.37.0 and later */ + sqlite3_autovacuum_pages, + /* Version 3.38.0 and later */ + sqlite3_error_offset, + sqlite3_vtab_rhs_value, + sqlite3_vtab_distinct, + sqlite3_vtab_in, + sqlite3_vtab_in_first, + sqlite3_vtab_in_next }; /* True if x is the directory separator character @@ -127876,13 +129894,14 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ #define PragTyp_SOFT_HEAP_LIMIT 35 #define PragTyp_SYNCHRONOUS 36 #define PragTyp_TABLE_INFO 37 -#define PragTyp_TEMP_STORE 38 -#define PragTyp_TEMP_STORE_DIRECTORY 39 -#define PragTyp_THREADS 40 -#define PragTyp_WAL_AUTOCHECKPOINT 41 -#define PragTyp_WAL_CHECKPOINT 42 -#define PragTyp_LOCK_STATUS 43 -#define PragTyp_STATS 44 +#define PragTyp_TABLE_LIST 38 +#define PragTyp_TEMP_STORE 39 +#define PragTyp_TEMP_STORE_DIRECTORY 40 +#define PragTyp_THREADS 41 +#define PragTyp_WAL_AUTOCHECKPOINT 42 +#define PragTyp_WAL_CHECKPOINT 43 +#define PragTyp_LOCK_STATUS 44 +#define PragTyp_STATS 45 /* Property flags associated with various pragma. */ #define PragFlg_NeedSchema 0x01 /* Force schema load before running */ @@ -127915,45 +129934,51 @@ static const char *const pragCName[] = { /* 13 */ "pk", /* 14 */ "hidden", /* table_info reuses 8 */ - /* 15 */ "seqno", /* Used by: index_xinfo */ - /* 16 */ "cid", - /* 17 */ "name", - /* 18 */ "desc", - /* 19 */ "coll", - /* 20 */ "key", - /* 21 */ "name", /* Used by: function_list */ - /* 22 */ "builtin", - /* 23 */ "type", - /* 24 */ "enc", - /* 25 */ "narg", - /* 26 */ "flags", - /* 27 */ "tbl", /* Used by: stats */ - /* 28 */ "idx", - /* 29 */ "wdth", - /* 30 */ "hght", - /* 31 */ "flgs", - /* 32 */ "seq", /* Used by: index_list */ - /* 33 */ "name", - /* 34 */ "unique", - /* 35 */ "origin", - /* 36 */ "partial", - /* 37 */ "table", /* Used by: foreign_key_check */ - /* 38 */ "rowid", - /* 39 */ "parent", - /* 40 */ "fkid", - /* index_info reuses 15 */ - /* 41 */ "seq", /* Used by: database_list */ - /* 42 */ "name", - /* 43 */ "file", - /* 44 */ "busy", /* Used by: wal_checkpoint */ - /* 45 */ "log", - /* 46 */ "checkpointed", - /* collation_list reuses 32 */ - /* 47 */ "database", /* Used by: lock_status */ - /* 48 */ "status", - /* 49 */ "cache_size", /* Used by: default_cache_size */ + /* 15 */ "schema", /* Used by: table_list */ + /* 16 */ "name", + /* 17 */ "type", + /* 18 */ "ncol", + /* 19 */ "wr", + /* 20 */ "strict", + /* 21 */ "seqno", /* Used by: index_xinfo */ + /* 22 */ "cid", + /* 23 */ "name", + /* 24 */ "desc", + /* 25 */ "coll", + /* 26 */ "key", + /* 27 */ "name", /* Used by: function_list */ + /* 28 */ "builtin", + /* 29 */ "type", + /* 30 */ "enc", + /* 31 */ "narg", + /* 32 */ "flags", + /* 33 */ "tbl", /* Used by: stats */ + /* 34 */ "idx", + /* 35 */ "wdth", + /* 36 */ "hght", + /* 37 */ "flgs", + /* 38 */ "seq", /* Used by: index_list */ + /* 39 */ "name", + /* 40 */ "unique", + /* 41 */ "origin", + /* 42 */ "partial", + /* 43 */ "table", /* Used by: foreign_key_check */ + /* 44 */ "rowid", + /* 45 */ "parent", + /* 46 */ "fkid", + /* index_info reuses 21 */ + /* 47 */ "seq", /* Used by: database_list */ + /* 48 */ "name", + /* 49 */ "file", + /* 50 */ "busy", /* Used by: wal_checkpoint */ + /* 51 */ "log", + /* 52 */ "checkpointed", + /* collation_list reuses 38 */ + /* 53 */ "database", /* Used by: lock_status */ + /* 54 */ "status", + /* 55 */ "cache_size", /* Used by: default_cache_size */ /* module_list pragma_list reuses 9 */ - /* 50 */ "timeout", /* Used by: busy_timeout */ + /* 56 */ "timeout", /* Used by: busy_timeout */ }; /* Definitions of all built-in pragmas */ @@ -128004,7 +130029,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "busy_timeout", /* ePragTyp: */ PragTyp_BUSY_TIMEOUT, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 50, 1, + /* ColNames: */ 56, 1, /* iArg: */ 0 }, #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) {/* zName: */ "cache_size", @@ -128043,7 +130068,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "collation_list", /* ePragTyp: */ PragTyp_COLLATION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 32, 2, + /* ColNames: */ 38, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS) @@ -128078,14 +130103,14 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "database_list", /* ePragTyp: */ PragTyp_DATABASE_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0, - /* ColNames: */ 41, 3, + /* ColNames: */ 47, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) {/* zName: */ "default_cache_size", /* ePragTyp: */ PragTyp_DEFAULT_CACHE_SIZE, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1, - /* ColNames: */ 49, 1, + /* ColNames: */ 55, 1, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -128115,7 +130140,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "foreign_key_check", /* ePragTyp: */ PragTyp_FOREIGN_KEY_CHECK, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 37, 4, + /* ColNames: */ 43, 4, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FOREIGN_KEY) @@ -128158,7 +130183,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 21, 6, + /* ColNames: */ 27, 6, /* iArg: */ 0 }, #endif #endif @@ -128187,23 +130212,23 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "index_info", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 15, 3, + /* ColNames: */ 21, 3, /* iArg: */ 0 }, {/* zName: */ "index_list", /* ePragTyp: */ PragTyp_INDEX_LIST, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 32, 5, + /* ColNames: */ 38, 5, /* iArg: */ 0 }, {/* zName: */ "index_xinfo", /* ePragTyp: */ PragTyp_INDEX_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, - /* ColNames: */ 15, 6, + /* ColNames: */ 21, 6, /* iArg: */ 1 }, #endif #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) {/* zName: */ "integrity_check", /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -128237,7 +130262,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "lock_status", /* ePragTyp: */ PragTyp_LOCK_STATUS, /* ePragFlg: */ PragFlg_Result0, - /* ColNames: */ 47, 2, + /* ColNames: */ 53, 2, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -128311,7 +130336,7 @@ static const PragmaName aPragmaName[] = { #if !defined(SQLITE_OMIT_INTEGRITY_CHECK) {/* zName: */ "quick_check", /* ePragTyp: */ PragTyp_INTEGRITY_CHECK, - /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 0, 0, /* iArg: */ 0 }, #endif @@ -128376,7 +130401,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "stats", /* ePragTyp: */ PragTyp_STATS, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq, - /* ColNames: */ 27, 5, + /* ColNames: */ 33, 5, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) @@ -128392,6 +130417,11 @@ static const PragmaName aPragmaName[] = { /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, /* ColNames: */ 8, 6, /* iArg: */ 0 }, + {/* zName: */ "table_list", + /* ePragTyp: */ PragTyp_TABLE_LIST, + /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1, + /* ColNames: */ 15, 6, + /* iArg: */ 0 }, {/* zName: */ "table_xinfo", /* ePragTyp: */ PragTyp_TABLE_INFO, /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt, @@ -128467,7 +130497,7 @@ static const PragmaName aPragmaName[] = { {/* zName: */ "wal_checkpoint", /* ePragTyp: */ PragTyp_WAL_CHECKPOINT, /* ePragFlg: */ PragFlg_NeedSchema, - /* ColNames: */ 44, 3, + /* ColNames: */ 50, 3, /* iArg: */ 0 }, #endif #if !defined(SQLITE_OMIT_FLAG_PRAGMAS) @@ -128478,7 +130508,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 67 on by default, 77 total. */ +/* Number of pragmas: 68 on by default, 78 total. */ /************** End of pragma.h **********************************************/ /************** Continuing where we left off in pragma.c *********************/ @@ -128920,7 +130950,11 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Locate the pragma in the lookup table */ pPragma = pragmaLocate(zLeft); - if( pPragma==0 ) goto pragma_out; + if( pPragma==0 ){ + /* IMP: R-43042-22504 No error messages are generated if an + ** unknown pragma is issued. */ + goto pragma_out; + } /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ @@ -129570,6 +131604,14 @@ SQLITE_PRIVATE void sqlite3Pragma( }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; + if( (mask & SQLITE_WriteSchema)!=0 + && sqlite3_stricmp(zRight, "reset")==0 + ){ + /* IMP: R-60817-01178 If the argument is "RESET" then schema + ** writing is disabled (as with "PRAGMA writable_schema=OFF") and, + ** in addition, the schema is reloaded. */ + sqlite3ResetAllSchemasOfConnection(db); + } } /* Many of the flag-pragmas modify the code generated by the SQL @@ -129610,6 +131652,7 @@ SQLITE_PRIVATE void sqlite3Pragma( sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ int isHidden = 0; + const Expr *pColExpr; if( pCol->colFlags & COLFLAG_NOINSERT ){ if( pPragma->iArg==0 ){ nHidden++; @@ -129630,13 +131673,16 @@ SQLITE_PRIVATE void sqlite3Pragma( }else{ for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } - assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 ); + pColExpr = sqlite3ColumnExpr(pTab,pCol); + assert( pColExpr==0 || pColExpr->op==TK_SPAN || isHidden>=2 ); + assert( pColExpr==0 || !ExprHasProperty(pColExpr, EP_IntValue) + || isHidden>=2 ); sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, - pCol->zName, + pCol->zCnName, sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, - pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0, + (isHidden>=2 || pColExpr==0) ? 0 : pColExpr->u.zToken, k, isHidden); } @@ -129644,6 +131690,85 @@ SQLITE_PRIVATE void sqlite3Pragma( } break; + /* + ** PRAGMA table_list + ** + ** Return a single row for each table, virtual table, or view in the + ** entire schema. + ** + ** schema: Name of attached database hold this table + ** name: Name of the table itself + ** type: "table", "view", "virtual", "shadow" + ** ncol: Number of columns + ** wr: True for a WITHOUT ROWID table + ** strict: True for a STRICT table + */ + case PragTyp_TABLE_LIST: { + int ii; + pParse->nMem = 6; + sqlite3CodeVerifyNamedSchema(pParse, zDb); + for(ii=0; iinDb; ii++){ + HashElem *k; + Hash *pHash; + int initNCol; + if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue; + + /* Ensure that the Table.nCol field is initialized for all views + ** and virtual tables. Each time we initialize a Table.nCol value + ** for a table, that can potentially disrupt the hash table, so restart + ** the initialization scan. + */ + pHash = &db->aDb[ii].pSchema->tblHash; + initNCol = sqliteHashCount(pHash); + while( initNCol-- ){ + for(k=sqliteHashFirst(pHash); 1; k=sqliteHashNext(k) ){ + Table *pTab; + if( k==0 ){ initNCol = 0; break; } + pTab = sqliteHashData(k); + if( pTab->nCol==0 ){ + char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName); + if( zSql ){ + sqlite3_stmt *pDummy = 0; + (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0); + (void)sqlite3_finalize(pDummy); + sqlite3DbFree(db, zSql); + } + if( db->mallocFailed ){ + sqlite3ErrorMsg(db->pParse, "out of memory"); + db->pParse->rc = SQLITE_NOMEM_BKPT; + } + pHash = &db->aDb[ii].pSchema->tblHash; + break; + } + } + } + + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){ + Table *pTab = sqliteHashData(k); + const char *zType; + if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue; + if( IsView(pTab) ){ + zType = "view"; + }else if( IsVirtual(pTab) ){ + zType = "virtual"; + }else if( pTab->tabFlags & TF_Shadow ){ + zType = "shadow"; + }else{ + zType = "table"; + } + sqlite3VdbeMultiLoad(v, 1, "sssiii", + db->aDb[ii].zDbSName, + sqlite3PreferredTableName(pTab->zName), + zType, + pTab->nCol, + (pTab->tabFlags & TF_WithoutRowid)!=0, + (pTab->tabFlags & TF_Strict)!=0 + ); + } + } + } + break; + #ifdef SQLITE_DEBUG case PragTyp_STATS: { Index *pIdx; @@ -129653,7 +131778,7 @@ SQLITE_PRIVATE void sqlite3Pragma( for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); sqlite3VdbeMultiLoad(v, 1, "ssiii", - pTab->zName, + sqlite3PreferredTableName(pTab->zName), 0, pTab->szTabRow, pTab->nRowLogEst, @@ -129703,7 +131828,7 @@ SQLITE_PRIVATE void sqlite3Pragma( for(i=0; iaiColumn[i]; sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, - cnum<0 ? 0 : pTab->aCol[cnum].zName); + cnum<0 ? 0 : pTab->aCol[cnum].zCnName); if( pPragma->iArg ){ sqlite3VdbeMultiLoad(v, 4, "isiX", pIdx->aSortOrder[i], @@ -129772,11 +131897,13 @@ SQLITE_PRIVATE void sqlite3Pragma( pParse->nMem = 6; for(i=0; iu.pHash ){ + assert( p->funcFlags & SQLITE_FUNC_BUILTIN ); pragmaFunclistLine(v, p, 1, showInternFunc); } } for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){ p = (FuncDef*)sqliteHashData(j); + assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); pragmaFunclistLine(v, p, 0, showInternFunc); } } @@ -129810,8 +131937,8 @@ SQLITE_PRIVATE void sqlite3Pragma( FKey *pFK; Table *pTab; pTab = sqlite3FindTable(db, zRight, zDb); - if( pTab ){ - pFK = pTab->pFKey; + if( pTab && IsOrdinaryTable(pTab) ){ + pFK = pTab->u.tab.pFKey; if( pFK ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i = 0; @@ -129824,7 +131951,7 @@ SQLITE_PRIVATE void sqlite3Pragma( i, j, pFK->zTo, - pTab->aCol[pFK->aCol[j].iFrom].zName, + pTab->aCol[pFK->aCol[j].iFrom].zCnName, pFK->aCol[j].zCol, actionName(pFK->aAction[1]), /* ON UPDATE */ actionName(pFK->aAction[0]), /* ON DELETE */ @@ -129870,7 +131997,7 @@ SQLITE_PRIVATE void sqlite3Pragma( pTab = (Table*)sqliteHashData(k); k = sqliteHashNext(k); } - if( pTab==0 || pTab->pFKey==0 ) continue; + if( pTab==0 || !IsOrdinaryTable(pTab) || pTab->u.tab.pFKey==0 ) continue; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; sqlite3CodeVerifySchema(pParse, iDb); @@ -129878,7 +132005,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead); sqlite3VdbeLoadString(v, regResult, pTab->zName); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ + assert( IsOrdinaryTable(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); if( pParent==0 ) continue; pIdx = 0; @@ -129900,7 +132028,8 @@ SQLITE_PRIVATE void sqlite3Pragma( if( pFK ) break; if( pParse->nTabnTab = i; addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); - for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ + assert( IsOrdinaryTable(pTab) ); + for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){ pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; @@ -129914,6 +132043,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** regRow..regRow+n. If any of the child key values are NULL, this ** row cannot cause an FK violation. Jump directly to addrOk in ** this case. */ + if( regRow+pFK->nCol>pParse->nMem ) pParse->nMem = regRow+pFK->nCol; for(j=0; jnCol; j++){ int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); @@ -130100,8 +132230,9 @@ SQLITE_PRIVATE void sqlite3Pragma( int loopTop; int iDataCur, iIdxCur; int r1 = -1; + int bStrict; - if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */ + if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, @@ -130121,23 +132252,48 @@ SQLITE_PRIVATE void sqlite3Pragma( /* Sanity check on record header decoding */ sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + VdbeComment((v, "(right-most column)")); } - /* Verify that all NOT NULL columns really are NOT NULL */ + /* Verify that all NOT NULL columns really are NOT NULL. At the + ** same time verify the type of the content of STRICT tables */ + bStrict = (pTab->tabFlags & TF_Strict)!=0; for(j=0; jnCol; j++){ char *zErr; - int jmp2; + Column *pCol = pTab->aCol + j; + int doError, jmp2; if( j==pTab->iPKey ) continue; - if( pTab->aCol[j].notNull==0 ) continue; + if( pCol->notNull==0 && !bStrict ) continue; + doError = bStrict ? sqlite3VdbeMakeLabel(pParse) : 0; sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); } - jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); - zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, - pTab->aCol[j].zName); - sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); - integrityCheckResultRow(v); - sqlite3VdbeJumpHere(v, jmp2); + if( pCol->notNull ){ + jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, + pCol->zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + if( bStrict && pCol->eCType!=COLTYPE_ANY ){ + sqlite3VdbeGoto(v, doError); + }else{ + integrityCheckResultRow(v); + } + sqlite3VdbeJumpHere(v, jmp2); + } + if( (pTab->tabFlags & TF_Strict)!=0 + && pCol->eCType!=COLTYPE_ANY + ){ + jmp2 = sqlite3VdbeAddOp3(v, OP_IsNullOrType, 3, 0, + sqlite3StdTypeMap[pCol->eCType-1]); + VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "non-%s value in %s.%s", + sqlite3StdType[pCol->eCType-1], + pTab->zName, pTab->aCol[j].zCnName); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + sqlite3VdbeResolveLabel(v, doError); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, jmp2); + } } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ @@ -130671,12 +132827,12 @@ SQLITE_PRIVATE void sqlite3Pragma( case PragTyp_ANALYSIS_LIMIT: { sqlite3_int64 N; if( zRight - && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK /* IMP: R-40975-20399 */ && N>=0 ){ db->nAnalysisLimit = (int)(N&0x7fffffff); } - returnSingleInt(v, db->nAnalysisLimit); + returnSingleInt(v, db->nAnalysisLimit); /* IMP: R-57594-65522 */ break; } @@ -131078,10 +133234,15 @@ static void corruptSchema( pData->rc = SQLITE_NOMEM_BKPT; }else if( pData->pzErrMsg[0]!=0 ){ /* A error message has already been generated. Do not overwrite it */ - }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){ + }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){ + static const char *azAlterType[] = { + "rename", + "drop column", + "add column" + }; *pData->pzErrMsg = sqlite3MPrintf(db, "error in %s %s after %s: %s", azObj[0], azObj[1], - (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column", + azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1], zExtra ); pData->rc = SQLITE_ERROR; @@ -131183,7 +133344,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char } } db->init.orphanTrigger = 0; - db->init.azInit = argv; + db->init.azInit = (const char**)argv; pStmt = 0; TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); rc = db->errCode; @@ -131202,6 +133363,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char } } } + db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ sqlite3_finalize(pStmt); }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ corruptSchema(pData, argv, 0); @@ -131432,7 +133594,7 @@ SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFl sqlite3ResetAllSchemasOfConnection(db); pDb = &db->aDb[iDb]; }else - if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ + if( rc==SQLITE_OK || ((db->flags&SQLITE_NoSchemaError) && rc!=SQLITE_NOMEM)){ /* Hack: If the SQLITE_NoSchemaError flag is set, then consider ** the schema loaded, even if errors (other than OOM) occurred. In ** this situation the current sqlite3_prepare() operation will fail, @@ -131611,8 +133773,14 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ /* ** Free all memory allocations in the pParse object */ -SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ +SQLITE_PRIVATE void sqlite3ParseObjectReset(Parse *pParse){ sqlite3 *db = pParse->db; + assert( db!=0 ); + assert( db->pParse==pParse ); + assert( pParse->nested==0 ); +#ifndef SQLITE_OMIT_SHARED_CACHE + sqlite3DbFree(db, pParse->aTableLock); +#endif while( pParse->pCleanup ){ ParseCleanup *pCleanup = pParse->pCleanup; pParse->pCleanup = pCleanup->pNext; @@ -131623,11 +133791,12 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ if( pParse->pConstExpr ){ sqlite3ExprListDelete(db, pParse->pConstExpr); } - if( db ){ - assert( db->lookaside.bDisable >= pParse->disableLookaside ); - db->lookaside.bDisable -= pParse->disableLookaside; - db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; - } + assert( db->lookaside.bDisable >= pParse->disableLookaside ); + db->lookaside.bDisable -= pParse->disableLookaside; + db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; + assert( pParse->db->pParse==pParse ); + db->pParse = pParse->pOuterParse; + pParse->db = 0; pParse->disableLookaside = 0; } @@ -131640,7 +133809,7 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ ** cost for this mechansim (an extra malloc), so it should not be used ** for common cleanups that happen on most calls. But for less ** common cleanups, we save a single NULL-pointer comparison in -** sqlite3ParserReset(), which reduces the total CPU cycle count. +** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. ** ** If a memory allocation error occurs, then the cleanup happens immediately. ** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the @@ -131680,6 +133849,33 @@ SQLITE_PRIVATE void *sqlite3ParserAddCleanup( return pPtr; } +/* +** Turn bulk memory into a valid Parse object and link that Parse object +** into database connection db. +** +** Call sqlite3ParseObjectReset() to undo this operation. +** +** Caution: Do not confuse this routine with sqlite3ParseObjectInit() which +** is generated by Lemon. +*/ +SQLITE_PRIVATE void sqlite3ParseObjectInit(Parse *pParse, sqlite3 *db){ + memset(PARSE_HDR(pParse), 0, PARSE_HDR_SZ); + memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); + assert( db->pParse!=pParse ); + pParse->pOuterParse = db->pParse; + db->pParse = pParse; + pParse->db = db; + if( db->mallocFailed ) sqlite3ErrorMsg(pParse, "out of memory"); +} + +/* +** Maximum number of times that we will try again to prepare a statement +** that returns SQLITE_ERROR_RETRY. +*/ +#ifndef SQLITE_MAX_PREPARE_RETRY +# define SQLITE_MAX_PREPARE_RETRY 25 +#endif + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ @@ -131692,16 +133888,19 @@ static int sqlite3Prepare( sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ - char *zErrMsg = 0; /* Error message */ int rc = SQLITE_OK; /* Result code */ int i; /* Loop counter */ Parse sParse; /* Parsing context */ - memset(&sParse, 0, PARSE_HDR_SZ); + /* sqlite3ParseObjectInit(&sParse, db); // inlined for performance */ + memset(PARSE_HDR(&sParse), 0, PARSE_HDR_SZ); memset(PARSE_TAIL(&sParse), 0, PARSE_TAIL_SZ); + sParse.pOuterParse = db->pParse; + db->pParse = &sParse; + sParse.db = db; sParse.pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); - /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ + if( db->mallocFailed ) sqlite3ErrorMsg(&sParse, "out of memory"); assert( sqlite3_mutex_held(db->mutex) ); /* For a long-term use prepared statement avoid the use of @@ -131754,7 +133953,6 @@ static int sqlite3Prepare( sqlite3VtabUnlockList(db); - sParse.db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; @@ -131767,14 +133965,14 @@ static int sqlite3Prepare( } zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ - sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); + sqlite3RunParser(&sParse, zSqlCopy); sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; sqlite3DbFree(db, zSqlCopy); }else{ sParse.zTail = &zSql[nBytes]; } }else{ - sqlite3RunParser(&sParse, zSql, &zErrMsg); + sqlite3RunParser(&sParse, zSql); } assert( 0==sParse.nQueryLoop ); @@ -131790,7 +133988,7 @@ static int sqlite3Prepare( sParse.checkSchema = 0; } if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ - if( sParse.checkSchema ){ + if( sParse.checkSchema && db->init.busy==0 ){ schemaIsValid(&sParse); } if( sParse.pVdbe ){ @@ -131798,14 +133996,14 @@ static int sqlite3Prepare( } assert( 0==(*ppStmt) ); rc = sParse.rc; - if( zErrMsg ){ - sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - sqlite3DbFree(db, zErrMsg); + if( sParse.zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); }else{ sqlite3Error(db, rc); } }else{ - assert( zErrMsg==0 ); + assert( sParse.zErrMsg==0 ); *ppStmt = (sqlite3_stmt*)sParse.pVdbe; rc = SQLITE_OK; sqlite3ErrorClear(db); @@ -131821,7 +134019,7 @@ static int sqlite3Prepare( end_prepare: - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); return rc; } static int sqlite3LockAndPrepare( @@ -131851,7 +134049,8 @@ static int sqlite3LockAndPrepare( ** reset is considered a permanent error. */ rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); assert( rc==SQLITE_OK || *ppStmt==0 ); - }while( rc==SQLITE_ERROR_RETRY + if( rc==SQLITE_OK || db->mallocFailed ) break; + }while( (rc==SQLITE_ERROR_RETRY && (cnt++)aCol, i=0; inCol; pCol++, i++){ - if( pCol->hName==h && sqlite3StrICmp(pCol->zName, zCol)==0 ) return i; + if( pCol->hName==h && sqlite3StrICmp(pCol->zCnName, zCol)==0 ) return i; } return -1; } @@ -132418,18 +134617,21 @@ static void addWhereTerm( pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); + assert( pE2!=0 || pEq==0 ); /* Due to db->mallocFailed test + ** in sqlite3DbMallocRawNN() called from + ** sqlite3PExpr(). */ if( pEq && isOuterJoin ){ ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = pE2->iTable; + pEq->w.iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } /* ** Set the EP_FromJoin property on all terms of the given expression. -** And set the Expr.iRightJoinTable to iTable for every term in the +** And set the Expr.w.iRightJoinTable to iTable for every term in the ** expression. ** ** The EP_FromJoin property is used on terms of an expression to tell @@ -132439,8 +134641,8 @@ static void addWhereTerm( ** WHERE clause during join processing but we need to remember that they ** originated in the ON or USING clause. ** -** The Expr.iRightJoinTable tells the WHERE clause processing that the -** expression depends on table iRightJoinTable even if that table is not +** The Expr.w.iRightJoinTable tells the WHERE clause processing that the +** expression depends on table w.iRightJoinTable even if that table is not ** explicitly mentioned in the expression. That information is needed ** for cases like this: ** @@ -132458,11 +134660,14 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); - p->iRightJoinTable = iTable; - if( p->op==TK_FUNCTION && p->x.pList ){ - int i; - for(i=0; ix.pList->nExpr; i++){ - sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); + p->w.iRightJoinTable = iTable; + if( p->op==TK_FUNCTION ){ + assert( ExprUseXList(p) ); + if( p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); + } } } sqlite3SetJoinExpr(p->pLeft, iTable); @@ -132471,7 +134676,7 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ } /* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every -** term that is marked with EP_FromJoin and iRightJoinTable==iTable into +** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into ** an ordinary term that omits the EP_FromJoin mark. ** ** This happens when a LEFT JOIN is simplified into an ordinary JOIN. @@ -132479,16 +134684,19 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ static void unsetJoinExpr(Expr *p, int iTable){ while( p ){ if( ExprHasProperty(p, EP_FromJoin) - && (iTable<0 || p->iRightJoinTable==iTable) ){ + && (iTable<0 || p->w.iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } if( p->op==TK_COLUMN && p->iTable==iTable ){ ExprClearProperty(p, EP_CanBeNull); } - if( p->op==TK_FUNCTION && p->x.pList ){ - int i; - for(i=0; ix.pList->nExpr; i++){ - unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); + if( p->op==TK_FUNCTION ){ + assert( ExprUseXList(p) ); + if( p->x.pList ){ + int i; + for(i=0; ix.pList->nExpr; i++){ + unsetJoinExpr(p->x.pList->a[i].pExpr, iTable); + } } } unsetJoinExpr(p->pLeft, iTable); @@ -132541,7 +134749,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int iLeftCol; /* Matching column in the left table */ if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue; - zName = pRightTab->aCol[j].zName; + zName = pRightTab->aCol[j].zCnName; if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){ addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j, isOuter, &p->pWhere); @@ -132944,7 +135152,9 @@ static void fixDistinctOpenEph( int iVal, /* Value returned by codeDistinct() */ int iOpenEphAddr /* Address of OP_OpenEphemeral instruction for iTab */ ){ - if( eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED ){ + if( pParse->nErr==0 + && (eTnctType==WHERE_DISTINCT_UNIQUE || eTnctType==WHERE_DISTINCT_ORDERED) + ){ Vdbe *v = pParse->pVdbe; sqlite3VdbeChangeToNoop(v, iOpenEphAddr); if( sqlite3VdbeGetOp(v, iOpenEphAddr+1)->opcode==OP_Explain ){ @@ -133001,9 +135211,13 @@ static void selectExprDefer( struct ExprList_item *pItem = &pEList->a[i]; if( pItem->u.x.iOrderByCol==0 ){ Expr *pExpr = pItem->pExpr; - Table *pTab = pExpr->y.pTab; - if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab) - && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF) + Table *pTab; + if( pExpr->op==TK_COLUMN + && pExpr->iColumn>=0 + && ALWAYS( ExprUseYTab(pExpr) ) + && (pTab = pExpr->y.pTab)!=0 + && IsOrdinaryTable(pTab) + && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)!=0 ){ int j; for(j=0; jiTable = pExpr->iTable; + assert( ExprUseYTab(pNew) ); pNew->y.pTab = pExpr->y.pTab; pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); @@ -133459,7 +135674,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ p->nRef = 1; memset(&p[1], 0, nExtra); }else{ - sqlite3OomFault(db); + return (KeyInfo*)sqlite3OomFault(db); } return p; } @@ -133630,6 +135845,9 @@ static void generateSortTail( iTab = pSort->iECursor; if( eDest==SRT_Output || eDest==SRT_Coroutine || eDest==SRT_Mem ){ + if( eDest==SRT_Mem && p->iOffset ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, pDest->iSdst); + } regRowid = 0; regRow = pDest->iSdst; }else{ @@ -133872,7 +136090,7 @@ static const char *columnTypeImpl( break; } - assert( pTab && pExpr->y.pTab==pTab ); + assert( pTab && ExprUseYTab(pExpr) && pExpr->y.pTab==pTab ); if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin @@ -133906,7 +136124,7 @@ static const char *columnTypeImpl( zType = "INTEGER"; zOrigCol = "rowid"; }else{ - zOrigCol = pTab->aCol[iCol].zName; + zOrigCol = pTab->aCol[iCol].zCnName; zType = sqlite3ColumnType(&pTab->aCol[iCol],0); } zOrigTab = pTab->zName; @@ -133932,9 +136150,11 @@ static const char *columnTypeImpl( ** statement. */ NameContext sNC; - Select *pS = pExpr->x.pSelect; - Expr *p = pS->pEList->a[0].pExpr; - assert( ExprHasProperty(pExpr, EP_xIsSelect) ); + Select *pS; + Expr *p; + assert( ExprUseXSelect(pExpr) ); + pS = pExpr->x.pSelect; + p = pS->pEList->a[0].pExpr; sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; @@ -134063,7 +136283,8 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames( assert( p!=0 ); assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ - assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */ + assert( p->op!=TK_COLUMN + || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */ if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zEName; @@ -134078,7 +136299,7 @@ SQLITE_PRIVATE void sqlite3GenerateColumnNames( if( iCol<0 ){ zCol = "rowid"; }else{ - zCol = pTab->aCol[iCol].zName; + zCol = pTab->aCol[iCol].zCnName; } if( fullName ){ char *zName = 0; @@ -134159,11 +136380,14 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); } - if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->y.pTab)!=0 ){ + if( pColExpr->op==TK_COLUMN + && ALWAYS( ExprUseYTab(pColExpr) ) + && (pTab = pColExpr->y.pTab)!=0 + ){ /* For columns use the column name name */ int iCol = pColExpr->iColumn; if( iCol<0 ) iCol = pTab->iPKey; - zName = iCol>=0 ? pTab->aCol[iCol].zName : "rowid"; + zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid"; }else if( pColExpr->op==TK_ID ){ assert( !ExprHasProperty(pColExpr, EP_IntValue) ); zName = pColExpr->u.zToken; @@ -134191,7 +136415,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } - pCol->zName = zName; + pCol->zCnName = zName; pCol->hName = sqlite3StrIHash(zName); sqlite3ColumnPropertiesFromName(0, pCol); if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ @@ -134201,7 +136425,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( sqlite3HashClear(&ht); if( db->mallocFailed ){ for(j=0; jpEList->a; for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ const char *zType; - int n, m; + i64 n, m; pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; zType = columnType(&sNC, p, 0, 0, 0); @@ -134253,17 +136477,21 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( pCol->affinity = sqlite3ExprAffinity(p); if( zType ){ m = sqlite3Strlen30(zType); - n = sqlite3Strlen30(pCol->zName); - pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); - if( pCol->zName ){ - memcpy(&pCol->zName[n+1], zType, m+1); + n = sqlite3Strlen30(pCol->zCnName); + pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2); + if( pCol->zCnName ){ + memcpy(&pCol->zCnName[n+1], zType, m+1); pCol->colFlags |= COLFLAG_HASTYPE; + }else{ + testcase( pCol->colFlags & COLFLAG_HASTYPE ); + pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL); } } if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; pColl = sqlite3ExprCollSeq(pParse, p); - if( pColl && pCol->zColl==0 ){ - pCol->zColl = sqlite3DbStrDup(db, pColl->zName); + if( pColl ){ + assert( pTab->pIndex==0 ); + sqlite3ColumnSetColl(db, pCol, pColl->zName); } } pTab->szTabRow = 1; /* Any non-zero value works */ @@ -134427,7 +136655,7 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ */ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ ExprList *pOrderBy = p->pOrderBy; - int nOrderBy = p->pOrderBy->nExpr; + int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0; sqlite3 *db = pParse->db; KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); if( pRet ){ @@ -134499,7 +136727,7 @@ static void generateWithRecursiveQuery( SrcList *pSrc = p->pSrc; /* The FROM clause of the recursive query */ int nCol = p->pEList->nExpr; /* Number of columns in the recursive table */ Vdbe *v = pParse->pVdbe; /* The prepared statement under construction */ - Select *pSetup = p->pPrior; /* The setup query */ + Select *pSetup; /* The setup query */ Select *pFirstRec; /* Left-most recursive term */ int addrTop; /* Top of the loop */ int addrCont, addrBreak; /* CONTINUE and BREAK addresses */ @@ -134583,7 +136811,6 @@ static void generateWithRecursiveQuery( ** iDistinct table. pFirstRec is left pointing to the left-most ** recursive term of the CTE. */ - pFirstRec = p; for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){ if( pFirstRec->selFlags & SF_Aggregate ){ sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); @@ -135049,6 +137276,7 @@ static int multiSelect( int nCol; /* Number of columns in result set */ assert( p->pNext==0 ); + assert( p->pEList!=0 ); nCol = p->pEList->nExpr; pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); if( !pKeyInfo ){ @@ -135083,7 +137311,11 @@ static int multiSelect( multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; - sqlite3SelectDelete(db, pDelete); + if( pDelete ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3SelectDelete, + pDelete); + } return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ @@ -135337,6 +137569,8 @@ static int multiSelectOrderBy( ){ int i, j; /* Loop counters */ Select *pPrior; /* Another SELECT immediately to our left */ + Select *pSplit; /* Left-most SELECT in the right-hand group */ + int nSelect; /* Number of SELECT statements in the compound */ Vdbe *v; /* Generate code to this VDBE */ SelectDest destA; /* Destination for coroutine A */ SelectDest destB; /* Destination for coroutine B */ @@ -135382,8 +137616,7 @@ static int multiSelectOrderBy( /* Patch up the ORDER BY clause */ op = p->op; - pPrior = p->pPrior; - assert( pPrior->pOrderBy==0 ); + assert( p->pPrior->pOrderBy==0 ); pOrderBy = p->pOrderBy; assert( pOrderBy ); nOrderBy = pOrderBy->nExpr; @@ -135396,6 +137629,7 @@ static int multiSelectOrderBy( for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){ struct ExprList_item *pItem; for(j=0, pItem=pOrderBy->a; ju.x.iOrderByCol>0 ); if( pItem->u.x.iOrderByCol==i ) break; } @@ -135422,6 +137656,7 @@ static int multiSelectOrderBy( struct ExprList_item *pItem; aPermute[0] = nOrderBy; for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){ + assert( pItem!=0 ); assert( pItem->u.x.iOrderByCol>0 ); assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ); aPermute[i] = pItem->u.x.iOrderByCol - 1; @@ -135431,11 +137666,6 @@ static int multiSelectOrderBy( pKeyMerge = 0; } - /* Reattach the ORDER BY clause to the query. - */ - p->pOrderBy = pOrderBy; - pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); - /* Allocate a range of temporary registers and the KeyInfo needed ** for the logic that removes duplicate result rows when the ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL). @@ -135460,12 +137690,30 @@ static int multiSelectOrderBy( /* Separate the left and the right query from one another */ - p->pPrior = 0; - pPrior->pNext = 0; - sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); - if( pPrior->pPrior==0 ){ - sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); + nSelect = 1; + if( (op==TK_ALL || op==TK_UNION) + && OptimizationEnabled(db, SQLITE_BalancedMerge) + ){ + for(pSplit=p; pSplit->pPrior!=0 && pSplit->op==op; pSplit=pSplit->pPrior){ + nSelect++; + assert( pSplit->pPrior->pNext==pSplit ); + } } + if( nSelect<=3 ){ + pSplit = p; + }else{ + pSplit = p; + for(i=2; ipPrior; } + } + pPrior = pSplit->pPrior; + assert( pPrior!=0 ); + pSplit->pPrior = 0; + pPrior->pNext = 0; + assert( p->pOrderBy == pOrderBy ); + assert( pOrderBy!=0 || db->mallocFailed ); + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); + sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); /* Compute the limit registers */ computeLimitRegisters(pParse, p, labelEnd); @@ -135616,12 +137864,11 @@ static int multiSelectOrderBy( /* Reassembly the compound query so that it will be freed correctly ** by the calling function */ - if( p->pPrior ){ - sqlite3SelectDelete(db, p->pPrior); + if( pSplit->pPrior ){ + sqlite3SelectDelete(db, pSplit->pPrior); } - p->pPrior = pPrior; - pPrior->pNext = p; - + pSplit->pPrior = pPrior; + pPrior->pNext = pSplit; sqlite3ExprListDelete(db, pPrior->pOrderBy); pPrior->pOrderBy = 0; @@ -135671,9 +137918,9 @@ static Expr *substExpr( ){ if( pExpr==0 ) return 0; if( ExprHasProperty(pExpr, EP_FromJoin) - && pExpr->iRightJoinTable==pSubst->iTable + && pExpr->w.iRightJoinTable==pSubst->iTable ){ - pExpr->iRightJoinTable = pSubst->iNewTable; + pExpr->w.iRightJoinTable = pSubst->iNewTable; } if( pExpr->op==TK_COLUMN && pExpr->iTable==pSubst->iTable @@ -135712,7 +137959,7 @@ static Expr *substExpr( ExprSetProperty(pNew, EP_CanBeNull); } if( ExprHasProperty(pExpr,EP_FromJoin) ){ - sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable); + sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable); } sqlite3ExprDelete(db, pExpr); pExpr = pNew; @@ -135734,7 +137981,7 @@ static Expr *substExpr( } pExpr->pLeft = substExpr(pSubst, pExpr->pLeft); pExpr->pRight = substExpr(pSubst, pExpr->pRight); - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ substSelect(pSubst, pExpr->x.pSelect, 1); }else{ substExprList(pSubst, pExpr->x.pList); @@ -135825,10 +138072,10 @@ static void recomputeColumnsUsed( ** new cursor number assigned, set an entry in the aCsrMap[] array ** to map the old cursor number to the new: ** -** aCsrMap[iOld] = iNew; +** aCsrMap[iOld+1] = iNew; ** ** The array is guaranteed by the caller to be large enough for all -** existing cursor numbers in pSrc. +** existing cursor numbers in pSrc. aCsrMap[0] is the array size. ** ** If pSrc contains any sub-selects, call this routine recursively ** on the FROM clause of each such sub-select, with iExcept set to -1. @@ -135844,10 +138091,11 @@ static void srclistRenumberCursors( for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ if( i!=iExcept ){ Select *p; - if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor]==0 ){ - aCsrMap[pItem->iCursor] = pParse->nTab++; + assert( pItem->iCursor < aCsrMap[0] ); + if( !pItem->fg.isRecursive || aCsrMap[pItem->iCursor+1]==0 ){ + aCsrMap[pItem->iCursor+1] = pParse->nTab++; } - pItem->iCursor = aCsrMap[pItem->iCursor]; + pItem->iCursor = aCsrMap[pItem->iCursor+1]; for(p=pItem->pSelect; p; p=p->pPrior){ srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); } @@ -135855,18 +138103,28 @@ static void srclistRenumberCursors( } } +/* +** *piCursor is a cursor number. Change it if it needs to be mapped. +*/ +static void renumberCursorDoMapping(Walker *pWalker, int *piCursor){ + int *aCsrMap = pWalker->u.aiCol; + int iCsr = *piCursor; + if( iCsr < aCsrMap[0] && aCsrMap[iCsr+1]>0 ){ + *piCursor = aCsrMap[iCsr+1]; + } +} + /* ** Expression walker callback used by renumberCursors() to update ** Expr objects to match newly assigned cursor numbers. */ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ - int *aCsrMap = pWalker->u.aiCol; int op = pExpr->op; - if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ - pExpr->iTable = aCsrMap[pExpr->iTable]; + if( op==TK_COLUMN || op==TK_IF_NULL_ROW ){ + renumberCursorDoMapping(pWalker, &pExpr->iTable); } - if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ - pExpr->iRightJoinTable = aCsrMap[pExpr->iRightJoinTable]; + if( ExprHasProperty(pExpr, EP_FromJoin) ){ + renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable); } return WRC_Continue; } @@ -136210,7 +138468,8 @@ static int flattenSubquery( if( pSrc->nSrc>1 ){ if( pParse->nSelect>500 ) return 0; - aCsrMap = sqlite3DbMallocZero(db, pParse->nTab*sizeof(int)); + aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int)); + if( aCsrMap ) aCsrMap[0] = pParse->nTab; } } @@ -136833,8 +139092,7 @@ static int pushDownWhereTerms( Parse *pParse, /* Parse context (for malloc() and error reporting) */ Select *pSubq, /* The subquery whose WHERE clause is to be augmented */ Expr *pWhere, /* The WHERE clause of the outer query */ - int iCursor, /* Cursor number of the subquery */ - int isLeftJoin /* True if pSubq is the right term of a LEFT JOIN */ + SrcItem *pSrc /* The subquery term of the outer FROM clause */ ){ Expr *pNew; int nChng = 0; @@ -136869,20 +139127,25 @@ static int pushDownWhereTerms( return 0; /* restriction (3) */ } while( pWhere->op==TK_AND ){ - nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, - iCursor, isLeftJoin); + nChng += pushDownWhereTerms(pParse, pSubq, pWhere->pRight, pSrc); pWhere = pWhere->pLeft; } + +#if 0 /* Legacy code. Checks now done by sqlite3ExprIsTableConstraint() */ if( isLeftJoin && (ExprHasProperty(pWhere,EP_FromJoin)==0 - || pWhere->iRightJoinTable!=iCursor) + || pWhere->w.iRightJoinTable!=iCursor) ){ return 0; /* restriction (4) */ } - if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){ + if( ExprHasProperty(pWhere,EP_FromJoin) + && pWhere->w.iRightJoinTable!=iCursor + ){ return 0; /* restriction (5) */ } - if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ +#endif + + if( sqlite3ExprIsTableConstraint(pWhere, pSrc) ){ nChng++; pSubq->selFlags |= SF_PushDown; while( pSubq ){ @@ -136890,8 +139153,8 @@ static int pushDownWhereTerms( pNew = sqlite3ExprDup(pParse->db, pWhere, 0); unsetJoinExpr(pNew, -1); x.pParse = pParse; - x.iTable = iCursor; - x.iNewTable = iCursor; + x.iTable = pSrc->iCursor; + x.iNewTable = pSrc->iCursor; x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); @@ -136933,7 +139196,7 @@ static int pushDownWhereTerms( */ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ - ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ + ExprList *pEList; /* Arguments to agg function */ const char *zFunc; /* Name of aggregate function pFunc */ ExprList *pOrderBy; u8 sortFlags = 0; @@ -136941,6 +139204,8 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ assert( *ppMinMax==0 ); assert( pFunc->op==TK_AGG_FUNCTION ); assert( !IsWindowFunc(pFunc) ); + assert( ExprUseXList(pFunc) ); + pEList = pFunc->x.pList; if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) @@ -136948,6 +139213,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ ){ return eRet; } + assert( !ExprHasProperty(pFunc, EP_IntValue) ); zFunc = pFunc->u.zToken; if( sqlite3StrICmp(zFunc, "min")==0 ){ eRet = WHERE_ORDERBY_MIN; @@ -136975,7 +139241,13 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ ** ** where table is a database table, not a sub-select or view. If the query ** does match this pattern, then a pointer to the Table object representing -** is returned. Otherwise, 0 is returned. +** is returned. Otherwise, NULL is returned. +** +** This routine checks to see if it is safe to use the count optimization. +** A correct answer is still obtained (though perhaps more slowly) if +** this routine returns NULL when it could have returned a table pointer. +** But returning the pointer when NULL should have been returned can +** result in incorrect answers and/or crashes. So, when in doubt, return NULL. */ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ Table *pTab; @@ -136983,19 +139255,26 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ assert( !p->pGroupBy ); - if( p->pWhere || p->pEList->nExpr!=1 - || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect + if( p->pWhere + || p->pEList->nExpr!=1 + || p->pSrc->nSrc!=1 + || p->pSrc->a[0].pSelect + || pAggInfo->nFunc!=1 ){ return 0; } pTab = p->pSrc->a[0].pTab; + assert( pTab!=0 ); + assert( !IsView(pTab) ); + if( !IsOrdinaryTable(pTab) ) return 0; pExpr = p->pEList->a[0].pExpr; - assert( pTab && !pTab->pSelect && pExpr ); - - if( IsVirtual(pTab) ) return 0; + assert( pExpr!=0 ); if( pExpr->op!=TK_AGG_FUNCTION ) return 0; - if( NEVER(pAggInfo->nFunc==0) ) return 0; + if( pExpr->pAggInfo!=pAggInfo ) return 0; if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0; + assert( pAggInfo->aFunc[0].pFExpr==pExpr ); + testcase( ExprHasProperty(pExpr, EP_Distinct) ); + testcase( ExprHasProperty(pExpr, EP_WinFunc) ); if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0; return pTab; @@ -137024,6 +139303,7 @@ SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ pParse->checkSchema = 1; return SQLITE_ERROR; } + assert( pFrom->fg.isCte==0 ); pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } @@ -137281,6 +139561,10 @@ static int resolveFromTermToCte( if( db->mallocFailed ) return 2; pFrom->pSelect->selFlags |= SF_CopyCte; assert( pFrom->pSelect ); + if( pFrom->fg.isIndexedBy ){ + sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy); + return 2; + } pFrom->fg.isCte = 1; pFrom->u2.pCteUse = pCteUse; pCteUse->nUse++; @@ -137535,30 +139819,31 @@ static int selectExpander(Walker *pWalker, Select *p){ return WRC_Abort; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) - if( IsVirtual(pTab) || pTab->pSelect ){ + if( !IsOrdinaryTable(pTab) ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pTab->pSelect - && (db->flags & SQLITE_EnableView)==0 - && pTab->pSchema!=db->aDb[1].pSchema - ){ - sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", - pTab->zName); + if( IsView(pTab) ){ + if( (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + pTab->zName); + } + pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0); } #ifndef SQLITE_OMIT_VIRTUALTABLE - assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); - if( IsVirtual(pTab) + else if( ALWAYS(IsVirtual(pTab)) && pFrom->fg.fromDDL - && ALWAYS(pTab->pVTable!=0) - && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) + && ALWAYS(pTab->u.vtab.p!=0) + && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) ){ sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", pTab->zName); } + assert( SQLITE_VTABRISK_Normal==1 && SQLITE_VTABRISK_High==2 ); #endif - pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ @@ -137577,7 +139862,8 @@ static int selectExpander(Walker *pWalker, Select *p){ /* Process NATURAL keywords, and ON and USING clauses of joins. */ - if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){ + assert( db->mallocFailed==0 || pParse->nErr!=0 ); + if( pParse->nErr || sqliteProcessJoin(pParse, p) ){ return WRC_Abort; } @@ -137658,7 +139944,7 @@ static int selectExpander(Walker *pWalker, Select *p){ zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } for(j=0; jnCol; j++){ - char *zName = pTab->aCol[j].zName; + char *zName = pTab->aCol[j].zCnName; char *zColname; /* The computed column name */ char *zToFree; /* Malloced string that needs to be freed */ Token sColname; /* Computed column name as a token */ @@ -137874,12 +140160,13 @@ SQLITE_PRIVATE void sqlite3SelectPrep( NameContext *pOuterNC /* Name context for container */ ){ assert( p!=0 || pParse->db->mallocFailed ); + assert( pParse->db->pParse==pParse ); if( pParse->db->mallocFailed ) return; if( p->selFlags & SF_HasTypeInfo ) return; sqlite3SelectExpand(pParse, p); - if( pParse->nErr || pParse->db->mallocFailed ) return; + if( pParse->nErr ) return; sqlite3ResolveSelectNames(pParse, p, pOuterNC); - if( pParse->nErr || pParse->db->mallocFailed ) return; + if( pParse->nErr ) return; sqlite3SelectAddTypeInfo(pParse, p); } @@ -137896,8 +140183,10 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ int i; struct AggInfo_func *pFunc; int nReg = pAggInfo->nFunc + pAggInfo->nColumn; + assert( pParse->db->pParse==pParse ); + assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); if( nReg==0 ) return; - if( pParse->nErr || pParse->db->mallocFailed ) return; + if( pParse->nErr ) return; #ifdef SQLITE_DEBUG /* Verify that all AggInfo registers are within the range specified by ** AggInfo.mnReg..AggInfo.mxReg */ @@ -137915,7 +140204,7 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pFExpr; - assert( !ExprHasProperty(pE, EP_xIsSelect) ); + assert( ExprUseXList(pE) ); if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " "argument"); @@ -137940,8 +140229,9 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ int i; struct AggInfo_func *pF; for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ - ExprList *pList = pF->pFExpr->x.pList; - assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) ); + ExprList *pList; + assert( ExprUseXList(pF->pFExpr) ); + pList = pF->pFExpr->x.pList; sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } @@ -137975,9 +140265,10 @@ static void updateAccumulator( int nArg; int addrNext = 0; int regAgg; - ExprList *pList = pF->pFExpr->x.pList; - assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) ); + ExprList *pList; + assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); + pList = pF->pFExpr->x.pList; if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ Expr *pFilter = pF->pFExpr->y.pWin->pFilter; if( pAggInfo->nAccumulator @@ -138090,8 +140381,16 @@ static void explainSimpleCount( static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op!=TK_AND ){ Select *pS = pWalker->u.pSelect; + /* This routine is called before the HAVING clause of the current + ** SELECT is analyzed for aggregates. So if pExpr->pAggInfo is set + ** here, it indicates that the expression is a correlated reference to a + ** column from an outer aggregate query, or an aggregate function that + ** belongs to an outer query. Do not move the expression to the WHERE + ** clause in this obscure case, as doing so may corrupt the outer Select + ** statements AggInfo structure. */ if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) && ExprAlwaysFalse(pExpr)==0 + && pExpr->pAggInfo==0 ){ sqlite3 *db = pWalker->pParse->db; Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); @@ -138215,7 +140514,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ if( p->pGroupBy ) return 0; pExpr = p->pEList->a[0].pExpr; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ + assert( ExprUseUToken(pExpr) ); if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ + assert( ExprUseXList(pExpr) ); if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ pSub = p->pSrc->a[0].pSelect; @@ -138308,10 +140609,12 @@ SQLITE_PRIVATE int sqlite3Select( u8 minMaxFlag; /* Flag for min/max queries */ db = pParse->db; + assert( pParse==db->pParse ); v = sqlite3GetVdbe(pParse); - if( p==0 || db->mallocFailed || pParse->nErr ){ + if( p==0 || pParse->nErr ){ return 1; } + assert( db->mallocFailed==0 ); if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); @@ -138346,9 +140649,10 @@ SQLITE_PRIVATE int sqlite3Select( p->selFlags |= SF_NoopOrderBy; } sqlite3SelectPrep(pParse, p, 0); - if( pParse->nErr || db->mallocFailed ){ + if( pParse->nErr ){ goto select_end; } + assert( db->mallocFailed==0 ); assert( p->pEList!=0 ); #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x104 ){ @@ -138357,11 +140661,16 @@ SQLITE_PRIVATE int sqlite3Select( } #endif - /* If the SF_UpdateFrom flag is set, then this function is being called + /* If the SF_UFSrcCheck flag is set, then this function is being called ** as part of populating the temp table for an UPDATE...FROM statement. ** In this case, it is an error if the target object (pSrc->a[0]) name - ** or alias is duplicated within FROM clause (pSrc->a[1..n]). */ - if( p->selFlags & SF_UpdateFrom ){ + ** or alias is duplicated within FROM clause (pSrc->a[1..n]). + ** + ** Postgres disallows this case too. The reason is that some other + ** systems handle this case differently, and not all the same way, + ** which is just confusing. To avoid this, we follow PG's lead and + ** disallow it altogether. */ + if( p->selFlags & SF_UFSrcCheck ){ SrcItem *p0 = &p->pSrc->a[0]; for(i=1; ipSrc->nSrc; i++){ SrcItem *p1 = &p->pSrc->a[i]; @@ -138373,6 +140682,12 @@ SQLITE_PRIVATE int sqlite3Select( goto select_end; } } + + /* Clear the SF_UFSrcCheck flag. The check has already been performed, + ** and leaving this flag set can cause errors if a compound sub-query + ** in p->pSrc is flattened into this query and this function called + ** again as part of compound SELECT processing. */ + p->selFlags &= ~SF_UFSrcCheck; } if( pDest->eDest==SRT_Output ){ @@ -138381,7 +140696,7 @@ SQLITE_PRIVATE int sqlite3Select( #ifndef SQLITE_OMIT_WINDOWFUNC if( sqlite3WindowRewrite(pParse, p) ){ - assert( db->mallocFailed || pParse->nErr>0 ); + assert( pParse->nErr ); goto select_end; } #if SELECTTRACE_ENABLED @@ -138444,6 +140759,39 @@ SQLITE_PRIVATE int sqlite3Select( if( (pSub->selFlags & SF_Aggregate)!=0 ) continue; assert( pSub->pGroupBy==0 ); + /* If a FROM-clause subquery has an ORDER BY clause that is not + ** really doing anything, then delete it now so that it does not + ** interfere with query flattening. See the discussion at + ** https://sqlite.org/forum/forumpost/2d76f2bcf65d256a + ** + ** Beware of these cases where the ORDER BY clause may not be safely + ** omitted: + ** + ** (1) There is also a LIMIT clause + ** (2) The subquery was added to help with window-function + ** processing + ** (3) The subquery is in the FROM clause of an UPDATE + ** (4) The outer query uses an aggregate function other than + ** the built-in count(), min(), or max(). + ** (5) The ORDER BY isn't going to accomplish anything because + ** one of: + ** (a) The outer query has a different ORDER BY clause + ** (b) The subquery is part of a join + ** See forum post 062d576715d277c8 + */ + if( pSub->pOrderBy!=0 + && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ + && pSub->pLimit==0 /* Condition (1) */ + && (pSub->selFlags & SF_OrderByReqd)==0 /* Condition (2) */ + && (p->selFlags & SF_OrderByReqd)==0 /* Condition (3) and (4) */ + && OptimizationEnabled(db, SQLITE_OmitOrderBy) + ){ + SELECTTRACE(0x100,pParse,p, + ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); + sqlite3ExprListDelete(db, pSub->pOrderBy); + pSub->pOrderBy = 0; + } + /* If the outer query contains a "complex" result set (that is, ** if the result set of the outer query uses functions or subqueries) ** and if the subquery contains an ORDER BY clause and if @@ -138586,9 +140934,9 @@ SQLITE_PRIVATE int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) - && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) - && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, - (pItem->fg.jointype & JT_OUTER)!=0) + && (pItem->fg.isCte==0 + || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) + && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem) ){ #if SELECTTRACE_ENABLED if( sqlite3SelectTrace & 0x100 ){ @@ -138647,6 +140995,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); if( pItem->iCursor!=pCteUse->iCur ){ sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); + VdbeComment((v, "%!S", pItem)); } pSub->nSelectRow = pCteUse->nRowEst; }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){ @@ -138822,7 +141171,7 @@ SQLITE_PRIVATE int sqlite3Select( /* Begin the database scan. */ SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, - p->pEList, wctrlFlags, p->nSelectRow); + p->pEList, p, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); @@ -138984,7 +141333,7 @@ SQLITE_PRIVATE int sqlite3Select( } for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); + assert( ExprUseXList(pExpr) ); sNC.ncFlags |= NC_InAggFunc; sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC @@ -139039,7 +141388,9 @@ SQLITE_PRIVATE int sqlite3Select( if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 - && pAggInfo->aFunc[0].pFExpr->x.pList + && ALWAYS(pAggInfo->aFunc[0].pFExpr!=0) + && ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr)) + && pAggInfo->aFunc[0].pFExpr->x.pList!=0 ){ Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr; pExpr = sqlite3ExprDup(db, pExpr, 0); @@ -139084,7 +141435,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, - WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 + 0, (WHERE_GROUPBY|(orderByGrp ? WHERE_SORTBYGROUP : 0)|distFlag), 0 ); if( pWInfo==0 ){ sqlite3ExprListDelete(db, pDistinct); @@ -139360,6 +141711,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); } }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){ + assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) ); pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList; distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0; } @@ -139381,7 +141733,7 @@ SQLITE_PRIVATE int sqlite3Select( SELECTTRACE(1,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, - pDistinct, minMaxFlag|distFlag, 0); + pDistinct, 0, minMaxFlag|distFlag, 0); if( pWInfo==0 ){ goto select_end; } @@ -139438,7 +141790,7 @@ SQLITE_PRIVATE int sqlite3Select( */ select_end: assert( db->mallocFailed==0 || db->mallocFailed==1 ); - pParse->nErr += db->mallocFailed; + assert( db->mallocFailed==0 || pParse->nErr!=0 ); sqlite3ExprListDelete(db, pMinMaxOrderBy); #ifdef SQLITE_DEBUG if( pAggInfo && !db->mallocFailed ){ @@ -139891,12 +142243,12 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( /* INSTEAD of triggers are only for views and views only support INSTEAD ** of triggers. */ - if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ + if( IsView(pTab) && tr_tm!=TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName->a); goto trigger_orphan_error; } - if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ + if( !IsView(pTab) && tr_tm==TK_INSTEAD ){ sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName->a); goto trigger_orphan_error; @@ -140033,7 +142385,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); testcase( z==0 ); sqlite3NestedParse(pParse, - "INSERT INTO %Q." DFLT_SCHEMA_TABLE + "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", db->aDb[iDb].zDbSName, zName, pTrig->table, z); @@ -140118,6 +142470,7 @@ static TriggerStep *triggerStepAllocate( sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; + if( pParse->nErr ) return 0; pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); if( pTriggerStep ){ char *z = (char*)&pTriggerStep[1]; @@ -140347,7 +142700,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ */ if( (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3NestedParse(pParse, - "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'", + "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'", db->aDb[iDb].zDbSName, pTrigger->zName ); sqlite3ChangeCookie(pParse, iDb); @@ -140549,11 +142902,11 @@ static ExprList *sqlite3ExpandReturning( for(jj=0; jjnCol; jj++){ Expr *pNewExpr; if( IsHiddenColumn(pTab->aCol+jj) ) continue; - pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zCnName); pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); if( !db->mallocFailed ){ struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; - pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zCnName); pItem->eEName = ENAME_NAME; } } @@ -140590,6 +142943,7 @@ static void codeReturningTrigger( assert( v!=0 ); assert( pParse->bReturning ); + assert( db->pParse==pParse ); pReturning = pParse->u1.pReturning; assert( pTrigger == &(pReturning->retTrig) ); memset(&sSelect, 0, sizeof(sSelect)); @@ -140598,13 +142952,15 @@ static void codeReturningTrigger( sSelect.pSrc = &sFrom; sFrom.nSrc = 1; sFrom.a[0].pTab = pTab; + sFrom.a[0].iCursor = -1; sqlite3SelectPrep(pParse, &sSelect, 0); - if( db->mallocFailed==0 && pParse->nErr==0 ){ + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); sqlite3GenerateColumnNames(pParse, &sSelect); } sqlite3ExprListDelete(db, sSelect.pEList); pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); - if( pNew ){ + if( !db->mallocFailed ){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); if( pReturning->nRetCol==0 ){ @@ -140616,7 +142972,9 @@ static void codeReturningTrigger( sNC.ncFlags = NC_UBaseReg; pParse->eTriggerOp = pTrigger->op; pParse->pTriggerTab = pTab; - if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){ + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK + && ALWAYS(!db->mallocFailed) + ){ int i; int nCol = pNew->nExpr; int reg = pParse->nMem+1; @@ -140624,16 +142982,20 @@ static void codeReturningTrigger( pReturning->iRetReg = reg; for(i=0; ia[i].pExpr; + assert( pCol!=0 ); /* Due to !db->mallocFailed ~9 lines above */ sqlite3ExprCodeFactorable(pParse, pCol, reg+i); + if( sqlite3ExprAffinity(pCol)==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, reg+i); + } } sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); } - sqlite3ExprListDelete(db, pNew); - pParse->eTriggerOp = 0; - pParse->pTriggerTab = 0; } + sqlite3ExprListDelete(db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; } @@ -140775,8 +143137,8 @@ static TriggerPrg *codeRowTrigger( Vdbe *v; /* Temporary VM */ NameContext sNC; /* Name context for sub-vdbe */ SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ - Parse *pSubParse; /* Parse context for sub-vdbe */ int iEndTrigger = 0; /* Label to jump to if WHEN is false */ + Parse sSubParse; /* Parse context for sub-vdbe */ assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); assert( pTop->pVdbe ); @@ -140798,19 +143160,17 @@ static TriggerPrg *codeRowTrigger( /* Allocate and populate a new Parse context to use for coding the ** trigger sub-program. */ - pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); - if( !pSubParse ) return 0; + sqlite3ParseObjectInit(&sSubParse, db); memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pSubParse; - pSubParse->db = db; - pSubParse->pTriggerTab = pTab; - pSubParse->pToplevel = pTop; - pSubParse->zAuthContext = pTrigger->zName; - pSubParse->eTriggerOp = pTrigger->op; - pSubParse->nQueryLoop = pParse->nQueryLoop; - pSubParse->disableVtab = pParse->disableVtab; + sNC.pParse = &sSubParse; + sSubParse.pTriggerTab = pTab; + sSubParse.pToplevel = pTop; + sSubParse.zAuthContext = pTrigger->zName; + sSubParse.eTriggerOp = pTrigger->op; + sSubParse.nQueryLoop = pParse->nQueryLoop; + sSubParse.disableVtab = pParse->disableVtab; - v = sqlite3GetVdbe(pSubParse); + v = sqlite3GetVdbe(&sSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), @@ -140836,14 +143196,14 @@ static TriggerPrg *codeRowTrigger( if( db->mallocFailed==0 && SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) ){ - iEndTrigger = sqlite3VdbeMakeLabel(pSubParse); - sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + iEndTrigger = sqlite3VdbeMakeLabel(&sSubParse); + sqlite3ExprIfFalse(&sSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); } sqlite3ExprDelete(db, pWhen); } /* Code the trigger program into the sub-vdbe. */ - codeTriggerProgram(pSubParse, pTrigger->step_list, orconf); + codeTriggerProgram(&sSubParse, pTrigger->step_list, orconf); /* Insert an OP_Halt at the end of the sub-program. */ if( iEndTrigger ){ @@ -140851,23 +143211,24 @@ static TriggerPrg *codeRowTrigger( } sqlite3VdbeAddOp0(v, OP_Halt); VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); + transferParseError(pParse, &sSubParse); - transferParseError(pParse, pSubParse); - if( db->mallocFailed==0 && pParse->nErr==0 ){ + if( pParse->nErr==0 ){ + assert( db->mallocFailed==0 ); pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } - pProgram->nMem = pSubParse->nMem; - pProgram->nCsr = pSubParse->nTab; + pProgram->nMem = sSubParse.nMem; + pProgram->nCsr = sSubParse.nTab; pProgram->token = (void *)pTrigger; - pPrg->aColmask[0] = pSubParse->oldmask; - pPrg->aColmask[1] = pSubParse->newmask; + pPrg->aColmask[0] = sSubParse.oldmask; + pPrg->aColmask[1] = sSubParse.newmask; sqlite3VdbeDelete(v); + }else{ + transferParseError(pParse, &sSubParse); } - assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); - sqlite3ParserReset(pSubParse); - sqlite3StackFree(db, pSubParse); - + assert( !sSubParse.pTriggerPrg && !sSubParse.nMaxArg ); + sqlite3ParseObjectReset(&sSubParse); return pPrg; } @@ -140900,6 +143261,7 @@ static TriggerPrg *getRowTrigger( /* If an existing TriggerPrg could not be located, create a new one. */ if( !pPrg ){ pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); + pParse->db->errByteOffset = -1; } return pPrg; @@ -140922,7 +143284,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ TriggerPrg *pPrg; pPrg = getRowTrigger(pParse, p, pTab, orconf); - assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); + assert( pPrg || pParse->nErr ); /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program ** is a pointer to the sub-vdbe containing the trigger program. */ @@ -141153,13 +143515,14 @@ static void updateVirtualTable( */ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ assert( pTab!=0 ); - if( !pTab->pSelect ){ + if( !IsView(pTab) ){ sqlite3_value *pValue = 0; u8 enc = ENC(sqlite3VdbeDb(v)); Column *pCol = &pTab->aCol[i]; - VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); + VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); assert( inCol ); - sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, + sqlite3ValueFromExpr(sqlite3VdbeDb(v), + sqlite3ColumnExpr(pTab,pCol), enc, pCol->affinity, &pValue); if( pValue ){ sqlite3VdbeAppendP4(v, pValue, P4_MEM); @@ -141329,7 +143692,7 @@ static void updateFromSelect( pList = sqlite3ExprListAppend(pParse, pList, pNew); } eDest = IsVirtual(pTab) ? SRT_Table : SRT_Upfrom; - }else if( pTab->pSelect ){ + }else if( IsView(pTab) ){ for(i=0; inCol; i++){ pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); } @@ -141352,8 +143715,9 @@ static void updateFromSelect( } } pSelect = sqlite3SelectNew(pParse, pList, - pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UpdateFrom|SF_IncludeHidden, pLimit2 + pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden, pLimit2 ); + if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; sqlite3SelectDestInit(&dest, eDest, iEph); dest.iSDParm2 = (pPk ? pPk->nKeyCol : -1); sqlite3Select(pParse, pSelect, &dest); @@ -141438,9 +143802,11 @@ SQLITE_PRIVATE void sqlite3Update( memset(&sContext, 0, sizeof(sContext)); db = pParse->db; - if( pParse->nErr || db->mallocFailed ){ + assert( db->pParse==pParse ); + if( pParse->nErr ){ goto update_cleanup; } + assert( db->mallocFailed==0 ); /* Locate the table which we want to update. */ @@ -141453,7 +143819,7 @@ SQLITE_PRIVATE void sqlite3Update( */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); - isView = pTab->pSelect!=0; + isView = IsView(pTab); assert( pTrigger || tmask==0 ); #else # define pTrigger 0 @@ -141542,13 +143908,16 @@ SQLITE_PRIVATE void sqlite3Update( */ chngRowid = chngPk = 0; for(i=0; inExpr; i++){ + u8 hCol = sqlite3StrIHash(pChanges->a[i].zEName); /* If this is an UPDATE with a FROM clause, do not resolve expressions ** here. The call to sqlite3Select() below will do that. */ if( nChangeFrom==0 && sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ goto update_cleanup; } for(j=0; jnCol; j++){ - if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zEName)==0 ){ + if( pTab->aCol[j].hName==hCol + && sqlite3StrICmp(pTab->aCol[j].zCnName, pChanges->a[i].zEName)==0 + ){ if( j==pTab->iPKey ){ chngRowid = 1; pRowidExpr = pChanges->a[i].pExpr; @@ -141562,7 +143931,7 @@ SQLITE_PRIVATE void sqlite3Update( testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); sqlite3ErrorMsg(pParse, "cannot UPDATE generated column \"%s\"", - pTab->aCol[j].zName); + pTab->aCol[j].zCnName); goto update_cleanup; } #endif @@ -141586,7 +143955,7 @@ SQLITE_PRIVATE void sqlite3Update( { int rc; rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, - j<0 ? "ROWID" : pTab->aCol[j].zName, + j<0 ? "ROWID" : pTab->aCol[j].zCnName, db->aDb[iDb].zDbSName); if( rc==SQLITE_DENY ){ goto update_cleanup; @@ -141618,8 +143987,10 @@ SQLITE_PRIVATE void sqlite3Update( for(i=0; inCol; i++){ if( aXRef[i]>=0 ) continue; if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue; - if( sqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt, - aXRef, chngRowid) ){ + if( sqlite3ExprReferencesUpdatedColumn( + sqlite3ColumnExpr(pTab, &pTab->aCol[i]), + aXRef, chngRowid) + ){ aXRef[i] = 99999; bProgress = 1; } @@ -141807,7 +144178,7 @@ SQLITE_PRIVATE void sqlite3Update( if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } - pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags,iIdxCur); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere,0,0,0,flags,iIdxCur); if( pWInfo==0 ) goto update_cleanup; /* A one-pass strategy that might update more than one row may not @@ -142207,9 +144578,7 @@ SQLITE_PRIVATE void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); - sqlite3VdbeSetNumCols(v, 1); - sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); + sqlite3CodeChangeCount(v, regRowCount, "rows updated"); } update_cleanup: @@ -142331,7 +144700,9 @@ static void updateVirtualTable( regRowid = ++pParse->nMem; /* Start scanning the virtual table */ - pWInfo = sqlite3WhereBegin(pParse, pSrc,pWhere,0,0,WHERE_ONEPASS_DESIRED,0); + pWInfo = sqlite3WhereBegin( + pParse, pSrc, pWhere, 0, 0, 0, WHERE_ONEPASS_DESIRED, 0 + ); if( pWInfo==0 ) return; /* Populate the argument registers. */ @@ -142711,7 +145082,7 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); VdbeComment((v, "%s.%s", pIdx->zName, - pTab->aCol[pPk->aiColumn[i]].zName)); + pTab->aCol[pPk->aiColumn[i]].zCnName)); } sqlite3VdbeVerifyAbortable(v, OE_Abort); i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); @@ -142893,8 +145264,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( Btree *pTemp; /* The temporary database we vacuum into */ u32 saved_mDbFlags; /* Saved value of db->mDbFlags */ u64 saved_flags; /* Saved value of db->flags */ - int saved_nChange; /* Saved value of db->nChange */ - int saved_nTotalChange; /* Saved value of db->nTotalChange */ + i64 saved_nChange; /* Saved value of db->nChange */ + i64 saved_nTotalChange; /* Saved value of db->nTotalChange */ u32 saved_openFlags; /* Saved value of db->openFlags */ u8 saved_mTrace; /* Saved trace settings */ Db *pDb = 0; /* Database to detach at end of vacuum */ @@ -142992,7 +145363,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( /* Do not attempt to change the page size for a WAL database */ if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) - ==PAGER_JOURNALMODE_WAL ){ + ==PAGER_JOURNALMODE_WAL + && pOut==0 + ){ db->nextPagesize = 0; } @@ -143341,7 +145714,7 @@ SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ VTable *pVtab; assert( IsVirtual(pTab) ); - for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + for(pVtab=pTab->u.vtab.p; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); return pVtab; } @@ -143354,7 +145727,8 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ assert( db ); assert( pVTab->nRef>0 ); - assert( db->magic==SQLITE_MAGIC_OPEN || db->magic==SQLITE_MAGIC_ZOMBIE ); + assert( db->eOpenState==SQLITE_STATE_OPEN + || db->eOpenState==SQLITE_STATE_ZOMBIE ); pVTab->nRef--; if( pVTab->nRef==0 ){ @@ -143369,21 +145743,24 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ /* ** Table p is a virtual table. This function moves all elements in the -** p->pVTable list to the sqlite3.pDisconnect lists of their associated +** p->u.vtab.p list to the sqlite3.pDisconnect lists of their associated ** database connections to be disconnected at the next opportunity. ** Except, if argument db is not NULL, then the entry associated with -** connection db is left in the p->pVTable list. +** connection db is left in the p->u.vtab.p list. */ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ VTable *pRet = 0; - VTable *pVTable = p->pVTable; - p->pVTable = 0; + VTable *pVTable; + + assert( IsVirtual(p) ); + pVTable = p->u.vtab.p; + p->u.vtab.p = 0; /* Assert that the mutex (if any) associated with the BtShared database ** that contains table p is held by the caller. See header comments ** above function sqlite3VtabUnlockList() for an explanation of why ** this makes it safe to access the sqlite3.pDisconnect list of any - ** database connection that may have an entry in the p->pVTable list. + ** database connection that may have an entry in the p->u.vtab.p list. */ assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); @@ -143393,7 +145770,7 @@ static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ assert( db2 ); if( db2==db ){ pRet = pVTable; - p->pVTable = pRet; + p->u.vtab.p = pRet; pRet->pNext = 0; }else{ pVTable->pNext = db2->pDisconnect; @@ -143421,7 +145798,7 @@ SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ assert( sqlite3BtreeHoldsAllMutexes(db) ); assert( sqlite3_mutex_held(db->mutex) ); - for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ + for(ppVTab=&p->u.vtab.p; *ppVTab; ppVTab=&(*ppVTab)->pNext){ if( (*ppVTab)->db==db ){ VTable *pVTab = *ppVTab; *ppVTab = pVTab->pNext; @@ -143484,37 +145861,41 @@ SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ ** database connection. */ SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ + assert( IsVirtual(p) ); if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); - if( p->azModuleArg ){ + if( p->u.vtab.azArg ){ int i; - for(i=0; inModuleArg; i++){ - if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); + for(i=0; iu.vtab.nArg; i++){ + if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]); } - sqlite3DbFree(db, p->azModuleArg); + sqlite3DbFree(db, p->u.vtab.azArg); } } /* -** Add a new module argument to pTable->azModuleArg[]. +** Add a new module argument to pTable->u.vtab.azArg[]. ** The string is not copied - the pointer is stored. The ** string will be freed automatically when the table is ** deleted. */ static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ - sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg); + sqlite3_int64 nBytes; char **azModuleArg; sqlite3 *db = pParse->db; - if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ + + assert( IsVirtual(pTable) ); + nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg); + if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); } - azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); + azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes); if( azModuleArg==0 ){ sqlite3DbFree(db, zArg); }else{ - int i = pTable->nModuleArg++; + int i = pTable->u.vtab.nArg++; azModuleArg[i] = zArg; azModuleArg[i+1] = 0; - pTable->azModuleArg = azModuleArg; + pTable->u.vtab.azArg = azModuleArg; } } @@ -143537,10 +145918,11 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( pTable = pParse->pNewTable; if( pTable==0 ) return; assert( 0==pTable->pIndex ); + pTable->eTabType = TABTYP_VTAB; db = pParse->db; - assert( pTable->nModuleArg==0 ); + assert( pTable->u.vtab.nArg==0 ); addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(pParse, pTable, 0); addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName)); @@ -143557,11 +145939,11 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( ** sqlite_schema table, has already been made by sqlite3StartTable(). ** The second call, to obtain permission to create the table, is made now. */ - if( pTable->azModuleArg ){ + if( pTable->u.vtab.azArg ){ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); /* The database the table is being created in */ sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, - pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); + pTable->u.vtab.azArg[0], pParse->db->aDb[iDb].zDbSName); } #endif } @@ -143589,9 +145971,10 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3 *db = pParse->db; /* The database connection */ if( pTab==0 ) return; + assert( IsVirtual(pTab) ); addArgumentToVtab(pParse); pParse->sArg.z = 0; - if( pTab->nModuleArg<1 ) return; + if( pTab->u.vtab.nArg<1 ) return; /* If the CREATE VIRTUAL TABLE statement is being entered for the ** first time (in other words if the virtual table is actually being @@ -143624,7 +146007,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3NestedParse(pParse, - "UPDATE %Q." DFLT_SCHEMA_TABLE " " + "UPDATE %Q." LEGACY_SCHEMA_TABLE " " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#%d", db->aDb[iDb].zDbSName, @@ -143644,18 +146027,14 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ iReg = ++pParse->nMem; sqlite3VdbeLoadString(v, iReg, pTab->zName); sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); - } - - /* If we are rereading the sqlite_schema table create the in-memory - ** record of the table. The xConnect() method is not called until - ** the first time the virtual table is used in an SQL statement. This - ** allows a schema that contains virtual tables to be loaded before - ** the required virtual table implementations are registered. */ - else { + }else{ + /* If we are rereading the sqlite_schema table create the in-memory + ** record of the table. */ Table *pOld; Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; - assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); + assert( zName!=0 ); + sqlite3MarkAllShadowTablesOf(db, pTab); pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); if( pOld ){ sqlite3OomFault(db); @@ -143706,13 +146085,16 @@ static int vtabCallConstructor( VtabCtx sCtx; VTable *pVTable; int rc; - const char *const*azArg = (const char *const*)pTab->azModuleArg; - int nArg = pTab->nModuleArg; + const char *const*azArg; + int nArg = pTab->u.vtab.nArg; char *zErr = 0; char *zModuleName; int iDb; VtabCtx *pCtx; + assert( IsVirtual(pTab) ); + azArg = (const char *const*)pTab->u.vtab.azArg; + /* Check that the virtual-table is not already being initialized */ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ if( pCtx->pTab==pTab ){ @@ -143739,7 +146121,7 @@ static int vtabCallConstructor( pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; + pTab->u.vtab.azArg[1] = db->aDb[iDb].zDbSName; /* Invoke the virtual table constructor */ assert( &db->pVtabCtx ); @@ -143778,12 +146160,12 @@ static int vtabCallConstructor( int iCol; u16 oooHidden = 0; /* If everything went according to plan, link the new VTable structure - ** into the linked list headed by pTab->pVTable. Then loop through the + ** into the linked list headed by pTab->u.vtab.p. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ - pVTable->pNext = pTab->pVTable; - pTab->pVTable = pVTable; + pVTable->pNext = pTab->u.vtab.p; + pTab->u.vtab.p = pVTable; for(iCol=0; iColnCol; iCol++){ char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); @@ -143836,16 +146218,17 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ int rc; assert( pTab ); - if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){ + assert( IsVirtual(pTab) ); + if( sqlite3GetVTable(db, pTab) ){ return SQLITE_OK; } /* Locate the required virtual table module */ - zMod = pTab->azModuleArg[0]; + zMod = pTab->u.vtab.azArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); if( !pMod ){ - const char *zModule = pTab->azModuleArg[0]; + const char *zModule = pTab->u.vtab.azArg[0]; sqlite3ErrorMsg(pParse, "no such module: %s", zModule); rc = SQLITE_ERROR; }else{ @@ -143908,10 +146291,10 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, const char *zMod; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - assert( pTab && IsVirtual(pTab) && !pTab->pVTable ); + assert( pTab && IsVirtual(pTab) && !pTab->u.vtab.p ); /* Locate the required virtual table module */ - zMod = pTab->azModuleArg[0]; + zMod = pTab->u.vtab.azArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); /* If the module has been registered and includes a Create method, @@ -143946,8 +146329,8 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ VtabCtx *pCtx; int rc = SQLITE_OK; Table *pTab; - char *zErr = 0; Parse sParse; + int initBusy; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ @@ -143964,20 +146347,27 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ pTab = pCtx->pTab; assert( IsVirtual(pTab) ); - memset(&sParse, 0, sizeof(sParse)); + sqlite3ParseObjectInit(&sParse, db); sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; - sParse.db = db; + sParse.disableTriggers = 1; + /* We should never be able to reach this point while loading the + ** schema. Nevertheless, defend against that (turn off db->init.busy) + ** in case a bug arises. */ + assert( db->init.busy==0 ); + initBusy = db->init.busy; + db->init.busy = 0; sParse.nQueryLoop = 1; - if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) - && sParse.pNewTable - && !db->mallocFailed - && !sParse.pNewTable->pSelect - && !IsVirtual(sParse.pNewTable) + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) + && ALWAYS(sParse.pNewTable!=0) + && ALWAYS(!db->mallocFailed) + && IsOrdinaryTable(sParse.pNewTable) ){ + assert( sParse.zErrMsg==0 ); if( !pTab->aCol ){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; + sqlite3ExprListDelete(db, pNew->u.tab.pDfltList); pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; @@ -144002,8 +146392,9 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ } pCtx->bDeclared = 1; }else{ - sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); - sqlite3DbFree(db, zErr); + sqlite3ErrorWithMsg(db, SQLITE_ERROR, + (sParse.zErrMsg ? "%s" : 0), sParse.zErrMsg); + sqlite3DbFree(db, sParse.zErrMsg); rc = SQLITE_ERROR; } sParse.eParseMode = PARSE_MODE_NORMAL; @@ -144012,7 +146403,8 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3VdbeFinalize(sParse.pVdbe); } sqlite3DeleteTable(db, sParse.pNewTable); - sqlite3ParserReset(&sParse); + sqlite3ParseObjectReset(&sParse); + db->init.busy = initBusy; assert( (rc&0xff)==rc ); rc = sqlite3ApiExit(db, rc); @@ -144032,10 +146424,13 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab Table *pTab; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); - if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ + if( ALWAYS(pTab!=0) + && ALWAYS(IsVirtual(pTab)) + && ALWAYS(pTab->u.vtab.p!=0) + ){ VTable *p; int (*xDestroy)(sqlite3_vtab *); - for(p=pTab->pVTable; p; p=p->pNext){ + for(p=pTab->u.vtab.p; p; p=p->pNext){ assert( p->pVtab ); if( p->pVtab->nRef>0 ){ return SQLITE_LOCKED; @@ -144049,9 +146444,9 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab rc = xDestroy(p->pVtab); /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ - assert( pTab->pVTable==p && p->pNext==0 ); + assert( pTab->u.vtab.p==p && p->pNext==0 ); p->pVtab = 0; - pTab->pVTable = 0; + pTab->u.vtab.p = 0; sqlite3VtabUnlock(p); } sqlite3DeleteTable(db, pTab); @@ -144265,6 +146660,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; + assert( ExprUseYTab(pExpr) ); pTab = pExpr->y.pTab; if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; @@ -144339,8 +146735,9 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ /* ** Check to see if virtual table module pMod can be have an eponymous ** virtual table instance. If it can, create one if one does not already -** exist. Return non-zero if the eponymous virtual table instance exists -** when this routine returns, and return zero if it does not exist. +** exist. Return non-zero if either the eponymous virtual table instance +** exists when this routine returns or if an attempt to create it failed +** and an error message was left in pParse. ** ** An eponymous virtual table instance is one that is named after its ** module, and more importantly, does not require a CREATE VIRTUAL TABLE @@ -144367,8 +146764,9 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ } pMod->pEpoTab = pTab; pTab->nTabRef = 1; + pTab->eTabType = TABTYP_VTAB; pTab->pSchema = db->aDb[0].pSchema; - assert( pTab->nModuleArg==0 ); + assert( pTab->u.vtab.nArg==0 ); pTab->iPKey = -1; pTab->tabFlags |= TF_Eponymous; addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); @@ -144379,7 +146777,6 @@ SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ sqlite3ErrorMsg(pParse, "%s", zErr); sqlite3DbFree(db, zErr); sqlite3VtabEponymousTableClear(db, pMod); - return 0; } return 1; } @@ -144558,6 +146955,7 @@ struct WhereLevel { u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif + int regFilter; /* Bloom filter */ u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ int p1, p2; /* Operands of the opcode used to end the loop */ @@ -144572,7 +146970,7 @@ struct WhereLevel { u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ - Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */ + Index *pCoveringIdx; /* Possible covering index for WHERE_MULTI_OR */ } u; struct WhereLoop *pWLoop; /* The selected WhereLoop object */ Bitmask notReady; /* FROM entries not usable at this level */ @@ -144616,10 +147014,12 @@ struct WhereLoop { } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ - u8 needFree; /* True if sqlite3_free(idxStr) is needed */ + u32 needFree : 1; /* True if sqlite3_free(idxStr) is needed */ + u32 bOmitOffset : 1; /* True to let virtual table handle offset */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ + u32 mHandleIn; /* Terms to handle as IN(...) instead of == */ } vtab; } u; u32 wsFlags; /* WHERE_* flags describing the plan */ @@ -144763,7 +147163,7 @@ struct WhereTerm { #define TERM_COPIED 0x0008 /* Has a child */ #define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ -#define TERM_OR_OK 0x0040 /* Used during OR-clause processing */ +#define TERM_OK 0x0040 /* Used during OR-clause processing */ #define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ #define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ #define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ @@ -144776,6 +147176,7 @@ struct WhereTerm { #else # define TERM_HIGHTRUTH 0 /* Only used with STAT4 */ #endif +#define TERM_SLICE 0x8000 /* One slice of a row-value/vector comparison */ /* ** An instance of the WhereScan object is used as an iterator for locating @@ -144786,11 +147187,11 @@ struct WhereScan { WhereClause *pWC; /* WhereClause currently being scanned */ const char *zCollName; /* Required collating sequence, if not NULL */ Expr *pIdxExpr; /* Search for this index expression */ - char idxaff; /* Must match this affinity, if zCollName!=NULL */ - unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */ - unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */ - u32 opMask; /* Acceptable operators */ int k; /* Resume scanning at this->pWC->a[this->k] */ + u32 opMask; /* Acceptable operators */ + char idxaff; /* Must match this affinity, if zCollName!=NULL */ + unsigned char iEquiv; /* Current slot in aiCur[] and aiColumn[] */ + unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */ int aiCur[11]; /* Cursors in the equivalence class */ i16 aiColumn[11]; /* Corresponding column number in the eq-class */ }; @@ -144814,6 +147215,7 @@ struct WhereClause { u8 hasOr; /* True if any a[].eOperator is WO_OR */ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ + int nBase; /* Number of terms through the last non-Virtual */ WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ #if defined(SQLITE_SMALL_STACK) WhereTerm aStatic[1]; /* Initial static space for a[] */ @@ -144871,11 +147273,6 @@ struct WhereMaskSet { int ix[BMS]; /* Cursor assigned to each bit */ }; -/* -** Initialize a WhereMaskSet object -*/ -#define initMaskSet(P) (P)->n=0 - /* ** This object is a convenience wrapper holding all information needed ** to construct WhereLoop objects for a particular query. @@ -144883,7 +147280,6 @@ struct WhereMaskSet { struct WhereLoopBuilder { WhereInfo *pWInfo; /* Information about this WHERE */ WhereClause *pWC; /* WHERE clause terms */ - ExprList *pOrderBy; /* ORDER BY clause */ WhereLoop *pNew; /* Template WhereLoop */ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ #ifdef SQLITE_ENABLE_STAT4 @@ -144951,6 +147347,9 @@ struct WhereInfo { ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ Expr *pWhere; /* The complete WHERE clause */ +#ifndef SQLITE_OMIT_VIRTUALTABLE + Select *pLimit; /* Used to access LIMIT expr/registers for vtabs */ +#endif int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ @@ -145004,8 +147403,14 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ); +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +); #else # define sqlite3WhereExplainOneScan(u,v,w,x) 0 +# define sqlite3WhereExplainBloomFilter(u,v,w) 0 #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS SQLITE_PRIVATE void sqlite3WhereAddScanStatus( @@ -145030,6 +147435,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause*, Select*); SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); @@ -145098,6 +147504,9 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */ #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */ +#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ +#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ +#define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ #endif /* !defined(SQLITE_WHEREINT_H) */ @@ -145113,7 +147522,7 @@ static const char *explainIndexColumnName(Index *pIdx, int i){ i = pIdx->aiColumn[i]; if( i==XN_EXPR ) return ""; if( i==XN_ROWID ) return "rowid"; - return pIdx->pTable->aCol[i].zName; + return pIdx->pTable->aCol[i].zCnName; } /* @@ -145260,19 +147669,27 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( explainIndexRange(&str, pLoop); } }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ - const char *zRangeOp; + char cRangeOp; +#if 0 /* Better output, but breaks many tests */ + const Table *pTab = pItem->pTab; + const char *zRowid = pTab->iPKey>=0 ? pTab->aCol[pTab->iPKey].zCnName: + "rowid"; +#else + const char *zRowid = "rowid"; +#endif + sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (%s", zRowid); if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){ - zRangeOp = "="; + cRangeOp = '='; }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){ - zRangeOp = ">? AND rowid<"; + sqlite3_str_appendf(&str, ">? AND %s", zRowid); + cRangeOp = '<'; }else if( flags&WHERE_BTM_LIMIT ){ - zRangeOp = ">"; + cRangeOp = '>'; }else{ assert( flags&WHERE_TOP_LIMIT); - zRangeOp = "<"; + cRangeOp = '<'; } - sqlite3_str_appendf(&str, - " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); + sqlite3_str_appendf(&str, "%c?)", cRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ @@ -145295,6 +147712,56 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( } return ret; } + +/* +** Add a single OP_Explain opcode that describes a Bloom filter. +** +** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or +** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not +** required and this routine is a no-op. +** +** If an OP_Explain opcode is added to the VM, its address is returned. +** Otherwise, if no OP_Explain is coded, zero is returned. +*/ +SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter( + const Parse *pParse, /* Parse context */ + const WhereInfo *pWInfo, /* WHERE clause */ + const WhereLevel *pLevel /* Bloom filter on this level */ +){ + int ret = 0; + SrcItem *pItem = &pWInfo->pTabList->a[pLevel->iFrom]; + Vdbe *v = pParse->pVdbe; /* VM being constructed */ + sqlite3 *db = pParse->db; /* Database handle */ + char *zMsg; /* Text to add to EQP output */ + int i; /* Loop counter */ + WhereLoop *pLoop; /* The where loop */ + StrAccum str; /* EQP output string */ + char zBuf[100]; /* Initial space for EQP output string */ + + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + str.printfFlags = SQLITE_PRINTF_INTERNAL; + sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem); + pLoop = pLevel->pWLoop; + if( pLoop->wsFlags & WHERE_IPK ){ + const Table *pTab = pItem->pTab; + if( pTab->iPKey>=0 ){ + sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName); + }else{ + sqlite3_str_appendf(&str, "rowid=?"); + } + }else{ + for(i=pLoop->nSkip; iu.btree.nEq; i++){ + const char *z = explainIndexColumnName(pLoop->u.btree.pIndex, i); + if( i>pLoop->nSkip ) sqlite3_str_append(&str, " AND ", 5); + sqlite3_str_appendf(&str, "%s=?", z); + } + } + sqlite3_str_append(&str, ")", 1); + zMsg = sqlite3StrAccumFinish(&str); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), + pParse->addrExplain, 0, zMsg,P4_DYNAMIC); + return ret; +} #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -145500,16 +147967,23 @@ static Expr *removeUnindexableInClauseTerms( Expr *pNew; pNew = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed==0 ){ - ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */ - ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */ + ExprList *pOrigRhs; /* Original unmodified RHS */ + ExprList *pOrigLhs; /* Original unmodified LHS */ ExprList *pRhs = 0; /* New RHS after modifications */ ExprList *pLhs = 0; /* New LHS after mods */ int i; /* Loop counter */ Select *pSelect; /* Pointer to the SELECT on the RHS */ + assert( ExprUseXSelect(pNew) ); + pOrigRhs = pNew->x.pSelect->pEList; + assert( pNew->pLeft!=0 ); + assert( ExprUseXList(pNew->pLeft) ); + pOrigLhs = pNew->pLeft->x.pList; for(i=iEq; inLTerm; i++){ if( pLoop->aLTerm[i]->pExpr==pX ){ - int iField = pLoop->aLTerm[i]->u.x.iField - 1; + int iField; + assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 ); + iField = pLoop->aLTerm[i]->u.x.iField - 1; if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; @@ -145624,7 +148098,7 @@ static int codeEqualityTerm( } iTab = 0; - if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ + if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){ eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ sqlite3 *db = pParse->db; @@ -145646,8 +148120,8 @@ static int codeEqualityTerm( sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverageIf(v, bRev); VdbeCoverageIf(v, !bRev); - assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); @@ -145811,6 +148285,7 @@ static int codeAllEqualityTerms( VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); j = sqlite3VdbeAddOp0(v, OP_Goto); + assert( pLevel->addrSkip==0 ); pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), iIdxCur, 0, regBase, nSkip); VdbeCoverageIf(v, bRev==0); @@ -145843,6 +148318,9 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); } } + } + for(j=nSkip; jaLTerm[j]; if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ /* No affinity ever needs to be (or should be) applied to a value @@ -145857,7 +148335,8 @@ static int codeAllEqualityTerms( sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); VdbeCoverage(v); } - if( pParse->db->mallocFailed==0 && pParse->nErr==0 ){ + if( pParse->nErr==0 ){ + assert( pParse->db->mallocFailed==0 ); if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ zAff[j] = SQLITE_AFF_BLOB; } @@ -146047,7 +148526,7 @@ static void codeCursorHint( sWalker.pParse = pParse; sWalker.u.pCCurHint = &sHint; pWC = &pWInfo->sWC; - for(i=0; inTerm; i++){ + for(i=0; inBase; i++){ pTerm = &pWC->a[i]; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->prereqAll & pLevel->notReady ) continue; @@ -146077,7 +148556,7 @@ static void codeCursorHint( if( pTabItem->fg.jointype & JT_LEFT ){ Expr *pExpr = pTerm->pExpr; if( !ExprHasProperty(pExpr, EP_FromJoin) - || pExpr->iRightJoinTable!=pTabItem->iCursor + || pExpr->w.iRightJoinTable!=pTabItem->iCursor ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintIsOrFunction; @@ -146189,7 +148668,7 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); if( p && sqlite3ExprIsVector(p) ){ #ifndef SQLITE_OMIT_SUBQUERY - if( (p->flags & EP_xIsSelect) ){ + if( ExprUseXSelect(p) ){ Vdbe *v = pParse->pVdbe; int iSelect; assert( p->op==TK_SELECT ); @@ -146199,7 +148678,9 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ #endif { int i; - ExprList *pList = p->x.pList; + const ExprList *pList; + assert( ExprUseXList(p) ); + pList = p->x.pList; assert( nReg<=pList->nExpr ); for(i=0; ia[i].pExpr, iReg+i); @@ -146247,15 +148728,16 @@ static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr = sqlite3ExprSkipCollate(pExpr); preserveExpr(pX, pExpr); pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; - pExpr->y.pTab = 0; testcase( ExprHasProperty(pExpr, EP_Skip) ); testcase( ExprHasProperty(pExpr, EP_Unlikely) ); - ExprClearProperty(pExpr, EP_Skip|EP_Unlikely); + ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn); + pExpr->y.pTab = 0; return WRC_Prune; }else{ return WRC_Continue; @@ -146270,7 +148752,7 @@ static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){ if( pExpr->op==TK_COLUMN ){ IdxExprTrans *pX = p->u.pIdxTrans; if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ - assert( pExpr->y.pTab!=0 ); + assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 ); preserveExpr(pX, pExpr); pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); pExpr->iTable = pX->iIdxCur; @@ -146318,15 +148800,16 @@ static void whereIndexExprTrans( for(iIdxCol=0; iIdxColnColumn; iIdxCol++){ i16 iRef = pIdx->aiColumn[iIdxCol]; if( iRef==XN_EXPR ){ - assert( aColExpr->a[iIdxCol].pExpr!=0 ); + assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 ); x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; w.xExprCallback = whereIndexExprTransNode; #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( iRef>=0 && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 - && (pTab->aCol[iRef].zColl==0 - || sqlite3StrICmp(pTab->aCol[iRef].zColl, sqlite3StrBINARY)==0) + && ((pTab->aCol[iRef].colFlags & COLFLAG_HASCOLL)==0 + || sqlite3StrICmp(sqlite3ColumnColl(&pTab->aCol[iRef]), + sqlite3StrBINARY)==0) ){ /* Check to see if there are direct references to generated columns ** that are contained in the index. Pulling the generated column @@ -146375,6 +148858,68 @@ static void whereApplyPartialIndexConstraints( } } +/* +** This routine is called right after An OP_Filter has been generated and +** before the corresponding index search has been performed. This routine +** checks to see if there are additional Bloom filters in inner loops that +** can be checked prior to doing the index lookup. If there are available +** inner-loop Bloom filters, then evaluate those filters now, before the +** index lookup. The idea is that a Bloom filter check is way faster than +** an index lookup, and the Bloom filter might return false, meaning that +** the index lookup can be skipped. +** +** We know that an inner loop uses a Bloom filter because it has the +** WhereLevel.regFilter set. If an inner-loop Bloom filter is checked, +** then clear the WhereLevel.regFilter value to prevent the Bloom filter +** from being checked a second time when the inner loop is evaluated. +*/ +static SQLITE_NOINLINE void filterPullDown( + Parse *pParse, /* Parsing context */ + WhereInfo *pWInfo, /* Complete information about the WHERE clause */ + int iLevel, /* Which level of pWInfo->a[] should be coded */ + int addrNxt, /* Jump here to bypass inner loops */ + Bitmask notReady /* Loops that are not ready */ +){ + while( ++iLevel < pWInfo->nLevel ){ + WhereLevel *pLevel = &pWInfo->a[iLevel]; + WhereLoop *pLoop = pLevel->pWLoop; + if( pLevel->regFilter==0 ) continue; + if( pLevel->pWLoop->nSkip ) continue; + /* ,--- Because sqlite3ConstructBloomFilter() has will not have set + ** vvvvv--' pLevel->regFilter if this were true. */ + if( NEVER(pLoop->prereq & notReady) ) continue; + assert( pLevel->addrBrk==0 ); + pLevel->addrBrk = addrNxt; + if( pLoop->wsFlags & WHERE_IPK ){ + WhereTerm *pTerm = pLoop->aLTerm[0]; + int regRowid; + assert( pTerm!=0 ); + assert( pTerm->pExpr!=0 ); + testcase( pTerm->wtFlags & TERM_VIRTUAL ); + regRowid = sqlite3GetTempReg(pParse); + regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, regRowid, 1); + VdbeCoverage(pParse->pVdbe); + }else{ + u16 nEq = pLoop->u.btree.nEq; + int r1; + char *zStartAff; + + assert( pLoop->wsFlags & WHERE_INDEXED ); + assert( (pLoop->wsFlags & WHERE_COLUMN_IN)==0 ); + r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff); + codeApplyAffinity(pParse, r1, nEq, zStartAff); + sqlite3DbFree(pParse->db, zStartAff); + sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter, + addrNxt, r1, nEq); + VdbeCoverage(pParse->pVdbe); + } + pLevel->regFilter = 0; + pLevel->addrBrk = 0; + } +} + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -146477,7 +149022,6 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( int iReg; /* P3 Value for OP_VFilter */ int addrNotFound; int nConstraint = pLoop->nLTerm; - int iIn; /* Counter for IN constraints */ iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; @@ -146486,11 +149030,27 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pTerm = pLoop->aLTerm[j]; if( NEVER(pTerm==0) ) continue; if( pTerm->eOperator & WO_IN ){ - codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); - addrNotFound = pLevel->addrNxt; + if( SMASKBIT32(j) & pLoop->u.vtab.mHandleIn ){ + int iTab = pParse->nTab++; + int iCache = ++pParse->nMem; + sqlite3CodeRhsOfIN(pParse, pTerm->pExpr, iTab); + sqlite3VdbeAddOp3(v, OP_VInitIn, iTab, iTarget, iCache); + }else{ + codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, iTarget); + addrNotFound = pLevel->addrNxt; + } }else{ Expr *pRight = pTerm->pExpr->pRight; codeExprOrVector(pParse, pRight, iTarget, 1); + if( pTerm->eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET + && pLoop->u.vtab.bOmitOffset + ){ + assert( pTerm->eOperator==WO_AUX ); + assert( pWInfo->pLimit!=0 ); + assert( pWInfo->pLimit->iOffset>0 ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWInfo->pLimit->iOffset); + VdbeComment((v,"Zero OFFSET counter")); + } } } sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); @@ -146506,40 +149066,55 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLevel->p1 = iCur; pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; pLevel->p2 = sqlite3VdbeCurrentAddr(v); - iIn = pLevel->u.in.nIn; - for(j=nConstraint-1; j>=0; j--){ + assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); + + for(j=0; jaLTerm[j]; - if( (pTerm->eOperator & WO_IN)!=0 ) iIn--; if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ disableTerm(pLevel, pTerm); - }else if( (pTerm->eOperator & WO_IN)!=0 - && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 + continue; + } + if( (pTerm->eOperator & WO_IN)!=0 + && (SMASKBIT32(j) & pLoop->u.vtab.mHandleIn)==0 + && !db->mallocFailed ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ VdbeOp *pOp; /* Opcode to access the value of the IN constraint */ + int iIn; /* IN loop corresponding to the j-th constraint */ /* Reload the constraint value into reg[iReg+j+2]. The same value ** was loaded into the same register prior to the OP_VFilter, but ** the xFilter implementation might have changed the datatype or - ** encoding of the value in the register, so it *must* be reloaded. */ - assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed ); - if( !db->mallocFailed ){ - assert( iIn>=0 && iInu.in.nIn ); + ** encoding of the value in the register, so it *must* be reloaded. + */ + for(iIn=0; ALWAYS(iInu.in.nIn); iIn++){ pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); - assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid ); - assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 ); - assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 ); - testcase( pOp->opcode==OP_Rowid ); - sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + if( (pOp->opcode==OP_Column && pOp->p3==iReg+j+2) + || (pOp->opcode==OP_Rowid && pOp->p2==iReg+j+2) + ){ + testcase( pOp->opcode==OP_Rowid ); + sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + break; + } } /* Generate code that will continue to the next row if - ** the IN constraint is not satisfied */ + ** the IN constraint is not satisfied + */ pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); - assert( pCompare!=0 || db->mallocFailed ); - if( pCompare ){ - pCompare->pLeft = pTerm->pExpr->pLeft; + if( !db->mallocFailed ){ + int iFld = pTerm->u.x.iField; + Expr *pLeft = pTerm->pExpr->pLeft; + assert( pLeft!=0 ); + if( iFld>0 ){ + assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); + assert( iFld<=pLeft->x.pList->nExpr ); + pCompare->pLeft = pLeft->x.pList->a[iFld-1].pExpr; + }else{ + pCompare->pLeft = pLeft; + } pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); if( pRight ){ pRight->iTable = iReg+j+2; @@ -146548,11 +149123,11 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ); } pCompare->pLeft = 0; - sqlite3ExprDelete(db, pCompare); } + sqlite3ExprDelete(db, pCompare); } } - assert( iIn==0 || db->mallocFailed ); + /* These registers need to be preserved in case there is an IN operator ** loop. So we could deallocate the registers here (and potentially ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems @@ -146580,12 +149155,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); addrNxt = pLevel->addrNxt; + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + iRowidReg, 1); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); pLevel->op = OP_Noop; - if( (pTerm->prereqAll & pLevel->notReady)==0 ){ - pTerm->wtFlags |= TERM_CODED; - } }else if( (pLoop->wsFlags & WHERE_IPK)!=0 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0 ){ @@ -146908,6 +149486,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); VdbeComment((v, "NULL-scan pass ctr")); } + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt, + regBase, nEq); + VdbeCoverage(v); + filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady); + } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); @@ -146956,8 +149540,19 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** range (if any). */ nConstraint = nEq; + assert( pLevel->p2==0 ); if( pRangeEnd ){ Expr *pRight = pRangeEnd->pExpr->pRight; + if( addrSeekScan ){ + /* For a seek-scan that has a range on the lowest term of the index, + ** we have to make the top of the loop be code that sets the end + ** condition of the range. Otherwise, the OP_SeekScan might jump + ** over that initialization, leaving the range-end value set to the + ** range-start value, resulting in a wrong answer. + ** See ticket 5981a8c041a3c2f3 (2021-11-02). + */ + pLevel->p2 = sqlite3VdbeCurrentAddr(v); + } codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 @@ -146991,7 +149586,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( sqlite3DbFree(db, zEndAff); /* Top of the loop body */ - pLevel->p2 = sqlite3VdbeCurrentAddr(v); + if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ @@ -147224,7 +149819,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y - ** Then for every term xN, evaluate as the subexpression: xN AND z + ** Then for every term xN, evaluate as the subexpression: xN AND y ** That way, terms in y that are factored into the disjunction will ** be picked up by the recursive calls to sqlite3WhereBegin() below. ** @@ -147236,6 +149831,20 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** This optimization also only applies if the (x1 OR x2 OR ...) term ** is not contained in the ON clause of a LEFT JOIN. ** See ticket http://www.sqlite.org/src/info/f2369304e4 + ** + ** 2022-02-04: Do not push down slices of a row-value comparison. + ** In other words, "w" or "y" may not be a slice of a vector. Otherwise, + ** the initialization of the right-hand operand of the vector comparison + ** might not occur, or might occur only in an OR branch that is not + ** taken. dbsqlfuzz 80a9fade844b4fb43564efc972bcb2c68270f5d1. + ** + ** 2022-03-03: Do not push down expressions that involve subqueries. + ** The subquery might get coded as a subroutine. Any table-references + ** in the subquery might be resolved to index-references for the index on + ** the OR branch in which the subroutine is coded. But if the subroutine + ** is invoked from a different OR branch that uses a different index, such + ** index-references will not work. tag-20220303a + ** https://sqlite.org/forum/forumpost/36937b197273d403 */ if( pWC->nTerm>1 ){ int iTerm; @@ -147244,9 +149853,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( if( &pWC->a[iTerm] == pTerm ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL ); testcase( pWC->a[iTerm].wtFlags & TERM_CODED ); - if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; + testcase( pWC->a[iTerm].wtFlags & TERM_SLICE ); + if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED|TERM_SLICE))!=0 ){ + continue; + } if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; - testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); + if( ExprHasProperty(pExpr, EP_Subquery) ) continue; /* tag-20220303a */ pExpr = sqlite3ExprDup(db, pExpr, 0); pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } @@ -147287,9 +149899,9 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( /* Loop through table entries that match term pOrTerm. */ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); - pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, 0, WHERE_OR_SUBCLAUSE, iCovCur); - assert( pSubWInfo || pParse->nErr || db->mallocFailed ); + assert( pSubWInfo || pParse->nErr ); if( pSubWInfo ){ WhereLoop *pSubLoop; int addrExplain = sqlite3WhereExplainOneScan( @@ -147398,7 +150010,10 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( } } ExplainQueryPlanPop(pParse); - pLevel->u.pCovidx = pCov; + assert( pLevel->pWLoop==pLoop ); + assert( (pLoop->wsFlags & WHERE_MULTI_OR)!=0 ); + assert( (pLoop->wsFlags & WHERE_IN_ABLE)==0 ); + pLevel->u.pCoveringIdx = pCov; if( pCov ) pLevel->iIdxCur = iCovCur; if( pAndExpr ){ pAndExpr->pLeft = 0; @@ -147525,7 +150140,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( ** then we cannot use the "t1.a=t2.b" constraint, but we can code ** the implied "t1.a=123" constraint. */ - for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){ + for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){ Expr *pE, sEAlt; WhereTerm *pAlt; if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -147542,12 +150157,13 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( #endif assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady, WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; if( (pAlt->eOperator & WO_IN) - && (pAlt->pExpr->flags & EP_xIsSelect) + && ExprUseXSelect(pAlt->pExpr) && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) ){ continue; @@ -147569,7 +150185,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); - for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ + for(pTerm=pWC->a, j=0; jnBase; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); testcase( pTerm->wtFlags & TERM_CODED ); if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; @@ -147680,6 +150296,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); } pTerm = &pWC->a[idx = pWC->nTerm++]; + if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm; if( p && ExprHasProperty(p, EP_Unlikely) ){ pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; }else{ @@ -147796,6 +150413,7 @@ static int isLikeOrGlob( #ifdef SQLITE_EBCDIC if( *pnoCase ) return 0; #endif + assert( ExprUseXList(pExpr) ); pList = pExpr->x.pList; pLeft = pList->a[1].pExpr; @@ -147811,7 +150429,8 @@ static int isLikeOrGlob( sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ - z = (u8*)pRight->u.zToken; + assert( !ExprHasProperty(pRight, EP_IntValue) ); + z = (u8*)pRight->u.zToken; } if( z ){ @@ -147840,7 +150459,9 @@ static int isLikeOrGlob( pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); if( pPrefix ){ int iFrom, iTo; - char *zNew = pPrefix->u.zToken; + char *zNew; + assert( !ExprHasProperty(pPrefix, EP_IntValue) ); + zNew = pPrefix->u.zToken; zNew[cnt] = 0; for(iFrom=iTo=0; iFromop!=TK_COLUMN || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT - || IsVirtual(pLeft->y.pTab) /* Value might be numeric */ + || (ALWAYS( ExprUseYTab(pLeft) ) + && pLeft->y.pTab + && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ ){ int isNum; double rDummy; @@ -147892,6 +150515,7 @@ static int isLikeOrGlob( if( op==TK_VARIABLE ){ Vdbe *v = pParse->pVdbe; sqlite3VdbeSetVarmask(v, pRight->iColumn); + assert( !ExprHasProperty(pRight, EP_IntValue) ); if( *pisComplete && pRight->u.zToken[1] ){ /* If the rhs of the LIKE expression is a variable, and the current ** value of the variable means there is no need to invoke the LIKE @@ -147965,6 +150589,7 @@ static int isAuxiliaryVtabOperator( Expr *pCol; /* Column reference */ int i; + assert( ExprUseXList(pExpr) ); pList = pExpr->x.pList; if( pList==0 || pList->nExpr!=2 ){ return 0; @@ -147978,9 +150603,11 @@ static int isAuxiliaryVtabOperator( ** MATCH(expression,vtab_column) */ pCol = pList->a[1].pExpr; + assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); if( ExprIsVtab(pCol) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; *ppRight = pList->a[0].pExpr; @@ -148001,6 +150628,7 @@ static int isAuxiliaryVtabOperator( ** with function names in an arbitrary case. */ pCol = pList->a[0].pExpr; + assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) ); testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); if( ExprIsVtab(pCol) ){ sqlite3_vtab *pVtab; @@ -148010,6 +150638,7 @@ static int isAuxiliaryVtabOperator( pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); + assert( !ExprHasProperty(pExpr, EP_IntValue) ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction!=0 ){ i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); @@ -148025,10 +150654,12 @@ static int isAuxiliaryVtabOperator( int res = 0; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; + assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) ); testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); if( ExprIsVtab(pLeft) ){ res++; } + assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) ); testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); if( pRight && ExprIsVtab(pRight) ){ res++; @@ -148052,7 +150683,7 @@ static int isAuxiliaryVtabOperator( static void transferJoinMarkings(Expr *pDerived, Expr *pBase){ if( pDerived ){ pDerived->flags |= pBase->flags & EP_FromJoin; - pDerived->iRightJoinTable = pBase->iRightJoinTable; + pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable; } } @@ -148281,6 +150912,7 @@ static void exprAnalyzeOrTerm( pOrTerm->u.pAndInfo = pAndInfo; pOrTerm->wtFlags |= TERM_ANDINFO; pOrTerm->eOperator = WO_AND; + pOrTerm->leftCursor = -1; pAndWC = &pAndInfo->wc; memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic)); sqlite3WhereClauseInit(pAndWC, pWC->pWInfo); @@ -148323,11 +150955,10 @@ static void exprAnalyzeOrTerm( ** empty. */ pOrInfo->indexable = indexable; + pTerm->eOperator = WO_OR; + pTerm->leftCursor = -1; if( indexable ){ - pTerm->eOperator = WO_OR; pWC->hasOr = 1; - }else{ - pTerm->eOperator = WO_OR; } /* For a two-way OR, attempt to implementation case 2. @@ -148382,7 +151013,7 @@ static void exprAnalyzeOrTerm( pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); - pOrTerm->wtFlags &= ~TERM_OR_OK; + pOrTerm->wtFlags &= ~TERM_OK; if( pOrTerm->leftCursor==iCursor ){ /* This is the 2-bit case and we are on the second iteration and ** current term is from the first iteration. So skip this term. */ @@ -148400,6 +151031,7 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); iColumn = pOrTerm->u.x.leftColumn; iCursor = pOrTerm->leftCursor; pLeft = pOrTerm->pExpr->pLeft; @@ -148420,8 +151052,9 @@ static void exprAnalyzeOrTerm( okToChngToIN = 1; for(; i>=0 && okToChngToIN; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); if( pOrTerm->leftCursor!=iCursor ){ - pOrTerm->wtFlags &= ~TERM_OR_OK; + pOrTerm->wtFlags &= ~TERM_OK; }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ @@ -148437,7 +151070,7 @@ static void exprAnalyzeOrTerm( if( affRight!=0 && affRight!=affLeft ){ okToChngToIN = 0; }else{ - pOrTerm->wtFlags |= TERM_OR_OK; + pOrTerm->wtFlags |= TERM_OK; } } } @@ -148454,8 +151087,9 @@ static void exprAnalyzeOrTerm( Expr *pNew; /* The complete IN operator */ for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){ - if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue; + if( (pOrTerm->wtFlags & TERM_OK)==0 ) continue; assert( pOrTerm->eOperator & WO_EQ ); + assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); assert( pOrTerm->leftCursor==iCursor ); assert( pOrTerm->u.x.leftColumn==iColumn ); pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); @@ -148468,7 +151102,7 @@ static void exprAnalyzeOrTerm( if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); - assert( !ExprHasProperty(pNew, EP_xIsSelect) ); + assert( ExprUseXList(pNew) ); pNew->x.pList = pList; idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -148596,6 +151230,7 @@ static int exprMightBeIndexed( assert( TK_ISop==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){ + assert( ExprUseXList(pExpr) ); pExpr = pExpr->x.pList->a[0].pExpr; } @@ -148653,30 +151288,47 @@ static void exprAnalyze( if( db->mallocFailed ){ return; } + assert( pWC->nTerm > idxTerm ); pTerm = &pWC->a[idxTerm]; pMaskSet = &pWInfo->sMaskSet; pExpr = pTerm->pExpr; + assert( pExpr!=0 ); /* Because malloc() has not failed */ assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); + pMaskSet->bVarSelect = 0; prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; if( op==TK_IN ){ assert( pExpr->pRight==0 ); if( sqlite3ExprCheckIN(pParse, pExpr) ) return; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); }else{ pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); } - }else if( op==TK_ISNULL ){ - pTerm->prereqRight = 0; + prereqAll = prereqLeft | pTerm->prereqRight; }else{ pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); + if( pExpr->pLeft==0 + || ExprHasProperty(pExpr, EP_xIsSelect|EP_IfNullRow) + || pExpr->x.pList!=0 + ){ + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); + }else{ + prereqAll = prereqLeft | pTerm->prereqRight; + } } - pMaskSet->bVarSelect = 0; - prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; + +#ifdef SQLITE_DEBUG + if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){ + printf("\n*** Incorrect prereqAll computed for:\n"); + sqlite3TreeViewExpr(0,pExpr,0); + abort(); + } +#endif + if( ExprHasProperty(pExpr, EP_FromJoin) ){ - Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable); prereqAll |= x; extraRight = x-1; /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ @@ -148698,11 +151350,13 @@ static void exprAnalyze( if( pTerm->u.x.iField>0 ){ assert( op==TK_IN ); assert( pLeft->op==TK_VECTOR ); + assert( ExprUseXList(pLeft) ); pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr; } if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){ pTerm->leftCursor = aiCurCol[0]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); pTerm->u.x.leftColumn = aiCurCol[1]; pTerm->eOperator = operatorMask(op) & opMask; } @@ -148740,12 +151394,18 @@ static void exprAnalyze( } pNew->wtFlags |= exprCommute(pParse, pDup); pNew->leftCursor = aiCurCol[0]; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); pNew->u.x.leftColumn = aiCurCol[1]; testcase( (prereqLeft | extraRight) != prereqLeft ); pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; - }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ + }else + if( op==TK_ISNULL + && !ExprHasProperty(pExpr,EP_FromJoin) + && 0==sqlite3ExprCanBeNull(pLeft) + ){ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); pExpr->op = TK_TRUEFALSE; pExpr->u.zToken = "false"; ExprSetProperty(pExpr, EP_IsFalse); @@ -148771,9 +151431,11 @@ static void exprAnalyze( ** BETWEEN term is skipped. */ else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){ - ExprList *pList = pExpr->x.pList; + ExprList *pList; int i; static const u8 ops[] = {TK_GE, TK_LE}; + assert( ExprUseXList(pExpr) ); + pList = pExpr->x.pList; assert( pList!=0 ); assert( pList->nExpr==2 ); for(i=0; i<2; i++){ @@ -148866,8 +151528,12 @@ static void exprAnalyze( const char *zCollSeqName; /* Name of collating sequence */ const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; + assert( ExprUseXList(pExpr) ); pLeft = pExpr->x.pList->a[1].pExpr; pStr2 = sqlite3ExprDup(db, pStr1, 0); + assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) ); + assert( pStr2==0 || !ExprHasProperty(pStr2, EP_IntValue) ); + /* Convert the lower bound to upper-case and the upper bound to ** lower-case (upper-case is less than lower-case in ASCII) so that @@ -148930,7 +151596,10 @@ static void exprAnalyze( ** no longer used. ** ** This is only required if at least one side of the comparison operation - ** is not a sub-select. */ + ** is not a sub-select. + ** + ** tag-20220128a + */ if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft @@ -148942,12 +151611,12 @@ static void exprAnalyze( for(i=0; ipLeft, i); - Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); + Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i, nLeft); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i, nLeft); pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); transferJoinMarkings(pNew, pExpr); - idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); + idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_SLICE); exprAnalyze(pSrc, pWC, idxNew); } pTerm = &pWC->a[idxTerm]; @@ -148967,6 +151636,7 @@ static void exprAnalyze( else if( pExpr->op==TK_IN && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR + && ALWAYS( ExprUseXSelect(pExpr) ) && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 @@ -148976,7 +151646,7 @@ static void exprAnalyze( int i; for(i=0; ipLeft); i++){ int idxNew; - idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); + idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL|TERM_SLICE); pWC->a[idxNew].u.x.iField = i+1; exprAnalyze(pSrc, pWC, idxNew); markTermAsChild(pWC, idxNew, idxTerm); @@ -149009,7 +151679,7 @@ static void exprAnalyze( 0, sqlite3ExprDup(db, pRight, 0)); if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ ExprSetProperty(pNewExpr, EP_FromJoin); - pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; + pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable; } idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -149072,6 +151742,113 @@ SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ } } +/* +** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or +** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the +** where-clause passed as the first argument. The value for the term +** is found in register iReg. +** +** In the common case where the value is a simple integer +** (example: "LIMIT 5 OFFSET 10") then the expression codes as a +** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value(). +** If not, then it codes as a TK_REGISTER expression. +*/ +static void whereAddLimitExpr( + WhereClause *pWC, /* Add the constraint to this WHERE clause */ + int iReg, /* Register that will hold value of the limit/offset */ + Expr *pExpr, /* Expression that defines the limit/offset */ + int iCsr, /* Cursor to which the constraint applies */ + int eMatchOp /* SQLITE_INDEX_CONSTRAINT_LIMIT or _OFFSET */ +){ + Parse *pParse = pWC->pWInfo->pParse; + sqlite3 *db = pParse->db; + Expr *pNew; + int iVal = 0; + + if( sqlite3ExprIsInteger(pExpr, &iVal) && iVal>=0 ){ + Expr *pVal = sqlite3Expr(db, TK_INTEGER, 0); + if( pVal==0 ) return; + ExprSetProperty(pVal, EP_IntValue); + pVal->u.iValue = iVal; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + }else{ + Expr *pVal = sqlite3Expr(db, TK_REGISTER, 0); + if( pVal==0 ) return; + pVal->iTable = iReg; + pNew = sqlite3PExpr(pParse, TK_MATCH, 0, pVal); + } + if( pNew ){ + WhereTerm *pTerm; + int idx; + idx = whereClauseInsert(pWC, pNew, TERM_DYNAMIC|TERM_VIRTUAL); + pTerm = &pWC->a[idx]; + pTerm->leftCursor = iCsr; + pTerm->eOperator = WO_AUX; + pTerm->eMatchOp = eMatchOp; + } +} + +/* +** Possibly add terms corresponding to the LIMIT and OFFSET clauses of the +** SELECT statement passed as the second argument. These terms are only +** added if: +** +** 1. The SELECT statement has a LIMIT clause, and +** 2. The SELECT statement is not an aggregate or DISTINCT query, and +** 3. The SELECT statement has exactly one object in its from clause, and +** that object is a virtual table, and +** 4. There are no terms in the WHERE clause that will not be passed +** to the virtual table xBestIndex method. +** 5. The ORDER BY clause, if any, will be made available to the xBestIndex +** method. +** +** LIMIT and OFFSET terms are ignored by most of the planner code. They +** exist only so that they may be passed to the xBestIndex method of the +** single virtual table in the FROM clause of the SELECT. +*/ +SQLITE_PRIVATE void sqlite3WhereAddLimit(WhereClause *pWC, Select *p){ + assert( p==0 || (p->pGroupBy==0 && (p->selFlags & SF_Aggregate)==0) ); + if( (p && p->pLimit) /* 1 */ + && (p->selFlags & (SF_Distinct|SF_Aggregate))==0 /* 2 */ + && (p->pSrc->nSrc==1 && IsVirtual(p->pSrc->a[0].pTab)) /* 3 */ + ){ + ExprList *pOrderBy = p->pOrderBy; + int iCsr = p->pSrc->a[0].iCursor; + int ii; + + /* Check condition (4). Return early if it is not met. */ + for(ii=0; iinTerm; ii++){ + if( pWC->a[ii].wtFlags & TERM_CODED ){ + /* This term is a vector operation that has been decomposed into + ** other, subsequent terms. It can be ignored. See tag-20220128a */ + assert( pWC->a[ii].wtFlags & TERM_VIRTUAL ); + assert( pWC->a[ii].eOperator==0 ); + continue; + } + if( pWC->a[ii].leftCursor!=iCsr ) return; + } + + /* Check condition (5). Return early if it is not met. */ + if( pOrderBy ){ + for(ii=0; iinExpr; ii++){ + Expr *pExpr = pOrderBy->a[ii].pExpr; + if( pExpr->op!=TK_COLUMN ) return; + if( pExpr->iTable!=iCsr ) return; + if( pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_BIGNULL ) return; + } + } + + /* All conditions are met. Add the terms to the where-clause object. */ + assert( p->pLimit->op==TK_LIMIT ); + whereAddLimitExpr(pWC, p->iLimit, p->pLimit->pLeft, + iCsr, SQLITE_INDEX_CONSTRAINT_LIMIT); + if( p->iOffset>0 ){ + whereAddLimitExpr(pWC, p->iOffset, p->pLimit->pRight, + iCsr, SQLITE_INDEX_CONSTRAINT_OFFSET); + } + } +} + /* ** Initialize a preallocated WhereClause structure. */ @@ -149083,6 +151860,7 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit( pWC->hasOr = 0; pWC->pOuter = 0; pWC->nTerm = 0; + pWC->nBase = 0; pWC->nSlot = ArraySize(pWC->aStatic); pWC->a = pWC->aStatic; } @@ -149093,17 +151871,34 @@ SQLITE_PRIVATE void sqlite3WhereClauseInit( ** sqlite3WhereClauseInit(). */ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ - int i; - WhereTerm *a; sqlite3 *db = pWC->pWInfo->pParse->db; - for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ - if( a->wtFlags & TERM_DYNAMIC ){ - sqlite3ExprDelete(db, a->pExpr); + assert( pWC->nTerm>=pWC->nBase ); + if( pWC->nTerm>0 ){ + WhereTerm *a = pWC->a; + WhereTerm *aLast = &pWC->a[pWC->nTerm-1]; +#ifdef SQLITE_DEBUG + int i; + /* Verify that every term past pWC->nBase is virtual */ + for(i=pWC->nBase; inTerm; i++){ + assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 ); } - if( a->wtFlags & TERM_ORINFO ){ - whereOrInfoDelete(db, a->u.pOrInfo); - }else if( a->wtFlags & TERM_ANDINFO ){ - whereAndInfoDelete(db, a->u.pAndInfo); +#endif + while(1){ + assert( a->eMatchOp==0 || a->eOperator==WO_AUX ); + if( a->wtFlags & TERM_DYNAMIC ){ + sqlite3ExprDelete(db, a->pExpr); + } + if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){ + if( a->wtFlags & TERM_ORINFO ){ + assert( (a->wtFlags & TERM_ANDINFO)==0 ); + whereOrInfoDelete(db, a->u.pOrInfo); + }else{ + assert( (a->wtFlags & TERM_ANDINFO)!=0 ); + whereAndInfoDelete(db, a->u.pAndInfo); + } + } + if( a==aLast ) break; + a++; } } if( pWC->a!=pWC->aStatic ){ @@ -149116,28 +151911,52 @@ SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ ** These routines walk (recursively) an expression tree and generate ** a bitmask indicating which tables are used in that expression ** tree. +** +** sqlite3WhereExprUsage(MaskSet, Expr) -> +** +** Return a Bitmask of all tables referenced by Expr. Expr can be +** be NULL, in which case 0 is returned. +** +** sqlite3WhereExprUsageNN(MaskSet, Expr) -> +** +** Same as sqlite3WhereExprUsage() except that Expr must not be +** NULL. The "NN" suffix on the name stands for "Not Null". +** +** sqlite3WhereExprListUsage(MaskSet, ExprList) -> +** +** Return a Bitmask of all tables referenced by every expression +** in the expression list ExprList. ExprList can be NULL, in which +** case 0 is returned. +** +** sqlite3WhereExprUsageFull(MaskSet, ExprList) -> +** +** Internal use only. Called only by sqlite3WhereExprUsageNN() for +** complex expressions that require pushing register values onto +** the stack. Many calls to sqlite3WhereExprUsageNN() do not need +** the more complex analysis done by this routine. Hence, the +** computations done by this routine are broken out into a separate +** "no-inline" function to avoid the stack push overhead in the +** common case where it is not needed. */ -SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ +static SQLITE_NOINLINE Bitmask sqlite3WhereExprUsageFull( + WhereMaskSet *pMaskSet, + Expr *p +){ Bitmask mask; - if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ - return sqlite3WhereGetMask(pMaskSet, p->iTable); - }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ - assert( p->op!=TK_IF_NULL_ROW ); - return 0; - } mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); if( p->pRight ){ mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); assert( p->x.pList==0 ); - }else if( ExprHasProperty(p, EP_xIsSelect) ){ + }else if( ExprUseXSelect(p) ){ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; mask |= exprSelectUsage(pMaskSet, p->x.pSelect); }else if( p->x.pList ){ mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC - if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){ + if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && ExprUseYWin(p) ){ + assert( p->y.pWin!=0 ); mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); @@ -149145,6 +151964,15 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ #endif return mask; } +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ + if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ + return sqlite3WhereGetMask(pMaskSet, p->iTable); + }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ + assert( p->op!=TK_IF_NULL_ROW ); + return 0; + } + return sqlite3WhereExprUsageFull(pMaskSet, p); +} SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; } @@ -149212,7 +152040,9 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( if( pColRef==0 ) return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; + assert( ExprUseYTab(pColRef) ); pColRef->y.pTab = pTab; + pItem->colUsed |= sqlite3ExprColUsed(pColRef); pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); @@ -149257,8 +152087,14 @@ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( */ typedef struct HiddenIndexInfo HiddenIndexInfo; struct HiddenIndexInfo { - WhereClause *pWC; /* The Where clause being analyzed */ - Parse *pParse; /* The parsing context */ + WhereClause *pWC; /* The Where clause being analyzed */ + Parse *pParse; /* The parsing context */ + int eDistinct; /* Value to return from sqlite3_vtab_distinct() */ + u32 mIn; /* Mask of terms that are IN (...) */ + u32 mHandleIn; /* Terms that vtab will handle as IN (...) */ + sqlite3_value *aRhs[1]; /* RHS values for constraints. MUST BE LAST + ** because extra space is allocated to hold up + ** to nTerm such values */ }; /* Forward declaration of methods */ @@ -149461,7 +152297,12 @@ whereOrInsert_done: SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ int i; assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); - for(i=0; in; i++){ + assert( pMaskSet->n>0 || pMaskSet->ix[0]<0 ); + assert( iCursor>=-1 ); + if( pMaskSet->ix[0]==iCursor ){ + return 1; + } + for(i=1; in; i++){ if( pMaskSet->ix[i]==iCursor ){ return MASKBIT(i); } @@ -149513,8 +152354,10 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ iColumn = pScan->aiColumn[pScan->iEquiv-1]; iCur = pScan->aiCur[pScan->iEquiv-1]; assert( pWC!=0 ); + assert( iCur>=0 ); do{ for(pTerm=pWC->a+k; knTerm; k++, pTerm++){ + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 || pTerm->leftCursor<0 ); if( pTerm->leftCursor==iCur && pTerm->u.x.leftColumn==iColumn && (iColumn!=XN_EXPR @@ -149556,7 +152399,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ } } if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0 - && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN + && (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0)) + && pX->op==TK_COLUMN && pX->iTable==pScan->aiCur[0] && pX->iColumn==pScan->aiColumn[0] ){ @@ -149643,16 +152487,16 @@ static WhereTerm *whereScanInit( if( pIdx ){ int j = iColumn; iColumn = pIdx->aiColumn[j]; - if( iColumn==XN_EXPR ){ - pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; - pScan->zCollName = pIdx->azColl[j]; - pScan->aiColumn[0] = XN_EXPR; - return whereScanInitIndexExpr(pScan); - }else if( iColumn==pIdx->pTable->iPKey ){ + if( iColumn==pIdx->pTable->iPKey ){ iColumn = XN_ROWID; }else if( iColumn>=0 ){ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity; pScan->zCollName = pIdx->azColl[j]; + }else if( iColumn==XN_EXPR ){ + pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr; + pScan->zCollName = pIdx->azColl[j]; + pScan->aiColumn[0] = XN_EXPR; + return whereScanInitIndexExpr(pScan); } }else if( iColumn==XN_EXPR ){ return 0; @@ -149895,12 +152739,14 @@ static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ int i; if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ - sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", + sqlite3DebugPrintf( + " constraint[%d]: col=%d termid=%d op=%d usabled=%d collseq=%s\n", i, p->aConstraint[i].iColumn, p->aConstraint[i].iTermOffset, p->aConstraint[i].op, - p->aConstraint[i].usable); + p->aConstraint[i].usable, + sqlite3_vtab_collation(p,i)); } for(i=0; inOrderBy; i++){ sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", @@ -149936,9 +152782,9 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ ** index existed. */ static int termCanDriveIndex( - WhereTerm *pTerm, /* WHERE clause term to check */ - SrcItem *pSrc, /* Table we are trying to access */ - Bitmask notReady /* Tables in outer loops of the join */ + const WhereTerm *pTerm, /* WHERE clause term to check */ + const SrcItem *pSrc, /* Table we are trying to access */ + const Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; if( pTerm->leftCursor!=pSrc->iCursor ) return 0; @@ -149953,6 +152799,7 @@ static int termCanDriveIndex( return 0; } if( (pTerm->prereqRight & notReady)!=0 ) return 0; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); if( pTerm->u.x.leftColumn<0 ) return 0; aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity; if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; @@ -149968,11 +152815,11 @@ static int termCanDriveIndex( ** and to set up the WhereLevel object pLevel so that the code generator ** makes use of the automatic index. */ -static void constructAutomaticIndex( +static SQLITE_NOINLINE void constructAutomaticIndex( Parse *pParse, /* The parsing context */ - WhereClause *pWC, /* The WHERE clause */ - SrcItem *pSrc, /* The FROM clause term to get the next index */ - Bitmask notReady, /* Mask of cursors that are not available */ + const WhereClause *pWC, /* The WHERE clause */ + const SrcItem *pSrc, /* The FROM clause term to get the next index */ + const Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ int nKeyCol; /* Number of columns in the constructed index */ @@ -150014,25 +152861,27 @@ static void constructAutomaticIndex( idxCols = 0; for(pTerm=pWC->a; pTermpExpr; - assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */ - || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */ - || pLoop->prereq!=0 ); /* table of a LEFT JOIN */ - if( pLoop->prereq==0 - && (pTerm->wtFlags & TERM_VIRTUAL)==0 - && !ExprHasProperty(pExpr, EP_FromJoin) - && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ + /* Make the automatic index a partial index if there are terms in the + ** WHERE clause (or the ON clause of a LEFT join) that constrain which + ** rows of the target table (pSrc) that can be used. */ + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsTableConstraint(pExpr, pSrc) + ){ pPartial = sqlite3ExprAnd(pParse, pPartial, sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ - int iCol = pTerm->u.x.leftColumn; - Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + int iCol; + Bitmask cMask; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + iCol = pTerm->u.x.leftColumn; + cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); testcase( iCol==BMS ); testcase( iCol==BMS-1 ); if( !sentWarning ){ sqlite3_log(SQLITE_WARNING_AUTOINDEX, "automatic index on %s(%s)", pTable->zName, - pTable->aCol[iCol].zName); + pTable->aCol[iCol].zCnName); sentWarning = 1; } if( (idxCols & cMask)==0 ){ @@ -150078,8 +152927,11 @@ static void constructAutomaticIndex( idxCols = 0; for(pTerm=pWC->a; pTermu.x.leftColumn; - Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); + int iCol; + Bitmask cMask; + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + iCol = pTerm->u.x.leftColumn; + cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol); testcase( iCol==BMS-1 ); testcase( iCol==BMS ); if( (idxCols & cMask)==0 ){ @@ -150121,6 +152973,10 @@ static void constructAutomaticIndex( sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "for %s", pTable->zName)); + if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){ + pLevel->regFilter = ++pParse->nMem; + sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter); + } /* Fill the automatic index with content */ pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; @@ -150143,6 +152999,10 @@ static void constructAutomaticIndex( regBase = sqlite3GenerateIndexKey( pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 ); + if( pLevel->regFilter ){ + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, + regBase, pLoop->u.btree.nEq); + } sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); @@ -150169,22 +153029,149 @@ end_auto_index_create: } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ +/* +** Generate bytecode that will initialize a Bloom filter that is appropriate +** for pLevel. +** +** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER +** flag set, initialize a Bloomfilter for them as well. Except don't do +** this recursive initialization if the SQLITE_BloomPulldown optimization has +** been turned off. +** +** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared +** from the loop, but the regFilter value is set to a register that implements +** the Bloom filter. When regFilter is positive, the +** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter +** and skip the subsequence B-Tree seek if the Bloom filter indicates that +** no matching rows exist. +** +** This routine may only be called if it has previously been determined that +** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit +** is set. +*/ +static SQLITE_NOINLINE void sqlite3ConstructBloomFilter( + WhereInfo *pWInfo, /* The WHERE clause */ + int iLevel, /* Index in pWInfo->a[] that is pLevel */ + WhereLevel *pLevel, /* Make a Bloom filter for this FROM term */ + Bitmask notReady /* Loops that are not ready */ +){ + int addrOnce; /* Address of opening OP_Once */ + int addrTop; /* Address of OP_Rewind */ + int addrCont; /* Jump here to skip a row */ + const WhereTerm *pTerm; /* For looping over WHERE clause terms */ + const WhereTerm *pWCEnd; /* Last WHERE clause term */ + Parse *pParse = pWInfo->pParse; /* Parsing context */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ + int iCur; /* Cursor for table getting the filter */ + + assert( pLoop!=0 ); + assert( v!=0 ); + assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + do{ + const SrcItem *pItem; + const Table *pTab; + u64 sz; + sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel); + addrCont = sqlite3VdbeMakeLabel(pParse); + iCur = pLevel->iTabCur; + pLevel->regFilter = ++pParse->nMem; + + /* The Bloom filter is a Blob held in a register. Initialize it + ** to zero-filled blob of at least 80K bits, but maybe more if the + ** estimated size of the table is larger. We could actually + ** measure the size of the table at run-time using OP_Count with + ** P3==1 and use that value to initialize the blob. But that makes + ** testing complicated. By basing the blob size on the value in the + ** sqlite_stat1 table, testing is much easier. + */ + pItem = &pWInfo->pTabList->a[pLevel->iFrom]; + assert( pItem!=0 ); + pTab = pItem->pTab; + assert( pTab!=0 ); + sz = sqlite3LogEstToInt(pTab->nRowLogEst); + if( sz<10000 ){ + sz = 10000; + }else if( sz>10000000 ){ + sz = 10000000; + } + sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter); + + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm]; + for(pTerm=pWInfo->sWC.a; pTermpExpr; + if( (pTerm->wtFlags & TERM_VIRTUAL)==0 + && sqlite3ExprIsTableConstraint(pExpr, pItem) + ){ + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + } + } + if( pLoop->wsFlags & WHERE_IPK ){ + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1); + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, 1); + sqlite3ReleaseTempReg(pParse, r1); + }else{ + Index *pIdx = pLoop->u.btree.pIndex; + int n = pLoop->u.btree.nEq; + int r1 = sqlite3GetTempRange(pParse, n); + int jj; + for(jj=0; jjaiColumn[jj]; + assert( pIdx->pTable==pItem->pTab ); + sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj); + } + sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n); + sqlite3ReleaseTempRange(pParse, r1, n); + } + sqlite3VdbeResolveLabel(v, addrCont); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); + pLoop->wsFlags &= ~WHERE_BLOOMFILTER; + if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break; + while( ++iLevel < pWInfo->nLevel ){ + const SrcItem *pTabItem; + pLevel = &pWInfo->a[iLevel]; + pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; + if( pTabItem->fg.jointype & JT_LEFT ) continue; + pLoop = pLevel->pWLoop; + if( NEVER(pLoop==0) ) continue; + if( pLoop->prereq & notReady ) continue; + if( (pLoop->wsFlags & (WHERE_BLOOMFILTER|WHERE_COLUMN_IN)) + ==WHERE_BLOOMFILTER + ){ + /* This is a candidate for bloom-filter pull-down (early evaluation). + ** The test that WHERE_COLUMN_IN is omitted is important, as we are + ** not able to do early evaluation of bloom filters that make use of + ** the IN operator */ + break; + } + } + }while( iLevel < pWInfo->nLevel ); + sqlite3VdbeJumpHere(v, addrOnce); +} + + #ifndef SQLITE_OMIT_VIRTUALTABLE /* ** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure -** by passing the pointer returned by this function to sqlite3_free(). +** by passing the pointer returned by this function to freeIndexInfo(). */ static sqlite3_index_info *allocateIndexInfo( - Parse *pParse, /* The parsing context */ + WhereInfo *pWInfo, /* The WHERE clause */ WhereClause *pWC, /* The WHERE clause being analyzed */ Bitmask mUnusable, /* Ignore terms with these prereqs */ SrcItem *pSrc, /* The FROM clause term that is the vtab */ - ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ int i, j; int nTerm; + Parse *pParse = pWInfo->pParse; struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_orderby *pIdxOrderBy; struct sqlite3_index_constraint_usage *pUsage; @@ -150193,10 +153180,21 @@ static sqlite3_index_info *allocateIndexInfo( int nOrderBy; sqlite3_index_info *pIdxInfo; u16 mNoOmit = 0; + const Table *pTab; + int eDistinct = 0; + ExprList *pOrderBy = pWInfo->pOrderBy; - /* Count the number of possible WHERE clause constraints referring - ** to this virtual table */ + assert( pSrc!=0 ); + pTab = pSrc->pTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); + + /* Find all WHERE clause constraints referring to this virtual table. + ** Mark each term with the TERM_OK flag. Set nTerm to the number of + ** terms found. + */ for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + pTerm->wtFlags &= ~TERM_OK; if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); @@ -150206,8 +153204,21 @@ static sqlite3_index_info *allocateIndexInfo( testcase( pTerm->eOperator & WO_ALL ); if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; if( pTerm->wtFlags & TERM_VNULL ) continue; - assert( pTerm->u.x.leftColumn>=(-1) ); + + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); + assert( pTerm->u.x.leftColumn>=XN_ROWID ); + assert( pTerm->u.x.leftColumnnCol ); + + /* tag-20191211-002: WHERE-clause constraints are not useful to the + ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the + ** equivalent restriction for ordinary tables. */ + if( (pSrc->fg.jointype & JT_LEFT)!=0 + && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + ){ + continue; + } nTerm++; + pTerm->wtFlags |= TERM_OK; } /* If the ORDER BY clause contains only columns in the current @@ -150219,11 +153230,47 @@ static sqlite3_index_info *allocateIndexInfo( int n = pOrderBy->nExpr; for(i=0; ia[i].pExpr; - if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; + Expr *pE2; + + /* Skip over constant terms in the ORDER BY clause */ + if( sqlite3ExprIsConstant(pExpr) ){ + continue; + } + + /* Virtual tables are unable to deal with NULLS FIRST */ if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break; + + /* First case - a direct column references without a COLLATE operator */ + if( pExpr->op==TK_COLUMN && pExpr->iTable==pSrc->iCursor ){ + assert( pExpr->iColumn>=XN_ROWID && pExpr->iColumnnCol ); + continue; + } + + /* 2nd case - a column reference with a COLLATE operator. Only match + ** of the COLLATE operator matches the collation of the column. */ + if( pExpr->op==TK_COLLATE + && (pE2 = pExpr->pLeft)->op==TK_COLUMN + && pE2->iTable==pSrc->iCursor + ){ + const char *zColl; /* The collating sequence name */ + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + assert( pExpr->u.zToken!=0 ); + assert( pE2->iColumn>=XN_ROWID && pE2->iColumnnCol ); + pExpr->iColumn = pE2->iColumn; + if( pE2->iColumn<0 ) continue; /* Collseq does not matter for rowid */ + zColl = sqlite3ColumnColl(&pTab->aCol[pE2->iColumn]); + if( zColl==0 ) zColl = sqlite3StrBINARY; + if( sqlite3_stricmp(pExpr->u.zToken, zColl)==0 ) continue; + } + + /* No matches cause a break out of the loop */ + break; } - if( i==n){ + if( i==n ){ nOrderBy = n; + if( (pWInfo->wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY)) ){ + eDistinct = 1 + ((pWInfo->wctrlFlags & WHERE_DISTINCTBY)!=0); + } } } @@ -150231,46 +153278,35 @@ static sqlite3_index_info *allocateIndexInfo( */ pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm - + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) ); + + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) + + sizeof(sqlite3_value*)*nTerm ); if( pIdxInfo==0 ){ sqlite3ErrorMsg(pParse, "out of memory"); return 0; } pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; - pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1]; + pIdxCons = (struct sqlite3_index_constraint*)&pHidden->aRhs[nTerm]; pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; - pIdxInfo->nOrderBy = nOrderBy; pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; pIdxInfo->aConstraintUsage = pUsage; pHidden->pWC = pWC; pHidden->pParse = pParse; + pHidden->eDistinct = eDistinct; + pHidden->mIn = 0; for(i=j=0, pTerm=pWC->a; inTerm; i++, pTerm++){ u16 op; - if( pTerm->leftCursor != pSrc->iCursor ) continue; - if( pTerm->prereqRight & mUnusable ) continue; - assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) ); - testcase( pTerm->eOperator & WO_IN ); - testcase( pTerm->eOperator & WO_IS ); - testcase( pTerm->eOperator & WO_ISNULL ); - testcase( pTerm->eOperator & WO_ALL ); - if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue; - if( pTerm->wtFlags & TERM_VNULL ) continue; - - /* tag-20191211-002: WHERE-clause constraints are not useful to the - ** right-hand table of a LEFT JOIN. See tag-20191211-001 for the - ** equivalent restriction for ordinary tables. */ - if( (pSrc->fg.jointype & JT_LEFT)!=0 - && !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - ){ - continue; - } - assert( pTerm->u.x.leftColumn>=(-1) ); + if( (pTerm->wtFlags & TERM_OK)==0 ) continue; pIdxCons[j].iColumn = pTerm->u.x.leftColumn; pIdxCons[j].iTermOffset = i; op = pTerm->eOperator & WO_ALL; - if( op==WO_IN ) op = WO_EQ; + if( op==WO_IN ){ + if( (pTerm->wtFlags & TERM_SLICE)==0 ){ + pHidden->mIn |= SMASKBIT32(j); + } + op = WO_EQ; + } if( op==WO_AUX ){ pIdxCons[j].op = pTerm->eMatchOp; }else if( op & (WO_ISNULL|WO_IS) ){ @@ -150303,17 +153339,42 @@ static sqlite3_index_info *allocateIndexInfo( j++; } + assert( j==nTerm ); pIdxInfo->nConstraint = j; - for(i=0; ia[i].pExpr; - pIdxOrderBy[i].iColumn = pExpr->iColumn; - pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; + if( sqlite3ExprIsConstant(pExpr) ) continue; + assert( pExpr->op==TK_COLUMN + || (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN + && pExpr->iColumn==pExpr->pLeft->iColumn) ); + pIdxOrderBy[j].iColumn = pExpr->iColumn; + pIdxOrderBy[j].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; + j++; } + pIdxInfo->nOrderBy = j; *pmNoOmit = mNoOmit; return pIdxInfo; } +/* +** Free an sqlite3_index_info structure allocated by allocateIndexInfo() +** and possibly modified by xBestIndex methods. +*/ +static void freeIndexInfo(sqlite3 *db, sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden; + int i; + assert( pIdxInfo!=0 ); + pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->pParse!=0 ); + assert( pHidden->pParse->db==db ); + for(i=0; inConstraint; i++){ + sqlite3ValueFree(pHidden->aRhs[i]); /* IMP: R-14553-25174 */ + pHidden->aRhs[i] = 0; + } + sqlite3DbFree(db, pIdxInfo); +} + /* ** The table object reference passed as the second argument to this function ** must represent a virtual table. This function invokes the xBestIndex() @@ -150335,7 +153396,9 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ int rc; whereTraceIndexInfoInputs(p); + pParse->db->nSchemaLock++; rc = pVtab->pModule->xBestIndex(pVtab, p); + pParse->db->nSchemaLock--; whereTraceIndexInfoOutputs(p); if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ @@ -151029,6 +154092,7 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; if( pTerm->eOperator & WO_SINGLE ){ + assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 ); sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", pTerm->leftCursor, pTerm->u.x.leftColumn); }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ @@ -151046,7 +154110,7 @@ SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); } - if( pTerm->u.x.iField ){ + if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){ sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField); } if( pTerm->iParent>=0 ){ @@ -151108,9 +154172,9 @@ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ sqlite3_free(z); } if( p->wsFlags & WHERE_SKIPSCAN ){ - sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); + sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); }else{ - sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); + sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm); } sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ @@ -151210,7 +154274,8 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ assert( pWInfo!=0 ); for(i=0; inLevel; i++){ WhereLevel *pLevel = &pWInfo->a[i]; - if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ + if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){ + assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 ); sqlite3DbFree(db, pLevel->u.in.aInLoop); } } @@ -151238,7 +154303,8 @@ static void whereUndoExprMods(WhereInfo *pWInfo){ /* ** Return TRUE if all of the following are true: ** -** (1) X has the same or lower cost that Y +** (1) X has the same or lower cost, or returns the same or fewer rows, +** than Y. ** (2) X uses fewer WHERE clause terms than Y ** (3) Every WHERE clause term used by X is also used by Y ** (4) X skips at least as many columns as Y @@ -151261,11 +154327,8 @@ static int whereLoopCheaperProperSubset( if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){ return 0; /* X is not a subset of Y */ } + if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0; if( pY->nSkip > pX->nSkip ) return 0; - if( pX->rRun >= pY->rRun ){ - if( pX->rRun > pY->rRun ) return 0; /* X costs more than Y */ - if( pX->nOut > pY->nOut ) return 0; /* X costs more than Y */ - } for(i=pX->nLTerm-1; i>=0; i--){ if( pX->aLTerm[i]==0 ) continue; for(j=pY->nLTerm-1; j>=0; j--){ @@ -151281,8 +154344,8 @@ static int whereLoopCheaperProperSubset( } /* -** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so -** that: +** Try to adjust the cost and number of output rows of WhereLoop pTemplate +** upwards or downwards so that: ** ** (1) pTemplate costs less than any other WhereLoops that are a proper ** subset of pTemplate @@ -151303,16 +154366,20 @@ static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){ /* Adjust pTemplate cost downward so that it is cheaper than its ** subset p. */ WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", - pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1)); - pTemplate->rRun = p->rRun; - pTemplate->nOut = p->nOut - 1; + pTemplate->rRun, pTemplate->nOut, + MIN(p->rRun, pTemplate->rRun), + MIN(p->nOut - 1, pTemplate->nOut))); + pTemplate->rRun = MIN(p->rRun, pTemplate->rRun); + pTemplate->nOut = MIN(p->nOut - 1, pTemplate->nOut); }else if( whereLoopCheaperProperSubset(pTemplate, p) ){ /* Adjust pTemplate cost upward so that it is costlier than p since ** pTemplate is a proper subset of p */ WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", - pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1)); - pTemplate->rRun = p->rRun; - pTemplate->nOut = p->nOut + 1; + pTemplate->rRun, pTemplate->nOut, + MAX(p->rRun, pTemplate->rRun), + MAX(p->nOut + 1, pTemplate->nOut))); + pTemplate->rRun = MAX(p->rRun, pTemplate->rRun); + pTemplate->nOut = MAX(p->nOut + 1, pTemplate->nOut); } } } @@ -151567,11 +154634,11 @@ static void whereLoopOutputAdjust( LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */ assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 ); - for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){ + for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){ assert( pTerm!=0 ); - if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break; - if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; if( (pTerm->prereqAll & notAllowed)!=0 ) continue; + if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue; + if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue; for(j=pLoop->nLTerm-1; j>=0; j--){ pX = pLoop->aLTerm[j]; if( pX==0 ) continue; @@ -151579,6 +154646,22 @@ static void whereLoopOutputAdjust( if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break; } if( j<0 ){ + if( pLoop->maskSelf==pTerm->prereqAll ){ + /* If there are extra terms in the WHERE clause not used by an index + ** that depend only on the table being scanned, and that will tend to + ** cause many rows to be omitted, then mark that table as + ** "self-culling". + ** + ** 2022-03-24: Self-culling only applies if either the extra terms + ** are straight comparison operators that are non-true with NULL + ** operand, or if the loop is not a LEFT JOIN. + */ + if( (pTerm->eOperator & 0x3f)!=0 + || (pWC->pWInfo->pTabList->a[pLoop->iTab].fg.jointype & JT_LEFT)==0 + ){ + pLoop->wsFlags |= WHERE_SELFCULL; + } + } if( pTerm->truthProb<=0 ){ /* If a truth probability is specified using the likelihood() hints, ** then use the probability provided by the application. */ @@ -151606,7 +154689,9 @@ static void whereLoopOutputAdjust( } } } - if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce; + if( pLoop->nOut > nRow-iReduce ){ + pLoop->nOut = nRow - iReduce; + } } /* @@ -151643,9 +154728,12 @@ static int whereRangeVectorLen( char aff; /* Comparison affinity */ char idxaff = 0; /* Indexed columns affinity */ CollSeq *pColl; /* Comparison collation sequence */ - Expr *pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr; - Expr *pRhs = pTerm->pExpr->pRight; - if( pRhs->flags & EP_xIsSelect ){ + Expr *pLhs, *pRhs; + + assert( ExprUseXList(pTerm->pExpr->pLeft) ); + pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr; + pRhs = pTerm->pExpr->pRight; + if( ExprUseXSelect(pRhs) ){ pRhs = pRhs->x.pSelect->pEList->a[i].pExpr; }else{ pRhs = pRhs->x.pList->a[i].pExpr; @@ -151806,7 +154894,7 @@ static int whereLoopAddBtreeIndex( if( eOp & WO_IN ){ Expr *pExpr = pTerm->pExpr; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ + if( ExprUseXSelect(pExpr) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ int i; nIn = 46; assert( 46==sqlite3LogEst(25) ); @@ -151947,7 +155035,7 @@ static int whereLoopAddBtreeIndex( if( nInMul==0 && pProbe->nSample && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol) - && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect)) + && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr)) && OptimizationEnabled(db, SQLITE_Stat4) ){ Expr *pExpr = pTerm->pExpr; @@ -152148,7 +155236,7 @@ static int whereUsablePartialIndex( for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ Expr *pExpr; pExpr = pTerm->pExpr; - if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) + if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab) && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) && (pTerm->wtFlags & TERM_VNULL)==0 @@ -152211,7 +155299,6 @@ static int whereLoopAddBtree( int iSortIdx = 1; /* Index number */ int b; /* A boolean value */ LogEst rSize; /* number of rows in the table */ - LogEst rLogSize; /* Logarithm of the number of rows in the table */ WhereClause *pWC; /* The parsed WHERE clause */ Table *pTab; /* Table being queried */ @@ -152224,6 +155311,7 @@ static int whereLoopAddBtree( assert( !IsVirtual(pSrc->pTab) ); if( pSrc->fg.isIndexedBy ){ + assert( pSrc->fg.isCte==0 ); /* An INDEXED BY clause specifies a particular index to use */ pProbe = pSrc->u2.pIBIndex; }else if( !HasRowid(pTab) ){ @@ -152254,7 +155342,6 @@ static int whereLoopAddBtree( pProbe = &sPk; } rSize = pTab->nRowLogEst; - rLogSize = estLog(rSize); #ifndef SQLITE_OMIT_AUTOMATIC_INDEX /* Automatic indexes */ @@ -152268,8 +155355,10 @@ static int whereLoopAddBtree( && !pSrc->fg.isRecursive /* Not a recursive common table expression. */ ){ /* Generate auto-index WhereLoops */ + LogEst rLogSize; /* Logarithm of the number of rows in the table */ WhereTerm *pTerm; WhereTerm *pWCEnd = pWC->a + pWC->nTerm; + rLogSize = estLog(rSize); for(pTerm=pWC->a; rc==SQLITE_OK && pTermprereqRight & pNew->maskSelf ) continue; if( termCanDriveIndex(pTerm, pSrc, 0) ){ @@ -152287,7 +155376,7 @@ static int whereLoopAddBtree( ** those objects, since there is no opportunity to add schema ** indexes on subqueries and views. */ pNew->rSetup = rLogSize + rSize; - if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){ + if( !IsView(pTab) && (pTab->tabFlags & TF_Ephemeral)==0 ){ pNew->rSetup += 28; }else{ pNew->rSetup -= 10; @@ -152449,6 +155538,15 @@ static int whereLoopAddBtree( #ifndef SQLITE_OMIT_VIRTUALTABLE +/* +** Return true if pTerm is a virtual table LIMIT or OFFSET term. +*/ +static int isLimitTerm(WhereTerm *pTerm){ + assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 ); + return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT + && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET; +} + /* ** Argument pIdxInfo is already populated with all constraints that may ** be used by the virtual table identified by pBuilder->pNew->iTab. This @@ -152476,9 +155574,11 @@ static int whereLoopAddVirtualOne( u16 mExclude, /* Exclude terms using these operators */ sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ u16 mNoOmit, /* Do not omit these constraints */ - int *pbIn /* OUT: True if plan uses an IN(...) op */ + int *pbIn, /* OUT: True if plan uses an IN(...) op */ + int *pbRetryLimit /* OUT: Retry without LIMIT/OFFSET */ ){ WhereClause *pWC = pBuilder->pWC; + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; struct sqlite3_index_constraint *pIdxCons; struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; int i; @@ -152501,6 +155601,7 @@ static int whereLoopAddVirtualOne( pIdxCons->usable = 0; if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 + && (pbRetryLimit || !isLimitTerm(pTerm)) ){ pIdxCons->usable = 1; } @@ -152516,6 +155617,7 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; + pHidden->mHandleIn = 0; /* Invoke the virtual table xBestIndex() method */ rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); @@ -152533,8 +155635,8 @@ static int whereLoopAddVirtualOne( mxTerm = -1; assert( pNew->nLSlot>=nConstraint ); - for(i=0; iaLTerm[i] = 0; - pNew->u.vtab.omitMask = 0; + memset(pNew->aLTerm, 0, sizeof(pNew->aLTerm[0])*nConstraint ); + memset(&pNew->u.vtab, 0, sizeof(pNew->u.vtab)); pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; ieMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET ){ + pNew->u.vtab.bOmitOffset = 1; + } } - if( (pTerm->eOperator & WO_IN)!=0 ){ + if( SMASKBIT32(i) & pHidden->mHandleIn ){ + pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm); + }else if( (pTerm->eOperator & WO_IN)!=0 ){ /* A virtual table that is constrained by an IN clause may not ** consume the ORDER BY clause because (1) the order of IN terms ** is not necessarily related to the order of output terms and @@ -152579,6 +155686,21 @@ static int whereLoopAddVirtualOne( pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE; *pbIn = 1; assert( (mExclude & WO_IN)==0 ); } + + if( isLimitTerm(pTerm) && *pbIn ){ + /* If there is an IN(...) term handled as an == (separate call to + ** xFilter for each value on the RHS of the IN) and a LIMIT or + ** OFFSET term handled as well, the plan is unusable. Set output + ** variable *pbRetryLimit to true to tell the caller to retry with + ** LIMIT and OFFSET disabled. */ + if( pIdxInfo->needToFreeIdxStr ){ + sqlite3_free(pIdxInfo->idxStr); + pIdxInfo->idxStr = 0; + pIdxInfo->needToFreeIdxStr = 0; + } + *pbRetryLimit = 1; + return SQLITE_OK; + } } } @@ -152623,11 +155745,19 @@ static int whereLoopAddVirtualOne( } /* -** If this function is invoked from within an xBestIndex() callback, it -** returns a pointer to a buffer containing the name of the collation -** sequence associated with element iCons of the sqlite3_index_info.aConstraint -** array. Or, if iCons is out of range or there is no active xBestIndex -** call, return NULL. +** Return the collating sequence for a constraint passed into xBestIndex. +** +** pIdxInfo must be an sqlite3_index_info structure passed into xBestIndex. +** This routine depends on there being a HiddenIndexInfo structure immediately +** following the sqlite3_index_info structure. +** +** Return a pointer to the collation name: +** +** 1. If there is an explicit COLLATE operator on the constaint, return it. +** +** 2. Else, if the column has an alternative collation, return that. +** +** 3. Otherwise, return "BINARY". */ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; @@ -152644,6 +155774,88 @@ SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int return zRet; } +/* +** Return true if constraint iCons is really an IN(...) constraint, or +** false otherwise. If iCons is an IN(...) constraint, set (if bHandle!=0) +** or clear (if bHandle==0) the flag to handle it using an iterator. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info *pIdxInfo, int iCons, int bHandle){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + u32 m = SMASKBIT32(iCons); + if( m & pHidden->mIn ){ + if( bHandle==0 ){ + pHidden->mHandleIn &= ~m; + }else if( bHandle>0 ){ + pHidden->mHandleIn |= m; + } + return 1; + } + return 0; +} + +/* +** This interface is callable from within the xBestIndex callback only. +** +** If possible, set (*ppVal) to point to an object containing the value +** on the right-hand-side of constraint iCons. +*/ +SQLITE_API int sqlite3_vtab_rhs_value( + sqlite3_index_info *pIdxInfo, /* Copy of first argument to xBestIndex */ + int iCons, /* Constraint for which RHS is wanted */ + sqlite3_value **ppVal /* Write value extracted here */ +){ + HiddenIndexInfo *pH = (HiddenIndexInfo*)&pIdxInfo[1]; + sqlite3_value *pVal = 0; + int rc = SQLITE_OK; + if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ + rc = SQLITE_MISUSE; /* EV: R-30545-25046 */ + }else{ + if( pH->aRhs[iCons]==0 ){ + WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; + rc = sqlite3ValueFromExpr( + pH->pParse->db, pTerm->pExpr->pRight, ENC(pH->pParse->db), + SQLITE_AFF_BLOB, &pH->aRhs[iCons] + ); + testcase( rc!=SQLITE_OK ); + } + pVal = pH->aRhs[iCons]; + } + *ppVal = pVal; + + if( rc==SQLITE_OK && pVal==0 ){ /* IMP: R-19933-32160 */ + rc = SQLITE_NOTFOUND; /* IMP: R-36424-56542 */ + } + + return rc; +} + +/* +** Return true if ORDER BY clause may be handled as DISTINCT. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + assert( pHidden->eDistinct==0 + || pHidden->eDistinct==1 + || pHidden->eDistinct==2 ); + return pHidden->eDistinct; +} + +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \ + && !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** Cause the prepared statement that is associated with a call to +** xBestIndex to open write transactions on all attached schemas. +** This is used by the (built-in) sqlite_dbpage virtual table. +*/ +SQLITE_PRIVATE void sqlite3VtabWriteAll(sqlite3_index_info *pIdxInfo){ + HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; + Parse *pParse = pHidden->pParse; + int nDb = pParse->db->nDb; + int i; + for(i=0; ipNew->iTab. That table is guaranteed to be a virtual table. @@ -152685,6 +155897,7 @@ static int whereLoopAddVirtual( WhereLoop *pNew; Bitmask mBest; /* Tables used by best possible plan */ u16 mNoOmit; + int bRetry = 0; /* True to retry with LIMIT/OFFSET disabled */ assert( (mPrereq & mUnusable)==0 ); pWInfo = pBuilder->pWInfo; @@ -152693,8 +155906,7 @@ static int whereLoopAddVirtual( pNew = pBuilder->pNew; pSrc = &pWInfo->pTabList->a[pNew->iTab]; assert( IsVirtual(pSrc->pTab) ); - p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy, - &mNoOmit); + p = allocateIndexInfo(pWInfo, pWC, mUnusable, pSrc, &mNoOmit); if( p==0 ) return SQLITE_NOMEM_BKPT; pNew->rSetup = 0; pNew->wsFlags = WHERE_VIRTUALTABLE; @@ -152702,14 +155914,22 @@ static int whereLoopAddVirtual( pNew->u.vtab.needFree = 0; nConstraint = p->nConstraint; if( whereLoopResize(pParse->db, pNew, nConstraint) ){ - sqlite3DbFree(pParse->db, p); + freeIndexInfo(pParse->db, p); return SQLITE_NOMEM_BKPT; } /* First call xBestIndex() with all constraints usable. */ WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName)); WHERETRACE(0x40, (" VirtualOne: all usable\n")); - rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, &bRetry + ); + if( bRetry ){ + assert( rc==SQLITE_OK ); + rc = whereLoopAddVirtualOne( + pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn, 0 + ); + } /* If the call to xBestIndex() with all terms enabled produced a plan ** that does not require any source tables (IOW: a plan with mBest==0) @@ -152727,7 +155947,7 @@ static int whereLoopAddVirtual( if( bIn ){ WHERETRACE(0x40, (" VirtualOne: all usable w/o IN\n")); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn); + pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn, 0); assert( bIn==0 ); mBestNoIn = pNew->prereq & ~mPrereq; if( mBestNoIn==0 ){ @@ -152754,7 +155974,7 @@ static int whereLoopAddVirtual( WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn); + pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn, 0); if( pNew->prereq==mPrereq ){ seenZero = 1; if( bIn==0 ) seenZeroNoIN = 1; @@ -152767,7 +155987,7 @@ static int whereLoopAddVirtual( if( rc==SQLITE_OK && seenZero==0 ){ WHERETRACE(0x40, (" VirtualOne: all disabled\n")); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn); + pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn, 0); if( bIn==0 ) seenZeroNoIN = 1; } @@ -152777,12 +155997,12 @@ static int whereLoopAddVirtual( if( rc==SQLITE_OK && seenZeroNoIN==0 ){ WHERETRACE(0x40, (" VirtualOne: all disabled and w/o IN\n")); rc = whereLoopAddVirtualOne( - pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn); + pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn, 0); } } if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); - sqlite3DbFreeNN(pParse->db, p); + freeIndexInfo(pParse->db, p); WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); return rc; } @@ -152826,7 +156046,6 @@ static int whereLoopAddOr( int i, j; sSubBuild = *pBuilder; - sSubBuild.pOrderBy = 0; sSubBuild.pOrSet = &sCur; WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm)); @@ -152838,6 +156057,7 @@ static int whereLoopAddOr( tempWC.pOuter = pWC; tempWC.op = TK_AND; tempWC.nTerm = 1; + tempWC.nBase = 1; tempWC.a = pOrTerm; sSubBuild.pWC = &tempWC; }else{ @@ -153309,7 +156529,7 @@ static i8 wherePathSatisfiesOrderBy( if( obSat==obDone ) return (i8)nOrderBy; if( !isOrderDistinct ){ for(i=nOrderBy-1; i>0; i--){ - Bitmask m = MASKBIT(i) - 1; + Bitmask m = ALWAYS(ipWInfo; if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0; @@ -153832,7 +157053,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pLoop = pBuilder->pNew; pLoop->wsFlags = 0; pLoop->nSkip = 0; - pTerm = sqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0); + pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0); + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); if( pTerm ){ testcase( pTerm->eOperator & WO_IS ); pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; @@ -153851,7 +157073,8 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ ) continue; opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ; for(j=0; jnKeyCol; j++){ - pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx); + pTerm = whereScanInit(&scan, pWC, iCur, j, opMask, pIdx); + while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan); if( pTerm==0 ) break; testcase( pTerm->eOperator & WO_IS ); pLoop->aLTerm[j] = pTerm; @@ -153880,8 +157103,14 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } + if( scan.iEquiv>1 ) pLoop->wsFlags |= WHERE_TRANSCONS; #ifdef SQLITE_DEBUG pLoop->cId = '0'; +#endif +#ifdef WHERETRACE_ENABLED + if( sqlite3WhereTrace ){ + sqlite3DebugPrintf("whereShortCut() used to compute solution\n"); + } #endif return 1; } @@ -153936,6 +157165,150 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ # define WHERETRACE_ALL_LOOPS(W,C) #endif +/* Attempt to omit tables from a join that do not affect the result. +** For a table to not affect the result, the following must be true: +** +** 1) The query must not be an aggregate. +** 2) The table must be the RHS of a LEFT JOIN. +** 3) Either the query must be DISTINCT, or else the ON or USING clause +** must contain a constraint that limits the scan of the table to +** at most a single row. +** 4) The table must not be referenced by any part of the query apart +** from its own USING or ON clause. +** +** For example, given: +** +** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); +** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); +** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); +** +** then table t2 can be omitted from the following: +** +** SELECT v1, v3 FROM t1 +** LEFT JOIN t2 ON (t1.ipk=t2.ipk) +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +** +** or from: +** +** SELECT DISTINCT v1, v3 FROM t1 +** LEFT JOIN t2 +** LEFT JOIN t3 ON (t1.ipk=t3.ipk) +*/ +static SQLITE_NOINLINE Bitmask whereOmitNoopJoin( + WhereInfo *pWInfo, + Bitmask notReady +){ + int i; + Bitmask tabUsed; + + /* Preconditions checked by the caller */ + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_OmitNoopJoin) ); + + /* These two preconditions checked by the caller combine to guarantee + ** condition (1) of the header comment */ + assert( pWInfo->pResultSet!=0 ); + assert( 0==(pWInfo->wctrlFlags & WHERE_AGG_DISTINCT) ); + + tabUsed = sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pResultSet); + if( pWInfo->pOrderBy ){ + tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy); + } + for(i=pWInfo->nLevel-1; i>=1; i--){ + WhereTerm *pTerm, *pEnd; + SrcItem *pItem; + WhereLoop *pLoop; + pLoop = pWInfo->a[i].pWLoop; + pItem = &pWInfo->pTabList->a[pLoop->iTab]; + if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0 + && (pLoop->wsFlags & WHERE_ONEROW)==0 + ){ + continue; + } + if( (tabUsed & pLoop->maskSelf)!=0 ) continue; + pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) + || pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor + ){ + break; + } + } + } + if( pTerm drop loop %c not used\n", pLoop->cId)); + notReady &= ~pLoop->maskSelf; + for(pTerm=pWInfo->sWC.a; pTermprereqAll & pLoop->maskSelf)!=0 ){ + pTerm->wtFlags |= TERM_CODED; + } + } + if( i!=pWInfo->nLevel-1 ){ + int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); + memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); + } + pWInfo->nLevel--; + assert( pWInfo->nLevel>0 ); + } + return notReady; +} + +/* +** Check to see if there are any SEARCH loops that might benefit from +** using a Bloom filter. Consider a Bloom filter if: +** +** (1) The SEARCH happens more than N times where N is the number +** of rows in the table that is being considered for the Bloom +** filter. +** (2) Some searches are expected to find zero rows. (This is determined +** by the WHERE_SELFCULL flag on the term.) +** (3) Bloom-filter processing is not disabled. (Checked by the +** caller.) +** (4) The size of the table being searched is known by ANALYZE. +** +** This block of code merely checks to see if a Bloom filter would be +** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the +** WhereLoop. The implementation of the Bloom filter comes further +** down where the code for each WhereLoop is generated. +*/ +static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful( + const WhereInfo *pWInfo +){ + int i; + LogEst nSearch; + + assert( pWInfo->nLevel>=2 ); + assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) ); + nSearch = pWInfo->a[0].pWLoop->nOut; + for(i=1; inLevel; i++){ + WhereLoop *pLoop = pWInfo->a[i].pWLoop; + const unsigned int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ); + if( (pLoop->wsFlags & reqFlags)==reqFlags + /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */ + && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0) + ){ + SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab]; + Table *pTab = pItem->pTab; + pTab->tabFlags |= TF_StatsUsed; + if( nSearch > pTab->nRowLogEst + && (pTab->tabFlags & TF_HasStat1)!=0 + ){ + testcase( pItem->fg.jointype & JT_LEFT ); + pLoop->wsFlags |= WHERE_BLOOMFILTER; + pLoop->wsFlags &= ~WHERE_IDX_ONLY; + WHERETRACE(0xffff, ( + "-> use Bloom-filter on loop %c because there are ~%.1e " + "lookups into %s which has only ~%.1e rows\n", + pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName, + (double)sqlite3LogEstToInt(pTab->nRowLogEst))); + } + } + nSearch += pLoop->nOut; + } +} + /* ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains @@ -154030,6 +157403,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( Expr *pWhere, /* The WHERE clause */ ExprList *pOrderBy, /* An ORDER BY (or GROUP BY) clause, or NULL */ ExprList *pResultSet, /* Query result set. Req'd for DISTINCT */ + Select *pLimit, /* Use this LIMIT/OFFSET clause, if any */ u16 wctrlFlags, /* The WHERE_* flags defined in sqliteInt.h */ int iAuxArg /* If WHERE_OR_SUBCLAUSE is set, index cursor number ** If WHERE_USE_LIMIT, then the limit amount */ @@ -154064,13 +157438,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */ testcase( pOrderBy && pOrderBy->nExpr==BMS-1 ); if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; - sWLB.pOrderBy = pOrderBy; - - /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via - ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ - if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ - wctrlFlags &= ~WHERE_WANT_DISTINCT; - } /* The number of tables in the FROM clause is limited by the number of ** bits in a Bitmask @@ -154113,11 +157480,18 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; +#ifndef SQLITE_OMIT_VIRTUALTABLE + pWInfo->pLimit = pLimit; +#endif memset(&pWInfo->nOBSat, 0, offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ pMaskSet = &pWInfo->sMaskSet; + pMaskSet->n = 0; + pMaskSet->ix[0] = -99; /* Initialize ix[0] to a value that can never be + ** a valid cursor number, to avoid an initial + ** test for pMaskSet->n==0 in sqlite3WhereGetMask() */ sWLB.pWInfo = pWInfo; sWLB.pWC = &pWInfo->sWC; sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo); @@ -154130,7 +157504,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Split the WHERE clause into separate subexpressions where each ** subexpression is separated by an AND operator. */ - initMaskSet(pMaskSet); sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); @@ -154138,7 +157511,9 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( */ if( nTabList==0 ){ if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr; - if( wctrlFlags & WHERE_WANT_DISTINCT ){ + if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0 + && OptimizationEnabled(db, SQLITE_DistinctOpt) + ){ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; } ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW")); @@ -154176,6 +157551,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( /* Analyze all of the subexpressions. */ sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); + sqlite3WhereAddLimit(&pWInfo->sWC, pLimit); if( db->mallocFailed ) goto whereBeginError; /* Special case: WHERE terms that do not refer to any tables in the join @@ -154189,7 +157565,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** FROM ... WHERE random()>0; -- eval random() once per row ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall */ - for(ii=0; iinTerm; ii++){ + for(ii=0; iinBase; ii++){ WhereTerm *pT = &sWLB.pWC->a[ii]; if( pT->wtFlags & TERM_VIRTUAL ) continue; if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ @@ -154199,7 +157575,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } if( wctrlFlags & WHERE_WANT_DISTINCT ){ - if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ + if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ + /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + wctrlFlags &= ~WHERE_WANT_DISTINCT; + pWInfo->wctrlFlags &= ~WHERE_WANT_DISTINCT; + }else if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){ /* The DISTINCT marking is pointless. Ignore it. */ pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE; }else if( pOrderBy==0 ){ @@ -154270,9 +157651,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = ALLBITS; } - if( pParse->nErr || db->mallocFailed ){ + if( pParse->nErr ){ goto whereBeginError; } + assert( db->mallocFailed==0 ); #ifdef WHERETRACE_ENABLED if( sqlite3WhereTrace ){ sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); @@ -154300,34 +157682,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } #endif - /* Attempt to omit tables from the join that do not affect the result. - ** For a table to not affect the result, the following must be true: + /* Attempt to omit tables from a join that do not affect the result. + ** See the comment on whereOmitNoopJoin() for further information. ** - ** 1) The query must not be an aggregate. - ** 2) The table must be the RHS of a LEFT JOIN. - ** 3) Either the query must be DISTINCT, or else the ON or USING clause - ** must contain a constraint that limits the scan of the table to - ** at most a single row. - ** 4) The table must not be referenced by any part of the query apart - ** from its own USING or ON clause. - ** - ** For example, given: - ** - ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1); - ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2); - ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3); - ** - ** then table t2 can be omitted from the following: - ** - ** SELECT v1, v3 FROM t1 - ** LEFT JOIN t2 ON (t1.ipk=t2.ipk) - ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) - ** - ** or from: - ** - ** SELECT DISTINCT v1, v3 FROM t1 - ** LEFT JOIN t2 - ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) + ** This query optimization is factored out into a separate "no-inline" + ** procedure to keep the sqlite3WhereBegin() procedure from becoming + ** too large. If sqlite3WhereBegin() becomes too large, that prevents + ** some C-compiler optimizers from in-lining the + ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to + ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ notReady = ~(Bitmask)0; if( pWInfo->nLevel>=2 @@ -154335,49 +157698,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */ && OptimizationEnabled(db, SQLITE_OmitNoopJoin) ){ - int i; - Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); - if( sWLB.pOrderBy ){ - tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); - } - for(i=pWInfo->nLevel-1; i>=1; i--){ - WhereTerm *pTerm, *pEnd; - SrcItem *pItem; - pLoop = pWInfo->a[i].pWLoop; - pItem = &pWInfo->pTabList->a[pLoop->iTab]; - if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; - if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 - && (pLoop->wsFlags & WHERE_ONEROW)==0 - ){ - continue; - } - if( (tabUsed & pLoop->maskSelf)!=0 ) continue; - pEnd = sWLB.pWC->a + sWLB.pWC->nTerm; - for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 ){ - if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin) - || pTerm->pExpr->iRightJoinTable!=pItem->iCursor - ){ - break; - } - } - } - if( pTerm drop loop %c not used\n", pLoop->cId)); - notReady &= ~pLoop->maskSelf; - for(pTerm=sWLB.pWC->a; pTermprereqAll & pLoop->maskSelf)!=0 ){ - pTerm->wtFlags |= TERM_CODED; - } - } - if( i!=pWInfo->nLevel-1 ){ - int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel); - memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte); - } - pWInfo->nLevel--; - nTabList--; - } + notReady = whereOmitNoopJoin(pWInfo, notReady); + nTabList = pWInfo->nLevel; + assert( nTabList>0 ); } + + /* Check to see if there are any SEARCH loops that might benefit from + ** using a Bloom filter. + */ + if( pWInfo->nLevel>=2 + && OptimizationEnabled(db, SQLITE_BloomFilter) + ){ + whereCheckIfBloomFilterIsUseful(pWInfo); + } + #if defined(WHERETRACE_ENABLED) if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); @@ -154438,7 +157772,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( pTab = pTabItem->pTab; iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; - if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ + if( (pTab->tabFlags & TF_Ephemeral)!=0 || IsView(pTab) ){ /* Do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -154464,6 +157798,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nColtabFlags & (TF_HasGenerated|TF_WithoutRowid))==0 + && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0 ){ /* If we know that only a prefix of the record will be used, ** it is advantageous to reduce the "column count" field in @@ -154563,15 +157898,20 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( for(ii=0; iinErr ) goto whereBeginError; pLevel = &pWInfo->a[ii]; wsFlags = pLevel->pWLoop->wsFlags; + if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){ + if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){ #ifndef SQLITE_OMIT_AUTOMATIC_INDEX - if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){ - constructAutomaticIndex(pParse, &pWInfo->sWC, - &pTabList->a[pLevel->iFrom], notReady, pLevel); + constructAutomaticIndex(pParse, &pWInfo->sWC, + &pTabList->a[pLevel->iFrom], notReady, pLevel); +#endif + }else{ + sqlite3ConstructBloomFilter(pWInfo, ii, pLevel, notReady); + } if( db->mallocFailed ) goto whereBeginError; } -#endif addrExplain = sqlite3WhereExplainOneScan( pParse, pTabList, pLevel, wctrlFlags ); @@ -154619,6 +157959,26 @@ whereBeginError: } #endif +#ifdef SQLITE_DEBUG +/* +** Return true if cursor iCur is opened by instruction k of the +** bytecode. Used inside of assert() only. +*/ +static int cursorIsOpen(Vdbe *v, int iCur, int k){ + while( k>=0 ){ + VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); + if( pOp->p1!=iCur ) continue; + if( pOp->opcode==OP_Close ) return 0; + if( pOp->opcode==OP_OpenRead ) return 1; + if( pOp->opcode==OP_OpenWrite ) return 1; + if( pOp->opcode==OP_OpenDup ) return 1; + if( pOp->opcode==OP_OpenAutoindex ) return 1; + if( pOp->opcode==OP_OpenEphemeral ) return 1; + } + return 0; +} +#endif /* SQLITE_DEBUG */ + /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -154684,7 +158044,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ }else{ sqlite3VdbeResolveLabel(v, pLevel->addrCont); } - if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ + if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; int j; sqlite3VdbeResolveLabel(v, pLevel->addrNxt); @@ -154753,8 +158113,14 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } if( (ws & WHERE_INDEXED) - || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) + || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx) ){ + if( ws & WHERE_MULTI_OR ){ + Index *pIx = pLevel->u.pCoveringIdx; + int iDb = sqlite3SchemaToIndex(db, pIx->pSchema); + sqlite3VdbeAddOp3(v, OP_ReopenIdx, pLevel->iIdxCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); + } sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); } if( pLevel->op==OP_Return ){ @@ -154801,7 +158167,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** created for the ONEPASS optimization. */ if( (pTab->tabFlags & TF_Ephemeral)==0 - && pTab->pSelect==0 + && !IsView(pTab) && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 ){ int ws = pLoop->wsFlags; @@ -154831,7 +158197,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){ pIdx = pLoop->u.btree.pIndex; }else if( pLoop->wsFlags & WHERE_MULTI_OR ){ - pIdx = pLevel->u.pCovidx; + pIdx = pLevel->u.pCoveringIdx; } if( pIdx && !db->mallocFailed @@ -154865,6 +158231,11 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ){ int x = pOp->p2; assert( pIdx->pTable==pTab ); +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + if( pOp->opcode==OP_Offset ){ + /* Do not need to translate the column number */ + }else +#endif if( !HasRowid(pTab) ){ Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; @@ -154878,9 +158249,22 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; OpcodeRewriteTrace(db, k, pOp); + }else{ + /* Unable to translate the table reference into an index + ** reference. Verify that this is harmless - that the + ** table being referenced really is open. + */ +#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + || pOp->opcode==OP_Offset + ); +#else + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 + || cursorIsOpen(v,pOp->p1,k) + ); +#endif } - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 - || pWInfo->eOnePass ); }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; pOp->opcode = OP_IdxRowid; @@ -155492,7 +158876,7 @@ static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } /* Window functions that use all window interfaces: xStep, xFinal, ** xValue, and xInverse */ #define WINDOWFUNCALL(name,nArg,extra) { \ - nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \ name ## InvFunc, name ## Name, {0} \ } @@ -155500,7 +158884,7 @@ static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } /* Window functions that are implemented using bytecode and thus have ** no-op routines for their methods */ #define WINDOWFUNCNOOP(name,nArg,extra) { \ - nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ noopStepFunc, noopValueFunc, noopValueFunc, \ noopStepFunc, name ## Name, {0} \ } @@ -155509,7 +158893,7 @@ static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } ** same routine for xFinalize and xValue and which never call ** xInverse. */ #define WINDOWFUNCX(name,nArg,extra) { \ - nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ + nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \ name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \ noopStepFunc, name ## Name, {0} \ } @@ -155819,9 +159203,7 @@ static ExprList *exprListAppendList( if( bIntToNull ){ int iDummy; Expr *pSub; - for(pSub=pDup; ExprHasProperty(pSub, EP_Skip); pSub=pSub->pLeft){ - assert( pSub ); - } + pSub = sqlite3ExprSkipCollateAndLikely(pDup); if( sqlite3ExprIsInteger(pSub, &iDummy) ){ pSub->op = TK_NULL; pSub->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); @@ -155854,7 +159236,8 @@ static int sqlite3WindowExtraAggFuncDepth(Walker *pWalker, Expr *pExpr){ static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){ - sqlite3ErrorMsg(pWalker->pParse, + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + sqlite3ErrorMsg(pWalker->pParse, "misuse of aggregate: %s()", pExpr->u.zToken); } return WRC_Continue; @@ -155869,7 +159252,11 @@ static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){ */ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ int rc = SQLITE_OK; - if( p->pWin && p->pPrior==0 && ALWAYS((p->selFlags & SF_WinRewrite)==0) ){ + if( p->pWin + && p->pPrior==0 + && ALWAYS((p->selFlags & SF_WinRewrite)==0) + && ALWAYS(!IN_RENAME_OBJECT) + ){ Vdbe *v = sqlite3GetVdbe(pParse); sqlite3 *db = pParse->db; Select *pSub = 0; /* The subquery */ @@ -155942,7 +159329,10 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ ** window function - one for the accumulator, another for interim ** results. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - ExprList *pArgs = pWin->pOwner->x.pList; + ExprList *pArgs; + assert( ExprUseXList(pWin->pOwner) ); + assert( pWin->pFunc!=0 ); + pArgs = pWin->pOwner->x.pList; if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); @@ -155979,11 +159369,14 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ ("New window-function subquery in FROM clause of (%u/%p)\n", p->selId, p)); p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); + assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside + ** of sqlite3DbMallocRawNN() called from + ** sqlite3SrcListAppend() */ if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; sqlite3SrcListAssignCursors(pParse, p->pSrc); - pSub->selFlags |= SF_Expanded; + pSub->selFlags |= SF_Expanded|SF_OrderByReqd; pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); pSub->selFlags |= (selFlags & SF_Aggregate); if( pTab2==0 ){ @@ -156006,15 +159399,14 @@ SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; - sqlite3DbFree(db, pTab); + + /* Defer deleting the temporary table pTab because if an error occurred, + ** there could still be references to that table embedded in the + ** result-set or ORDER BY clause of the SELECT statement p. */ + sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab); } - if( rc ){ - if( pParse->nErr==0 ){ - assert( pParse->db->mallocFailed ); - sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); - } - } + assert( rc==SQLITE_OK || pParse->nErr!=0 ); return rc; } @@ -156255,7 +159647,12 @@ SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin){ ** different, or 2 if it cannot be determined if the objects are identical ** or not. Identical window objects can be processed in a single scan. */ -SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){ +SQLITE_PRIVATE int sqlite3WindowCompare( + const Parse *pParse, + const Window *p1, + const Window *p2, + int bFilter +){ int res; if( NEVER(p1==0) || NEVER(p2==0) ) return 1; if( p1->eFrmType!=p2->eFrmType ) return 1; @@ -156327,8 +159724,11 @@ SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ ** regApp+1: integer value used to ensure keys are unique ** regApp+2: output of MakeRecord */ - ExprList *pList = pWin->pOwner->x.pList; - KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); + ExprList *pList; + KeyInfo *pKeyInfo; + assert( ExprUseXList(pWin->pOwner) ); + pList = pWin->pOwner->x.pList; + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); pWin->csrApp = pParse->nTab++; pWin->regApp = pParse->nMem+1; pParse->nMem += 3; @@ -156416,7 +159816,9 @@ static void windowCheckValue(Parse *pParse, int reg, int eCond){ ** with the object passed as the only argument to this function. */ static int windowArgCount(Window *pWin){ - ExprList *pList = pWin->pOwner->x.pList; + const ExprList *pList; + assert( ExprUseXList(pWin->pOwner) ); + pList = pWin->pOwner->x.pList; return (pList ? pList->nExpr : 0); } @@ -156601,6 +160003,7 @@ static void windowAggStep( int addrIf = 0; if( pWin->pFilter ){ int regTmp; + assert( ExprUseXList(pWin->pOwner) ); assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); regTmp = sqlite3GetTempReg(pParse); @@ -156614,13 +160017,14 @@ static void windowAggStep( int iOp = sqlite3VdbeCurrentAddr(v); int iEnd; + assert( ExprUseXList(pWin->pOwner) ); nArg = pWin->pOwner->x.pList->nExpr; regArg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); for(iEnd=sqlite3VdbeCurrentAddr(v); iOpopcode==OP_Column && pOp->p1==pWin->iEphCsr ){ + if( pOp->opcode==OP_Column && pOp->p1==pMWin->iEphCsr ){ pOp->p1 = csr; } } @@ -156628,6 +160032,7 @@ static void windowAggStep( if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl; assert( nArg>0 ); + assert( ExprUseXList(pWin->pOwner) ); pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); } @@ -156813,6 +160218,7 @@ static void windowReturnOneRow(WindowCodeArg *p){ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; + assert( ExprUseXList(pWin->pOwner) ); if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){ @@ -158148,10 +161554,7 @@ static void updateDeleteLimitError( } - /* Construct a new Expr object from a single identifier. Use the - ** new Expr to populate pOut. Set the span of pOut to be the identifier - ** that created the expression. - */ + /* Construct a new Expr object from a single token */ static Expr *tokenExpr(Parse *pParse, int op, Token t){ Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ @@ -158162,15 +161565,16 @@ static void updateDeleteLimitError( ExprClearVVAProperties(p); p->iAgg = -1; p->pLeft = p->pRight = 0; - p->x.pList = 0; p->pAggInfo = 0; - p->y.pTab = 0; + memset(&p->x, 0, sizeof(p->x)); + memset(&p->y, 0, sizeof(p->y)); p->op2 = 0; p->iTable = 0; p->iColumn = 0; p->u.zToken = (char*)&p[1]; memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; + p->w.iOfst = (int)(t.z - pParse->zTail); if( sqlite3Isquote(p->u.zToken[0]) ){ sqlite3DequoteExpr(p); } @@ -158250,8 +161654,8 @@ static void updateDeleteLimitError( #define TK_LP 22 #define TK_RP 23 #define TK_AS 24 -#define TK_WITHOUT 25 -#define TK_COMMA 26 +#define TK_COMMA 25 +#define TK_WITHOUT 26 #define TK_ABORT 27 #define TK_ACTION 28 #define TK_AFTER 29 @@ -158337,78 +161741,79 @@ static void updateDeleteLimitError( #define TK_SLASH 109 #define TK_REM 110 #define TK_CONCAT 111 -#define TK_COLLATE 112 -#define TK_BITNOT 113 -#define TK_ON 114 -#define TK_INDEXED 115 -#define TK_STRING 116 -#define TK_JOIN_KW 117 -#define TK_CONSTRAINT 118 -#define TK_DEFAULT 119 -#define TK_NULL 120 -#define TK_PRIMARY 121 -#define TK_UNIQUE 122 -#define TK_CHECK 123 -#define TK_REFERENCES 124 -#define TK_AUTOINCR 125 -#define TK_INSERT 126 -#define TK_DELETE 127 -#define TK_UPDATE 128 -#define TK_SET 129 -#define TK_DEFERRABLE 130 -#define TK_FOREIGN 131 -#define TK_DROP 132 -#define TK_UNION 133 -#define TK_ALL 134 -#define TK_EXCEPT 135 -#define TK_INTERSECT 136 -#define TK_SELECT 137 -#define TK_VALUES 138 -#define TK_DISTINCT 139 -#define TK_DOT 140 -#define TK_FROM 141 -#define TK_JOIN 142 -#define TK_USING 143 -#define TK_ORDER 144 -#define TK_GROUP 145 -#define TK_HAVING 146 -#define TK_LIMIT 147 -#define TK_WHERE 148 -#define TK_RETURNING 149 -#define TK_INTO 150 -#define TK_NOTHING 151 -#define TK_FLOAT 152 -#define TK_BLOB 153 -#define TK_INTEGER 154 -#define TK_VARIABLE 155 -#define TK_CASE 156 -#define TK_WHEN 157 -#define TK_THEN 158 -#define TK_ELSE 159 -#define TK_INDEX 160 -#define TK_ALTER 161 -#define TK_ADD 162 -#define TK_WINDOW 163 -#define TK_OVER 164 -#define TK_FILTER 165 -#define TK_COLUMN 166 -#define TK_AGG_FUNCTION 167 -#define TK_AGG_COLUMN 168 -#define TK_TRUEFALSE 169 -#define TK_ISNOT 170 -#define TK_FUNCTION 171 -#define TK_UMINUS 172 -#define TK_UPLUS 173 -#define TK_TRUTH 174 -#define TK_REGISTER 175 -#define TK_VECTOR 176 -#define TK_SELECT_COLUMN 177 -#define TK_IF_NULL_ROW 178 -#define TK_ASTERISK 179 -#define TK_SPAN 180 -#define TK_ERROR 181 -#define TK_SPACE 182 -#define TK_ILLEGAL 183 +#define TK_PTR 112 +#define TK_COLLATE 113 +#define TK_BITNOT 114 +#define TK_ON 115 +#define TK_INDEXED 116 +#define TK_STRING 117 +#define TK_JOIN_KW 118 +#define TK_CONSTRAINT 119 +#define TK_DEFAULT 120 +#define TK_NULL 121 +#define TK_PRIMARY 122 +#define TK_UNIQUE 123 +#define TK_CHECK 124 +#define TK_REFERENCES 125 +#define TK_AUTOINCR 126 +#define TK_INSERT 127 +#define TK_DELETE 128 +#define TK_UPDATE 129 +#define TK_SET 130 +#define TK_DEFERRABLE 131 +#define TK_FOREIGN 132 +#define TK_DROP 133 +#define TK_UNION 134 +#define TK_ALL 135 +#define TK_EXCEPT 136 +#define TK_INTERSECT 137 +#define TK_SELECT 138 +#define TK_VALUES 139 +#define TK_DISTINCT 140 +#define TK_DOT 141 +#define TK_FROM 142 +#define TK_JOIN 143 +#define TK_USING 144 +#define TK_ORDER 145 +#define TK_GROUP 146 +#define TK_HAVING 147 +#define TK_LIMIT 148 +#define TK_WHERE 149 +#define TK_RETURNING 150 +#define TK_INTO 151 +#define TK_NOTHING 152 +#define TK_FLOAT 153 +#define TK_BLOB 154 +#define TK_INTEGER 155 +#define TK_VARIABLE 156 +#define TK_CASE 157 +#define TK_WHEN 158 +#define TK_THEN 159 +#define TK_ELSE 160 +#define TK_INDEX 161 +#define TK_ALTER 162 +#define TK_ADD 163 +#define TK_WINDOW 164 +#define TK_OVER 165 +#define TK_FILTER 166 +#define TK_COLUMN 167 +#define TK_AGG_FUNCTION 168 +#define TK_AGG_COLUMN 169 +#define TK_TRUEFALSE 170 +#define TK_ISNOT 171 +#define TK_FUNCTION 172 +#define TK_UMINUS 173 +#define TK_UPLUS 174 +#define TK_TRUTH 175 +#define TK_REGISTER 176 +#define TK_VECTOR 177 +#define TK_SELECT_COLUMN 178 +#define TK_IF_NULL_ROW 179 +#define TK_ASTERISK 180 +#define TK_SPAN 181 +#define TK_ERROR 182 +#define TK_SPACE 183 +#define TK_ILLEGAL 184 #endif /**************** End token definitions ***************************************/ @@ -158468,29 +161873,30 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 317 +#define YYNOCODE 319 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 101 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - Window* yy49; - ExprList* yy70; - Select* yy81; - With* yy103; - struct FrameBound yy117; - struct {int value; int mask;} yy139; - SrcList* yy153; - TriggerStep* yy157; - Upsert* yy190; - struct TrigEvent yy262; - Cte* yy329; - int yy376; - Expr* yy404; - IdList* yy436; - const char* yy504; - u8 yy552; + TriggerStep* yy33; + Window* yy41; + Select* yy47; + SrcList* yy131; + struct TrigEvent yy180; + struct {int value; int mask;} yy231; + IdList* yy254; + u32 yy285; + ExprList* yy322; + Cte* yy385; + int yy394; + Upsert* yy444; + u8 yy516; + With* yy521; + const char* yy522; + Expr* yy528; + struct FrameBound yy595; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -158506,18 +161912,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 570 -#define YYNRULE 398 -#define YYNRULE_WITH_ACTION 337 -#define YYNTOKEN 184 -#define YY_MAX_SHIFT 569 -#define YY_MIN_SHIFTREDUCE 825 -#define YY_MAX_SHIFTREDUCE 1222 -#define YY_ERROR_ACTION 1223 -#define YY_ACCEPT_ACTION 1224 -#define YY_NO_ACTION 1225 -#define YY_MIN_REDUCE 1226 -#define YY_MAX_REDUCE 1623 +#define YYNSTATE 574 +#define YYNRULE 402 +#define YYNRULE_WITH_ACTION 340 +#define YYNTOKEN 185 +#define YY_MAX_SHIFT 573 +#define YY_MIN_SHIFTREDUCE 831 +#define YY_MAX_SHIFTREDUCE 1232 +#define YY_ERROR_ACTION 1233 +#define YY_ACCEPT_ACTION 1234 +#define YY_NO_ACTION 1235 +#define YY_MIN_REDUCE 1236 +#define YY_MAX_REDUCE 1637 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -158584,601 +161990,612 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2023) +#define YY_ACTTAB_COUNT (2070) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 563, 1295, 563, 1274, 168, 1257, 115, 112, 218, 373, - /* 10 */ 563, 1295, 374, 563, 488, 563, 115, 112, 218, 406, - /* 20 */ 1300, 1300, 41, 41, 41, 41, 514, 1504, 520, 1298, - /* 30 */ 1298, 959, 41, 41, 1260, 71, 71, 51, 51, 960, - /* 40 */ 557, 557, 557, 122, 123, 113, 1200, 1200, 1035, 1038, - /* 50 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 414, 406, - /* 60 */ 273, 273, 273, 273, 115, 112, 218, 115, 112, 218, - /* 70 */ 197, 268, 545, 560, 515, 560, 211, 563, 385, 248, - /* 80 */ 215, 521, 399, 122, 123, 113, 1200, 1200, 1035, 1038, - /* 90 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 540, 13, - /* 100 */ 13, 1259, 119, 119, 119, 119, 118, 118, 117, 117, - /* 110 */ 117, 116, 441, 1176, 419, 197, 446, 320, 512, 1539, - /* 120 */ 1545, 372, 1547, 6, 371, 1176, 1148, 394, 1148, 406, - /* 130 */ 1545, 534, 115, 112, 218, 1415, 99, 30, 121, 121, - /* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117, - /* 150 */ 117, 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, - /* 160 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 31, 1176, - /* 170 */ 1177, 1178, 241, 357, 1558, 501, 498, 497, 317, 124, - /* 180 */ 319, 1176, 1177, 1178, 1176, 496, 119, 119, 119, 119, - /* 190 */ 118, 118, 117, 117, 117, 116, 441, 139, 96, 406, - /* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 441, - /* 210 */ 541, 1532, 119, 119, 119, 119, 118, 118, 117, 117, - /* 220 */ 117, 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, - /* 230 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 406, 441, - /* 240 */ 1176, 1177, 1178, 81, 439, 439, 439, 80, 119, 119, - /* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 488, - /* 260 */ 1176, 318, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, - /* 270 */ 1028, 120, 120, 121, 121, 121, 121, 493, 1025, 1025, - /* 280 */ 1036, 1039, 119, 119, 119, 119, 118, 118, 117, 117, - /* 290 */ 117, 116, 441, 1584, 995, 1224, 1, 1, 569, 2, - /* 300 */ 1228, 1267, 137, 1503, 245, 305, 473, 140, 406, 860, - /* 310 */ 561, 1176, 914, 914, 1308, 359, 1176, 1177, 1178, 462, - /* 320 */ 330, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 330 */ 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, - /* 340 */ 1028, 120, 120, 121, 121, 121, 121, 328, 273, 273, - /* 350 */ 1015, 83, 1029, 425, 1564, 569, 2, 1228, 304, 554, - /* 360 */ 925, 560, 305, 944, 140, 860, 1006, 1176, 1177, 1178, - /* 370 */ 1005, 1308, 411, 213, 511, 229, 119, 119, 119, 119, - /* 380 */ 118, 118, 117, 117, 117, 116, 441, 519, 347, 116, - /* 390 */ 441, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 400 */ 116, 441, 1005, 1005, 1007, 273, 273, 445, 563, 16, - /* 410 */ 16, 1590, 563, 1540, 563, 406, 1176, 6, 560, 344, - /* 420 */ 182, 118, 118, 117, 117, 117, 116, 441, 416, 142, - /* 430 */ 71, 71, 229, 563, 71, 71, 55, 55, 203, 122, - /* 440 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, - /* 450 */ 121, 121, 121, 121, 217, 13, 13, 1176, 406, 568, - /* 460 */ 1400, 1228, 502, 137, 445, 168, 305, 545, 140, 1180, - /* 470 */ 424, 545, 1176, 1177, 1178, 1308, 544, 438, 437, 944, - /* 480 */ 513, 452, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, - /* 490 */ 1028, 120, 120, 121, 121, 121, 121, 315, 119, 119, - /* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 273, - /* 510 */ 273, 1143, 416, 1176, 1177, 1178, 543, 563, 1143, 304, - /* 520 */ 554, 1561, 560, 1207, 1143, 1207, 1180, 1143, 406, 530, - /* 530 */ 421, 1143, 864, 183, 1143, 143, 229, 562, 32, 71, - /* 540 */ 71, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 550 */ 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, - /* 560 */ 1028, 120, 120, 121, 121, 121, 121, 406, 445, 241, - /* 570 */ 1176, 857, 501, 498, 497, 1176, 526, 189, 245, 538, - /* 580 */ 1539, 282, 496, 370, 6, 563, 529, 477, 5, 279, - /* 590 */ 1015, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, - /* 600 */ 120, 120, 121, 121, 121, 121, 1006, 13, 13, 1414, - /* 610 */ 1005, 119, 119, 119, 119, 118, 118, 117, 117, 117, - /* 620 */ 116, 441, 426, 273, 273, 1176, 1176, 1177, 1178, 1619, - /* 630 */ 392, 1176, 1177, 1178, 1176, 342, 560, 406, 525, 361, - /* 640 */ 430, 1161, 1005, 1005, 1007, 348, 411, 357, 1558, 488, - /* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, - /* 660 */ 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, - /* 670 */ 120, 120, 121, 121, 121, 121, 406, 830, 831, 832, - /* 680 */ 1016, 1176, 1177, 1178, 396, 285, 148, 1312, 304, 554, - /* 690 */ 1176, 1177, 1178, 1467, 216, 3, 337, 137, 340, 560, - /* 700 */ 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, - /* 710 */ 120, 121, 121, 121, 121, 563, 504, 946, 273, 273, - /* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, - /* 730 */ 441, 560, 1176, 427, 563, 451, 98, 13, 13, 259, - /* 740 */ 276, 356, 507, 351, 506, 246, 406, 361, 469, 1530, - /* 750 */ 1000, 347, 293, 304, 554, 1589, 71, 71, 889, 119, - /* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 441, - /* 770 */ 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, - /* 780 */ 120, 121, 121, 121, 121, 406, 1143, 1078, 1176, 1177, - /* 790 */ 1178, 416, 1080, 300, 150, 995, 1080, 361, 361, 1143, - /* 800 */ 361, 378, 1143, 477, 563, 244, 243, 242, 1278, 122, - /* 810 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, - /* 820 */ 121, 121, 121, 121, 563, 880, 13, 13, 483, 119, - /* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 441, - /* 840 */ 1176, 191, 540, 563, 147, 149, 13, 13, 328, 457, - /* 850 */ 316, 1083, 1083, 485, 1537, 406, 505, 1530, 6, 1514, - /* 860 */ 284, 192, 1277, 145, 881, 71, 71, 488, 119, 119, - /* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 122, - /* 880 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, - /* 890 */ 121, 121, 121, 121, 563, 471, 1176, 1177, 1178, 406, - /* 900 */ 852, 327, 301, 462, 330, 1516, 270, 1530, 1530, 944, - /* 910 */ 1531, 1307, 313, 9, 842, 251, 71, 71, 477, 428, - /* 920 */ 146, 488, 38, 945, 101, 113, 1200, 1200, 1035, 1038, - /* 930 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 119, 119, - /* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 563, - /* 950 */ 1197, 1099, 563, 436, 563, 1533, 563, 852, 1122, 1617, - /* 960 */ 454, 290, 1617, 546, 251, 1303, 1100, 267, 267, 281, - /* 970 */ 404, 70, 70, 460, 71, 71, 71, 71, 13, 13, - /* 980 */ 560, 1101, 119, 119, 119, 119, 118, 118, 117, 117, - /* 990 */ 117, 116, 441, 542, 104, 273, 273, 273, 273, 1197, - /* 1000 */ 217, 1468, 900, 471, 450, 563, 1473, 1197, 560, 447, - /* 1010 */ 560, 545, 901, 440, 406, 1058, 292, 274, 274, 198, - /* 1020 */ 547, 450, 449, 1473, 1475, 944, 455, 56, 56, 410, - /* 1030 */ 560, 1122, 1618, 379, 406, 1618, 404, 1120, 122, 123, - /* 1040 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, - /* 1050 */ 121, 121, 121, 1460, 406, 12, 1197, 1512, 122, 123, - /* 1060 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, - /* 1070 */ 121, 121, 121, 308, 471, 126, 359, 286, 122, 111, - /* 1080 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, - /* 1090 */ 121, 121, 121, 309, 450, 471, 1473, 119, 119, 119, - /* 1100 */ 119, 118, 118, 117, 117, 117, 116, 441, 1176, 563, - /* 1110 */ 1120, 482, 563, 312, 433, 479, 197, 119, 119, 119, - /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 441, 405, 12, - /* 1130 */ 536, 15, 15, 478, 43, 43, 509, 119, 119, 119, - /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 441, 289, 535, - /* 1150 */ 294, 563, 294, 391, 1220, 438, 437, 406, 1154, 403, - /* 1160 */ 402, 1400, 920, 1204, 1176, 1177, 1178, 919, 1206, 291, - /* 1170 */ 1306, 1249, 412, 57, 57, 488, 1205, 563, 556, 412, - /* 1180 */ 1176, 1344, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, - /* 1190 */ 120, 120, 121, 121, 121, 121, 1400, 1143, 563, 44, - /* 1200 */ 44, 1207, 194, 1207, 273, 273, 1400, 461, 537, 1154, - /* 1210 */ 1143, 108, 555, 1143, 4, 391, 1121, 560, 1538, 335, - /* 1220 */ 58, 58, 6, 1246, 1099, 380, 1400, 376, 558, 1536, - /* 1230 */ 563, 422, 1221, 6, 304, 554, 1176, 1177, 1178, 1100, - /* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, - /* 1250 */ 441, 442, 59, 59, 1101, 516, 1535, 273, 273, 563, - /* 1260 */ 6, 563, 110, 552, 563, 528, 423, 413, 169, 548, - /* 1270 */ 560, 108, 555, 137, 4, 551, 484, 272, 215, 222, - /* 1280 */ 211, 60, 60, 61, 61, 98, 62, 62, 558, 273, - /* 1290 */ 273, 563, 1015, 467, 1221, 563, 434, 563, 106, 106, - /* 1300 */ 8, 920, 560, 273, 273, 107, 919, 442, 565, 564, - /* 1310 */ 563, 442, 1005, 45, 45, 464, 560, 46, 46, 47, - /* 1320 */ 47, 84, 202, 552, 1215, 404, 468, 563, 205, 304, - /* 1330 */ 554, 563, 49, 49, 563, 522, 404, 532, 563, 867, - /* 1340 */ 563, 105, 531, 103, 1005, 1005, 1007, 1008, 27, 50, - /* 1350 */ 50, 563, 1015, 63, 63, 475, 64, 64, 106, 106, - /* 1360 */ 65, 65, 14, 14, 17, 107, 563, 442, 565, 564, - /* 1370 */ 563, 303, 1005, 66, 66, 563, 226, 563, 959, 563, - /* 1380 */ 543, 404, 1196, 1343, 871, 278, 960, 456, 128, 128, - /* 1390 */ 563, 1065, 67, 67, 563, 206, 867, 52, 52, 68, - /* 1400 */ 68, 69, 69, 417, 1005, 1005, 1007, 1008, 27, 1563, - /* 1410 */ 1165, 444, 53, 53, 277, 1519, 156, 156, 307, 389, - /* 1420 */ 389, 388, 262, 386, 1165, 444, 839, 321, 277, 108, - /* 1430 */ 555, 523, 4, 389, 389, 388, 262, 386, 563, 223, - /* 1440 */ 839, 311, 326, 1492, 1117, 98, 558, 393, 1065, 310, - /* 1450 */ 563, 476, 563, 223, 563, 311, 879, 878, 1009, 277, - /* 1460 */ 157, 157, 463, 310, 389, 389, 388, 262, 386, 442, - /* 1470 */ 518, 839, 76, 76, 54, 54, 72, 72, 355, 225, - /* 1480 */ 563, 552, 275, 563, 223, 325, 311, 161, 354, 465, - /* 1490 */ 135, 563, 228, 225, 310, 532, 563, 206, 886, 887, - /* 1500 */ 533, 161, 129, 129, 135, 73, 73, 224, 962, 963, - /* 1510 */ 1015, 563, 287, 130, 130, 1009, 106, 106, 131, 131, - /* 1520 */ 563, 224, 563, 107, 225, 442, 565, 564, 997, 1276, - /* 1530 */ 1005, 250, 161, 127, 127, 135, 108, 555, 1077, 4, - /* 1540 */ 1077, 407, 155, 155, 154, 154, 304, 554, 1126, 563, - /* 1550 */ 1331, 563, 224, 558, 470, 407, 563, 250, 563, 1491, - /* 1560 */ 304, 554, 1005, 1005, 1007, 1008, 27, 563, 480, 332, - /* 1570 */ 448, 136, 136, 134, 134, 1340, 442, 336, 132, 132, - /* 1580 */ 133, 133, 563, 1076, 448, 1076, 407, 563, 552, 75, - /* 1590 */ 75, 304, 554, 339, 341, 343, 108, 555, 563, 4, - /* 1600 */ 1577, 299, 532, 563, 77, 77, 1291, 531, 472, 74, - /* 1610 */ 74, 250, 1275, 558, 350, 448, 331, 1015, 360, 98, - /* 1620 */ 42, 42, 1352, 106, 106, 48, 48, 1399, 494, 1327, - /* 1630 */ 107, 247, 442, 565, 564, 345, 442, 1005, 98, 1061, - /* 1640 */ 953, 917, 247, 250, 110, 1552, 550, 850, 552, 918, - /* 1650 */ 144, 1338, 110, 549, 1405, 1256, 1248, 1237, 1236, 1238, - /* 1660 */ 1571, 1324, 208, 390, 489, 265, 363, 200, 365, 1005, - /* 1670 */ 1005, 1007, 1008, 27, 11, 280, 221, 1015, 323, 474, - /* 1680 */ 1274, 367, 212, 106, 106, 924, 1386, 324, 288, 1381, - /* 1690 */ 107, 453, 442, 565, 564, 283, 329, 1005, 1391, 499, - /* 1700 */ 353, 1374, 1464, 108, 555, 1463, 4, 1574, 1390, 397, - /* 1710 */ 1215, 171, 254, 369, 383, 207, 195, 196, 1511, 553, - /* 1720 */ 558, 1509, 415, 1212, 100, 555, 83, 4, 204, 1005, - /* 1730 */ 1005, 1007, 1008, 27, 180, 166, 173, 219, 79, 82, - /* 1740 */ 458, 558, 175, 442, 35, 1387, 176, 459, 177, 178, - /* 1750 */ 492, 231, 96, 1469, 395, 552, 1393, 1392, 36, 466, - /* 1760 */ 1395, 184, 398, 481, 442, 1458, 235, 89, 1480, 487, - /* 1770 */ 266, 334, 237, 188, 490, 400, 552, 338, 238, 508, - /* 1780 */ 1239, 239, 1294, 1293, 1015, 1292, 1285, 429, 91, 871, - /* 1790 */ 106, 106, 1588, 213, 401, 1587, 431, 107, 1264, 442, - /* 1800 */ 565, 564, 1263, 352, 1005, 1015, 1262, 1586, 1557, 517, - /* 1810 */ 432, 106, 106, 1284, 297, 298, 358, 524, 107, 1335, - /* 1820 */ 442, 565, 564, 95, 1336, 1005, 252, 253, 435, 125, - /* 1830 */ 543, 1543, 10, 1444, 377, 1542, 1005, 1005, 1007, 1008, - /* 1840 */ 27, 97, 527, 375, 362, 102, 260, 364, 381, 1317, - /* 1850 */ 382, 1334, 366, 1245, 1333, 1316, 368, 1005, 1005, 1007, - /* 1860 */ 1008, 27, 1359, 1358, 34, 199, 1171, 566, 261, 263, - /* 1870 */ 264, 567, 1234, 158, 1229, 141, 295, 159, 1496, 302, - /* 1880 */ 1497, 1495, 1494, 160, 826, 209, 443, 201, 306, 210, - /* 1890 */ 78, 220, 1075, 138, 1073, 314, 162, 172, 1196, 227, - /* 1900 */ 174, 903, 322, 230, 1089, 179, 163, 164, 418, 408, - /* 1910 */ 409, 170, 181, 85, 86, 420, 87, 165, 1092, 88, - /* 1920 */ 233, 232, 1088, 151, 18, 234, 1081, 250, 333, 1209, - /* 1930 */ 185, 486, 236, 186, 37, 841, 491, 354, 240, 346, - /* 1940 */ 495, 187, 90, 869, 19, 20, 500, 503, 349, 92, - /* 1950 */ 167, 152, 296, 882, 93, 510, 94, 1159, 153, 1041, - /* 1960 */ 1128, 39, 214, 269, 1127, 271, 249, 952, 190, 947, - /* 1970 */ 110, 1149, 21, 7, 1153, 22, 1145, 23, 1147, 24, - /* 1980 */ 1133, 25, 1152, 33, 539, 193, 26, 1056, 98, 1042, - /* 1990 */ 1040, 1044, 1098, 1045, 1097, 256, 255, 28, 40, 257, - /* 2000 */ 1010, 851, 109, 29, 913, 559, 384, 387, 258, 1167, - /* 2010 */ 1166, 1225, 1225, 1225, 1579, 1225, 1225, 1225, 1225, 1225, - /* 2020 */ 1225, 1225, 1578, + /* 0 */ 566, 1307, 566, 1286, 201, 201, 566, 116, 112, 222, + /* 10 */ 566, 1307, 377, 566, 116, 112, 222, 397, 408, 409, + /* 20 */ 1260, 378, 1269, 41, 41, 41, 41, 1412, 1517, 71, + /* 30 */ 71, 967, 1258, 41, 41, 491, 71, 71, 272, 968, + /* 40 */ 298, 476, 298, 123, 124, 114, 1210, 1210, 1044, 1047, + /* 50 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 543, 409, + /* 60 */ 1234, 1, 1, 573, 2, 1238, 548, 116, 112, 222, + /* 70 */ 309, 480, 142, 548, 1272, 524, 116, 112, 222, 1320, + /* 80 */ 417, 523, 547, 123, 124, 114, 1210, 1210, 1044, 1047, + /* 90 */ 1036, 1036, 121, 121, 122, 122, 122, 122, 424, 116, + /* 100 */ 112, 222, 120, 120, 120, 120, 119, 119, 118, 118, + /* 110 */ 118, 117, 113, 444, 277, 277, 277, 277, 560, 560, + /* 120 */ 560, 1558, 376, 1560, 1186, 375, 1157, 563, 1157, 563, + /* 130 */ 409, 1558, 537, 252, 219, 1553, 99, 141, 449, 6, + /* 140 */ 365, 233, 120, 120, 120, 120, 119, 119, 118, 118, + /* 150 */ 118, 117, 113, 444, 123, 124, 114, 1210, 1210, 1044, + /* 160 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 138, + /* 170 */ 289, 1186, 1546, 448, 118, 118, 118, 117, 113, 444, + /* 180 */ 125, 1186, 1187, 1188, 144, 465, 334, 566, 150, 127, + /* 190 */ 444, 122, 122, 122, 122, 115, 120, 120, 120, 120, + /* 200 */ 119, 119, 118, 118, 118, 117, 113, 444, 454, 419, + /* 210 */ 13, 13, 215, 120, 120, 120, 120, 119, 119, 118, + /* 220 */ 118, 118, 117, 113, 444, 422, 308, 557, 1186, 1187, + /* 230 */ 1188, 441, 440, 409, 1271, 122, 122, 122, 122, 120, + /* 240 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113, + /* 250 */ 444, 1543, 98, 1033, 1033, 1045, 1048, 123, 124, 114, + /* 260 */ 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, + /* 270 */ 122, 122, 566, 406, 405, 1186, 566, 409, 1217, 319, + /* 280 */ 1217, 80, 81, 120, 120, 120, 120, 119, 119, 118, + /* 290 */ 118, 118, 117, 113, 444, 70, 70, 1186, 1604, 71, + /* 300 */ 71, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, + /* 310 */ 121, 121, 122, 122, 122, 122, 120, 120, 120, 120, + /* 320 */ 119, 119, 118, 118, 118, 117, 113, 444, 1037, 210, + /* 330 */ 1186, 365, 1186, 1187, 1188, 245, 548, 399, 504, 501, + /* 340 */ 500, 108, 558, 138, 4, 516, 933, 433, 499, 217, + /* 350 */ 514, 522, 352, 879, 1186, 1187, 1188, 383, 561, 566, + /* 360 */ 120, 120, 120, 120, 119, 119, 118, 118, 118, 117, + /* 370 */ 113, 444, 277, 277, 16, 16, 1598, 441, 440, 153, + /* 380 */ 409, 445, 13, 13, 1279, 563, 1214, 1186, 1187, 1188, + /* 390 */ 1003, 1216, 264, 555, 1574, 186, 566, 427, 138, 1215, + /* 400 */ 308, 557, 472, 138, 123, 124, 114, 1210, 1210, 1044, + /* 410 */ 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, 55, + /* 420 */ 55, 413, 1023, 507, 1217, 1186, 1217, 474, 106, 106, + /* 430 */ 1312, 1312, 1186, 171, 566, 384, 107, 380, 445, 568, + /* 440 */ 567, 430, 1543, 1013, 332, 549, 565, 263, 280, 360, + /* 450 */ 510, 355, 509, 250, 491, 308, 557, 71, 71, 351, + /* 460 */ 308, 557, 374, 120, 120, 120, 120, 119, 119, 118, + /* 470 */ 118, 118, 117, 113, 444, 1013, 1013, 1015, 1016, 27, + /* 480 */ 277, 277, 1186, 1187, 1188, 1152, 566, 528, 409, 1186, + /* 490 */ 1187, 1188, 348, 563, 548, 1260, 533, 517, 1152, 1516, + /* 500 */ 317, 1152, 285, 550, 485, 569, 566, 569, 482, 51, + /* 510 */ 51, 207, 123, 124, 114, 1210, 1210, 1044, 1047, 1036, + /* 520 */ 1036, 121, 121, 122, 122, 122, 122, 171, 1412, 13, + /* 530 */ 13, 409, 277, 277, 1186, 505, 119, 119, 118, 118, + /* 540 */ 118, 117, 113, 444, 429, 563, 518, 220, 515, 1552, + /* 550 */ 365, 546, 1186, 6, 532, 123, 124, 114, 1210, 1210, + /* 560 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 570 */ 145, 120, 120, 120, 120, 119, 119, 118, 118, 118, + /* 580 */ 117, 113, 444, 245, 566, 474, 504, 501, 500, 566, + /* 590 */ 1481, 1186, 1187, 1188, 1310, 1310, 499, 1186, 149, 425, + /* 600 */ 1186, 480, 409, 274, 365, 952, 872, 56, 56, 1186, + /* 610 */ 1187, 1188, 71, 71, 120, 120, 120, 120, 119, 119, + /* 620 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 630 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 640 */ 122, 409, 541, 1552, 83, 865, 98, 6, 928, 529, + /* 650 */ 848, 543, 151, 927, 1186, 1187, 1188, 1186, 1187, 1188, + /* 660 */ 290, 1543, 187, 1633, 395, 123, 124, 114, 1210, 1210, + /* 670 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 680 */ 566, 954, 566, 453, 953, 120, 120, 120, 120, 119, + /* 690 */ 119, 118, 118, 118, 117, 113, 444, 1152, 221, 1186, + /* 700 */ 331, 453, 452, 13, 13, 13, 13, 1003, 365, 463, + /* 710 */ 1152, 193, 409, 1152, 382, 1543, 1170, 32, 297, 474, + /* 720 */ 195, 1527, 5, 952, 120, 120, 120, 120, 119, 119, + /* 730 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 740 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 750 */ 122, 409, 1067, 419, 1186, 1024, 1186, 1187, 1188, 1186, + /* 760 */ 419, 332, 460, 320, 544, 1545, 442, 442, 442, 566, + /* 770 */ 3, 117, 113, 444, 453, 123, 124, 114, 1210, 1210, + /* 780 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 790 */ 1473, 566, 15, 15, 293, 120, 120, 120, 120, 119, + /* 800 */ 119, 118, 118, 118, 117, 113, 444, 1186, 566, 1486, + /* 810 */ 1412, 1186, 1187, 1188, 13, 13, 1186, 1187, 1188, 1544, + /* 820 */ 271, 271, 409, 286, 308, 557, 1008, 1486, 1488, 196, + /* 830 */ 288, 71, 71, 563, 120, 120, 120, 120, 119, 119, + /* 840 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 850 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 860 */ 122, 409, 201, 1087, 1186, 1187, 1188, 1324, 304, 1529, + /* 870 */ 388, 278, 278, 450, 564, 402, 922, 922, 566, 563, + /* 880 */ 566, 426, 491, 480, 563, 123, 124, 114, 1210, 1210, + /* 890 */ 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, 122, + /* 900 */ 1486, 71, 71, 13, 13, 120, 120, 120, 120, 119, + /* 910 */ 119, 118, 118, 118, 117, 113, 444, 566, 545, 566, + /* 920 */ 1577, 573, 2, 1238, 1092, 1092, 488, 1480, 309, 1525, + /* 930 */ 142, 324, 409, 836, 837, 838, 312, 1320, 305, 363, + /* 940 */ 43, 43, 57, 57, 120, 120, 120, 120, 119, 119, + /* 950 */ 118, 118, 118, 117, 113, 444, 123, 124, 114, 1210, + /* 960 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 970 */ 122, 12, 277, 277, 566, 1152, 409, 572, 428, 1238, + /* 980 */ 465, 334, 296, 474, 309, 563, 142, 249, 1152, 308, + /* 990 */ 557, 1152, 321, 1320, 323, 491, 455, 71, 71, 233, + /* 1000 */ 283, 101, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, + /* 1010 */ 121, 122, 122, 122, 122, 120, 120, 120, 120, 119, + /* 1020 */ 119, 118, 118, 118, 117, 113, 444, 1108, 277, 277, + /* 1030 */ 1412, 448, 394, 1230, 439, 277, 277, 248, 247, 246, + /* 1040 */ 1319, 563, 1109, 313, 198, 294, 491, 1318, 563, 464, + /* 1050 */ 566, 1427, 394, 1130, 1023, 233, 414, 1110, 295, 120, + /* 1060 */ 120, 120, 120, 119, 119, 118, 118, 118, 117, 113, + /* 1070 */ 444, 1014, 104, 71, 71, 1013, 322, 496, 908, 566, + /* 1080 */ 277, 277, 277, 277, 1108, 1261, 415, 448, 909, 361, + /* 1090 */ 1571, 1315, 409, 563, 952, 563, 9, 202, 255, 1109, + /* 1100 */ 316, 487, 44, 44, 249, 559, 415, 1013, 1013, 1015, + /* 1110 */ 443, 1231, 409, 1603, 1110, 897, 123, 124, 114, 1210, + /* 1120 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1130 */ 122, 1231, 409, 1207, 215, 554, 123, 124, 114, 1210, + /* 1140 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1150 */ 122, 1131, 1631, 470, 1631, 255, 123, 111, 114, 1210, + /* 1160 */ 1210, 1044, 1047, 1036, 1036, 121, 121, 122, 122, 122, + /* 1170 */ 122, 1131, 1632, 414, 1632, 120, 120, 120, 120, 119, + /* 1180 */ 119, 118, 118, 118, 117, 113, 444, 221, 209, 351, + /* 1190 */ 1207, 1207, 147, 1426, 491, 120, 120, 120, 120, 119, + /* 1200 */ 119, 118, 118, 118, 117, 113, 444, 1256, 539, 519, + /* 1210 */ 888, 551, 952, 12, 566, 120, 120, 120, 120, 119, + /* 1220 */ 119, 118, 118, 118, 117, 113, 444, 538, 566, 860, + /* 1230 */ 1129, 361, 1571, 346, 1356, 409, 1163, 58, 58, 339, + /* 1240 */ 1355, 508, 277, 277, 277, 277, 277, 277, 1207, 889, + /* 1250 */ 1129, 59, 59, 459, 363, 563, 566, 563, 96, 563, + /* 1260 */ 124, 114, 1210, 1210, 1044, 1047, 1036, 1036, 121, 121, + /* 1270 */ 122, 122, 122, 122, 566, 1412, 566, 281, 1186, 60, + /* 1280 */ 60, 110, 392, 392, 391, 266, 389, 860, 1163, 845, + /* 1290 */ 566, 481, 566, 436, 341, 1152, 344, 61, 61, 62, + /* 1300 */ 62, 967, 227, 1550, 315, 431, 540, 6, 1152, 968, + /* 1310 */ 566, 1152, 314, 45, 45, 46, 46, 512, 120, 120, + /* 1320 */ 120, 120, 119, 119, 118, 118, 118, 117, 113, 444, + /* 1330 */ 416, 173, 1532, 47, 47, 1186, 1187, 1188, 108, 558, + /* 1340 */ 325, 4, 229, 1551, 928, 566, 437, 6, 566, 927, + /* 1350 */ 164, 566, 1290, 137, 1190, 561, 566, 1549, 566, 1089, + /* 1360 */ 566, 6, 566, 1089, 531, 566, 868, 8, 49, 49, + /* 1370 */ 228, 50, 50, 566, 63, 63, 566, 457, 445, 64, + /* 1380 */ 64, 65, 65, 14, 14, 66, 66, 407, 129, 129, + /* 1390 */ 555, 566, 458, 566, 1505, 486, 67, 67, 566, 52, + /* 1400 */ 52, 546, 407, 467, 535, 410, 226, 1023, 566, 534, + /* 1410 */ 308, 557, 1190, 407, 68, 68, 69, 69, 566, 1023, + /* 1420 */ 566, 53, 53, 868, 1014, 106, 106, 525, 1013, 566, + /* 1430 */ 1504, 159, 159, 107, 451, 445, 568, 567, 471, 307, + /* 1440 */ 1013, 160, 160, 76, 76, 566, 1548, 466, 407, 407, + /* 1450 */ 6, 1225, 54, 54, 478, 276, 219, 566, 887, 886, + /* 1460 */ 1013, 1013, 1015, 84, 206, 1206, 230, 282, 72, 72, + /* 1470 */ 329, 483, 1013, 1013, 1015, 1016, 27, 1576, 1174, 447, + /* 1480 */ 130, 130, 281, 148, 105, 38, 103, 392, 392, 391, + /* 1490 */ 266, 389, 566, 1126, 845, 396, 566, 108, 558, 566, + /* 1500 */ 4, 311, 566, 30, 17, 566, 279, 227, 566, 315, + /* 1510 */ 108, 558, 468, 4, 561, 73, 73, 314, 566, 157, + /* 1520 */ 157, 566, 131, 131, 526, 132, 132, 561, 128, 128, + /* 1530 */ 566, 158, 158, 566, 31, 291, 566, 445, 330, 521, + /* 1540 */ 98, 152, 152, 420, 136, 136, 1005, 229, 254, 555, + /* 1550 */ 445, 479, 336, 135, 135, 164, 133, 133, 137, 134, + /* 1560 */ 134, 875, 555, 535, 566, 473, 566, 254, 536, 475, + /* 1570 */ 335, 254, 98, 894, 895, 228, 535, 566, 1023, 566, + /* 1580 */ 1074, 534, 210, 232, 106, 106, 1352, 75, 75, 77, + /* 1590 */ 77, 1023, 107, 340, 445, 568, 567, 106, 106, 1013, + /* 1600 */ 74, 74, 42, 42, 566, 107, 343, 445, 568, 567, + /* 1610 */ 410, 497, 1013, 251, 359, 308, 557, 1135, 349, 875, + /* 1620 */ 98, 1070, 345, 251, 358, 1591, 347, 48, 48, 1017, + /* 1630 */ 1303, 1013, 1013, 1015, 1016, 27, 1289, 1287, 1074, 451, + /* 1640 */ 961, 925, 254, 110, 1013, 1013, 1015, 1016, 27, 1174, + /* 1650 */ 447, 970, 971, 281, 108, 558, 1288, 4, 392, 392, + /* 1660 */ 391, 266, 389, 1343, 1086, 845, 1086, 1085, 858, 1085, + /* 1670 */ 146, 561, 926, 354, 110, 303, 364, 553, 227, 1364, + /* 1680 */ 315, 108, 558, 1411, 4, 1339, 492, 1017, 314, 1350, + /* 1690 */ 1565, 552, 1417, 1268, 445, 204, 1259, 1247, 561, 1246, + /* 1700 */ 1248, 1584, 269, 1336, 367, 369, 555, 371, 11, 212, + /* 1710 */ 393, 225, 1393, 284, 1398, 456, 287, 327, 229, 328, + /* 1720 */ 292, 445, 1386, 216, 333, 1403, 164, 477, 373, 137, + /* 1730 */ 1402, 400, 502, 555, 1286, 1023, 357, 1477, 199, 1587, + /* 1740 */ 211, 106, 106, 932, 1476, 1225, 228, 556, 175, 107, + /* 1750 */ 200, 445, 568, 567, 258, 387, 1013, 1524, 1522, 223, + /* 1760 */ 1222, 418, 1023, 83, 208, 79, 82, 184, 106, 106, + /* 1770 */ 1482, 169, 177, 461, 179, 462, 107, 1399, 445, 568, + /* 1780 */ 567, 410, 180, 1013, 495, 181, 308, 557, 1013, 1013, + /* 1790 */ 1015, 1016, 27, 182, 35, 235, 100, 558, 398, 4, + /* 1800 */ 96, 1405, 1404, 36, 484, 469, 1407, 188, 401, 1471, + /* 1810 */ 451, 89, 1493, 561, 239, 1013, 1013, 1015, 1016, 27, + /* 1820 */ 490, 338, 270, 241, 192, 342, 493, 242, 403, 1249, + /* 1830 */ 243, 511, 432, 1297, 1306, 91, 445, 1305, 1304, 879, + /* 1840 */ 217, 434, 435, 1570, 1276, 1602, 520, 1601, 555, 301, + /* 1850 */ 527, 404, 1275, 302, 356, 1274, 1600, 95, 1347, 366, + /* 1860 */ 1296, 362, 1348, 368, 256, 257, 1556, 1555, 438, 1346, + /* 1870 */ 370, 126, 1345, 10, 1371, 546, 381, 1023, 102, 1457, + /* 1880 */ 97, 530, 34, 106, 106, 570, 1180, 372, 265, 1329, + /* 1890 */ 379, 107, 203, 445, 568, 567, 1328, 385, 1013, 1370, + /* 1900 */ 386, 267, 268, 571, 1244, 161, 1239, 162, 1509, 1510, + /* 1910 */ 1508, 143, 1507, 299, 832, 213, 214, 78, 446, 205, + /* 1920 */ 310, 306, 163, 224, 1084, 140, 1082, 318, 165, 176, + /* 1930 */ 1013, 1013, 1015, 1016, 27, 178, 1206, 231, 911, 234, + /* 1940 */ 326, 1098, 183, 421, 166, 167, 411, 185, 85, 423, + /* 1950 */ 412, 86, 174, 87, 168, 88, 1101, 236, 1097, 237, + /* 1960 */ 154, 18, 238, 254, 337, 1219, 489, 1090, 240, 190, + /* 1970 */ 37, 847, 189, 494, 358, 244, 350, 506, 191, 877, + /* 1980 */ 90, 498, 19, 20, 503, 92, 353, 890, 300, 170, + /* 1990 */ 155, 93, 513, 94, 1168, 156, 1050, 1137, 39, 218, + /* 2000 */ 273, 275, 1136, 960, 194, 955, 110, 1154, 1158, 253, + /* 2010 */ 7, 1162, 1156, 21, 22, 1161, 1142, 23, 24, 25, + /* 2020 */ 33, 542, 26, 260, 197, 98, 1065, 1051, 1049, 1053, + /* 2030 */ 1107, 1054, 1106, 259, 28, 40, 562, 1018, 859, 109, + /* 2040 */ 29, 921, 390, 1176, 172, 139, 1175, 1235, 261, 1235, + /* 2050 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 262, 1235, 1235, + /* 2060 */ 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1235, 1593, 1592, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 192, 221, 192, 223, 192, 214, 272, 273, 274, 217, - /* 10 */ 192, 231, 217, 192, 192, 192, 272, 273, 274, 19, - /* 20 */ 233, 234, 214, 215, 214, 215, 203, 293, 203, 233, - /* 30 */ 234, 31, 214, 215, 214, 214, 215, 214, 215, 39, - /* 40 */ 208, 209, 210, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 236, 19, - /* 60 */ 237, 238, 237, 238, 272, 273, 274, 272, 273, 274, - /* 70 */ 192, 211, 251, 250, 251, 250, 26, 192, 200, 254, - /* 80 */ 255, 260, 204, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 192, 214, - /* 100 */ 215, 214, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 112, 59, 229, 192, 294, 16, 306, 307, - /* 120 */ 312, 313, 312, 311, 314, 59, 86, 204, 88, 19, - /* 130 */ 312, 313, 272, 273, 274, 271, 26, 22, 54, 55, - /* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, - /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 53, 115, - /* 170 */ 116, 117, 118, 309, 310, 121, 122, 123, 77, 69, - /* 180 */ 79, 115, 116, 117, 59, 131, 102, 103, 104, 105, - /* 190 */ 106, 107, 108, 109, 110, 111, 112, 72, 148, 19, - /* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112, - /* 210 */ 304, 305, 102, 103, 104, 105, 106, 107, 108, 109, - /* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, - /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 112, - /* 240 */ 115, 116, 117, 24, 208, 209, 210, 67, 102, 103, - /* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 192, - /* 260 */ 59, 160, 43, 44, 45, 46, 47, 48, 49, 50, - /* 270 */ 51, 52, 53, 54, 55, 56, 57, 19, 46, 47, - /* 280 */ 48, 49, 102, 103, 104, 105, 106, 107, 108, 109, - /* 290 */ 110, 111, 112, 213, 73, 184, 185, 186, 187, 188, - /* 300 */ 189, 221, 81, 236, 46, 194, 192, 196, 19, 59, - /* 310 */ 133, 59, 135, 136, 203, 192, 115, 116, 117, 127, - /* 320 */ 128, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, - /* 340 */ 51, 52, 53, 54, 55, 56, 57, 126, 237, 238, - /* 350 */ 100, 150, 120, 230, 186, 187, 188, 189, 137, 138, - /* 360 */ 108, 250, 194, 26, 196, 115, 116, 115, 116, 117, - /* 370 */ 120, 203, 114, 164, 165, 264, 102, 103, 104, 105, - /* 380 */ 106, 107, 108, 109, 110, 111, 112, 192, 130, 111, - /* 390 */ 112, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 400 */ 111, 112, 152, 153, 154, 237, 238, 296, 192, 214, - /* 410 */ 215, 228, 192, 307, 192, 19, 59, 311, 250, 23, - /* 420 */ 22, 106, 107, 108, 109, 110, 111, 112, 192, 72, - /* 430 */ 214, 215, 264, 192, 214, 215, 214, 215, 149, 43, - /* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 450 */ 54, 55, 56, 57, 117, 214, 215, 59, 19, 187, - /* 460 */ 192, 189, 23, 81, 296, 192, 194, 251, 196, 59, - /* 470 */ 229, 251, 115, 116, 117, 203, 260, 106, 107, 142, - /* 480 */ 260, 267, 43, 44, 45, 46, 47, 48, 49, 50, - /* 490 */ 51, 52, 53, 54, 55, 56, 57, 261, 102, 103, - /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 237, - /* 510 */ 238, 76, 192, 115, 116, 117, 144, 192, 76, 137, - /* 520 */ 138, 192, 250, 152, 89, 154, 116, 92, 19, 87, - /* 530 */ 262, 89, 23, 22, 92, 163, 264, 192, 22, 214, - /* 540 */ 215, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, - /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 296, 118, - /* 570 */ 59, 23, 121, 122, 123, 59, 251, 26, 46, 306, - /* 580 */ 307, 261, 131, 192, 311, 192, 144, 192, 22, 203, - /* 590 */ 100, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 600 */ 52, 53, 54, 55, 56, 57, 116, 214, 215, 271, - /* 610 */ 120, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 620 */ 111, 112, 229, 237, 238, 59, 115, 116, 117, 299, - /* 630 */ 300, 115, 116, 117, 59, 16, 250, 19, 192, 192, - /* 640 */ 19, 23, 152, 153, 154, 24, 114, 309, 310, 192, - /* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 670 */ 52, 53, 54, 55, 56, 57, 19, 7, 8, 9, - /* 680 */ 23, 115, 116, 117, 203, 290, 239, 238, 137, 138, - /* 690 */ 115, 116, 117, 236, 192, 22, 77, 81, 79, 250, - /* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 710 */ 53, 54, 55, 56, 57, 192, 95, 142, 237, 238, - /* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 730 */ 112, 250, 59, 112, 192, 119, 26, 214, 215, 118, - /* 740 */ 119, 120, 121, 122, 123, 124, 19, 192, 267, 302, - /* 750 */ 23, 130, 229, 137, 138, 23, 214, 215, 26, 102, - /* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 780 */ 53, 54, 55, 56, 57, 19, 76, 11, 115, 116, - /* 790 */ 117, 192, 29, 251, 239, 73, 33, 192, 192, 89, - /* 800 */ 192, 192, 92, 192, 192, 126, 127, 128, 224, 43, - /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 820 */ 54, 55, 56, 57, 192, 35, 214, 215, 65, 102, - /* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - /* 840 */ 59, 229, 192, 192, 239, 239, 214, 215, 126, 127, - /* 850 */ 128, 126, 127, 128, 307, 19, 66, 302, 311, 192, - /* 860 */ 261, 229, 224, 22, 74, 214, 215, 192, 102, 103, - /* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43, - /* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 890 */ 54, 55, 56, 57, 192, 192, 115, 116, 117, 19, - /* 900 */ 59, 290, 251, 127, 128, 192, 23, 302, 302, 26, - /* 910 */ 302, 236, 192, 22, 21, 24, 214, 215, 192, 129, - /* 920 */ 22, 192, 24, 142, 158, 45, 46, 47, 48, 49, - /* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103, - /* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 192, - /* 950 */ 59, 12, 192, 251, 192, 305, 192, 116, 22, 23, - /* 960 */ 242, 203, 26, 203, 24, 236, 27, 237, 238, 266, - /* 970 */ 252, 214, 215, 80, 214, 215, 214, 215, 214, 215, - /* 980 */ 250, 42, 102, 103, 104, 105, 106, 107, 108, 109, - /* 990 */ 110, 111, 112, 229, 158, 237, 238, 237, 238, 59, - /* 1000 */ 117, 281, 63, 192, 192, 192, 192, 116, 250, 192, - /* 1010 */ 250, 251, 73, 251, 19, 122, 290, 237, 238, 24, - /* 1020 */ 260, 209, 210, 209, 210, 142, 242, 214, 215, 197, - /* 1030 */ 250, 22, 23, 276, 19, 26, 252, 101, 43, 44, - /* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 1050 */ 55, 56, 57, 160, 19, 211, 116, 192, 43, 44, - /* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 1070 */ 55, 56, 57, 192, 192, 22, 192, 266, 43, 44, - /* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 1090 */ 55, 56, 57, 192, 282, 192, 282, 102, 103, 104, - /* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 192, - /* 1110 */ 101, 279, 192, 192, 230, 283, 192, 102, 103, 104, - /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 204, 211, - /* 1130 */ 66, 214, 215, 289, 214, 215, 108, 102, 103, 104, - /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 266, 85, - /* 1150 */ 226, 192, 228, 22, 23, 106, 107, 19, 94, 106, - /* 1160 */ 107, 192, 134, 114, 115, 116, 117, 139, 119, 266, - /* 1170 */ 203, 206, 207, 214, 215, 192, 127, 192, 206, 207, - /* 1180 */ 59, 192, 44, 45, 46, 47, 48, 49, 50, 51, - /* 1190 */ 52, 53, 54, 55, 56, 57, 192, 76, 192, 214, - /* 1200 */ 215, 152, 284, 154, 237, 238, 192, 289, 87, 145, - /* 1210 */ 89, 19, 20, 92, 22, 22, 23, 250, 307, 236, - /* 1220 */ 214, 215, 311, 203, 12, 247, 192, 249, 36, 307, - /* 1230 */ 192, 262, 101, 311, 137, 138, 115, 116, 117, 27, - /* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 1250 */ 112, 59, 214, 215, 42, 203, 307, 237, 238, 192, - /* 1260 */ 311, 192, 26, 71, 192, 144, 262, 297, 298, 203, - /* 1270 */ 250, 19, 20, 81, 22, 63, 262, 254, 255, 15, - /* 1280 */ 26, 214, 215, 214, 215, 26, 214, 215, 36, 237, - /* 1290 */ 238, 192, 100, 114, 101, 192, 262, 192, 106, 107, - /* 1300 */ 48, 134, 250, 237, 238, 113, 139, 115, 116, 117, - /* 1310 */ 192, 59, 120, 214, 215, 242, 250, 214, 215, 214, - /* 1320 */ 215, 148, 149, 71, 60, 252, 242, 192, 149, 137, - /* 1330 */ 138, 192, 214, 215, 192, 19, 252, 85, 192, 59, - /* 1340 */ 192, 157, 90, 159, 152, 153, 154, 155, 156, 214, - /* 1350 */ 215, 192, 100, 214, 215, 19, 214, 215, 106, 107, - /* 1360 */ 214, 215, 214, 215, 22, 113, 192, 115, 116, 117, - /* 1370 */ 192, 242, 120, 214, 215, 192, 24, 192, 31, 192, - /* 1380 */ 144, 252, 26, 192, 125, 99, 39, 192, 214, 215, - /* 1390 */ 192, 59, 214, 215, 192, 141, 116, 214, 215, 214, - /* 1400 */ 215, 214, 215, 61, 152, 153, 154, 155, 156, 0, - /* 1410 */ 1, 2, 214, 215, 5, 192, 214, 215, 132, 10, - /* 1420 */ 11, 12, 13, 14, 1, 2, 17, 192, 5, 19, - /* 1430 */ 20, 115, 22, 10, 11, 12, 13, 14, 192, 30, - /* 1440 */ 17, 32, 23, 192, 23, 26, 36, 26, 116, 40, - /* 1450 */ 192, 115, 192, 30, 192, 32, 119, 120, 59, 5, - /* 1460 */ 214, 215, 128, 40, 10, 11, 12, 13, 14, 59, - /* 1470 */ 19, 17, 214, 215, 214, 215, 214, 215, 120, 70, - /* 1480 */ 192, 71, 22, 192, 30, 151, 32, 78, 130, 128, - /* 1490 */ 81, 192, 140, 70, 40, 85, 192, 141, 7, 8, - /* 1500 */ 90, 78, 214, 215, 81, 214, 215, 98, 83, 84, - /* 1510 */ 100, 192, 151, 214, 215, 116, 106, 107, 214, 215, - /* 1520 */ 192, 98, 192, 113, 70, 115, 116, 117, 23, 224, - /* 1530 */ 120, 26, 78, 214, 215, 81, 19, 20, 152, 22, - /* 1540 */ 154, 132, 214, 215, 214, 215, 137, 138, 97, 192, - /* 1550 */ 256, 192, 98, 36, 23, 132, 192, 26, 192, 192, - /* 1560 */ 137, 138, 152, 153, 154, 155, 156, 192, 192, 192, - /* 1570 */ 161, 214, 215, 214, 215, 192, 59, 192, 214, 215, - /* 1580 */ 214, 215, 192, 152, 161, 154, 132, 192, 71, 214, - /* 1590 */ 215, 137, 138, 192, 192, 192, 19, 20, 192, 22, - /* 1600 */ 140, 253, 85, 192, 214, 215, 192, 90, 23, 214, - /* 1610 */ 215, 26, 192, 36, 192, 161, 23, 100, 192, 26, - /* 1620 */ 214, 215, 192, 106, 107, 214, 215, 192, 23, 192, - /* 1630 */ 113, 26, 115, 116, 117, 23, 59, 120, 26, 23, - /* 1640 */ 23, 23, 26, 26, 26, 316, 234, 23, 71, 23, - /* 1650 */ 26, 192, 26, 192, 192, 192, 192, 192, 192, 192, - /* 1660 */ 192, 253, 212, 190, 286, 285, 253, 240, 253, 152, - /* 1670 */ 153, 154, 155, 156, 241, 243, 295, 100, 291, 291, - /* 1680 */ 223, 253, 227, 106, 107, 108, 269, 244, 244, 265, - /* 1690 */ 113, 257, 115, 116, 117, 257, 243, 120, 269, 218, - /* 1700 */ 217, 265, 217, 19, 20, 217, 22, 195, 269, 269, - /* 1710 */ 60, 295, 140, 257, 243, 241, 247, 247, 199, 278, - /* 1720 */ 36, 199, 199, 38, 19, 20, 150, 22, 149, 152, - /* 1730 */ 153, 154, 155, 156, 22, 43, 232, 295, 292, 292, - /* 1740 */ 18, 36, 235, 59, 268, 270, 235, 199, 235, 235, - /* 1750 */ 18, 198, 148, 281, 244, 71, 270, 270, 268, 244, - /* 1760 */ 232, 232, 244, 199, 59, 244, 198, 157, 288, 62, - /* 1770 */ 199, 287, 198, 22, 219, 219, 71, 199, 198, 114, - /* 1780 */ 199, 198, 216, 216, 100, 216, 225, 64, 22, 125, - /* 1790 */ 106, 107, 222, 164, 219, 222, 24, 113, 216, 115, - /* 1800 */ 116, 117, 218, 216, 120, 100, 216, 216, 310, 303, - /* 1810 */ 112, 106, 107, 225, 280, 280, 219, 143, 113, 259, - /* 1820 */ 115, 116, 117, 114, 259, 120, 199, 91, 82, 147, - /* 1830 */ 144, 315, 22, 275, 199, 315, 152, 153, 154, 155, - /* 1840 */ 156, 146, 145, 247, 258, 157, 25, 258, 245, 248, - /* 1850 */ 244, 259, 258, 202, 259, 248, 258, 152, 153, 154, - /* 1860 */ 155, 156, 263, 263, 26, 246, 13, 201, 193, 193, - /* 1870 */ 6, 191, 191, 205, 191, 220, 220, 205, 211, 277, - /* 1880 */ 211, 211, 211, 205, 4, 212, 3, 22, 162, 212, - /* 1890 */ 211, 15, 23, 16, 23, 138, 129, 150, 26, 24, - /* 1900 */ 141, 20, 16, 143, 1, 141, 129, 129, 61, 301, - /* 1910 */ 301, 298, 150, 53, 53, 37, 53, 129, 115, 53, - /* 1920 */ 140, 34, 1, 5, 22, 114, 68, 26, 160, 75, - /* 1930 */ 68, 41, 140, 114, 24, 20, 19, 130, 124, 23, - /* 1940 */ 67, 22, 22, 59, 22, 22, 67, 96, 24, 22, - /* 1950 */ 37, 23, 67, 28, 148, 22, 26, 23, 23, 23, - /* 1960 */ 23, 22, 140, 23, 97, 23, 34, 115, 22, 142, - /* 1970 */ 26, 75, 34, 44, 75, 34, 88, 34, 86, 34, - /* 1980 */ 23, 34, 93, 22, 24, 26, 34, 23, 26, 23, - /* 1990 */ 23, 23, 23, 11, 23, 22, 26, 22, 22, 140, - /* 2000 */ 23, 23, 22, 22, 134, 26, 23, 15, 140, 1, - /* 2010 */ 1, 317, 317, 317, 140, 317, 317, 317, 317, 317, - /* 2020 */ 317, 317, 140, 317, 317, 317, 317, 317, 317, 317, - /* 2030 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2040 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2050 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2060 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2070 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2080 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2090 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2100 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2110 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2120 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2130 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2140 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2150 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2160 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2170 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2180 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2190 */ 317, 317, 317, 317, 317, 317, 317, 317, 317, 317, - /* 2200 */ 317, 317, 317, 317, 317, 317, 317, + /* 0 */ 193, 223, 193, 225, 193, 193, 193, 274, 275, 276, + /* 10 */ 193, 233, 219, 193, 274, 275, 276, 206, 206, 19, + /* 20 */ 193, 219, 216, 216, 217, 216, 217, 193, 295, 216, + /* 30 */ 217, 31, 205, 216, 217, 193, 216, 217, 213, 39, + /* 40 */ 228, 193, 230, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 193, 19, + /* 60 */ 185, 186, 187, 188, 189, 190, 253, 274, 275, 276, + /* 70 */ 195, 193, 197, 253, 216, 262, 274, 275, 276, 204, + /* 80 */ 238, 204, 262, 43, 44, 45, 46, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 264, 274, + /* 100 */ 275, 276, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 113, 239, 240, 239, 240, 210, 211, + /* 120 */ 212, 314, 315, 314, 59, 316, 86, 252, 88, 252, + /* 130 */ 19, 314, 315, 256, 257, 309, 25, 72, 296, 313, + /* 140 */ 193, 266, 102, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 113, 43, 44, 45, 46, 47, 48, + /* 160 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 81, + /* 170 */ 292, 59, 307, 298, 108, 109, 110, 111, 112, 113, + /* 180 */ 69, 116, 117, 118, 72, 128, 129, 193, 241, 22, + /* 190 */ 113, 54, 55, 56, 57, 58, 102, 103, 104, 105, + /* 200 */ 106, 107, 108, 109, 110, 111, 112, 113, 120, 193, + /* 210 */ 216, 217, 25, 102, 103, 104, 105, 106, 107, 108, + /* 220 */ 109, 110, 111, 112, 113, 231, 138, 139, 116, 117, + /* 230 */ 118, 106, 107, 19, 216, 54, 55, 56, 57, 102, + /* 240 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 250 */ 113, 304, 25, 46, 47, 48, 49, 43, 44, 45, + /* 260 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + /* 270 */ 56, 57, 193, 106, 107, 59, 193, 19, 153, 263, + /* 280 */ 155, 67, 24, 102, 103, 104, 105, 106, 107, 108, + /* 290 */ 109, 110, 111, 112, 113, 216, 217, 59, 230, 216, + /* 300 */ 217, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 310 */ 52, 53, 54, 55, 56, 57, 102, 103, 104, 105, + /* 320 */ 106, 107, 108, 109, 110, 111, 112, 113, 121, 142, + /* 330 */ 59, 193, 116, 117, 118, 119, 253, 204, 122, 123, + /* 340 */ 124, 19, 20, 81, 22, 262, 108, 19, 132, 165, + /* 350 */ 166, 193, 24, 126, 116, 117, 118, 278, 36, 193, + /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 370 */ 112, 113, 239, 240, 216, 217, 215, 106, 107, 241, + /* 380 */ 19, 59, 216, 217, 223, 252, 115, 116, 117, 118, + /* 390 */ 73, 120, 26, 71, 193, 22, 193, 231, 81, 128, + /* 400 */ 138, 139, 269, 81, 43, 44, 45, 46, 47, 48, + /* 410 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 216, + /* 420 */ 217, 198, 100, 95, 153, 59, 155, 193, 106, 107, + /* 430 */ 235, 236, 59, 193, 193, 249, 114, 251, 116, 117, + /* 440 */ 118, 113, 304, 121, 127, 204, 193, 119, 120, 121, + /* 450 */ 122, 123, 124, 125, 193, 138, 139, 216, 217, 131, + /* 460 */ 138, 139, 193, 102, 103, 104, 105, 106, 107, 108, + /* 470 */ 109, 110, 111, 112, 113, 153, 154, 155, 156, 157, + /* 480 */ 239, 240, 116, 117, 118, 76, 193, 193, 19, 116, + /* 490 */ 117, 118, 23, 252, 253, 193, 87, 204, 89, 238, + /* 500 */ 193, 92, 268, 262, 281, 203, 193, 205, 285, 216, + /* 510 */ 217, 150, 43, 44, 45, 46, 47, 48, 49, 50, + /* 520 */ 51, 52, 53, 54, 55, 56, 57, 193, 193, 216, + /* 530 */ 217, 19, 239, 240, 59, 23, 106, 107, 108, 109, + /* 540 */ 110, 111, 112, 113, 231, 252, 253, 193, 308, 309, + /* 550 */ 193, 145, 59, 313, 145, 43, 44, 45, 46, 47, + /* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 570 */ 164, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 580 */ 111, 112, 113, 119, 193, 193, 122, 123, 124, 193, + /* 590 */ 283, 116, 117, 118, 235, 236, 132, 59, 241, 264, + /* 600 */ 59, 193, 19, 23, 193, 25, 23, 216, 217, 116, + /* 610 */ 117, 118, 216, 217, 102, 103, 104, 105, 106, 107, + /* 620 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 630 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 640 */ 57, 19, 308, 309, 151, 23, 25, 313, 135, 253, + /* 650 */ 21, 193, 241, 140, 116, 117, 118, 116, 117, 118, + /* 660 */ 268, 304, 22, 301, 302, 43, 44, 45, 46, 47, + /* 670 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 680 */ 193, 143, 193, 193, 143, 102, 103, 104, 105, 106, + /* 690 */ 107, 108, 109, 110, 111, 112, 113, 76, 118, 59, + /* 700 */ 292, 211, 212, 216, 217, 216, 217, 73, 193, 80, + /* 710 */ 89, 25, 19, 92, 193, 304, 23, 22, 231, 193, + /* 720 */ 231, 193, 22, 143, 102, 103, 104, 105, 106, 107, + /* 730 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 740 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 750 */ 57, 19, 123, 193, 59, 23, 116, 117, 118, 59, + /* 760 */ 193, 127, 128, 129, 306, 307, 210, 211, 212, 193, + /* 770 */ 22, 111, 112, 113, 284, 43, 44, 45, 46, 47, + /* 780 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 790 */ 161, 193, 216, 217, 268, 102, 103, 104, 105, 106, + /* 800 */ 107, 108, 109, 110, 111, 112, 113, 59, 193, 193, + /* 810 */ 193, 116, 117, 118, 216, 217, 116, 117, 118, 304, + /* 820 */ 239, 240, 19, 263, 138, 139, 23, 211, 212, 231, + /* 830 */ 263, 216, 217, 252, 102, 103, 104, 105, 106, 107, + /* 840 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 850 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 860 */ 57, 19, 193, 11, 116, 117, 118, 240, 253, 193, + /* 870 */ 201, 239, 240, 193, 134, 206, 136, 137, 193, 252, + /* 880 */ 193, 264, 193, 193, 252, 43, 44, 45, 46, 47, + /* 890 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + /* 900 */ 284, 216, 217, 216, 217, 102, 103, 104, 105, 106, + /* 910 */ 107, 108, 109, 110, 111, 112, 113, 193, 231, 193, + /* 920 */ 187, 188, 189, 190, 127, 128, 129, 238, 195, 193, + /* 930 */ 197, 16, 19, 7, 8, 9, 193, 204, 253, 193, + /* 940 */ 216, 217, 216, 217, 102, 103, 104, 105, 106, 107, + /* 950 */ 108, 109, 110, 111, 112, 113, 43, 44, 45, 46, + /* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 970 */ 57, 213, 239, 240, 193, 76, 19, 188, 232, 190, + /* 980 */ 128, 129, 292, 193, 195, 252, 197, 46, 89, 138, + /* 990 */ 139, 92, 77, 204, 79, 193, 269, 216, 217, 266, + /* 1000 */ 204, 159, 45, 46, 47, 48, 49, 50, 51, 52, + /* 1010 */ 53, 54, 55, 56, 57, 102, 103, 104, 105, 106, + /* 1020 */ 107, 108, 109, 110, 111, 112, 113, 12, 239, 240, + /* 1030 */ 193, 298, 22, 23, 253, 239, 240, 127, 128, 129, + /* 1040 */ 238, 252, 27, 193, 286, 204, 193, 204, 252, 291, + /* 1050 */ 193, 273, 22, 23, 100, 266, 115, 42, 268, 102, + /* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 1070 */ 113, 117, 159, 216, 217, 121, 161, 19, 63, 193, + /* 1080 */ 239, 240, 239, 240, 12, 208, 209, 298, 73, 311, + /* 1090 */ 312, 238, 19, 252, 25, 252, 22, 24, 24, 27, + /* 1100 */ 193, 264, 216, 217, 46, 208, 209, 153, 154, 155, + /* 1110 */ 253, 101, 19, 23, 42, 25, 43, 44, 45, 46, + /* 1120 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1130 */ 57, 101, 19, 59, 25, 63, 43, 44, 45, 46, + /* 1140 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1150 */ 57, 22, 23, 115, 25, 24, 43, 44, 45, 46, + /* 1160 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + /* 1170 */ 57, 22, 23, 115, 25, 102, 103, 104, 105, 106, + /* 1180 */ 107, 108, 109, 110, 111, 112, 113, 118, 150, 131, + /* 1190 */ 59, 117, 22, 273, 193, 102, 103, 104, 105, 106, + /* 1200 */ 107, 108, 109, 110, 111, 112, 113, 204, 66, 204, + /* 1210 */ 35, 204, 143, 213, 193, 102, 103, 104, 105, 106, + /* 1220 */ 107, 108, 109, 110, 111, 112, 113, 85, 193, 59, + /* 1230 */ 101, 311, 312, 16, 193, 19, 94, 216, 217, 238, + /* 1240 */ 193, 66, 239, 240, 239, 240, 239, 240, 117, 74, + /* 1250 */ 101, 216, 217, 193, 193, 252, 193, 252, 149, 252, + /* 1260 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 1270 */ 54, 55, 56, 57, 193, 193, 193, 5, 59, 216, + /* 1280 */ 217, 25, 10, 11, 12, 13, 14, 117, 146, 17, + /* 1290 */ 193, 291, 193, 232, 77, 76, 79, 216, 217, 216, + /* 1300 */ 217, 31, 30, 309, 32, 130, 87, 313, 89, 39, + /* 1310 */ 193, 92, 40, 216, 217, 216, 217, 108, 102, 103, + /* 1320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + /* 1330 */ 299, 300, 193, 216, 217, 116, 117, 118, 19, 20, + /* 1340 */ 193, 22, 70, 309, 135, 193, 264, 313, 193, 140, + /* 1350 */ 78, 193, 226, 81, 59, 36, 193, 309, 193, 29, + /* 1360 */ 193, 313, 193, 33, 145, 193, 59, 48, 216, 217, + /* 1370 */ 98, 216, 217, 193, 216, 217, 193, 244, 59, 216, + /* 1380 */ 217, 216, 217, 216, 217, 216, 217, 254, 216, 217, + /* 1390 */ 71, 193, 244, 193, 193, 65, 216, 217, 193, 216, + /* 1400 */ 217, 145, 254, 244, 85, 133, 15, 100, 193, 90, + /* 1410 */ 138, 139, 117, 254, 216, 217, 216, 217, 193, 100, + /* 1420 */ 193, 216, 217, 116, 117, 106, 107, 19, 121, 193, + /* 1430 */ 193, 216, 217, 114, 162, 116, 117, 118, 244, 244, + /* 1440 */ 121, 216, 217, 216, 217, 193, 309, 129, 254, 254, + /* 1450 */ 313, 60, 216, 217, 19, 256, 257, 193, 120, 121, + /* 1460 */ 153, 154, 155, 149, 150, 25, 24, 99, 216, 217, + /* 1470 */ 152, 193, 153, 154, 155, 156, 157, 0, 1, 2, + /* 1480 */ 216, 217, 5, 22, 158, 24, 160, 10, 11, 12, + /* 1490 */ 13, 14, 193, 23, 17, 25, 193, 19, 20, 193, + /* 1500 */ 22, 133, 193, 22, 22, 193, 22, 30, 193, 32, + /* 1510 */ 19, 20, 129, 22, 36, 216, 217, 40, 193, 216, + /* 1520 */ 217, 193, 216, 217, 116, 216, 217, 36, 216, 217, + /* 1530 */ 193, 216, 217, 193, 53, 152, 193, 59, 23, 19, + /* 1540 */ 25, 216, 217, 61, 216, 217, 23, 70, 25, 71, + /* 1550 */ 59, 116, 193, 216, 217, 78, 216, 217, 81, 216, + /* 1560 */ 217, 59, 71, 85, 193, 23, 193, 25, 90, 23, + /* 1570 */ 23, 25, 25, 7, 8, 98, 85, 193, 100, 193, + /* 1580 */ 59, 90, 142, 141, 106, 107, 193, 216, 217, 216, + /* 1590 */ 217, 100, 114, 193, 116, 117, 118, 106, 107, 121, + /* 1600 */ 216, 217, 216, 217, 193, 114, 193, 116, 117, 118, + /* 1610 */ 133, 23, 121, 25, 121, 138, 139, 97, 23, 117, + /* 1620 */ 25, 23, 193, 25, 131, 141, 193, 216, 217, 59, + /* 1630 */ 193, 153, 154, 155, 156, 157, 226, 193, 117, 162, + /* 1640 */ 23, 23, 25, 25, 153, 154, 155, 156, 157, 1, + /* 1650 */ 2, 83, 84, 5, 19, 20, 226, 22, 10, 11, + /* 1660 */ 12, 13, 14, 258, 153, 17, 155, 153, 23, 155, + /* 1670 */ 25, 36, 23, 193, 25, 255, 193, 236, 30, 193, + /* 1680 */ 32, 19, 20, 193, 22, 193, 288, 117, 40, 193, + /* 1690 */ 318, 193, 193, 193, 59, 242, 193, 193, 36, 193, + /* 1700 */ 193, 193, 287, 255, 255, 255, 71, 255, 243, 214, + /* 1710 */ 191, 297, 267, 245, 271, 259, 259, 293, 70, 246, + /* 1720 */ 246, 59, 267, 229, 245, 271, 78, 293, 259, 81, + /* 1730 */ 271, 271, 220, 71, 225, 100, 219, 219, 249, 196, + /* 1740 */ 243, 106, 107, 108, 219, 60, 98, 280, 297, 114, + /* 1750 */ 249, 116, 117, 118, 141, 245, 121, 200, 200, 297, + /* 1760 */ 38, 200, 100, 151, 150, 294, 294, 22, 106, 107, + /* 1770 */ 283, 43, 234, 18, 237, 200, 114, 272, 116, 117, + /* 1780 */ 118, 133, 237, 121, 18, 237, 138, 139, 153, 154, + /* 1790 */ 155, 156, 157, 237, 270, 199, 19, 20, 246, 22, + /* 1800 */ 149, 272, 272, 270, 200, 246, 234, 234, 246, 246, + /* 1810 */ 162, 158, 290, 36, 199, 153, 154, 155, 156, 157, + /* 1820 */ 62, 289, 200, 199, 22, 200, 221, 199, 221, 200, + /* 1830 */ 199, 115, 64, 227, 218, 22, 59, 218, 218, 126, + /* 1840 */ 165, 24, 113, 312, 218, 224, 305, 224, 71, 282, + /* 1850 */ 144, 221, 220, 282, 218, 218, 218, 115, 261, 260, + /* 1860 */ 227, 221, 261, 260, 200, 91, 317, 317, 82, 261, + /* 1870 */ 260, 148, 261, 22, 265, 145, 200, 100, 158, 277, + /* 1880 */ 147, 146, 25, 106, 107, 202, 13, 260, 194, 250, + /* 1890 */ 249, 114, 248, 116, 117, 118, 250, 247, 121, 265, + /* 1900 */ 246, 194, 6, 192, 192, 207, 192, 207, 213, 213, + /* 1910 */ 213, 222, 213, 222, 4, 214, 214, 213, 3, 22, + /* 1920 */ 163, 279, 207, 15, 23, 16, 23, 139, 130, 151, + /* 1930 */ 153, 154, 155, 156, 157, 142, 25, 24, 20, 144, + /* 1940 */ 16, 1, 142, 61, 130, 130, 303, 151, 53, 37, + /* 1950 */ 303, 53, 300, 53, 130, 53, 116, 34, 1, 141, + /* 1960 */ 5, 22, 115, 25, 161, 75, 41, 68, 141, 115, + /* 1970 */ 24, 20, 68, 19, 131, 125, 23, 96, 22, 59, + /* 1980 */ 22, 67, 22, 22, 67, 22, 24, 28, 67, 37, + /* 1990 */ 23, 149, 22, 25, 23, 23, 23, 23, 22, 141, + /* 2000 */ 23, 23, 97, 116, 22, 143, 25, 88, 75, 34, + /* 2010 */ 44, 75, 86, 34, 34, 93, 23, 34, 34, 34, + /* 2020 */ 22, 24, 34, 22, 25, 25, 23, 23, 23, 23, + /* 2030 */ 23, 11, 23, 25, 22, 22, 25, 23, 23, 22, + /* 2040 */ 22, 135, 15, 1, 25, 23, 1, 319, 141, 319, + /* 2050 */ 319, 319, 319, 319, 319, 319, 319, 141, 319, 319, + /* 2060 */ 319, 319, 319, 319, 319, 319, 319, 319, 141, 141, + /* 2070 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2080 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2090 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2100 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2110 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2120 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2130 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2140 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2150 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2160 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2170 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2180 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2190 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2200 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2210 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2220 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2230 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2240 */ 319, 319, 319, 319, 319, 319, 319, 319, 319, 319, + /* 2250 */ 319, 319, 319, 319, 319, }; -#define YY_SHIFT_COUNT (569) +#define YY_SHIFT_COUNT (573) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2009) +#define YY_SHIFT_MAX (2045) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1423, 1409, 1454, 1192, 1192, 382, 1252, 1410, 1517, 1684, - /* 10 */ 1684, 1684, 221, 0, 0, 180, 1015, 1684, 1684, 1684, - /* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 30 */ 1049, 1049, 1121, 1121, 54, 616, 382, 382, 382, 382, - /* 40 */ 382, 40, 110, 219, 289, 396, 439, 509, 548, 618, - /* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015, - /* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, - /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1577, 1684, - /* 80 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 90 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 100 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, - /* 110 */ 1684, 1684, 1684, 1705, 1684, 1684, 1684, 1684, 1684, 1684, - /* 120 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 146, 84, 84, - /* 130 */ 84, 84, 84, 274, 315, 125, 97, 357, 66, 66, - /* 140 */ 893, 258, 66, 66, 371, 371, 66, 551, 551, 551, - /* 150 */ 551, 192, 209, 209, 278, 127, 2023, 2023, 621, 621, - /* 160 */ 621, 201, 398, 398, 398, 398, 939, 939, 442, 936, - /* 170 */ 1009, 66, 66, 66, 66, 66, 66, 66, 66, 66, - /* 180 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - /* 190 */ 66, 710, 710, 66, 776, 435, 435, 410, 410, 372, - /* 200 */ 1097, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 250, 490, - /* 210 */ 490, 511, 451, 516, 252, 566, 575, 781, 673, 66, - /* 220 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 722, - /* 230 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - /* 240 */ 66, 66, 790, 790, 790, 66, 66, 66, 883, 66, - /* 250 */ 66, 66, 891, 1064, 66, 66, 1212, 66, 66, 66, - /* 260 */ 66, 66, 66, 66, 66, 725, 763, 177, 940, 940, - /* 270 */ 940, 940, 337, 177, 177, 1028, 1053, 670, 1264, 1179, - /* 280 */ 1173, 1254, 1316, 1173, 1316, 1336, 50, 1179, 1179, 50, - /* 290 */ 1179, 1254, 1336, 1259, 732, 532, 1347, 1347, 1347, 1316, - /* 300 */ 1236, 1236, 1184, 1356, 1167, 898, 1650, 1650, 1572, 1572, - /* 310 */ 1685, 1685, 1572, 1576, 1579, 1712, 1692, 1722, 1722, 1722, - /* 320 */ 1722, 1572, 1732, 1604, 1579, 1579, 1604, 1712, 1692, 1604, - /* 330 */ 1692, 1604, 1572, 1732, 1610, 1707, 1572, 1732, 1751, 1572, - /* 340 */ 1732, 1572, 1732, 1751, 1665, 1665, 1665, 1723, 1766, 1766, - /* 350 */ 1751, 1665, 1664, 1665, 1723, 1665, 1665, 1629, 1772, 1698, - /* 360 */ 1698, 1751, 1674, 1709, 1674, 1709, 1674, 1709, 1674, 1709, - /* 370 */ 1572, 1736, 1736, 1746, 1746, 1682, 1686, 1810, 1572, 1688, - /* 380 */ 1682, 1695, 1697, 1604, 1821, 1838, 1853, 1853, 1864, 1864, - /* 390 */ 1864, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, - /* 400 */ 2023, 2023, 2023, 2023, 2023, 2023, 232, 101, 1131, 1193, - /* 410 */ 619, 679, 841, 1421, 1286, 115, 1352, 1334, 1361, 1419, - /* 420 */ 1342, 1505, 1531, 1585, 1593, 1605, 1612, 1280, 1337, 1491, - /* 430 */ 1358, 1451, 1332, 1616, 1617, 1425, 1618, 1386, 1431, 1624, - /* 440 */ 1626, 1399, 1460, 1880, 1883, 1865, 1726, 1876, 1877, 1869, - /* 450 */ 1871, 1757, 1747, 1767, 1872, 1872, 1875, 1759, 1881, 1760, - /* 460 */ 1886, 1903, 1764, 1777, 1872, 1778, 1847, 1878, 1872, 1762, - /* 470 */ 1860, 1861, 1863, 1866, 1788, 1803, 1887, 1780, 1921, 1918, - /* 480 */ 1902, 1811, 1768, 1858, 1901, 1862, 1854, 1890, 1792, 1819, - /* 490 */ 1910, 1915, 1917, 1807, 1814, 1919, 1873, 1920, 1922, 1916, - /* 500 */ 1923, 1879, 1884, 1924, 1851, 1925, 1927, 1885, 1913, 1928, - /* 510 */ 1806, 1933, 1934, 1935, 1936, 1930, 1937, 1939, 1867, 1822, - /* 520 */ 1940, 1942, 1852, 1932, 1946, 1827, 1944, 1938, 1941, 1943, - /* 530 */ 1945, 1888, 1896, 1892, 1929, 1899, 1889, 1947, 1957, 1961, - /* 540 */ 1960, 1959, 1962, 1952, 1964, 1944, 1966, 1967, 1968, 1969, - /* 550 */ 1970, 1971, 1973, 1982, 1975, 1976, 1977, 1978, 1980, 1981, - /* 560 */ 1979, 1870, 1859, 1868, 1874, 1882, 1983, 1992, 2008, 2009, + /* 0 */ 1648, 1477, 1272, 322, 322, 262, 1319, 1478, 1491, 1662, + /* 10 */ 1662, 1662, 317, 0, 0, 214, 1093, 1662, 1662, 1662, + /* 20 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 30 */ 271, 271, 1219, 1219, 216, 88, 262, 262, 262, 262, + /* 40 */ 262, 40, 111, 258, 361, 469, 512, 583, 622, 693, + /* 50 */ 732, 803, 842, 913, 1073, 1093, 1093, 1093, 1093, 1093, + /* 60 */ 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093, + /* 70 */ 1093, 1093, 1093, 1113, 1093, 1216, 957, 957, 1635, 1662, + /* 80 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 90 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 100 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, + /* 110 */ 1662, 1662, 1662, 1662, 1777, 1662, 1662, 1662, 1662, 1662, + /* 120 */ 1662, 1662, 1662, 1662, 1662, 1662, 1662, 1662, 137, 181, + /* 130 */ 181, 181, 181, 181, 94, 430, 66, 65, 112, 366, + /* 140 */ 475, 475, 629, 1058, 475, 475, 125, 125, 475, 686, + /* 150 */ 686, 686, 660, 686, 57, 184, 184, 77, 77, 2070, + /* 160 */ 2070, 328, 328, 328, 493, 373, 373, 373, 373, 1015, + /* 170 */ 1015, 409, 366, 1129, 1149, 475, 475, 475, 475, 475, + /* 180 */ 475, 475, 475, 475, 475, 475, 475, 475, 475, 475, + /* 190 */ 475, 475, 475, 475, 475, 621, 621, 475, 852, 899, + /* 200 */ 899, 1295, 1295, 406, 851, 2070, 2070, 2070, 2070, 2070, + /* 210 */ 2070, 2070, 1307, 954, 954, 640, 464, 695, 238, 700, + /* 220 */ 538, 541, 748, 475, 475, 475, 475, 475, 475, 475, + /* 230 */ 475, 475, 475, 634, 475, 475, 475, 475, 475, 475, + /* 240 */ 475, 475, 475, 475, 475, 475, 1175, 1175, 1175, 475, + /* 250 */ 475, 475, 580, 475, 475, 475, 1074, 1142, 475, 475, + /* 260 */ 1072, 475, 475, 475, 475, 475, 475, 475, 475, 797, + /* 270 */ 1330, 740, 1131, 1131, 1131, 1131, 1069, 740, 740, 1209, + /* 280 */ 167, 926, 1391, 1038, 1314, 187, 1408, 1314, 1408, 1435, + /* 290 */ 1109, 1038, 1038, 1109, 1038, 187, 1435, 227, 1090, 941, + /* 300 */ 1270, 1270, 1270, 1408, 1256, 1256, 1326, 1440, 513, 1461, + /* 310 */ 1685, 1685, 1613, 1613, 1722, 1722, 1613, 1612, 1614, 1745, + /* 320 */ 1728, 1755, 1755, 1755, 1755, 1613, 1766, 1651, 1614, 1614, + /* 330 */ 1651, 1745, 1728, 1651, 1728, 1651, 1613, 1766, 1653, 1758, + /* 340 */ 1613, 1766, 1802, 1613, 1766, 1613, 1766, 1802, 1716, 1716, + /* 350 */ 1716, 1768, 1813, 1813, 1802, 1716, 1713, 1716, 1768, 1716, + /* 360 */ 1716, 1675, 1817, 1729, 1729, 1802, 1706, 1742, 1706, 1742, + /* 370 */ 1706, 1742, 1706, 1742, 1613, 1774, 1774, 1786, 1786, 1723, + /* 380 */ 1730, 1851, 1613, 1720, 1723, 1733, 1735, 1651, 1857, 1873, + /* 390 */ 1873, 1896, 1896, 1896, 2070, 2070, 2070, 2070, 2070, 2070, + /* 400 */ 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 2070, 207, + /* 410 */ 915, 1010, 1030, 1217, 910, 1170, 1470, 1368, 1481, 1442, + /* 420 */ 1318, 1383, 1515, 1482, 1523, 1542, 1546, 1547, 1588, 1595, + /* 430 */ 1502, 1338, 1566, 1493, 1520, 1521, 1598, 1617, 1568, 1618, + /* 440 */ 1511, 1514, 1645, 1649, 1570, 1484, 1910, 1915, 1897, 1757, + /* 450 */ 1908, 1909, 1901, 1903, 1788, 1778, 1798, 1911, 1911, 1913, + /* 460 */ 1793, 1918, 1795, 1924, 1940, 1800, 1814, 1911, 1815, 1882, + /* 470 */ 1912, 1911, 1796, 1895, 1898, 1900, 1902, 1824, 1840, 1923, + /* 480 */ 1818, 1957, 1955, 1939, 1847, 1803, 1899, 1938, 1904, 1890, + /* 490 */ 1925, 1827, 1854, 1946, 1951, 1954, 1843, 1850, 1956, 1914, + /* 500 */ 1958, 1960, 1953, 1961, 1917, 1920, 1962, 1881, 1959, 1963, + /* 510 */ 1921, 1952, 1967, 1842, 1970, 1971, 1972, 1973, 1968, 1974, + /* 520 */ 1976, 1905, 1858, 1977, 1978, 1887, 1975, 1982, 1862, 1981, + /* 530 */ 1979, 1980, 1983, 1984, 1919, 1933, 1926, 1966, 1936, 1922, + /* 540 */ 1985, 1993, 1998, 1997, 1999, 2000, 1988, 2003, 1981, 2004, + /* 550 */ 2005, 2006, 2007, 2008, 2009, 2001, 2020, 2012, 2013, 2014, + /* 560 */ 2015, 2017, 2018, 2011, 1906, 1907, 1916, 1927, 1928, 2019, + /* 570 */ 2022, 2027, 2042, 2045, }; -#define YY_REDUCE_COUNT (405) -#define YY_REDUCE_MIN (-266) -#define YY_REDUCE_MAX (1683) +#define YY_REDUCE_COUNT (408) +#define YY_REDUCE_MIN (-267) +#define YY_REDUCE_MAX (1715) static const short yy_reduce_ofst[] = { - /* 0 */ 111, 168, 272, 760, -177, -175, -192, -190, -182, -179, - /* 10 */ 216, 220, 481, -208, -205, -266, -140, -115, 241, 393, - /* 20 */ 523, 325, 612, 632, 542, 651, 764, 757, 702, 762, - /* 30 */ 812, 814, -188, 273, 924, 386, 758, 967, 1020, 1052, - /* 40 */ 1066, -256, -256, -256, -256, -256, -256, -256, -256, -256, - /* 50 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, - /* 60 */ -256, -256, -256, -256, -256, -256, -256, -256, -256, -256, - /* 70 */ -256, -256, -256, -256, -256, -256, -256, -256, 195, 222, - /* 80 */ 813, 917, 920, 959, 985, 1006, 1038, 1067, 1069, 1072, - /* 90 */ 1099, 1103, 1105, 1118, 1135, 1139, 1142, 1146, 1148, 1159, - /* 100 */ 1174, 1178, 1183, 1185, 1187, 1198, 1202, 1246, 1258, 1260, - /* 110 */ 1262, 1288, 1291, 1299, 1304, 1319, 1328, 1330, 1357, 1359, - /* 120 */ 1364, 1366, 1375, 1390, 1395, 1406, 1411, -256, -256, -256, - /* 130 */ -256, -256, -256, -256, -256, 447, -256, 555, -178, 605, - /* 140 */ 832, -220, 606, -94, -168, 36, -122, 730, 780, 730, - /* 150 */ 780, 918, -136, 338, -256, -256, -256, -256, 80, 80, - /* 160 */ 80, 720, 703, 811, 882, 903, -213, -204, 106, 330, - /* 170 */ 330, -77, 236, 320, 599, 67, 457, 675, 729, 395, - /* 180 */ 268, 611, 969, 1004, 726, 1014, 983, 123, 884, 608, - /* 190 */ 1034, 547, 911, 650, 844, 922, 949, 965, 972, 978, - /* 200 */ 449, 970, 718, 784, 1073, 1084, 1023, 1129, -209, -180, - /* 210 */ -113, 114, 183, 329, 345, 391, 446, 502, 609, 667, - /* 220 */ 713, 817, 865, 881, 901, 921, 989, 1191, 1195, 214, - /* 230 */ 1223, 1235, 1251, 1367, 1376, 1377, 1383, 1385, 1401, 1402, - /* 240 */ 1403, 1414, 584, 638, 1305, 1420, 1422, 1426, 1294, 1430, - /* 250 */ 1435, 1437, 1348, 1329, 1459, 1461, 1412, 1462, 345, 1463, - /* 260 */ 1464, 1465, 1466, 1467, 1468, 1378, 1380, 1427, 1408, 1413, - /* 270 */ 1415, 1428, 1294, 1427, 1427, 1433, 1450, 1473, 1381, 1417, - /* 280 */ 1424, 1432, 1434, 1436, 1438, 1387, 1443, 1429, 1439, 1444, - /* 290 */ 1440, 1453, 1388, 1481, 1455, 1457, 1483, 1485, 1488, 1456, - /* 300 */ 1469, 1470, 1441, 1471, 1474, 1512, 1416, 1442, 1519, 1522, - /* 310 */ 1446, 1447, 1523, 1472, 1475, 1476, 1504, 1507, 1511, 1513, - /* 320 */ 1514, 1548, 1553, 1510, 1486, 1487, 1515, 1490, 1528, 1518, - /* 330 */ 1529, 1521, 1564, 1568, 1480, 1484, 1571, 1574, 1555, 1578, - /* 340 */ 1580, 1581, 1583, 1556, 1566, 1567, 1569, 1561, 1570, 1573, - /* 350 */ 1575, 1582, 1584, 1587, 1588, 1590, 1591, 1498, 1506, 1534, - /* 360 */ 1535, 1597, 1560, 1586, 1565, 1589, 1592, 1594, 1595, 1598, - /* 370 */ 1627, 1516, 1520, 1599, 1600, 1601, 1596, 1558, 1635, 1602, - /* 380 */ 1607, 1619, 1603, 1606, 1651, 1666, 1675, 1676, 1680, 1681, - /* 390 */ 1683, 1608, 1609, 1613, 1668, 1667, 1669, 1670, 1671, 1672, - /* 400 */ 1655, 1656, 1673, 1677, 1679, 1678, + /* 0 */ -125, 733, 789, 241, 293, -123, -193, -191, -183, -187, + /* 10 */ -180, 83, 133, -207, -198, -267, -175, -6, 166, 313, + /* 20 */ 487, 396, 489, 598, 615, 685, 687, 79, 781, 857, + /* 30 */ 490, 616, 240, 334, -188, 796, 841, 843, 1003, 1005, + /* 40 */ 1007, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 50 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 60 */ -260, -260, -260, -260, -260, -260, -260, -260, -260, -260, + /* 70 */ -260, -260, -260, -260, -260, -260, -260, -260, 158, 203, + /* 80 */ 391, 576, 724, 726, 886, 1021, 1035, 1063, 1081, 1083, + /* 90 */ 1097, 1099, 1117, 1152, 1155, 1158, 1163, 1165, 1167, 1169, + /* 100 */ 1172, 1180, 1183, 1198, 1200, 1205, 1215, 1225, 1227, 1236, + /* 110 */ 1252, 1264, 1299, 1303, 1306, 1309, 1312, 1315, 1325, 1328, + /* 120 */ 1337, 1340, 1343, 1371, 1373, 1384, 1386, 1411, -260, -260, + /* 130 */ -260, -260, -260, -260, -260, -260, -260, -53, 138, 302, + /* 140 */ -158, 357, 223, -222, 411, 458, -92, 556, 669, 581, + /* 150 */ 632, 581, -260, 632, 758, 778, 920, -260, -260, -260, + /* 160 */ -260, 161, 161, 161, 307, 234, 392, 526, 790, 195, + /* 170 */ 359, -174, -173, 362, 362, -189, 16, 560, 567, 261, + /* 180 */ 689, 802, 853, -122, -166, 408, 335, 617, 690, 837, + /* 190 */ 1001, 746, 1061, 515, 1082, 994, 1034, -135, 1000, 1048, + /* 200 */ 1137, 877, 897, 186, 627, 1031, 1133, 1148, 1159, 1194, + /* 210 */ 1199, 1195, -194, -142, 18, -152, 68, 201, 253, 269, + /* 220 */ 294, 354, 521, 528, 676, 680, 736, 743, 850, 907, + /* 230 */ 1041, 1047, 1060, 727, 1139, 1147, 1201, 1237, 1278, 1359, + /* 240 */ 1393, 1400, 1413, 1429, 1433, 1437, 1126, 1410, 1430, 1444, + /* 250 */ 1480, 1483, 1405, 1486, 1490, 1492, 1420, 1372, 1496, 1498, + /* 260 */ 1441, 1499, 253, 1500, 1503, 1504, 1506, 1507, 1508, 1398, + /* 270 */ 1415, 1453, 1448, 1449, 1450, 1452, 1405, 1453, 1453, 1465, + /* 280 */ 1495, 1519, 1414, 1443, 1445, 1468, 1456, 1455, 1457, 1424, + /* 290 */ 1473, 1454, 1459, 1474, 1460, 1479, 1434, 1512, 1494, 1509, + /* 300 */ 1517, 1518, 1525, 1469, 1489, 1501, 1467, 1510, 1497, 1543, + /* 310 */ 1451, 1462, 1557, 1558, 1471, 1472, 1561, 1487, 1505, 1524, + /* 320 */ 1538, 1537, 1545, 1548, 1556, 1575, 1596, 1552, 1529, 1530, + /* 330 */ 1559, 1533, 1572, 1562, 1573, 1563, 1604, 1615, 1522, 1532, + /* 340 */ 1622, 1624, 1605, 1625, 1628, 1629, 1631, 1607, 1616, 1619, + /* 350 */ 1620, 1606, 1621, 1623, 1630, 1626, 1632, 1636, 1633, 1637, + /* 360 */ 1638, 1531, 1541, 1567, 1571, 1640, 1597, 1599, 1601, 1603, + /* 370 */ 1608, 1610, 1611, 1627, 1664, 1549, 1550, 1609, 1634, 1639, + /* 380 */ 1641, 1602, 1676, 1642, 1646, 1644, 1650, 1654, 1683, 1694, + /* 390 */ 1707, 1711, 1712, 1714, 1643, 1647, 1652, 1698, 1695, 1696, + /* 400 */ 1697, 1699, 1700, 1689, 1691, 1701, 1702, 1704, 1715, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1623, 1623, 1623, 1453, 1223, 1332, 1223, 1223, 1223, 1453, - /* 10 */ 1453, 1453, 1223, 1362, 1362, 1506, 1254, 1223, 1223, 1223, - /* 20 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1452, 1223, 1223, - /* 30 */ 1223, 1223, 1541, 1541, 1223, 1223, 1223, 1223, 1223, 1223, - /* 40 */ 1223, 1223, 1371, 1223, 1378, 1223, 1223, 1223, 1223, 1223, - /* 50 */ 1454, 1455, 1223, 1223, 1223, 1505, 1507, 1470, 1385, 1384, - /* 60 */ 1383, 1382, 1488, 1349, 1376, 1369, 1373, 1448, 1449, 1447, - /* 70 */ 1451, 1455, 1454, 1223, 1372, 1419, 1433, 1418, 1223, 1223, - /* 80 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 90 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 100 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 110 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 120 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1427, 1432, 1438, - /* 130 */ 1431, 1428, 1421, 1420, 1422, 1223, 1423, 1223, 1223, 1223, - /* 140 */ 1244, 1296, 1223, 1223, 1223, 1223, 1223, 1525, 1524, 1223, - /* 150 */ 1223, 1254, 1413, 1412, 1424, 1425, 1435, 1434, 1513, 1576, - /* 160 */ 1575, 1471, 1223, 1223, 1223, 1223, 1223, 1223, 1541, 1223, - /* 170 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 180 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 190 */ 1223, 1541, 1541, 1223, 1254, 1541, 1541, 1250, 1250, 1356, - /* 200 */ 1223, 1520, 1323, 1323, 1323, 1323, 1332, 1323, 1223, 1223, - /* 210 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 220 */ 1223, 1223, 1223, 1510, 1508, 1223, 1223, 1223, 1223, 1223, - /* 230 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 240 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 250 */ 1223, 1223, 1328, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 260 */ 1223, 1223, 1223, 1223, 1570, 1223, 1483, 1310, 1328, 1328, - /* 270 */ 1328, 1328, 1330, 1311, 1309, 1322, 1255, 1230, 1615, 1388, - /* 280 */ 1377, 1329, 1351, 1377, 1351, 1612, 1375, 1388, 1388, 1375, - /* 290 */ 1388, 1329, 1612, 1271, 1592, 1266, 1362, 1362, 1362, 1351, - /* 300 */ 1356, 1356, 1450, 1329, 1322, 1223, 1615, 1615, 1337, 1337, - /* 310 */ 1614, 1614, 1337, 1471, 1599, 1397, 1299, 1305, 1305, 1305, - /* 320 */ 1305, 1337, 1241, 1375, 1599, 1599, 1375, 1397, 1299, 1375, - /* 330 */ 1299, 1375, 1337, 1241, 1487, 1609, 1337, 1241, 1461, 1337, - /* 340 */ 1241, 1337, 1241, 1461, 1297, 1297, 1297, 1286, 1223, 1223, - /* 350 */ 1461, 1297, 1271, 1297, 1286, 1297, 1297, 1559, 1223, 1465, - /* 360 */ 1465, 1461, 1355, 1350, 1355, 1350, 1355, 1350, 1355, 1350, - /* 370 */ 1337, 1551, 1551, 1365, 1365, 1370, 1356, 1456, 1337, 1223, - /* 380 */ 1370, 1368, 1366, 1375, 1247, 1289, 1573, 1573, 1569, 1569, - /* 390 */ 1569, 1620, 1620, 1520, 1585, 1254, 1254, 1254, 1254, 1585, - /* 400 */ 1273, 1273, 1255, 1255, 1254, 1585, 1223, 1223, 1223, 1223, - /* 410 */ 1223, 1223, 1580, 1223, 1515, 1472, 1341, 1223, 1223, 1223, - /* 420 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 430 */ 1223, 1526, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 440 */ 1223, 1223, 1402, 1223, 1226, 1517, 1223, 1223, 1223, 1223, - /* 450 */ 1223, 1223, 1223, 1223, 1379, 1380, 1342, 1223, 1223, 1223, - /* 460 */ 1223, 1223, 1223, 1223, 1394, 1223, 1223, 1223, 1389, 1223, - /* 470 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1611, 1223, 1223, - /* 480 */ 1223, 1223, 1223, 1223, 1486, 1485, 1223, 1223, 1339, 1223, - /* 490 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 500 */ 1223, 1223, 1269, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 510 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 520 */ 1223, 1223, 1223, 1223, 1223, 1223, 1367, 1223, 1223, 1223, - /* 530 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 540 */ 1223, 1556, 1357, 1223, 1223, 1602, 1223, 1223, 1223, 1223, - /* 550 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, - /* 560 */ 1596, 1313, 1404, 1223, 1403, 1407, 1223, 1235, 1223, 1223, + /* 0 */ 1637, 1637, 1637, 1466, 1233, 1344, 1233, 1233, 1233, 1466, + /* 10 */ 1466, 1466, 1233, 1374, 1374, 1519, 1266, 1233, 1233, 1233, + /* 20 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1465, 1233, 1233, + /* 30 */ 1233, 1233, 1554, 1554, 1233, 1233, 1233, 1233, 1233, 1233, + /* 40 */ 1233, 1233, 1383, 1233, 1390, 1233, 1233, 1233, 1233, 1233, + /* 50 */ 1467, 1468, 1233, 1233, 1233, 1518, 1520, 1483, 1397, 1396, + /* 60 */ 1395, 1394, 1501, 1361, 1388, 1381, 1385, 1461, 1462, 1460, + /* 70 */ 1464, 1468, 1467, 1233, 1384, 1431, 1445, 1430, 1233, 1233, + /* 80 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 90 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 100 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 110 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 120 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1439, 1444, + /* 130 */ 1451, 1443, 1440, 1433, 1432, 1434, 1435, 1233, 1233, 1257, + /* 140 */ 1233, 1233, 1254, 1308, 1233, 1233, 1233, 1233, 1233, 1538, + /* 150 */ 1537, 1233, 1436, 1233, 1266, 1425, 1424, 1448, 1437, 1447, + /* 160 */ 1446, 1526, 1590, 1589, 1484, 1233, 1233, 1233, 1233, 1233, + /* 170 */ 1233, 1554, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 180 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 190 */ 1233, 1233, 1233, 1233, 1233, 1554, 1554, 1233, 1266, 1554, + /* 200 */ 1554, 1262, 1262, 1368, 1233, 1533, 1335, 1335, 1335, 1335, + /* 210 */ 1344, 1335, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 220 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1523, 1521, 1233, + /* 230 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 240 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 250 */ 1233, 1233, 1233, 1233, 1233, 1233, 1340, 1233, 1233, 1233, + /* 260 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1583, 1233, + /* 270 */ 1496, 1322, 1340, 1340, 1340, 1340, 1342, 1323, 1321, 1334, + /* 280 */ 1267, 1240, 1629, 1400, 1389, 1341, 1363, 1389, 1363, 1626, + /* 290 */ 1387, 1400, 1400, 1387, 1400, 1341, 1626, 1283, 1606, 1278, + /* 300 */ 1374, 1374, 1374, 1363, 1368, 1368, 1463, 1341, 1334, 1233, + /* 310 */ 1629, 1629, 1349, 1349, 1628, 1628, 1349, 1484, 1613, 1409, + /* 320 */ 1311, 1317, 1317, 1317, 1317, 1349, 1251, 1387, 1613, 1613, + /* 330 */ 1387, 1409, 1311, 1387, 1311, 1387, 1349, 1251, 1500, 1623, + /* 340 */ 1349, 1251, 1474, 1349, 1251, 1349, 1251, 1474, 1309, 1309, + /* 350 */ 1309, 1298, 1233, 1233, 1474, 1309, 1283, 1309, 1298, 1309, + /* 360 */ 1309, 1572, 1233, 1478, 1478, 1474, 1367, 1362, 1367, 1362, + /* 370 */ 1367, 1362, 1367, 1362, 1349, 1564, 1564, 1377, 1377, 1382, + /* 380 */ 1368, 1469, 1349, 1233, 1382, 1380, 1378, 1387, 1301, 1586, + /* 390 */ 1586, 1582, 1582, 1582, 1634, 1634, 1533, 1599, 1266, 1266, + /* 400 */ 1266, 1266, 1599, 1285, 1285, 1267, 1267, 1266, 1599, 1233, + /* 410 */ 1233, 1233, 1233, 1233, 1233, 1594, 1233, 1528, 1485, 1353, + /* 420 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 430 */ 1233, 1233, 1233, 1233, 1539, 1233, 1233, 1233, 1233, 1233, + /* 440 */ 1233, 1233, 1233, 1233, 1233, 1414, 1233, 1236, 1530, 1233, + /* 450 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1391, 1392, 1354, + /* 460 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1406, 1233, 1233, + /* 470 */ 1233, 1401, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 480 */ 1625, 1233, 1233, 1233, 1233, 1233, 1233, 1499, 1498, 1233, + /* 490 */ 1233, 1351, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 500 */ 1233, 1233, 1233, 1233, 1233, 1281, 1233, 1233, 1233, 1233, + /* 510 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 520 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1379, + /* 530 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 540 */ 1233, 1233, 1233, 1233, 1569, 1369, 1233, 1233, 1616, 1233, + /* 550 */ 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, 1233, + /* 560 */ 1233, 1233, 1233, 1610, 1325, 1416, 1233, 1415, 1419, 1255, + /* 570 */ 1233, 1245, 1233, 1233, }; /********** End of lemon-generated parsing tables *****************************/ @@ -159223,8 +162640,8 @@ static const YYCODETYPE yyFallback[] = { 0, /* LP => nothing */ 0, /* RP => nothing */ 0, /* AS => nothing */ - 59, /* WITHOUT => ID */ 0, /* COMMA => nothing */ + 59, /* WITHOUT => ID */ 59, /* ABORT => ID */ 59, /* ACTION => ID */ 59, /* AFTER => ID */ @@ -159310,6 +162727,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* SLASH => nothing */ 0, /* REM => nothing */ 0, /* CONCAT => nothing */ + 0, /* PTR => nothing */ 0, /* COLLATE => nothing */ 0, /* BITNOT => nothing */ 0, /* ON => nothing */ @@ -159433,9 +162851,9 @@ struct yyParser { }; typedef struct yyParser yyParser; +/* #include */ #ifndef NDEBUG /* #include */ -/* #include */ static FILE *yyTraceFILE = 0; static char *yyTracePrompt = 0; #endif /* NDEBUG */ @@ -159495,8 +162913,8 @@ static const char *const yyTokenName[] = { /* 22 */ "LP", /* 23 */ "RP", /* 24 */ "AS", - /* 25 */ "WITHOUT", - /* 26 */ "COMMA", + /* 25 */ "COMMA", + /* 26 */ "WITHOUT", /* 27 */ "ABORT", /* 28 */ "ACTION", /* 29 */ "AFTER", @@ -159582,211 +163000,213 @@ static const char *const yyTokenName[] = { /* 109 */ "SLASH", /* 110 */ "REM", /* 111 */ "CONCAT", - /* 112 */ "COLLATE", - /* 113 */ "BITNOT", - /* 114 */ "ON", - /* 115 */ "INDEXED", - /* 116 */ "STRING", - /* 117 */ "JOIN_KW", - /* 118 */ "CONSTRAINT", - /* 119 */ "DEFAULT", - /* 120 */ "NULL", - /* 121 */ "PRIMARY", - /* 122 */ "UNIQUE", - /* 123 */ "CHECK", - /* 124 */ "REFERENCES", - /* 125 */ "AUTOINCR", - /* 126 */ "INSERT", - /* 127 */ "DELETE", - /* 128 */ "UPDATE", - /* 129 */ "SET", - /* 130 */ "DEFERRABLE", - /* 131 */ "FOREIGN", - /* 132 */ "DROP", - /* 133 */ "UNION", - /* 134 */ "ALL", - /* 135 */ "EXCEPT", - /* 136 */ "INTERSECT", - /* 137 */ "SELECT", - /* 138 */ "VALUES", - /* 139 */ "DISTINCT", - /* 140 */ "DOT", - /* 141 */ "FROM", - /* 142 */ "JOIN", - /* 143 */ "USING", - /* 144 */ "ORDER", - /* 145 */ "GROUP", - /* 146 */ "HAVING", - /* 147 */ "LIMIT", - /* 148 */ "WHERE", - /* 149 */ "RETURNING", - /* 150 */ "INTO", - /* 151 */ "NOTHING", - /* 152 */ "FLOAT", - /* 153 */ "BLOB", - /* 154 */ "INTEGER", - /* 155 */ "VARIABLE", - /* 156 */ "CASE", - /* 157 */ "WHEN", - /* 158 */ "THEN", - /* 159 */ "ELSE", - /* 160 */ "INDEX", - /* 161 */ "ALTER", - /* 162 */ "ADD", - /* 163 */ "WINDOW", - /* 164 */ "OVER", - /* 165 */ "FILTER", - /* 166 */ "COLUMN", - /* 167 */ "AGG_FUNCTION", - /* 168 */ "AGG_COLUMN", - /* 169 */ "TRUEFALSE", - /* 170 */ "ISNOT", - /* 171 */ "FUNCTION", - /* 172 */ "UMINUS", - /* 173 */ "UPLUS", - /* 174 */ "TRUTH", - /* 175 */ "REGISTER", - /* 176 */ "VECTOR", - /* 177 */ "SELECT_COLUMN", - /* 178 */ "IF_NULL_ROW", - /* 179 */ "ASTERISK", - /* 180 */ "SPAN", - /* 181 */ "ERROR", - /* 182 */ "SPACE", - /* 183 */ "ILLEGAL", - /* 184 */ "input", - /* 185 */ "cmdlist", - /* 186 */ "ecmd", - /* 187 */ "cmdx", - /* 188 */ "explain", - /* 189 */ "cmd", - /* 190 */ "transtype", - /* 191 */ "trans_opt", - /* 192 */ "nm", - /* 193 */ "savepoint_opt", - /* 194 */ "create_table", - /* 195 */ "create_table_args", - /* 196 */ "createkw", - /* 197 */ "temp", - /* 198 */ "ifnotexists", - /* 199 */ "dbnm", - /* 200 */ "columnlist", - /* 201 */ "conslist_opt", - /* 202 */ "table_options", - /* 203 */ "select", - /* 204 */ "columnname", - /* 205 */ "carglist", - /* 206 */ "typetoken", - /* 207 */ "typename", - /* 208 */ "signed", - /* 209 */ "plus_num", - /* 210 */ "minus_num", - /* 211 */ "scanpt", - /* 212 */ "scantok", - /* 213 */ "ccons", - /* 214 */ "term", - /* 215 */ "expr", - /* 216 */ "onconf", - /* 217 */ "sortorder", - /* 218 */ "autoinc", - /* 219 */ "eidlist_opt", - /* 220 */ "refargs", - /* 221 */ "defer_subclause", - /* 222 */ "generated", - /* 223 */ "refarg", - /* 224 */ "refact", - /* 225 */ "init_deferred_pred_opt", - /* 226 */ "conslist", - /* 227 */ "tconscomma", - /* 228 */ "tcons", - /* 229 */ "sortlist", - /* 230 */ "eidlist", - /* 231 */ "defer_subclause_opt", - /* 232 */ "orconf", - /* 233 */ "resolvetype", - /* 234 */ "raisetype", - /* 235 */ "ifexists", - /* 236 */ "fullname", - /* 237 */ "selectnowith", - /* 238 */ "oneselect", - /* 239 */ "wqlist", - /* 240 */ "multiselect_op", - /* 241 */ "distinct", - /* 242 */ "selcollist", - /* 243 */ "from", - /* 244 */ "where_opt", - /* 245 */ "groupby_opt", - /* 246 */ "having_opt", - /* 247 */ "orderby_opt", - /* 248 */ "limit_opt", - /* 249 */ "window_clause", - /* 250 */ "values", - /* 251 */ "nexprlist", - /* 252 */ "sclp", - /* 253 */ "as", - /* 254 */ "seltablist", - /* 255 */ "stl_prefix", - /* 256 */ "joinop", - /* 257 */ "indexed_opt", - /* 258 */ "on_opt", - /* 259 */ "using_opt", - /* 260 */ "exprlist", - /* 261 */ "xfullname", - /* 262 */ "idlist", - /* 263 */ "nulls", - /* 264 */ "with", - /* 265 */ "where_opt_ret", - /* 266 */ "setlist", - /* 267 */ "insert_cmd", - /* 268 */ "idlist_opt", - /* 269 */ "upsert", - /* 270 */ "returning", - /* 271 */ "filter_over", - /* 272 */ "likeop", - /* 273 */ "between_op", - /* 274 */ "in_op", - /* 275 */ "paren_exprlist", - /* 276 */ "case_operand", - /* 277 */ "case_exprlist", - /* 278 */ "case_else", - /* 279 */ "uniqueflag", - /* 280 */ "collate", - /* 281 */ "vinto", - /* 282 */ "nmnum", - /* 283 */ "trigger_decl", - /* 284 */ "trigger_cmd_list", - /* 285 */ "trigger_time", - /* 286 */ "trigger_event", - /* 287 */ "foreach_clause", - /* 288 */ "when_clause", - /* 289 */ "trigger_cmd", - /* 290 */ "trnm", - /* 291 */ "tridxby", - /* 292 */ "database_kw_opt", - /* 293 */ "key_opt", - /* 294 */ "add_column_fullname", - /* 295 */ "kwcolumn_opt", - /* 296 */ "create_vtab", - /* 297 */ "vtabarglist", - /* 298 */ "vtabarg", - /* 299 */ "vtabargtoken", - /* 300 */ "lp", - /* 301 */ "anylist", - /* 302 */ "wqitem", - /* 303 */ "wqas", - /* 304 */ "windowdefn_list", - /* 305 */ "windowdefn", - /* 306 */ "window", - /* 307 */ "frame_opt", - /* 308 */ "part_opt", - /* 309 */ "filter_clause", - /* 310 */ "over_clause", - /* 311 */ "range_or_rows", - /* 312 */ "frame_bound", - /* 313 */ "frame_bound_s", - /* 314 */ "frame_bound_e", - /* 315 */ "frame_exclude_opt", - /* 316 */ "frame_exclude", + /* 112 */ "PTR", + /* 113 */ "COLLATE", + /* 114 */ "BITNOT", + /* 115 */ "ON", + /* 116 */ "INDEXED", + /* 117 */ "STRING", + /* 118 */ "JOIN_KW", + /* 119 */ "CONSTRAINT", + /* 120 */ "DEFAULT", + /* 121 */ "NULL", + /* 122 */ "PRIMARY", + /* 123 */ "UNIQUE", + /* 124 */ "CHECK", + /* 125 */ "REFERENCES", + /* 126 */ "AUTOINCR", + /* 127 */ "INSERT", + /* 128 */ "DELETE", + /* 129 */ "UPDATE", + /* 130 */ "SET", + /* 131 */ "DEFERRABLE", + /* 132 */ "FOREIGN", + /* 133 */ "DROP", + /* 134 */ "UNION", + /* 135 */ "ALL", + /* 136 */ "EXCEPT", + /* 137 */ "INTERSECT", + /* 138 */ "SELECT", + /* 139 */ "VALUES", + /* 140 */ "DISTINCT", + /* 141 */ "DOT", + /* 142 */ "FROM", + /* 143 */ "JOIN", + /* 144 */ "USING", + /* 145 */ "ORDER", + /* 146 */ "GROUP", + /* 147 */ "HAVING", + /* 148 */ "LIMIT", + /* 149 */ "WHERE", + /* 150 */ "RETURNING", + /* 151 */ "INTO", + /* 152 */ "NOTHING", + /* 153 */ "FLOAT", + /* 154 */ "BLOB", + /* 155 */ "INTEGER", + /* 156 */ "VARIABLE", + /* 157 */ "CASE", + /* 158 */ "WHEN", + /* 159 */ "THEN", + /* 160 */ "ELSE", + /* 161 */ "INDEX", + /* 162 */ "ALTER", + /* 163 */ "ADD", + /* 164 */ "WINDOW", + /* 165 */ "OVER", + /* 166 */ "FILTER", + /* 167 */ "COLUMN", + /* 168 */ "AGG_FUNCTION", + /* 169 */ "AGG_COLUMN", + /* 170 */ "TRUEFALSE", + /* 171 */ "ISNOT", + /* 172 */ "FUNCTION", + /* 173 */ "UMINUS", + /* 174 */ "UPLUS", + /* 175 */ "TRUTH", + /* 176 */ "REGISTER", + /* 177 */ "VECTOR", + /* 178 */ "SELECT_COLUMN", + /* 179 */ "IF_NULL_ROW", + /* 180 */ "ASTERISK", + /* 181 */ "SPAN", + /* 182 */ "ERROR", + /* 183 */ "SPACE", + /* 184 */ "ILLEGAL", + /* 185 */ "input", + /* 186 */ "cmdlist", + /* 187 */ "ecmd", + /* 188 */ "cmdx", + /* 189 */ "explain", + /* 190 */ "cmd", + /* 191 */ "transtype", + /* 192 */ "trans_opt", + /* 193 */ "nm", + /* 194 */ "savepoint_opt", + /* 195 */ "create_table", + /* 196 */ "create_table_args", + /* 197 */ "createkw", + /* 198 */ "temp", + /* 199 */ "ifnotexists", + /* 200 */ "dbnm", + /* 201 */ "columnlist", + /* 202 */ "conslist_opt", + /* 203 */ "table_option_set", + /* 204 */ "select", + /* 205 */ "table_option", + /* 206 */ "columnname", + /* 207 */ "carglist", + /* 208 */ "typetoken", + /* 209 */ "typename", + /* 210 */ "signed", + /* 211 */ "plus_num", + /* 212 */ "minus_num", + /* 213 */ "scanpt", + /* 214 */ "scantok", + /* 215 */ "ccons", + /* 216 */ "term", + /* 217 */ "expr", + /* 218 */ "onconf", + /* 219 */ "sortorder", + /* 220 */ "autoinc", + /* 221 */ "eidlist_opt", + /* 222 */ "refargs", + /* 223 */ "defer_subclause", + /* 224 */ "generated", + /* 225 */ "refarg", + /* 226 */ "refact", + /* 227 */ "init_deferred_pred_opt", + /* 228 */ "conslist", + /* 229 */ "tconscomma", + /* 230 */ "tcons", + /* 231 */ "sortlist", + /* 232 */ "eidlist", + /* 233 */ "defer_subclause_opt", + /* 234 */ "orconf", + /* 235 */ "resolvetype", + /* 236 */ "raisetype", + /* 237 */ "ifexists", + /* 238 */ "fullname", + /* 239 */ "selectnowith", + /* 240 */ "oneselect", + /* 241 */ "wqlist", + /* 242 */ "multiselect_op", + /* 243 */ "distinct", + /* 244 */ "selcollist", + /* 245 */ "from", + /* 246 */ "where_opt", + /* 247 */ "groupby_opt", + /* 248 */ "having_opt", + /* 249 */ "orderby_opt", + /* 250 */ "limit_opt", + /* 251 */ "window_clause", + /* 252 */ "values", + /* 253 */ "nexprlist", + /* 254 */ "sclp", + /* 255 */ "as", + /* 256 */ "seltablist", + /* 257 */ "stl_prefix", + /* 258 */ "joinop", + /* 259 */ "indexed_opt", + /* 260 */ "on_opt", + /* 261 */ "using_opt", + /* 262 */ "exprlist", + /* 263 */ "xfullname", + /* 264 */ "idlist", + /* 265 */ "nulls", + /* 266 */ "with", + /* 267 */ "where_opt_ret", + /* 268 */ "setlist", + /* 269 */ "insert_cmd", + /* 270 */ "idlist_opt", + /* 271 */ "upsert", + /* 272 */ "returning", + /* 273 */ "filter_over", + /* 274 */ "likeop", + /* 275 */ "between_op", + /* 276 */ "in_op", + /* 277 */ "paren_exprlist", + /* 278 */ "case_operand", + /* 279 */ "case_exprlist", + /* 280 */ "case_else", + /* 281 */ "uniqueflag", + /* 282 */ "collate", + /* 283 */ "vinto", + /* 284 */ "nmnum", + /* 285 */ "trigger_decl", + /* 286 */ "trigger_cmd_list", + /* 287 */ "trigger_time", + /* 288 */ "trigger_event", + /* 289 */ "foreach_clause", + /* 290 */ "when_clause", + /* 291 */ "trigger_cmd", + /* 292 */ "trnm", + /* 293 */ "tridxby", + /* 294 */ "database_kw_opt", + /* 295 */ "key_opt", + /* 296 */ "add_column_fullname", + /* 297 */ "kwcolumn_opt", + /* 298 */ "create_vtab", + /* 299 */ "vtabarglist", + /* 300 */ "vtabarg", + /* 301 */ "vtabargtoken", + /* 302 */ "lp", + /* 303 */ "anylist", + /* 304 */ "wqitem", + /* 305 */ "wqas", + /* 306 */ "windowdefn_list", + /* 307 */ "windowdefn", + /* 308 */ "window", + /* 309 */ "frame_opt", + /* 310 */ "part_opt", + /* 311 */ "filter_clause", + /* 312 */ "over_clause", + /* 313 */ "range_or_rows", + /* 314 */ "frame_bound", + /* 315 */ "frame_bound_s", + /* 316 */ "frame_bound_e", + /* 317 */ "frame_exclude_opt", + /* 318 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -159813,385 +163233,389 @@ static const char *const yyRuleName[] = { /* 16 */ "ifnotexists ::= IF NOT EXISTS", /* 17 */ "temp ::= TEMP", /* 18 */ "temp ::=", - /* 19 */ "create_table_args ::= LP columnlist conslist_opt RP table_options", + /* 19 */ "create_table_args ::= LP columnlist conslist_opt RP table_option_set", /* 20 */ "create_table_args ::= AS select", - /* 21 */ "table_options ::=", - /* 22 */ "table_options ::= WITHOUT nm", - /* 23 */ "columnname ::= nm typetoken", - /* 24 */ "typetoken ::=", - /* 25 */ "typetoken ::= typename LP signed RP", - /* 26 */ "typetoken ::= typename LP signed COMMA signed RP", - /* 27 */ "typename ::= typename ID|STRING", - /* 28 */ "scanpt ::=", - /* 29 */ "scantok ::=", - /* 30 */ "ccons ::= CONSTRAINT nm", - /* 31 */ "ccons ::= DEFAULT scantok term", - /* 32 */ "ccons ::= DEFAULT LP expr RP", - /* 33 */ "ccons ::= DEFAULT PLUS scantok term", - /* 34 */ "ccons ::= DEFAULT MINUS scantok term", - /* 35 */ "ccons ::= DEFAULT scantok ID|INDEXED", - /* 36 */ "ccons ::= NOT NULL onconf", - /* 37 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", - /* 38 */ "ccons ::= UNIQUE onconf", - /* 39 */ "ccons ::= CHECK LP expr RP", - /* 40 */ "ccons ::= REFERENCES nm eidlist_opt refargs", - /* 41 */ "ccons ::= defer_subclause", - /* 42 */ "ccons ::= COLLATE ID|STRING", - /* 43 */ "generated ::= LP expr RP", - /* 44 */ "generated ::= LP expr RP ID", - /* 45 */ "autoinc ::=", - /* 46 */ "autoinc ::= AUTOINCR", - /* 47 */ "refargs ::=", - /* 48 */ "refargs ::= refargs refarg", - /* 49 */ "refarg ::= MATCH nm", - /* 50 */ "refarg ::= ON INSERT refact", - /* 51 */ "refarg ::= ON DELETE refact", - /* 52 */ "refarg ::= ON UPDATE refact", - /* 53 */ "refact ::= SET NULL", - /* 54 */ "refact ::= SET DEFAULT", - /* 55 */ "refact ::= CASCADE", - /* 56 */ "refact ::= RESTRICT", - /* 57 */ "refact ::= NO ACTION", - /* 58 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", - /* 59 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", - /* 60 */ "init_deferred_pred_opt ::=", - /* 61 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", - /* 62 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", - /* 63 */ "conslist_opt ::=", - /* 64 */ "tconscomma ::= COMMA", - /* 65 */ "tcons ::= CONSTRAINT nm", - /* 66 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", - /* 67 */ "tcons ::= UNIQUE LP sortlist RP onconf", - /* 68 */ "tcons ::= CHECK LP expr RP onconf", - /* 69 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", - /* 70 */ "defer_subclause_opt ::=", - /* 71 */ "onconf ::=", - /* 72 */ "onconf ::= ON CONFLICT resolvetype", - /* 73 */ "orconf ::=", - /* 74 */ "orconf ::= OR resolvetype", - /* 75 */ "resolvetype ::= IGNORE", - /* 76 */ "resolvetype ::= REPLACE", - /* 77 */ "cmd ::= DROP TABLE ifexists fullname", - /* 78 */ "ifexists ::= IF EXISTS", - /* 79 */ "ifexists ::=", - /* 80 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", - /* 81 */ "cmd ::= DROP VIEW ifexists fullname", - /* 82 */ "cmd ::= select", - /* 83 */ "select ::= WITH wqlist selectnowith", - /* 84 */ "select ::= WITH RECURSIVE wqlist selectnowith", - /* 85 */ "select ::= selectnowith", - /* 86 */ "selectnowith ::= selectnowith multiselect_op oneselect", - /* 87 */ "multiselect_op ::= UNION", - /* 88 */ "multiselect_op ::= UNION ALL", - /* 89 */ "multiselect_op ::= EXCEPT|INTERSECT", - /* 90 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", - /* 91 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", - /* 92 */ "values ::= VALUES LP nexprlist RP", - /* 93 */ "values ::= values COMMA LP nexprlist RP", - /* 94 */ "distinct ::= DISTINCT", - /* 95 */ "distinct ::= ALL", - /* 96 */ "distinct ::=", - /* 97 */ "sclp ::=", - /* 98 */ "selcollist ::= sclp scanpt expr scanpt as", - /* 99 */ "selcollist ::= sclp scanpt STAR", - /* 100 */ "selcollist ::= sclp scanpt nm DOT STAR", - /* 101 */ "as ::= AS nm", - /* 102 */ "as ::=", - /* 103 */ "from ::=", - /* 104 */ "from ::= FROM seltablist", - /* 105 */ "stl_prefix ::= seltablist joinop", - /* 106 */ "stl_prefix ::=", - /* 107 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", - /* 108 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", - /* 109 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", - /* 110 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", - /* 111 */ "dbnm ::=", - /* 112 */ "dbnm ::= DOT nm", - /* 113 */ "fullname ::= nm", - /* 114 */ "fullname ::= nm DOT nm", - /* 115 */ "xfullname ::= nm", - /* 116 */ "xfullname ::= nm DOT nm", - /* 117 */ "xfullname ::= nm DOT nm AS nm", - /* 118 */ "xfullname ::= nm AS nm", - /* 119 */ "joinop ::= COMMA|JOIN", - /* 120 */ "joinop ::= JOIN_KW JOIN", - /* 121 */ "joinop ::= JOIN_KW nm JOIN", - /* 122 */ "joinop ::= JOIN_KW nm nm JOIN", - /* 123 */ "on_opt ::= ON expr", - /* 124 */ "on_opt ::=", - /* 125 */ "indexed_opt ::=", - /* 126 */ "indexed_opt ::= INDEXED BY nm", - /* 127 */ "indexed_opt ::= NOT INDEXED", - /* 128 */ "using_opt ::= USING LP idlist RP", - /* 129 */ "using_opt ::=", - /* 130 */ "orderby_opt ::=", - /* 131 */ "orderby_opt ::= ORDER BY sortlist", - /* 132 */ "sortlist ::= sortlist COMMA expr sortorder nulls", - /* 133 */ "sortlist ::= expr sortorder nulls", - /* 134 */ "sortorder ::= ASC", - /* 135 */ "sortorder ::= DESC", - /* 136 */ "sortorder ::=", - /* 137 */ "nulls ::= NULLS FIRST", - /* 138 */ "nulls ::= NULLS LAST", - /* 139 */ "nulls ::=", - /* 140 */ "groupby_opt ::=", - /* 141 */ "groupby_opt ::= GROUP BY nexprlist", - /* 142 */ "having_opt ::=", - /* 143 */ "having_opt ::= HAVING expr", - /* 144 */ "limit_opt ::=", - /* 145 */ "limit_opt ::= LIMIT expr", - /* 146 */ "limit_opt ::= LIMIT expr OFFSET expr", - /* 147 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 148 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", - /* 149 */ "where_opt ::=", - /* 150 */ "where_opt ::= WHERE expr", - /* 151 */ "where_opt_ret ::=", - /* 152 */ "where_opt_ret ::= WHERE expr", - /* 153 */ "where_opt_ret ::= RETURNING selcollist", - /* 154 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", - /* 155 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", - /* 156 */ "setlist ::= setlist COMMA nm EQ expr", - /* 157 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 158 */ "setlist ::= nm EQ expr", - /* 159 */ "setlist ::= LP idlist RP EQ expr", - /* 160 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 161 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", - /* 162 */ "upsert ::=", - /* 163 */ "upsert ::= RETURNING selcollist", - /* 164 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", - /* 165 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", - /* 166 */ "upsert ::= ON CONFLICT DO NOTHING returning", - /* 167 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", - /* 168 */ "returning ::= RETURNING selcollist", - /* 169 */ "insert_cmd ::= INSERT orconf", - /* 170 */ "insert_cmd ::= REPLACE", - /* 171 */ "idlist_opt ::=", - /* 172 */ "idlist_opt ::= LP idlist RP", - /* 173 */ "idlist ::= idlist COMMA nm", - /* 174 */ "idlist ::= nm", - /* 175 */ "expr ::= LP expr RP", - /* 176 */ "expr ::= ID|INDEXED", - /* 177 */ "expr ::= JOIN_KW", - /* 178 */ "expr ::= nm DOT nm", - /* 179 */ "expr ::= nm DOT nm DOT nm", - /* 180 */ "term ::= NULL|FLOAT|BLOB", - /* 181 */ "term ::= STRING", - /* 182 */ "term ::= INTEGER", - /* 183 */ "expr ::= VARIABLE", - /* 184 */ "expr ::= expr COLLATE ID|STRING", - /* 185 */ "expr ::= CAST LP expr AS typetoken RP", - /* 186 */ "expr ::= ID|INDEXED LP distinct exprlist RP", - /* 187 */ "expr ::= ID|INDEXED LP STAR RP", - /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", - /* 189 */ "expr ::= ID|INDEXED LP STAR RP filter_over", - /* 190 */ "term ::= CTIME_KW", - /* 191 */ "expr ::= LP nexprlist COMMA expr RP", - /* 192 */ "expr ::= expr AND expr", - /* 193 */ "expr ::= expr OR expr", - /* 194 */ "expr ::= expr LT|GT|GE|LE expr", - /* 195 */ "expr ::= expr EQ|NE expr", - /* 196 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 197 */ "expr ::= expr PLUS|MINUS expr", - /* 198 */ "expr ::= expr STAR|SLASH|REM expr", - /* 199 */ "expr ::= expr CONCAT expr", - /* 200 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 201 */ "expr ::= expr likeop expr", - /* 202 */ "expr ::= expr likeop expr ESCAPE expr", - /* 203 */ "expr ::= expr ISNULL|NOTNULL", - /* 204 */ "expr ::= expr NOT NULL", - /* 205 */ "expr ::= expr IS expr", - /* 206 */ "expr ::= expr IS NOT expr", - /* 207 */ "expr ::= NOT expr", - /* 208 */ "expr ::= BITNOT expr", - /* 209 */ "expr ::= PLUS|MINUS expr", - /* 210 */ "between_op ::= BETWEEN", - /* 211 */ "between_op ::= NOT BETWEEN", - /* 212 */ "expr ::= expr between_op expr AND expr", - /* 213 */ "in_op ::= IN", - /* 214 */ "in_op ::= NOT IN", - /* 215 */ "expr ::= expr in_op LP exprlist RP", - /* 216 */ "expr ::= LP select RP", - /* 217 */ "expr ::= expr in_op LP select RP", - /* 218 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 219 */ "expr ::= EXISTS LP select RP", - /* 220 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 221 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 222 */ "case_exprlist ::= WHEN expr THEN expr", - /* 223 */ "case_else ::= ELSE expr", - /* 224 */ "case_else ::=", - /* 225 */ "case_operand ::= expr", - /* 226 */ "case_operand ::=", - /* 227 */ "exprlist ::=", - /* 228 */ "nexprlist ::= nexprlist COMMA expr", - /* 229 */ "nexprlist ::= expr", - /* 230 */ "paren_exprlist ::=", - /* 231 */ "paren_exprlist ::= LP exprlist RP", - /* 232 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 233 */ "uniqueflag ::= UNIQUE", - /* 234 */ "uniqueflag ::=", - /* 235 */ "eidlist_opt ::=", - /* 236 */ "eidlist_opt ::= LP eidlist RP", - /* 237 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 238 */ "eidlist ::= nm collate sortorder", - /* 239 */ "collate ::=", - /* 240 */ "collate ::= COLLATE ID|STRING", - /* 241 */ "cmd ::= DROP INDEX ifexists fullname", - /* 242 */ "cmd ::= VACUUM vinto", - /* 243 */ "cmd ::= VACUUM nm vinto", - /* 244 */ "vinto ::= INTO expr", - /* 245 */ "vinto ::=", - /* 246 */ "cmd ::= PRAGMA nm dbnm", - /* 247 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 248 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 249 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 250 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 251 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 252 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 253 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 254 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 255 */ "trigger_time ::= BEFORE|AFTER", - /* 256 */ "trigger_time ::= INSTEAD OF", - /* 257 */ "trigger_time ::=", - /* 258 */ "trigger_event ::= DELETE|INSERT", - /* 259 */ "trigger_event ::= UPDATE", - /* 260 */ "trigger_event ::= UPDATE OF idlist", - /* 261 */ "when_clause ::=", - /* 262 */ "when_clause ::= WHEN expr", - /* 263 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 264 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 265 */ "trnm ::= nm DOT nm", - /* 266 */ "tridxby ::= INDEXED BY nm", - /* 267 */ "tridxby ::= NOT INDEXED", - /* 268 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 269 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 270 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 271 */ "trigger_cmd ::= scanpt select scanpt", - /* 272 */ "expr ::= RAISE LP IGNORE RP", - /* 273 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 274 */ "raisetype ::= ROLLBACK", - /* 275 */ "raisetype ::= ABORT", - /* 276 */ "raisetype ::= FAIL", - /* 277 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 278 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 279 */ "cmd ::= DETACH database_kw_opt expr", - /* 280 */ "key_opt ::=", - /* 281 */ "key_opt ::= KEY expr", - /* 282 */ "cmd ::= REINDEX", - /* 283 */ "cmd ::= REINDEX nm dbnm", - /* 284 */ "cmd ::= ANALYZE", - /* 285 */ "cmd ::= ANALYZE nm dbnm", - /* 286 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 287 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 288 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", - /* 289 */ "add_column_fullname ::= fullname", - /* 290 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 291 */ "cmd ::= create_vtab", - /* 292 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 293 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 294 */ "vtabarg ::=", - /* 295 */ "vtabargtoken ::= ANY", - /* 296 */ "vtabargtoken ::= lp anylist RP", - /* 297 */ "lp ::= LP", - /* 298 */ "with ::= WITH wqlist", - /* 299 */ "with ::= WITH RECURSIVE wqlist", - /* 300 */ "wqas ::= AS", - /* 301 */ "wqas ::= AS MATERIALIZED", - /* 302 */ "wqas ::= AS NOT MATERIALIZED", - /* 303 */ "wqitem ::= nm eidlist_opt wqas LP select RP", - /* 304 */ "wqlist ::= wqitem", - /* 305 */ "wqlist ::= wqlist COMMA wqitem", - /* 306 */ "windowdefn_list ::= windowdefn", - /* 307 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 308 */ "windowdefn ::= nm AS LP window RP", - /* 309 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 310 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 311 */ "window ::= ORDER BY sortlist frame_opt", - /* 312 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 313 */ "window ::= frame_opt", - /* 314 */ "window ::= nm frame_opt", - /* 315 */ "frame_opt ::=", - /* 316 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 317 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 318 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 319 */ "frame_bound_s ::= frame_bound", - /* 320 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 321 */ "frame_bound_e ::= frame_bound", - /* 322 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 323 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 324 */ "frame_bound ::= CURRENT ROW", - /* 325 */ "frame_exclude_opt ::=", - /* 326 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 327 */ "frame_exclude ::= NO OTHERS", - /* 328 */ "frame_exclude ::= CURRENT ROW", - /* 329 */ "frame_exclude ::= GROUP|TIES", - /* 330 */ "window_clause ::= WINDOW windowdefn_list", - /* 331 */ "filter_over ::= filter_clause over_clause", - /* 332 */ "filter_over ::= over_clause", - /* 333 */ "filter_over ::= filter_clause", - /* 334 */ "over_clause ::= OVER LP window RP", - /* 335 */ "over_clause ::= OVER nm", - /* 336 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 337 */ "input ::= cmdlist", - /* 338 */ "cmdlist ::= cmdlist ecmd", - /* 339 */ "cmdlist ::= ecmd", - /* 340 */ "ecmd ::= SEMI", - /* 341 */ "ecmd ::= cmdx SEMI", - /* 342 */ "ecmd ::= explain cmdx SEMI", - /* 343 */ "trans_opt ::=", - /* 344 */ "trans_opt ::= TRANSACTION", - /* 345 */ "trans_opt ::= TRANSACTION nm", - /* 346 */ "savepoint_opt ::= SAVEPOINT", - /* 347 */ "savepoint_opt ::=", - /* 348 */ "cmd ::= create_table create_table_args", - /* 349 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 350 */ "columnlist ::= columnname carglist", - /* 351 */ "nm ::= ID|INDEXED", - /* 352 */ "nm ::= STRING", - /* 353 */ "nm ::= JOIN_KW", - /* 354 */ "typetoken ::= typename", - /* 355 */ "typename ::= ID|STRING", - /* 356 */ "signed ::= plus_num", - /* 357 */ "signed ::= minus_num", - /* 358 */ "carglist ::= carglist ccons", - /* 359 */ "carglist ::=", - /* 360 */ "ccons ::= NULL onconf", - /* 361 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 362 */ "ccons ::= AS generated", - /* 363 */ "conslist_opt ::= COMMA conslist", - /* 364 */ "conslist ::= conslist tconscomma tcons", - /* 365 */ "conslist ::= tcons", - /* 366 */ "tconscomma ::=", - /* 367 */ "defer_subclause_opt ::= defer_subclause", - /* 368 */ "resolvetype ::= raisetype", - /* 369 */ "selectnowith ::= oneselect", - /* 370 */ "oneselect ::= values", - /* 371 */ "sclp ::= selcollist COMMA", - /* 372 */ "as ::= ID|STRING", - /* 373 */ "returning ::=", - /* 374 */ "expr ::= term", - /* 375 */ "likeop ::= LIKE_KW|MATCH", - /* 376 */ "exprlist ::= nexprlist", - /* 377 */ "nmnum ::= plus_num", - /* 378 */ "nmnum ::= nm", - /* 379 */ "nmnum ::= ON", - /* 380 */ "nmnum ::= DELETE", - /* 381 */ "nmnum ::= DEFAULT", - /* 382 */ "plus_num ::= INTEGER|FLOAT", - /* 383 */ "foreach_clause ::=", - /* 384 */ "foreach_clause ::= FOR EACH ROW", - /* 385 */ "trnm ::= nm", - /* 386 */ "tridxby ::=", - /* 387 */ "database_kw_opt ::= DATABASE", - /* 388 */ "database_kw_opt ::=", - /* 389 */ "kwcolumn_opt ::=", - /* 390 */ "kwcolumn_opt ::= COLUMNKW", - /* 391 */ "vtabarglist ::= vtabarg", - /* 392 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 393 */ "vtabarg ::= vtabarg vtabargtoken", - /* 394 */ "anylist ::=", - /* 395 */ "anylist ::= anylist LP anylist RP", - /* 396 */ "anylist ::= anylist ANY", - /* 397 */ "with ::=", + /* 21 */ "table_option_set ::=", + /* 22 */ "table_option_set ::= table_option_set COMMA table_option", + /* 23 */ "table_option ::= WITHOUT nm", + /* 24 */ "table_option ::= nm", + /* 25 */ "columnname ::= nm typetoken", + /* 26 */ "typetoken ::=", + /* 27 */ "typetoken ::= typename LP signed RP", + /* 28 */ "typetoken ::= typename LP signed COMMA signed RP", + /* 29 */ "typename ::= typename ID|STRING", + /* 30 */ "scanpt ::=", + /* 31 */ "scantok ::=", + /* 32 */ "ccons ::= CONSTRAINT nm", + /* 33 */ "ccons ::= DEFAULT scantok term", + /* 34 */ "ccons ::= DEFAULT LP expr RP", + /* 35 */ "ccons ::= DEFAULT PLUS scantok term", + /* 36 */ "ccons ::= DEFAULT MINUS scantok term", + /* 37 */ "ccons ::= DEFAULT scantok ID|INDEXED", + /* 38 */ "ccons ::= NOT NULL onconf", + /* 39 */ "ccons ::= PRIMARY KEY sortorder onconf autoinc", + /* 40 */ "ccons ::= UNIQUE onconf", + /* 41 */ "ccons ::= CHECK LP expr RP", + /* 42 */ "ccons ::= REFERENCES nm eidlist_opt refargs", + /* 43 */ "ccons ::= defer_subclause", + /* 44 */ "ccons ::= COLLATE ID|STRING", + /* 45 */ "generated ::= LP expr RP", + /* 46 */ "generated ::= LP expr RP ID", + /* 47 */ "autoinc ::=", + /* 48 */ "autoinc ::= AUTOINCR", + /* 49 */ "refargs ::=", + /* 50 */ "refargs ::= refargs refarg", + /* 51 */ "refarg ::= MATCH nm", + /* 52 */ "refarg ::= ON INSERT refact", + /* 53 */ "refarg ::= ON DELETE refact", + /* 54 */ "refarg ::= ON UPDATE refact", + /* 55 */ "refact ::= SET NULL", + /* 56 */ "refact ::= SET DEFAULT", + /* 57 */ "refact ::= CASCADE", + /* 58 */ "refact ::= RESTRICT", + /* 59 */ "refact ::= NO ACTION", + /* 60 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", + /* 61 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", + /* 62 */ "init_deferred_pred_opt ::=", + /* 63 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED", + /* 64 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE", + /* 65 */ "conslist_opt ::=", + /* 66 */ "tconscomma ::= COMMA", + /* 67 */ "tcons ::= CONSTRAINT nm", + /* 68 */ "tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf", + /* 69 */ "tcons ::= UNIQUE LP sortlist RP onconf", + /* 70 */ "tcons ::= CHECK LP expr RP onconf", + /* 71 */ "tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt", + /* 72 */ "defer_subclause_opt ::=", + /* 73 */ "onconf ::=", + /* 74 */ "onconf ::= ON CONFLICT resolvetype", + /* 75 */ "orconf ::=", + /* 76 */ "orconf ::= OR resolvetype", + /* 77 */ "resolvetype ::= IGNORE", + /* 78 */ "resolvetype ::= REPLACE", + /* 79 */ "cmd ::= DROP TABLE ifexists fullname", + /* 80 */ "ifexists ::= IF EXISTS", + /* 81 */ "ifexists ::=", + /* 82 */ "cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select", + /* 83 */ "cmd ::= DROP VIEW ifexists fullname", + /* 84 */ "cmd ::= select", + /* 85 */ "select ::= WITH wqlist selectnowith", + /* 86 */ "select ::= WITH RECURSIVE wqlist selectnowith", + /* 87 */ "select ::= selectnowith", + /* 88 */ "selectnowith ::= selectnowith multiselect_op oneselect", + /* 89 */ "multiselect_op ::= UNION", + /* 90 */ "multiselect_op ::= UNION ALL", + /* 91 */ "multiselect_op ::= EXCEPT|INTERSECT", + /* 92 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt", + /* 93 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt", + /* 94 */ "values ::= VALUES LP nexprlist RP", + /* 95 */ "values ::= values COMMA LP nexprlist RP", + /* 96 */ "distinct ::= DISTINCT", + /* 97 */ "distinct ::= ALL", + /* 98 */ "distinct ::=", + /* 99 */ "sclp ::=", + /* 100 */ "selcollist ::= sclp scanpt expr scanpt as", + /* 101 */ "selcollist ::= sclp scanpt STAR", + /* 102 */ "selcollist ::= sclp scanpt nm DOT STAR", + /* 103 */ "as ::= AS nm", + /* 104 */ "as ::=", + /* 105 */ "from ::=", + /* 106 */ "from ::= FROM seltablist", + /* 107 */ "stl_prefix ::= seltablist joinop", + /* 108 */ "stl_prefix ::=", + /* 109 */ "seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt", + /* 110 */ "seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt", + /* 111 */ "seltablist ::= stl_prefix LP select RP as on_opt using_opt", + /* 112 */ "seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt", + /* 113 */ "dbnm ::=", + /* 114 */ "dbnm ::= DOT nm", + /* 115 */ "fullname ::= nm", + /* 116 */ "fullname ::= nm DOT nm", + /* 117 */ "xfullname ::= nm", + /* 118 */ "xfullname ::= nm DOT nm", + /* 119 */ "xfullname ::= nm DOT nm AS nm", + /* 120 */ "xfullname ::= nm AS nm", + /* 121 */ "joinop ::= COMMA|JOIN", + /* 122 */ "joinop ::= JOIN_KW JOIN", + /* 123 */ "joinop ::= JOIN_KW nm JOIN", + /* 124 */ "joinop ::= JOIN_KW nm nm JOIN", + /* 125 */ "on_opt ::= ON expr", + /* 126 */ "on_opt ::=", + /* 127 */ "indexed_opt ::=", + /* 128 */ "indexed_opt ::= INDEXED BY nm", + /* 129 */ "indexed_opt ::= NOT INDEXED", + /* 130 */ "using_opt ::= USING LP idlist RP", + /* 131 */ "using_opt ::=", + /* 132 */ "orderby_opt ::=", + /* 133 */ "orderby_opt ::= ORDER BY sortlist", + /* 134 */ "sortlist ::= sortlist COMMA expr sortorder nulls", + /* 135 */ "sortlist ::= expr sortorder nulls", + /* 136 */ "sortorder ::= ASC", + /* 137 */ "sortorder ::= DESC", + /* 138 */ "sortorder ::=", + /* 139 */ "nulls ::= NULLS FIRST", + /* 140 */ "nulls ::= NULLS LAST", + /* 141 */ "nulls ::=", + /* 142 */ "groupby_opt ::=", + /* 143 */ "groupby_opt ::= GROUP BY nexprlist", + /* 144 */ "having_opt ::=", + /* 145 */ "having_opt ::= HAVING expr", + /* 146 */ "limit_opt ::=", + /* 147 */ "limit_opt ::= LIMIT expr", + /* 148 */ "limit_opt ::= LIMIT expr OFFSET expr", + /* 149 */ "limit_opt ::= LIMIT expr COMMA expr", + /* 150 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", + /* 151 */ "where_opt ::=", + /* 152 */ "where_opt ::= WHERE expr", + /* 153 */ "where_opt_ret ::=", + /* 154 */ "where_opt_ret ::= WHERE expr", + /* 155 */ "where_opt_ret ::= RETURNING selcollist", + /* 156 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 157 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 158 */ "setlist ::= setlist COMMA nm EQ expr", + /* 159 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 160 */ "setlist ::= nm EQ expr", + /* 161 */ "setlist ::= LP idlist RP EQ expr", + /* 162 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 163 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 164 */ "upsert ::=", + /* 165 */ "upsert ::= RETURNING selcollist", + /* 166 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 167 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 168 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 169 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 170 */ "returning ::= RETURNING selcollist", + /* 171 */ "insert_cmd ::= INSERT orconf", + /* 172 */ "insert_cmd ::= REPLACE", + /* 173 */ "idlist_opt ::=", + /* 174 */ "idlist_opt ::= LP idlist RP", + /* 175 */ "idlist ::= idlist COMMA nm", + /* 176 */ "idlist ::= nm", + /* 177 */ "expr ::= LP expr RP", + /* 178 */ "expr ::= ID|INDEXED", + /* 179 */ "expr ::= JOIN_KW", + /* 180 */ "expr ::= nm DOT nm", + /* 181 */ "expr ::= nm DOT nm DOT nm", + /* 182 */ "term ::= NULL|FLOAT|BLOB", + /* 183 */ "term ::= STRING", + /* 184 */ "term ::= INTEGER", + /* 185 */ "expr ::= VARIABLE", + /* 186 */ "expr ::= expr COLLATE ID|STRING", + /* 187 */ "expr ::= CAST LP expr AS typetoken RP", + /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 189 */ "expr ::= ID|INDEXED LP STAR RP", + /* 190 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", + /* 191 */ "expr ::= ID|INDEXED LP STAR RP filter_over", + /* 192 */ "term ::= CTIME_KW", + /* 193 */ "expr ::= LP nexprlist COMMA expr RP", + /* 194 */ "expr ::= expr AND expr", + /* 195 */ "expr ::= expr OR expr", + /* 196 */ "expr ::= expr LT|GT|GE|LE expr", + /* 197 */ "expr ::= expr EQ|NE expr", + /* 198 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 199 */ "expr ::= expr PLUS|MINUS expr", + /* 200 */ "expr ::= expr STAR|SLASH|REM expr", + /* 201 */ "expr ::= expr CONCAT expr", + /* 202 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 203 */ "expr ::= expr likeop expr", + /* 204 */ "expr ::= expr likeop expr ESCAPE expr", + /* 205 */ "expr ::= expr ISNULL|NOTNULL", + /* 206 */ "expr ::= expr NOT NULL", + /* 207 */ "expr ::= expr IS expr", + /* 208 */ "expr ::= expr IS NOT expr", + /* 209 */ "expr ::= NOT expr", + /* 210 */ "expr ::= BITNOT expr", + /* 211 */ "expr ::= PLUS|MINUS expr", + /* 212 */ "expr ::= expr PTR expr", + /* 213 */ "between_op ::= BETWEEN", + /* 214 */ "between_op ::= NOT BETWEEN", + /* 215 */ "expr ::= expr between_op expr AND expr", + /* 216 */ "in_op ::= IN", + /* 217 */ "in_op ::= NOT IN", + /* 218 */ "expr ::= expr in_op LP exprlist RP", + /* 219 */ "expr ::= LP select RP", + /* 220 */ "expr ::= expr in_op LP select RP", + /* 221 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 222 */ "expr ::= EXISTS LP select RP", + /* 223 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 224 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 225 */ "case_exprlist ::= WHEN expr THEN expr", + /* 226 */ "case_else ::= ELSE expr", + /* 227 */ "case_else ::=", + /* 228 */ "case_operand ::= expr", + /* 229 */ "case_operand ::=", + /* 230 */ "exprlist ::=", + /* 231 */ "nexprlist ::= nexprlist COMMA expr", + /* 232 */ "nexprlist ::= expr", + /* 233 */ "paren_exprlist ::=", + /* 234 */ "paren_exprlist ::= LP exprlist RP", + /* 235 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 236 */ "uniqueflag ::= UNIQUE", + /* 237 */ "uniqueflag ::=", + /* 238 */ "eidlist_opt ::=", + /* 239 */ "eidlist_opt ::= LP eidlist RP", + /* 240 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 241 */ "eidlist ::= nm collate sortorder", + /* 242 */ "collate ::=", + /* 243 */ "collate ::= COLLATE ID|STRING", + /* 244 */ "cmd ::= DROP INDEX ifexists fullname", + /* 245 */ "cmd ::= VACUUM vinto", + /* 246 */ "cmd ::= VACUUM nm vinto", + /* 247 */ "vinto ::= INTO expr", + /* 248 */ "vinto ::=", + /* 249 */ "cmd ::= PRAGMA nm dbnm", + /* 250 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 251 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 252 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 253 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 254 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 255 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 256 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 257 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 258 */ "trigger_time ::= BEFORE|AFTER", + /* 259 */ "trigger_time ::= INSTEAD OF", + /* 260 */ "trigger_time ::=", + /* 261 */ "trigger_event ::= DELETE|INSERT", + /* 262 */ "trigger_event ::= UPDATE", + /* 263 */ "trigger_event ::= UPDATE OF idlist", + /* 264 */ "when_clause ::=", + /* 265 */ "when_clause ::= WHEN expr", + /* 266 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 267 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 268 */ "trnm ::= nm DOT nm", + /* 269 */ "tridxby ::= INDEXED BY nm", + /* 270 */ "tridxby ::= NOT INDEXED", + /* 271 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 272 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 273 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 274 */ "trigger_cmd ::= scanpt select scanpt", + /* 275 */ "expr ::= RAISE LP IGNORE RP", + /* 276 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 277 */ "raisetype ::= ROLLBACK", + /* 278 */ "raisetype ::= ABORT", + /* 279 */ "raisetype ::= FAIL", + /* 280 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 281 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 282 */ "cmd ::= DETACH database_kw_opt expr", + /* 283 */ "key_opt ::=", + /* 284 */ "key_opt ::= KEY expr", + /* 285 */ "cmd ::= REINDEX", + /* 286 */ "cmd ::= REINDEX nm dbnm", + /* 287 */ "cmd ::= ANALYZE", + /* 288 */ "cmd ::= ANALYZE nm dbnm", + /* 289 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 290 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 291 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 292 */ "add_column_fullname ::= fullname", + /* 293 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 294 */ "cmd ::= create_vtab", + /* 295 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 296 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 297 */ "vtabarg ::=", + /* 298 */ "vtabargtoken ::= ANY", + /* 299 */ "vtabargtoken ::= lp anylist RP", + /* 300 */ "lp ::= LP", + /* 301 */ "with ::= WITH wqlist", + /* 302 */ "with ::= WITH RECURSIVE wqlist", + /* 303 */ "wqas ::= AS", + /* 304 */ "wqas ::= AS MATERIALIZED", + /* 305 */ "wqas ::= AS NOT MATERIALIZED", + /* 306 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 307 */ "wqlist ::= wqitem", + /* 308 */ "wqlist ::= wqlist COMMA wqitem", + /* 309 */ "windowdefn_list ::= windowdefn", + /* 310 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 311 */ "windowdefn ::= nm AS LP window RP", + /* 312 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 313 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 314 */ "window ::= ORDER BY sortlist frame_opt", + /* 315 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 316 */ "window ::= frame_opt", + /* 317 */ "window ::= nm frame_opt", + /* 318 */ "frame_opt ::=", + /* 319 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 320 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 321 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 322 */ "frame_bound_s ::= frame_bound", + /* 323 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 324 */ "frame_bound_e ::= frame_bound", + /* 325 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 326 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 327 */ "frame_bound ::= CURRENT ROW", + /* 328 */ "frame_exclude_opt ::=", + /* 329 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 330 */ "frame_exclude ::= NO OTHERS", + /* 331 */ "frame_exclude ::= CURRENT ROW", + /* 332 */ "frame_exclude ::= GROUP|TIES", + /* 333 */ "window_clause ::= WINDOW windowdefn_list", + /* 334 */ "filter_over ::= filter_clause over_clause", + /* 335 */ "filter_over ::= over_clause", + /* 336 */ "filter_over ::= filter_clause", + /* 337 */ "over_clause ::= OVER LP window RP", + /* 338 */ "over_clause ::= OVER nm", + /* 339 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 340 */ "input ::= cmdlist", + /* 341 */ "cmdlist ::= cmdlist ecmd", + /* 342 */ "cmdlist ::= ecmd", + /* 343 */ "ecmd ::= SEMI", + /* 344 */ "ecmd ::= cmdx SEMI", + /* 345 */ "ecmd ::= explain cmdx SEMI", + /* 346 */ "trans_opt ::=", + /* 347 */ "trans_opt ::= TRANSACTION", + /* 348 */ "trans_opt ::= TRANSACTION nm", + /* 349 */ "savepoint_opt ::= SAVEPOINT", + /* 350 */ "savepoint_opt ::=", + /* 351 */ "cmd ::= create_table create_table_args", + /* 352 */ "table_option_set ::= table_option", + /* 353 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 354 */ "columnlist ::= columnname carglist", + /* 355 */ "nm ::= ID|INDEXED", + /* 356 */ "nm ::= STRING", + /* 357 */ "nm ::= JOIN_KW", + /* 358 */ "typetoken ::= typename", + /* 359 */ "typename ::= ID|STRING", + /* 360 */ "signed ::= plus_num", + /* 361 */ "signed ::= minus_num", + /* 362 */ "carglist ::= carglist ccons", + /* 363 */ "carglist ::=", + /* 364 */ "ccons ::= NULL onconf", + /* 365 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 366 */ "ccons ::= AS generated", + /* 367 */ "conslist_opt ::= COMMA conslist", + /* 368 */ "conslist ::= conslist tconscomma tcons", + /* 369 */ "conslist ::= tcons", + /* 370 */ "tconscomma ::=", + /* 371 */ "defer_subclause_opt ::= defer_subclause", + /* 372 */ "resolvetype ::= raisetype", + /* 373 */ "selectnowith ::= oneselect", + /* 374 */ "oneselect ::= values", + /* 375 */ "sclp ::= selcollist COMMA", + /* 376 */ "as ::= ID|STRING", + /* 377 */ "returning ::=", + /* 378 */ "expr ::= term", + /* 379 */ "likeop ::= LIKE_KW|MATCH", + /* 380 */ "exprlist ::= nexprlist", + /* 381 */ "nmnum ::= plus_num", + /* 382 */ "nmnum ::= nm", + /* 383 */ "nmnum ::= ON", + /* 384 */ "nmnum ::= DELETE", + /* 385 */ "nmnum ::= DEFAULT", + /* 386 */ "plus_num ::= INTEGER|FLOAT", + /* 387 */ "foreach_clause ::=", + /* 388 */ "foreach_clause ::= FOR EACH ROW", + /* 389 */ "trnm ::= nm", + /* 390 */ "tridxby ::=", + /* 391 */ "database_kw_opt ::= DATABASE", + /* 392 */ "database_kw_opt ::=", + /* 393 */ "kwcolumn_opt ::=", + /* 394 */ "kwcolumn_opt ::= COLUMNKW", + /* 395 */ "vtabarglist ::= vtabarg", + /* 396 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 397 */ "vtabarg ::= vtabarg vtabargtoken", + /* 398 */ "anylist ::=", + /* 399 */ "anylist ::= anylist LP anylist RP", + /* 400 */ "anylist ::= anylist ANY", + /* 401 */ "with ::=", }; #endif /* NDEBUG */ @@ -160317,99 +163741,99 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 203: /* select */ - case 237: /* selectnowith */ - case 238: /* oneselect */ - case 250: /* values */ + case 204: /* select */ + case 239: /* selectnowith */ + case 240: /* oneselect */ + case 252: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy81)); +sqlite3SelectDelete(pParse->db, (yypminor->yy47)); } break; - case 214: /* term */ - case 215: /* expr */ - case 244: /* where_opt */ - case 246: /* having_opt */ - case 258: /* on_opt */ - case 265: /* where_opt_ret */ - case 276: /* case_operand */ - case 278: /* case_else */ - case 281: /* vinto */ - case 288: /* when_clause */ - case 293: /* key_opt */ - case 309: /* filter_clause */ + case 216: /* term */ + case 217: /* expr */ + case 246: /* where_opt */ + case 248: /* having_opt */ + case 260: /* on_opt */ + case 267: /* where_opt_ret */ + case 278: /* case_operand */ + case 280: /* case_else */ + case 283: /* vinto */ + case 290: /* when_clause */ + case 295: /* key_opt */ + case 311: /* filter_clause */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy404)); +sqlite3ExprDelete(pParse->db, (yypminor->yy528)); } break; - case 219: /* eidlist_opt */ - case 229: /* sortlist */ - case 230: /* eidlist */ - case 242: /* selcollist */ - case 245: /* groupby_opt */ - case 247: /* orderby_opt */ - case 251: /* nexprlist */ - case 252: /* sclp */ - case 260: /* exprlist */ - case 266: /* setlist */ - case 275: /* paren_exprlist */ - case 277: /* case_exprlist */ - case 308: /* part_opt */ + case 221: /* eidlist_opt */ + case 231: /* sortlist */ + case 232: /* eidlist */ + case 244: /* selcollist */ + case 247: /* groupby_opt */ + case 249: /* orderby_opt */ + case 253: /* nexprlist */ + case 254: /* sclp */ + case 262: /* exprlist */ + case 268: /* setlist */ + case 277: /* paren_exprlist */ + case 279: /* case_exprlist */ + case 310: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy70)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy322)); } break; - case 236: /* fullname */ - case 243: /* from */ - case 254: /* seltablist */ - case 255: /* stl_prefix */ - case 261: /* xfullname */ + case 238: /* fullname */ + case 245: /* from */ + case 256: /* seltablist */ + case 257: /* stl_prefix */ + case 263: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy153)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy131)); } break; - case 239: /* wqlist */ + case 241: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy103)); +sqlite3WithDelete(pParse->db, (yypminor->yy521)); } break; - case 249: /* window_clause */ - case 304: /* windowdefn_list */ + case 251: /* window_clause */ + case 306: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy49)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy41)); } break; - case 259: /* using_opt */ - case 262: /* idlist */ - case 268: /* idlist_opt */ + case 261: /* using_opt */ + case 264: /* idlist */ + case 270: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy436)); +sqlite3IdListDelete(pParse->db, (yypminor->yy254)); } break; - case 271: /* filter_over */ - case 305: /* windowdefn */ - case 306: /* window */ - case 307: /* frame_opt */ - case 310: /* over_clause */ + case 273: /* filter_over */ + case 307: /* windowdefn */ + case 308: /* window */ + case 309: /* frame_opt */ + case 312: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy49)); +sqlite3WindowDelete(pParse->db, (yypminor->yy41)); } break; - case 284: /* trigger_cmd_list */ - case 289: /* trigger_cmd */ + case 286: /* trigger_cmd_list */ + case 291: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy157)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy33)); } break; - case 286: /* trigger_event */ + case 288: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy262).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy180).b); } break; - case 312: /* frame_bound */ - case 313: /* frame_bound_s */ - case 314: /* frame_bound_e */ + case 314: /* frame_bound */ + case 315: /* frame_bound_s */ + case 316: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy117).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy595).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -160700,404 +164124,408 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 188, /* (0) explain ::= EXPLAIN */ - 188, /* (1) explain ::= EXPLAIN QUERY PLAN */ - 187, /* (2) cmdx ::= cmd */ - 189, /* (3) cmd ::= BEGIN transtype trans_opt */ - 190, /* (4) transtype ::= */ - 190, /* (5) transtype ::= DEFERRED */ - 190, /* (6) transtype ::= IMMEDIATE */ - 190, /* (7) transtype ::= EXCLUSIVE */ - 189, /* (8) cmd ::= COMMIT|END trans_opt */ - 189, /* (9) cmd ::= ROLLBACK trans_opt */ - 189, /* (10) cmd ::= SAVEPOINT nm */ - 189, /* (11) cmd ::= RELEASE savepoint_opt nm */ - 189, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 194, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 196, /* (14) createkw ::= CREATE */ - 198, /* (15) ifnotexists ::= */ - 198, /* (16) ifnotexists ::= IF NOT EXISTS */ - 197, /* (17) temp ::= TEMP */ - 197, /* (18) temp ::= */ - 195, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ - 195, /* (20) create_table_args ::= AS select */ - 202, /* (21) table_options ::= */ - 202, /* (22) table_options ::= WITHOUT nm */ - 204, /* (23) columnname ::= nm typetoken */ - 206, /* (24) typetoken ::= */ - 206, /* (25) typetoken ::= typename LP signed RP */ - 206, /* (26) typetoken ::= typename LP signed COMMA signed RP */ - 207, /* (27) typename ::= typename ID|STRING */ - 211, /* (28) scanpt ::= */ - 212, /* (29) scantok ::= */ - 213, /* (30) ccons ::= CONSTRAINT nm */ - 213, /* (31) ccons ::= DEFAULT scantok term */ - 213, /* (32) ccons ::= DEFAULT LP expr RP */ - 213, /* (33) ccons ::= DEFAULT PLUS scantok term */ - 213, /* (34) ccons ::= DEFAULT MINUS scantok term */ - 213, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */ - 213, /* (36) ccons ::= NOT NULL onconf */ - 213, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 213, /* (38) ccons ::= UNIQUE onconf */ - 213, /* (39) ccons ::= CHECK LP expr RP */ - 213, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */ - 213, /* (41) ccons ::= defer_subclause */ - 213, /* (42) ccons ::= COLLATE ID|STRING */ - 222, /* (43) generated ::= LP expr RP */ - 222, /* (44) generated ::= LP expr RP ID */ - 218, /* (45) autoinc ::= */ - 218, /* (46) autoinc ::= AUTOINCR */ - 220, /* (47) refargs ::= */ - 220, /* (48) refargs ::= refargs refarg */ - 223, /* (49) refarg ::= MATCH nm */ - 223, /* (50) refarg ::= ON INSERT refact */ - 223, /* (51) refarg ::= ON DELETE refact */ - 223, /* (52) refarg ::= ON UPDATE refact */ - 224, /* (53) refact ::= SET NULL */ - 224, /* (54) refact ::= SET DEFAULT */ - 224, /* (55) refact ::= CASCADE */ - 224, /* (56) refact ::= RESTRICT */ - 224, /* (57) refact ::= NO ACTION */ - 221, /* (58) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 221, /* (59) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 225, /* (60) init_deferred_pred_opt ::= */ - 225, /* (61) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 225, /* (62) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 201, /* (63) conslist_opt ::= */ - 227, /* (64) tconscomma ::= COMMA */ - 228, /* (65) tcons ::= CONSTRAINT nm */ - 228, /* (66) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 228, /* (67) tcons ::= UNIQUE LP sortlist RP onconf */ - 228, /* (68) tcons ::= CHECK LP expr RP onconf */ - 228, /* (69) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 231, /* (70) defer_subclause_opt ::= */ - 216, /* (71) onconf ::= */ - 216, /* (72) onconf ::= ON CONFLICT resolvetype */ - 232, /* (73) orconf ::= */ - 232, /* (74) orconf ::= OR resolvetype */ - 233, /* (75) resolvetype ::= IGNORE */ - 233, /* (76) resolvetype ::= REPLACE */ - 189, /* (77) cmd ::= DROP TABLE ifexists fullname */ - 235, /* (78) ifexists ::= IF EXISTS */ - 235, /* (79) ifexists ::= */ - 189, /* (80) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 189, /* (81) cmd ::= DROP VIEW ifexists fullname */ - 189, /* (82) cmd ::= select */ - 203, /* (83) select ::= WITH wqlist selectnowith */ - 203, /* (84) select ::= WITH RECURSIVE wqlist selectnowith */ - 203, /* (85) select ::= selectnowith */ - 237, /* (86) selectnowith ::= selectnowith multiselect_op oneselect */ - 240, /* (87) multiselect_op ::= UNION */ - 240, /* (88) multiselect_op ::= UNION ALL */ - 240, /* (89) multiselect_op ::= EXCEPT|INTERSECT */ - 238, /* (90) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 238, /* (91) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - 250, /* (92) values ::= VALUES LP nexprlist RP */ - 250, /* (93) values ::= values COMMA LP nexprlist RP */ - 241, /* (94) distinct ::= DISTINCT */ - 241, /* (95) distinct ::= ALL */ - 241, /* (96) distinct ::= */ - 252, /* (97) sclp ::= */ - 242, /* (98) selcollist ::= sclp scanpt expr scanpt as */ - 242, /* (99) selcollist ::= sclp scanpt STAR */ - 242, /* (100) selcollist ::= sclp scanpt nm DOT STAR */ - 253, /* (101) as ::= AS nm */ - 253, /* (102) as ::= */ - 243, /* (103) from ::= */ - 243, /* (104) from ::= FROM seltablist */ - 255, /* (105) stl_prefix ::= seltablist joinop */ - 255, /* (106) stl_prefix ::= */ - 254, /* (107) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - 254, /* (108) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - 254, /* (109) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - 254, /* (110) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - 199, /* (111) dbnm ::= */ - 199, /* (112) dbnm ::= DOT nm */ - 236, /* (113) fullname ::= nm */ - 236, /* (114) fullname ::= nm DOT nm */ - 261, /* (115) xfullname ::= nm */ - 261, /* (116) xfullname ::= nm DOT nm */ - 261, /* (117) xfullname ::= nm DOT nm AS nm */ - 261, /* (118) xfullname ::= nm AS nm */ - 256, /* (119) joinop ::= COMMA|JOIN */ - 256, /* (120) joinop ::= JOIN_KW JOIN */ - 256, /* (121) joinop ::= JOIN_KW nm JOIN */ - 256, /* (122) joinop ::= JOIN_KW nm nm JOIN */ - 258, /* (123) on_opt ::= ON expr */ - 258, /* (124) on_opt ::= */ - 257, /* (125) indexed_opt ::= */ - 257, /* (126) indexed_opt ::= INDEXED BY nm */ - 257, /* (127) indexed_opt ::= NOT INDEXED */ - 259, /* (128) using_opt ::= USING LP idlist RP */ - 259, /* (129) using_opt ::= */ - 247, /* (130) orderby_opt ::= */ - 247, /* (131) orderby_opt ::= ORDER BY sortlist */ - 229, /* (132) sortlist ::= sortlist COMMA expr sortorder nulls */ - 229, /* (133) sortlist ::= expr sortorder nulls */ - 217, /* (134) sortorder ::= ASC */ - 217, /* (135) sortorder ::= DESC */ - 217, /* (136) sortorder ::= */ - 263, /* (137) nulls ::= NULLS FIRST */ - 263, /* (138) nulls ::= NULLS LAST */ - 263, /* (139) nulls ::= */ - 245, /* (140) groupby_opt ::= */ - 245, /* (141) groupby_opt ::= GROUP BY nexprlist */ - 246, /* (142) having_opt ::= */ - 246, /* (143) having_opt ::= HAVING expr */ - 248, /* (144) limit_opt ::= */ - 248, /* (145) limit_opt ::= LIMIT expr */ - 248, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ - 248, /* (147) limit_opt ::= LIMIT expr COMMA expr */ - 189, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 244, /* (149) where_opt ::= */ - 244, /* (150) where_opt ::= WHERE expr */ - 265, /* (151) where_opt_ret ::= */ - 265, /* (152) where_opt_ret ::= WHERE expr */ - 265, /* (153) where_opt_ret ::= RETURNING selcollist */ - 265, /* (154) where_opt_ret ::= WHERE expr RETURNING selcollist */ - 189, /* (155) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - 266, /* (156) setlist ::= setlist COMMA nm EQ expr */ - 266, /* (157) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 266, /* (158) setlist ::= nm EQ expr */ - 266, /* (159) setlist ::= LP idlist RP EQ expr */ - 189, /* (160) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 189, /* (161) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 269, /* (162) upsert ::= */ - 269, /* (163) upsert ::= RETURNING selcollist */ - 269, /* (164) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - 269, /* (165) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - 269, /* (166) upsert ::= ON CONFLICT DO NOTHING returning */ - 269, /* (167) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - 270, /* (168) returning ::= RETURNING selcollist */ - 267, /* (169) insert_cmd ::= INSERT orconf */ - 267, /* (170) insert_cmd ::= REPLACE */ - 268, /* (171) idlist_opt ::= */ - 268, /* (172) idlist_opt ::= LP idlist RP */ - 262, /* (173) idlist ::= idlist COMMA nm */ - 262, /* (174) idlist ::= nm */ - 215, /* (175) expr ::= LP expr RP */ - 215, /* (176) expr ::= ID|INDEXED */ - 215, /* (177) expr ::= JOIN_KW */ - 215, /* (178) expr ::= nm DOT nm */ - 215, /* (179) expr ::= nm DOT nm DOT nm */ - 214, /* (180) term ::= NULL|FLOAT|BLOB */ - 214, /* (181) term ::= STRING */ - 214, /* (182) term ::= INTEGER */ - 215, /* (183) expr ::= VARIABLE */ - 215, /* (184) expr ::= expr COLLATE ID|STRING */ - 215, /* (185) expr ::= CAST LP expr AS typetoken RP */ - 215, /* (186) expr ::= ID|INDEXED LP distinct exprlist RP */ - 215, /* (187) expr ::= ID|INDEXED LP STAR RP */ - 215, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - 215, /* (189) expr ::= ID|INDEXED LP STAR RP filter_over */ - 214, /* (190) term ::= CTIME_KW */ - 215, /* (191) expr ::= LP nexprlist COMMA expr RP */ - 215, /* (192) expr ::= expr AND expr */ - 215, /* (193) expr ::= expr OR expr */ - 215, /* (194) expr ::= expr LT|GT|GE|LE expr */ - 215, /* (195) expr ::= expr EQ|NE expr */ - 215, /* (196) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 215, /* (197) expr ::= expr PLUS|MINUS expr */ - 215, /* (198) expr ::= expr STAR|SLASH|REM expr */ - 215, /* (199) expr ::= expr CONCAT expr */ - 272, /* (200) likeop ::= NOT LIKE_KW|MATCH */ - 215, /* (201) expr ::= expr likeop expr */ - 215, /* (202) expr ::= expr likeop expr ESCAPE expr */ - 215, /* (203) expr ::= expr ISNULL|NOTNULL */ - 215, /* (204) expr ::= expr NOT NULL */ - 215, /* (205) expr ::= expr IS expr */ - 215, /* (206) expr ::= expr IS NOT expr */ - 215, /* (207) expr ::= NOT expr */ - 215, /* (208) expr ::= BITNOT expr */ - 215, /* (209) expr ::= PLUS|MINUS expr */ - 273, /* (210) between_op ::= BETWEEN */ - 273, /* (211) between_op ::= NOT BETWEEN */ - 215, /* (212) expr ::= expr between_op expr AND expr */ - 274, /* (213) in_op ::= IN */ - 274, /* (214) in_op ::= NOT IN */ - 215, /* (215) expr ::= expr in_op LP exprlist RP */ - 215, /* (216) expr ::= LP select RP */ - 215, /* (217) expr ::= expr in_op LP select RP */ - 215, /* (218) expr ::= expr in_op nm dbnm paren_exprlist */ - 215, /* (219) expr ::= EXISTS LP select RP */ - 215, /* (220) expr ::= CASE case_operand case_exprlist case_else END */ - 277, /* (221) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 277, /* (222) case_exprlist ::= WHEN expr THEN expr */ - 278, /* (223) case_else ::= ELSE expr */ - 278, /* (224) case_else ::= */ - 276, /* (225) case_operand ::= expr */ - 276, /* (226) case_operand ::= */ - 260, /* (227) exprlist ::= */ - 251, /* (228) nexprlist ::= nexprlist COMMA expr */ - 251, /* (229) nexprlist ::= expr */ - 275, /* (230) paren_exprlist ::= */ - 275, /* (231) paren_exprlist ::= LP exprlist RP */ - 189, /* (232) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 279, /* (233) uniqueflag ::= UNIQUE */ - 279, /* (234) uniqueflag ::= */ - 219, /* (235) eidlist_opt ::= */ - 219, /* (236) eidlist_opt ::= LP eidlist RP */ - 230, /* (237) eidlist ::= eidlist COMMA nm collate sortorder */ - 230, /* (238) eidlist ::= nm collate sortorder */ - 280, /* (239) collate ::= */ - 280, /* (240) collate ::= COLLATE ID|STRING */ - 189, /* (241) cmd ::= DROP INDEX ifexists fullname */ - 189, /* (242) cmd ::= VACUUM vinto */ - 189, /* (243) cmd ::= VACUUM nm vinto */ - 281, /* (244) vinto ::= INTO expr */ - 281, /* (245) vinto ::= */ - 189, /* (246) cmd ::= PRAGMA nm dbnm */ - 189, /* (247) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 189, /* (248) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 189, /* (249) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 189, /* (250) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 209, /* (251) plus_num ::= PLUS INTEGER|FLOAT */ - 210, /* (252) minus_num ::= MINUS INTEGER|FLOAT */ - 189, /* (253) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 283, /* (254) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 285, /* (255) trigger_time ::= BEFORE|AFTER */ - 285, /* (256) trigger_time ::= INSTEAD OF */ - 285, /* (257) trigger_time ::= */ - 286, /* (258) trigger_event ::= DELETE|INSERT */ - 286, /* (259) trigger_event ::= UPDATE */ - 286, /* (260) trigger_event ::= UPDATE OF idlist */ - 288, /* (261) when_clause ::= */ - 288, /* (262) when_clause ::= WHEN expr */ - 284, /* (263) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 284, /* (264) trigger_cmd_list ::= trigger_cmd SEMI */ - 290, /* (265) trnm ::= nm DOT nm */ - 291, /* (266) tridxby ::= INDEXED BY nm */ - 291, /* (267) tridxby ::= NOT INDEXED */ - 289, /* (268) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 289, /* (269) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 289, /* (270) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 289, /* (271) trigger_cmd ::= scanpt select scanpt */ - 215, /* (272) expr ::= RAISE LP IGNORE RP */ - 215, /* (273) expr ::= RAISE LP raisetype COMMA nm RP */ - 234, /* (274) raisetype ::= ROLLBACK */ - 234, /* (275) raisetype ::= ABORT */ - 234, /* (276) raisetype ::= FAIL */ - 189, /* (277) cmd ::= DROP TRIGGER ifexists fullname */ - 189, /* (278) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 189, /* (279) cmd ::= DETACH database_kw_opt expr */ - 293, /* (280) key_opt ::= */ - 293, /* (281) key_opt ::= KEY expr */ - 189, /* (282) cmd ::= REINDEX */ - 189, /* (283) cmd ::= REINDEX nm dbnm */ - 189, /* (284) cmd ::= ANALYZE */ - 189, /* (285) cmd ::= ANALYZE nm dbnm */ - 189, /* (286) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 189, /* (287) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 189, /* (288) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - 294, /* (289) add_column_fullname ::= fullname */ - 189, /* (290) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 189, /* (291) cmd ::= create_vtab */ - 189, /* (292) cmd ::= create_vtab LP vtabarglist RP */ - 296, /* (293) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 298, /* (294) vtabarg ::= */ - 299, /* (295) vtabargtoken ::= ANY */ - 299, /* (296) vtabargtoken ::= lp anylist RP */ - 300, /* (297) lp ::= LP */ - 264, /* (298) with ::= WITH wqlist */ - 264, /* (299) with ::= WITH RECURSIVE wqlist */ - 303, /* (300) wqas ::= AS */ - 303, /* (301) wqas ::= AS MATERIALIZED */ - 303, /* (302) wqas ::= AS NOT MATERIALIZED */ - 302, /* (303) wqitem ::= nm eidlist_opt wqas LP select RP */ - 239, /* (304) wqlist ::= wqitem */ - 239, /* (305) wqlist ::= wqlist COMMA wqitem */ - 304, /* (306) windowdefn_list ::= windowdefn */ - 304, /* (307) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 305, /* (308) windowdefn ::= nm AS LP window RP */ - 306, /* (309) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 306, /* (310) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 306, /* (311) window ::= ORDER BY sortlist frame_opt */ - 306, /* (312) window ::= nm ORDER BY sortlist frame_opt */ - 306, /* (313) window ::= frame_opt */ - 306, /* (314) window ::= nm frame_opt */ - 307, /* (315) frame_opt ::= */ - 307, /* (316) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 307, /* (317) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 311, /* (318) range_or_rows ::= RANGE|ROWS|GROUPS */ - 313, /* (319) frame_bound_s ::= frame_bound */ - 313, /* (320) frame_bound_s ::= UNBOUNDED PRECEDING */ - 314, /* (321) frame_bound_e ::= frame_bound */ - 314, /* (322) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 312, /* (323) frame_bound ::= expr PRECEDING|FOLLOWING */ - 312, /* (324) frame_bound ::= CURRENT ROW */ - 315, /* (325) frame_exclude_opt ::= */ - 315, /* (326) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 316, /* (327) frame_exclude ::= NO OTHERS */ - 316, /* (328) frame_exclude ::= CURRENT ROW */ - 316, /* (329) frame_exclude ::= GROUP|TIES */ - 249, /* (330) window_clause ::= WINDOW windowdefn_list */ - 271, /* (331) filter_over ::= filter_clause over_clause */ - 271, /* (332) filter_over ::= over_clause */ - 271, /* (333) filter_over ::= filter_clause */ - 310, /* (334) over_clause ::= OVER LP window RP */ - 310, /* (335) over_clause ::= OVER nm */ - 309, /* (336) filter_clause ::= FILTER LP WHERE expr RP */ - 184, /* (337) input ::= cmdlist */ - 185, /* (338) cmdlist ::= cmdlist ecmd */ - 185, /* (339) cmdlist ::= ecmd */ - 186, /* (340) ecmd ::= SEMI */ - 186, /* (341) ecmd ::= cmdx SEMI */ - 186, /* (342) ecmd ::= explain cmdx SEMI */ - 191, /* (343) trans_opt ::= */ - 191, /* (344) trans_opt ::= TRANSACTION */ - 191, /* (345) trans_opt ::= TRANSACTION nm */ - 193, /* (346) savepoint_opt ::= SAVEPOINT */ - 193, /* (347) savepoint_opt ::= */ - 189, /* (348) cmd ::= create_table create_table_args */ - 200, /* (349) columnlist ::= columnlist COMMA columnname carglist */ - 200, /* (350) columnlist ::= columnname carglist */ - 192, /* (351) nm ::= ID|INDEXED */ - 192, /* (352) nm ::= STRING */ - 192, /* (353) nm ::= JOIN_KW */ - 206, /* (354) typetoken ::= typename */ - 207, /* (355) typename ::= ID|STRING */ - 208, /* (356) signed ::= plus_num */ - 208, /* (357) signed ::= minus_num */ - 205, /* (358) carglist ::= carglist ccons */ - 205, /* (359) carglist ::= */ - 213, /* (360) ccons ::= NULL onconf */ - 213, /* (361) ccons ::= GENERATED ALWAYS AS generated */ - 213, /* (362) ccons ::= AS generated */ - 201, /* (363) conslist_opt ::= COMMA conslist */ - 226, /* (364) conslist ::= conslist tconscomma tcons */ - 226, /* (365) conslist ::= tcons */ - 227, /* (366) tconscomma ::= */ - 231, /* (367) defer_subclause_opt ::= defer_subclause */ - 233, /* (368) resolvetype ::= raisetype */ - 237, /* (369) selectnowith ::= oneselect */ - 238, /* (370) oneselect ::= values */ - 252, /* (371) sclp ::= selcollist COMMA */ - 253, /* (372) as ::= ID|STRING */ - 270, /* (373) returning ::= */ - 215, /* (374) expr ::= term */ - 272, /* (375) likeop ::= LIKE_KW|MATCH */ - 260, /* (376) exprlist ::= nexprlist */ - 282, /* (377) nmnum ::= plus_num */ - 282, /* (378) nmnum ::= nm */ - 282, /* (379) nmnum ::= ON */ - 282, /* (380) nmnum ::= DELETE */ - 282, /* (381) nmnum ::= DEFAULT */ - 209, /* (382) plus_num ::= INTEGER|FLOAT */ - 287, /* (383) foreach_clause ::= */ - 287, /* (384) foreach_clause ::= FOR EACH ROW */ - 290, /* (385) trnm ::= nm */ - 291, /* (386) tridxby ::= */ - 292, /* (387) database_kw_opt ::= DATABASE */ - 292, /* (388) database_kw_opt ::= */ - 295, /* (389) kwcolumn_opt ::= */ - 295, /* (390) kwcolumn_opt ::= COLUMNKW */ - 297, /* (391) vtabarglist ::= vtabarg */ - 297, /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ - 298, /* (393) vtabarg ::= vtabarg vtabargtoken */ - 301, /* (394) anylist ::= */ - 301, /* (395) anylist ::= anylist LP anylist RP */ - 301, /* (396) anylist ::= anylist ANY */ - 264, /* (397) with ::= */ + 189, /* (0) explain ::= EXPLAIN */ + 189, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 188, /* (2) cmdx ::= cmd */ + 190, /* (3) cmd ::= BEGIN transtype trans_opt */ + 191, /* (4) transtype ::= */ + 191, /* (5) transtype ::= DEFERRED */ + 191, /* (6) transtype ::= IMMEDIATE */ + 191, /* (7) transtype ::= EXCLUSIVE */ + 190, /* (8) cmd ::= COMMIT|END trans_opt */ + 190, /* (9) cmd ::= ROLLBACK trans_opt */ + 190, /* (10) cmd ::= SAVEPOINT nm */ + 190, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 190, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 195, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 197, /* (14) createkw ::= CREATE */ + 199, /* (15) ifnotexists ::= */ + 199, /* (16) ifnotexists ::= IF NOT EXISTS */ + 198, /* (17) temp ::= TEMP */ + 198, /* (18) temp ::= */ + 196, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ + 196, /* (20) create_table_args ::= AS select */ + 203, /* (21) table_option_set ::= */ + 203, /* (22) table_option_set ::= table_option_set COMMA table_option */ + 205, /* (23) table_option ::= WITHOUT nm */ + 205, /* (24) table_option ::= nm */ + 206, /* (25) columnname ::= nm typetoken */ + 208, /* (26) typetoken ::= */ + 208, /* (27) typetoken ::= typename LP signed RP */ + 208, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + 209, /* (29) typename ::= typename ID|STRING */ + 213, /* (30) scanpt ::= */ + 214, /* (31) scantok ::= */ + 215, /* (32) ccons ::= CONSTRAINT nm */ + 215, /* (33) ccons ::= DEFAULT scantok term */ + 215, /* (34) ccons ::= DEFAULT LP expr RP */ + 215, /* (35) ccons ::= DEFAULT PLUS scantok term */ + 215, /* (36) ccons ::= DEFAULT MINUS scantok term */ + 215, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + 215, /* (38) ccons ::= NOT NULL onconf */ + 215, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 215, /* (40) ccons ::= UNIQUE onconf */ + 215, /* (41) ccons ::= CHECK LP expr RP */ + 215, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + 215, /* (43) ccons ::= defer_subclause */ + 215, /* (44) ccons ::= COLLATE ID|STRING */ + 224, /* (45) generated ::= LP expr RP */ + 224, /* (46) generated ::= LP expr RP ID */ + 220, /* (47) autoinc ::= */ + 220, /* (48) autoinc ::= AUTOINCR */ + 222, /* (49) refargs ::= */ + 222, /* (50) refargs ::= refargs refarg */ + 225, /* (51) refarg ::= MATCH nm */ + 225, /* (52) refarg ::= ON INSERT refact */ + 225, /* (53) refarg ::= ON DELETE refact */ + 225, /* (54) refarg ::= ON UPDATE refact */ + 226, /* (55) refact ::= SET NULL */ + 226, /* (56) refact ::= SET DEFAULT */ + 226, /* (57) refact ::= CASCADE */ + 226, /* (58) refact ::= RESTRICT */ + 226, /* (59) refact ::= NO ACTION */ + 223, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 223, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 227, /* (62) init_deferred_pred_opt ::= */ + 227, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 227, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 202, /* (65) conslist_opt ::= */ + 229, /* (66) tconscomma ::= COMMA */ + 230, /* (67) tcons ::= CONSTRAINT nm */ + 230, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 230, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + 230, /* (70) tcons ::= CHECK LP expr RP onconf */ + 230, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 233, /* (72) defer_subclause_opt ::= */ + 218, /* (73) onconf ::= */ + 218, /* (74) onconf ::= ON CONFLICT resolvetype */ + 234, /* (75) orconf ::= */ + 234, /* (76) orconf ::= OR resolvetype */ + 235, /* (77) resolvetype ::= IGNORE */ + 235, /* (78) resolvetype ::= REPLACE */ + 190, /* (79) cmd ::= DROP TABLE ifexists fullname */ + 237, /* (80) ifexists ::= IF EXISTS */ + 237, /* (81) ifexists ::= */ + 190, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 190, /* (83) cmd ::= DROP VIEW ifexists fullname */ + 190, /* (84) cmd ::= select */ + 204, /* (85) select ::= WITH wqlist selectnowith */ + 204, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + 204, /* (87) select ::= selectnowith */ + 239, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + 242, /* (89) multiselect_op ::= UNION */ + 242, /* (90) multiselect_op ::= UNION ALL */ + 242, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + 240, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 240, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 252, /* (94) values ::= VALUES LP nexprlist RP */ + 252, /* (95) values ::= values COMMA LP nexprlist RP */ + 243, /* (96) distinct ::= DISTINCT */ + 243, /* (97) distinct ::= ALL */ + 243, /* (98) distinct ::= */ + 254, /* (99) sclp ::= */ + 244, /* (100) selcollist ::= sclp scanpt expr scanpt as */ + 244, /* (101) selcollist ::= sclp scanpt STAR */ + 244, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ + 255, /* (103) as ::= AS nm */ + 255, /* (104) as ::= */ + 245, /* (105) from ::= */ + 245, /* (106) from ::= FROM seltablist */ + 257, /* (107) stl_prefix ::= seltablist joinop */ + 257, /* (108) stl_prefix ::= */ + 256, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 256, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 256, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 256, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 200, /* (113) dbnm ::= */ + 200, /* (114) dbnm ::= DOT nm */ + 238, /* (115) fullname ::= nm */ + 238, /* (116) fullname ::= nm DOT nm */ + 263, /* (117) xfullname ::= nm */ + 263, /* (118) xfullname ::= nm DOT nm */ + 263, /* (119) xfullname ::= nm DOT nm AS nm */ + 263, /* (120) xfullname ::= nm AS nm */ + 258, /* (121) joinop ::= COMMA|JOIN */ + 258, /* (122) joinop ::= JOIN_KW JOIN */ + 258, /* (123) joinop ::= JOIN_KW nm JOIN */ + 258, /* (124) joinop ::= JOIN_KW nm nm JOIN */ + 260, /* (125) on_opt ::= ON expr */ + 260, /* (126) on_opt ::= */ + 259, /* (127) indexed_opt ::= */ + 259, /* (128) indexed_opt ::= INDEXED BY nm */ + 259, /* (129) indexed_opt ::= NOT INDEXED */ + 261, /* (130) using_opt ::= USING LP idlist RP */ + 261, /* (131) using_opt ::= */ + 249, /* (132) orderby_opt ::= */ + 249, /* (133) orderby_opt ::= ORDER BY sortlist */ + 231, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ + 231, /* (135) sortlist ::= expr sortorder nulls */ + 219, /* (136) sortorder ::= ASC */ + 219, /* (137) sortorder ::= DESC */ + 219, /* (138) sortorder ::= */ + 265, /* (139) nulls ::= NULLS FIRST */ + 265, /* (140) nulls ::= NULLS LAST */ + 265, /* (141) nulls ::= */ + 247, /* (142) groupby_opt ::= */ + 247, /* (143) groupby_opt ::= GROUP BY nexprlist */ + 248, /* (144) having_opt ::= */ + 248, /* (145) having_opt ::= HAVING expr */ + 250, /* (146) limit_opt ::= */ + 250, /* (147) limit_opt ::= LIMIT expr */ + 250, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ + 250, /* (149) limit_opt ::= LIMIT expr COMMA expr */ + 190, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 246, /* (151) where_opt ::= */ + 246, /* (152) where_opt ::= WHERE expr */ + 267, /* (153) where_opt_ret ::= */ + 267, /* (154) where_opt_ret ::= WHERE expr */ + 267, /* (155) where_opt_ret ::= RETURNING selcollist */ + 267, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 190, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 268, /* (158) setlist ::= setlist COMMA nm EQ expr */ + 268, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 268, /* (160) setlist ::= nm EQ expr */ + 268, /* (161) setlist ::= LP idlist RP EQ expr */ + 190, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 190, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 271, /* (164) upsert ::= */ + 271, /* (165) upsert ::= RETURNING selcollist */ + 271, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 271, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 271, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ + 271, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 272, /* (170) returning ::= RETURNING selcollist */ + 269, /* (171) insert_cmd ::= INSERT orconf */ + 269, /* (172) insert_cmd ::= REPLACE */ + 270, /* (173) idlist_opt ::= */ + 270, /* (174) idlist_opt ::= LP idlist RP */ + 264, /* (175) idlist ::= idlist COMMA nm */ + 264, /* (176) idlist ::= nm */ + 217, /* (177) expr ::= LP expr RP */ + 217, /* (178) expr ::= ID|INDEXED */ + 217, /* (179) expr ::= JOIN_KW */ + 217, /* (180) expr ::= nm DOT nm */ + 217, /* (181) expr ::= nm DOT nm DOT nm */ + 216, /* (182) term ::= NULL|FLOAT|BLOB */ + 216, /* (183) term ::= STRING */ + 216, /* (184) term ::= INTEGER */ + 217, /* (185) expr ::= VARIABLE */ + 217, /* (186) expr ::= expr COLLATE ID|STRING */ + 217, /* (187) expr ::= CAST LP expr AS typetoken RP */ + 217, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + 217, /* (189) expr ::= ID|INDEXED LP STAR RP */ + 217, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + 217, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + 216, /* (192) term ::= CTIME_KW */ + 217, /* (193) expr ::= LP nexprlist COMMA expr RP */ + 217, /* (194) expr ::= expr AND expr */ + 217, /* (195) expr ::= expr OR expr */ + 217, /* (196) expr ::= expr LT|GT|GE|LE expr */ + 217, /* (197) expr ::= expr EQ|NE expr */ + 217, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 217, /* (199) expr ::= expr PLUS|MINUS expr */ + 217, /* (200) expr ::= expr STAR|SLASH|REM expr */ + 217, /* (201) expr ::= expr CONCAT expr */ + 274, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + 217, /* (203) expr ::= expr likeop expr */ + 217, /* (204) expr ::= expr likeop expr ESCAPE expr */ + 217, /* (205) expr ::= expr ISNULL|NOTNULL */ + 217, /* (206) expr ::= expr NOT NULL */ + 217, /* (207) expr ::= expr IS expr */ + 217, /* (208) expr ::= expr IS NOT expr */ + 217, /* (209) expr ::= NOT expr */ + 217, /* (210) expr ::= BITNOT expr */ + 217, /* (211) expr ::= PLUS|MINUS expr */ + 217, /* (212) expr ::= expr PTR expr */ + 275, /* (213) between_op ::= BETWEEN */ + 275, /* (214) between_op ::= NOT BETWEEN */ + 217, /* (215) expr ::= expr between_op expr AND expr */ + 276, /* (216) in_op ::= IN */ + 276, /* (217) in_op ::= NOT IN */ + 217, /* (218) expr ::= expr in_op LP exprlist RP */ + 217, /* (219) expr ::= LP select RP */ + 217, /* (220) expr ::= expr in_op LP select RP */ + 217, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */ + 217, /* (222) expr ::= EXISTS LP select RP */ + 217, /* (223) expr ::= CASE case_operand case_exprlist case_else END */ + 279, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 279, /* (225) case_exprlist ::= WHEN expr THEN expr */ + 280, /* (226) case_else ::= ELSE expr */ + 280, /* (227) case_else ::= */ + 278, /* (228) case_operand ::= expr */ + 278, /* (229) case_operand ::= */ + 262, /* (230) exprlist ::= */ + 253, /* (231) nexprlist ::= nexprlist COMMA expr */ + 253, /* (232) nexprlist ::= expr */ + 277, /* (233) paren_exprlist ::= */ + 277, /* (234) paren_exprlist ::= LP exprlist RP */ + 190, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 281, /* (236) uniqueflag ::= UNIQUE */ + 281, /* (237) uniqueflag ::= */ + 221, /* (238) eidlist_opt ::= */ + 221, /* (239) eidlist_opt ::= LP eidlist RP */ + 232, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ + 232, /* (241) eidlist ::= nm collate sortorder */ + 282, /* (242) collate ::= */ + 282, /* (243) collate ::= COLLATE ID|STRING */ + 190, /* (244) cmd ::= DROP INDEX ifexists fullname */ + 190, /* (245) cmd ::= VACUUM vinto */ + 190, /* (246) cmd ::= VACUUM nm vinto */ + 283, /* (247) vinto ::= INTO expr */ + 283, /* (248) vinto ::= */ + 190, /* (249) cmd ::= PRAGMA nm dbnm */ + 190, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 190, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 190, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 190, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 211, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ + 212, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ + 190, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 285, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 287, /* (258) trigger_time ::= BEFORE|AFTER */ + 287, /* (259) trigger_time ::= INSTEAD OF */ + 287, /* (260) trigger_time ::= */ + 288, /* (261) trigger_event ::= DELETE|INSERT */ + 288, /* (262) trigger_event ::= UPDATE */ + 288, /* (263) trigger_event ::= UPDATE OF idlist */ + 290, /* (264) when_clause ::= */ + 290, /* (265) when_clause ::= WHEN expr */ + 286, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 286, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ + 292, /* (268) trnm ::= nm DOT nm */ + 293, /* (269) tridxby ::= INDEXED BY nm */ + 293, /* (270) tridxby ::= NOT INDEXED */ + 291, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 291, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 291, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 291, /* (274) trigger_cmd ::= scanpt select scanpt */ + 217, /* (275) expr ::= RAISE LP IGNORE RP */ + 217, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ + 236, /* (277) raisetype ::= ROLLBACK */ + 236, /* (278) raisetype ::= ABORT */ + 236, /* (279) raisetype ::= FAIL */ + 190, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ + 190, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 190, /* (282) cmd ::= DETACH database_kw_opt expr */ + 295, /* (283) key_opt ::= */ + 295, /* (284) key_opt ::= KEY expr */ + 190, /* (285) cmd ::= REINDEX */ + 190, /* (286) cmd ::= REINDEX nm dbnm */ + 190, /* (287) cmd ::= ANALYZE */ + 190, /* (288) cmd ::= ANALYZE nm dbnm */ + 190, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 190, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 190, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 296, /* (292) add_column_fullname ::= fullname */ + 190, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 190, /* (294) cmd ::= create_vtab */ + 190, /* (295) cmd ::= create_vtab LP vtabarglist RP */ + 298, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 300, /* (297) vtabarg ::= */ + 301, /* (298) vtabargtoken ::= ANY */ + 301, /* (299) vtabargtoken ::= lp anylist RP */ + 302, /* (300) lp ::= LP */ + 266, /* (301) with ::= WITH wqlist */ + 266, /* (302) with ::= WITH RECURSIVE wqlist */ + 305, /* (303) wqas ::= AS */ + 305, /* (304) wqas ::= AS MATERIALIZED */ + 305, /* (305) wqas ::= AS NOT MATERIALIZED */ + 304, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ + 241, /* (307) wqlist ::= wqitem */ + 241, /* (308) wqlist ::= wqlist COMMA wqitem */ + 306, /* (309) windowdefn_list ::= windowdefn */ + 306, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 307, /* (311) windowdefn ::= nm AS LP window RP */ + 308, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 308, /* (314) window ::= ORDER BY sortlist frame_opt */ + 308, /* (315) window ::= nm ORDER BY sortlist frame_opt */ + 308, /* (316) window ::= frame_opt */ + 308, /* (317) window ::= nm frame_opt */ + 309, /* (318) frame_opt ::= */ + 309, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 309, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 313, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + 315, /* (322) frame_bound_s ::= frame_bound */ + 315, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + 316, /* (324) frame_bound_e ::= frame_bound */ + 316, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 314, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + 314, /* (327) frame_bound ::= CURRENT ROW */ + 317, /* (328) frame_exclude_opt ::= */ + 317, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 318, /* (330) frame_exclude ::= NO OTHERS */ + 318, /* (331) frame_exclude ::= CURRENT ROW */ + 318, /* (332) frame_exclude ::= GROUP|TIES */ + 251, /* (333) window_clause ::= WINDOW windowdefn_list */ + 273, /* (334) filter_over ::= filter_clause over_clause */ + 273, /* (335) filter_over ::= over_clause */ + 273, /* (336) filter_over ::= filter_clause */ + 312, /* (337) over_clause ::= OVER LP window RP */ + 312, /* (338) over_clause ::= OVER nm */ + 311, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + 185, /* (340) input ::= cmdlist */ + 186, /* (341) cmdlist ::= cmdlist ecmd */ + 186, /* (342) cmdlist ::= ecmd */ + 187, /* (343) ecmd ::= SEMI */ + 187, /* (344) ecmd ::= cmdx SEMI */ + 187, /* (345) ecmd ::= explain cmdx SEMI */ + 192, /* (346) trans_opt ::= */ + 192, /* (347) trans_opt ::= TRANSACTION */ + 192, /* (348) trans_opt ::= TRANSACTION nm */ + 194, /* (349) savepoint_opt ::= SAVEPOINT */ + 194, /* (350) savepoint_opt ::= */ + 190, /* (351) cmd ::= create_table create_table_args */ + 203, /* (352) table_option_set ::= table_option */ + 201, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + 201, /* (354) columnlist ::= columnname carglist */ + 193, /* (355) nm ::= ID|INDEXED */ + 193, /* (356) nm ::= STRING */ + 193, /* (357) nm ::= JOIN_KW */ + 208, /* (358) typetoken ::= typename */ + 209, /* (359) typename ::= ID|STRING */ + 210, /* (360) signed ::= plus_num */ + 210, /* (361) signed ::= minus_num */ + 207, /* (362) carglist ::= carglist ccons */ + 207, /* (363) carglist ::= */ + 215, /* (364) ccons ::= NULL onconf */ + 215, /* (365) ccons ::= GENERATED ALWAYS AS generated */ + 215, /* (366) ccons ::= AS generated */ + 202, /* (367) conslist_opt ::= COMMA conslist */ + 228, /* (368) conslist ::= conslist tconscomma tcons */ + 228, /* (369) conslist ::= tcons */ + 229, /* (370) tconscomma ::= */ + 233, /* (371) defer_subclause_opt ::= defer_subclause */ + 235, /* (372) resolvetype ::= raisetype */ + 239, /* (373) selectnowith ::= oneselect */ + 240, /* (374) oneselect ::= values */ + 254, /* (375) sclp ::= selcollist COMMA */ + 255, /* (376) as ::= ID|STRING */ + 272, /* (377) returning ::= */ + 217, /* (378) expr ::= term */ + 274, /* (379) likeop ::= LIKE_KW|MATCH */ + 262, /* (380) exprlist ::= nexprlist */ + 284, /* (381) nmnum ::= plus_num */ + 284, /* (382) nmnum ::= nm */ + 284, /* (383) nmnum ::= ON */ + 284, /* (384) nmnum ::= DELETE */ + 284, /* (385) nmnum ::= DEFAULT */ + 211, /* (386) plus_num ::= INTEGER|FLOAT */ + 289, /* (387) foreach_clause ::= */ + 289, /* (388) foreach_clause ::= FOR EACH ROW */ + 292, /* (389) trnm ::= nm */ + 293, /* (390) tridxby ::= */ + 294, /* (391) database_kw_opt ::= DATABASE */ + 294, /* (392) database_kw_opt ::= */ + 297, /* (393) kwcolumn_opt ::= */ + 297, /* (394) kwcolumn_opt ::= COLUMNKW */ + 299, /* (395) vtabarglist ::= vtabarg */ + 299, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ + 300, /* (397) vtabarg ::= vtabarg vtabargtoken */ + 303, /* (398) anylist ::= */ + 303, /* (399) anylist ::= anylist LP anylist RP */ + 303, /* (400) anylist ::= anylist ANY */ + 266, /* (401) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -161122,385 +164550,389 @@ static const signed char yyRuleInfoNRhs[] = { -3, /* (16) ifnotexists ::= IF NOT EXISTS */ -1, /* (17) temp ::= TEMP */ 0, /* (18) temp ::= */ - -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ + -5, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_option_set */ -2, /* (20) create_table_args ::= AS select */ - 0, /* (21) table_options ::= */ - -2, /* (22) table_options ::= WITHOUT nm */ - -2, /* (23) columnname ::= nm typetoken */ - 0, /* (24) typetoken ::= */ - -4, /* (25) typetoken ::= typename LP signed RP */ - -6, /* (26) typetoken ::= typename LP signed COMMA signed RP */ - -2, /* (27) typename ::= typename ID|STRING */ - 0, /* (28) scanpt ::= */ - 0, /* (29) scantok ::= */ - -2, /* (30) ccons ::= CONSTRAINT nm */ - -3, /* (31) ccons ::= DEFAULT scantok term */ - -4, /* (32) ccons ::= DEFAULT LP expr RP */ - -4, /* (33) ccons ::= DEFAULT PLUS scantok term */ - -4, /* (34) ccons ::= DEFAULT MINUS scantok term */ - -3, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */ - -3, /* (36) ccons ::= NOT NULL onconf */ - -5, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - -2, /* (38) ccons ::= UNIQUE onconf */ - -4, /* (39) ccons ::= CHECK LP expr RP */ - -4, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */ - -1, /* (41) ccons ::= defer_subclause */ - -2, /* (42) ccons ::= COLLATE ID|STRING */ - -3, /* (43) generated ::= LP expr RP */ - -4, /* (44) generated ::= LP expr RP ID */ - 0, /* (45) autoinc ::= */ - -1, /* (46) autoinc ::= AUTOINCR */ - 0, /* (47) refargs ::= */ - -2, /* (48) refargs ::= refargs refarg */ - -2, /* (49) refarg ::= MATCH nm */ - -3, /* (50) refarg ::= ON INSERT refact */ - -3, /* (51) refarg ::= ON DELETE refact */ - -3, /* (52) refarg ::= ON UPDATE refact */ - -2, /* (53) refact ::= SET NULL */ - -2, /* (54) refact ::= SET DEFAULT */ - -1, /* (55) refact ::= CASCADE */ - -1, /* (56) refact ::= RESTRICT */ - -2, /* (57) refact ::= NO ACTION */ - -3, /* (58) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - -2, /* (59) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 0, /* (60) init_deferred_pred_opt ::= */ - -2, /* (61) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - -2, /* (62) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 0, /* (63) conslist_opt ::= */ - -1, /* (64) tconscomma ::= COMMA */ - -2, /* (65) tcons ::= CONSTRAINT nm */ - -7, /* (66) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - -5, /* (67) tcons ::= UNIQUE LP sortlist RP onconf */ - -5, /* (68) tcons ::= CHECK LP expr RP onconf */ - -10, /* (69) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 0, /* (70) defer_subclause_opt ::= */ - 0, /* (71) onconf ::= */ - -3, /* (72) onconf ::= ON CONFLICT resolvetype */ - 0, /* (73) orconf ::= */ - -2, /* (74) orconf ::= OR resolvetype */ - -1, /* (75) resolvetype ::= IGNORE */ - -1, /* (76) resolvetype ::= REPLACE */ - -4, /* (77) cmd ::= DROP TABLE ifexists fullname */ - -2, /* (78) ifexists ::= IF EXISTS */ - 0, /* (79) ifexists ::= */ - -9, /* (80) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - -4, /* (81) cmd ::= DROP VIEW ifexists fullname */ - -1, /* (82) cmd ::= select */ - -3, /* (83) select ::= WITH wqlist selectnowith */ - -4, /* (84) select ::= WITH RECURSIVE wqlist selectnowith */ - -1, /* (85) select ::= selectnowith */ - -3, /* (86) selectnowith ::= selectnowith multiselect_op oneselect */ - -1, /* (87) multiselect_op ::= UNION */ - -2, /* (88) multiselect_op ::= UNION ALL */ - -1, /* (89) multiselect_op ::= EXCEPT|INTERSECT */ - -9, /* (90) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - -10, /* (91) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - -4, /* (92) values ::= VALUES LP nexprlist RP */ - -5, /* (93) values ::= values COMMA LP nexprlist RP */ - -1, /* (94) distinct ::= DISTINCT */ - -1, /* (95) distinct ::= ALL */ - 0, /* (96) distinct ::= */ - 0, /* (97) sclp ::= */ - -5, /* (98) selcollist ::= sclp scanpt expr scanpt as */ - -3, /* (99) selcollist ::= sclp scanpt STAR */ - -5, /* (100) selcollist ::= sclp scanpt nm DOT STAR */ - -2, /* (101) as ::= AS nm */ - 0, /* (102) as ::= */ - 0, /* (103) from ::= */ - -2, /* (104) from ::= FROM seltablist */ - -2, /* (105) stl_prefix ::= seltablist joinop */ - 0, /* (106) stl_prefix ::= */ - -7, /* (107) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - -9, /* (108) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - -7, /* (109) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - -7, /* (110) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - 0, /* (111) dbnm ::= */ - -2, /* (112) dbnm ::= DOT nm */ - -1, /* (113) fullname ::= nm */ - -3, /* (114) fullname ::= nm DOT nm */ - -1, /* (115) xfullname ::= nm */ - -3, /* (116) xfullname ::= nm DOT nm */ - -5, /* (117) xfullname ::= nm DOT nm AS nm */ - -3, /* (118) xfullname ::= nm AS nm */ - -1, /* (119) joinop ::= COMMA|JOIN */ - -2, /* (120) joinop ::= JOIN_KW JOIN */ - -3, /* (121) joinop ::= JOIN_KW nm JOIN */ - -4, /* (122) joinop ::= JOIN_KW nm nm JOIN */ - -2, /* (123) on_opt ::= ON expr */ - 0, /* (124) on_opt ::= */ - 0, /* (125) indexed_opt ::= */ - -3, /* (126) indexed_opt ::= INDEXED BY nm */ - -2, /* (127) indexed_opt ::= NOT INDEXED */ - -4, /* (128) using_opt ::= USING LP idlist RP */ - 0, /* (129) using_opt ::= */ - 0, /* (130) orderby_opt ::= */ - -3, /* (131) orderby_opt ::= ORDER BY sortlist */ - -5, /* (132) sortlist ::= sortlist COMMA expr sortorder nulls */ - -3, /* (133) sortlist ::= expr sortorder nulls */ - -1, /* (134) sortorder ::= ASC */ - -1, /* (135) sortorder ::= DESC */ - 0, /* (136) sortorder ::= */ - -2, /* (137) nulls ::= NULLS FIRST */ - -2, /* (138) nulls ::= NULLS LAST */ - 0, /* (139) nulls ::= */ - 0, /* (140) groupby_opt ::= */ - -3, /* (141) groupby_opt ::= GROUP BY nexprlist */ - 0, /* (142) having_opt ::= */ - -2, /* (143) having_opt ::= HAVING expr */ - 0, /* (144) limit_opt ::= */ - -2, /* (145) limit_opt ::= LIMIT expr */ - -4, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ - -4, /* (147) limit_opt ::= LIMIT expr COMMA expr */ - -6, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ - 0, /* (149) where_opt ::= */ - -2, /* (150) where_opt ::= WHERE expr */ - 0, /* (151) where_opt_ret ::= */ - -2, /* (152) where_opt_ret ::= WHERE expr */ - -2, /* (153) where_opt_ret ::= RETURNING selcollist */ - -4, /* (154) where_opt_ret ::= WHERE expr RETURNING selcollist */ - -9, /* (155) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ - -5, /* (156) setlist ::= setlist COMMA nm EQ expr */ - -7, /* (157) setlist ::= setlist COMMA LP idlist RP EQ expr */ - -3, /* (158) setlist ::= nm EQ expr */ - -5, /* (159) setlist ::= LP idlist RP EQ expr */ - -7, /* (160) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - -8, /* (161) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ - 0, /* (162) upsert ::= */ - -2, /* (163) upsert ::= RETURNING selcollist */ - -12, /* (164) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ - -9, /* (165) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ - -5, /* (166) upsert ::= ON CONFLICT DO NOTHING returning */ - -8, /* (167) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ - -2, /* (168) returning ::= RETURNING selcollist */ - -2, /* (169) insert_cmd ::= INSERT orconf */ - -1, /* (170) insert_cmd ::= REPLACE */ - 0, /* (171) idlist_opt ::= */ - -3, /* (172) idlist_opt ::= LP idlist RP */ - -3, /* (173) idlist ::= idlist COMMA nm */ - -1, /* (174) idlist ::= nm */ - -3, /* (175) expr ::= LP expr RP */ - -1, /* (176) expr ::= ID|INDEXED */ - -1, /* (177) expr ::= JOIN_KW */ - -3, /* (178) expr ::= nm DOT nm */ - -5, /* (179) expr ::= nm DOT nm DOT nm */ - -1, /* (180) term ::= NULL|FLOAT|BLOB */ - -1, /* (181) term ::= STRING */ - -1, /* (182) term ::= INTEGER */ - -1, /* (183) expr ::= VARIABLE */ - -3, /* (184) expr ::= expr COLLATE ID|STRING */ - -6, /* (185) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (186) expr ::= ID|INDEXED LP distinct exprlist RP */ - -4, /* (187) expr ::= ID|INDEXED LP STAR RP */ - -6, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - -5, /* (189) expr ::= ID|INDEXED LP STAR RP filter_over */ - -1, /* (190) term ::= CTIME_KW */ - -5, /* (191) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (192) expr ::= expr AND expr */ - -3, /* (193) expr ::= expr OR expr */ - -3, /* (194) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (195) expr ::= expr EQ|NE expr */ - -3, /* (196) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (197) expr ::= expr PLUS|MINUS expr */ - -3, /* (198) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (199) expr ::= expr CONCAT expr */ - -2, /* (200) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (201) expr ::= expr likeop expr */ - -5, /* (202) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (203) expr ::= expr ISNULL|NOTNULL */ - -3, /* (204) expr ::= expr NOT NULL */ - -3, /* (205) expr ::= expr IS expr */ - -4, /* (206) expr ::= expr IS NOT expr */ - -2, /* (207) expr ::= NOT expr */ - -2, /* (208) expr ::= BITNOT expr */ - -2, /* (209) expr ::= PLUS|MINUS expr */ - -1, /* (210) between_op ::= BETWEEN */ - -2, /* (211) between_op ::= NOT BETWEEN */ - -5, /* (212) expr ::= expr between_op expr AND expr */ - -1, /* (213) in_op ::= IN */ - -2, /* (214) in_op ::= NOT IN */ - -5, /* (215) expr ::= expr in_op LP exprlist RP */ - -3, /* (216) expr ::= LP select RP */ - -5, /* (217) expr ::= expr in_op LP select RP */ - -5, /* (218) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (219) expr ::= EXISTS LP select RP */ - -5, /* (220) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (221) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (222) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (223) case_else ::= ELSE expr */ - 0, /* (224) case_else ::= */ - -1, /* (225) case_operand ::= expr */ - 0, /* (226) case_operand ::= */ - 0, /* (227) exprlist ::= */ - -3, /* (228) nexprlist ::= nexprlist COMMA expr */ - -1, /* (229) nexprlist ::= expr */ - 0, /* (230) paren_exprlist ::= */ - -3, /* (231) paren_exprlist ::= LP exprlist RP */ - -12, /* (232) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (233) uniqueflag ::= UNIQUE */ - 0, /* (234) uniqueflag ::= */ - 0, /* (235) eidlist_opt ::= */ - -3, /* (236) eidlist_opt ::= LP eidlist RP */ - -5, /* (237) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (238) eidlist ::= nm collate sortorder */ - 0, /* (239) collate ::= */ - -2, /* (240) collate ::= COLLATE ID|STRING */ - -4, /* (241) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (242) cmd ::= VACUUM vinto */ - -3, /* (243) cmd ::= VACUUM nm vinto */ - -2, /* (244) vinto ::= INTO expr */ - 0, /* (245) vinto ::= */ - -3, /* (246) cmd ::= PRAGMA nm dbnm */ - -5, /* (247) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (248) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (249) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (250) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (251) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (252) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (253) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (254) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (255) trigger_time ::= BEFORE|AFTER */ - -2, /* (256) trigger_time ::= INSTEAD OF */ - 0, /* (257) trigger_time ::= */ - -1, /* (258) trigger_event ::= DELETE|INSERT */ - -1, /* (259) trigger_event ::= UPDATE */ - -3, /* (260) trigger_event ::= UPDATE OF idlist */ - 0, /* (261) when_clause ::= */ - -2, /* (262) when_clause ::= WHEN expr */ - -3, /* (263) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (264) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (265) trnm ::= nm DOT nm */ - -3, /* (266) tridxby ::= INDEXED BY nm */ - -2, /* (267) tridxby ::= NOT INDEXED */ - -9, /* (268) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (269) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (270) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (271) trigger_cmd ::= scanpt select scanpt */ - -4, /* (272) expr ::= RAISE LP IGNORE RP */ - -6, /* (273) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (274) raisetype ::= ROLLBACK */ - -1, /* (275) raisetype ::= ABORT */ - -1, /* (276) raisetype ::= FAIL */ - -4, /* (277) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (278) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (279) cmd ::= DETACH database_kw_opt expr */ - 0, /* (280) key_opt ::= */ - -2, /* (281) key_opt ::= KEY expr */ - -1, /* (282) cmd ::= REINDEX */ - -3, /* (283) cmd ::= REINDEX nm dbnm */ - -1, /* (284) cmd ::= ANALYZE */ - -3, /* (285) cmd ::= ANALYZE nm dbnm */ - -6, /* (286) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (287) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -6, /* (288) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ - -1, /* (289) add_column_fullname ::= fullname */ - -8, /* (290) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (291) cmd ::= create_vtab */ - -4, /* (292) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (293) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (294) vtabarg ::= */ - -1, /* (295) vtabargtoken ::= ANY */ - -3, /* (296) vtabargtoken ::= lp anylist RP */ - -1, /* (297) lp ::= LP */ - -2, /* (298) with ::= WITH wqlist */ - -3, /* (299) with ::= WITH RECURSIVE wqlist */ - -1, /* (300) wqas ::= AS */ - -2, /* (301) wqas ::= AS MATERIALIZED */ - -3, /* (302) wqas ::= AS NOT MATERIALIZED */ - -6, /* (303) wqitem ::= nm eidlist_opt wqas LP select RP */ - -1, /* (304) wqlist ::= wqitem */ - -3, /* (305) wqlist ::= wqlist COMMA wqitem */ - -1, /* (306) windowdefn_list ::= windowdefn */ - -3, /* (307) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (308) windowdefn ::= nm AS LP window RP */ - -5, /* (309) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (310) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (311) window ::= ORDER BY sortlist frame_opt */ - -5, /* (312) window ::= nm ORDER BY sortlist frame_opt */ - -1, /* (313) window ::= frame_opt */ - -2, /* (314) window ::= nm frame_opt */ - 0, /* (315) frame_opt ::= */ - -3, /* (316) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (317) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (318) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (319) frame_bound_s ::= frame_bound */ - -2, /* (320) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (321) frame_bound_e ::= frame_bound */ - -2, /* (322) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (323) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (324) frame_bound ::= CURRENT ROW */ - 0, /* (325) frame_exclude_opt ::= */ - -2, /* (326) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (327) frame_exclude ::= NO OTHERS */ - -2, /* (328) frame_exclude ::= CURRENT ROW */ - -1, /* (329) frame_exclude ::= GROUP|TIES */ - -2, /* (330) window_clause ::= WINDOW windowdefn_list */ - -2, /* (331) filter_over ::= filter_clause over_clause */ - -1, /* (332) filter_over ::= over_clause */ - -1, /* (333) filter_over ::= filter_clause */ - -4, /* (334) over_clause ::= OVER LP window RP */ - -2, /* (335) over_clause ::= OVER nm */ - -5, /* (336) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (337) input ::= cmdlist */ - -2, /* (338) cmdlist ::= cmdlist ecmd */ - -1, /* (339) cmdlist ::= ecmd */ - -1, /* (340) ecmd ::= SEMI */ - -2, /* (341) ecmd ::= cmdx SEMI */ - -3, /* (342) ecmd ::= explain cmdx SEMI */ - 0, /* (343) trans_opt ::= */ - -1, /* (344) trans_opt ::= TRANSACTION */ - -2, /* (345) trans_opt ::= TRANSACTION nm */ - -1, /* (346) savepoint_opt ::= SAVEPOINT */ - 0, /* (347) savepoint_opt ::= */ - -2, /* (348) cmd ::= create_table create_table_args */ - -4, /* (349) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (350) columnlist ::= columnname carglist */ - -1, /* (351) nm ::= ID|INDEXED */ - -1, /* (352) nm ::= STRING */ - -1, /* (353) nm ::= JOIN_KW */ - -1, /* (354) typetoken ::= typename */ - -1, /* (355) typename ::= ID|STRING */ - -1, /* (356) signed ::= plus_num */ - -1, /* (357) signed ::= minus_num */ - -2, /* (358) carglist ::= carglist ccons */ - 0, /* (359) carglist ::= */ - -2, /* (360) ccons ::= NULL onconf */ - -4, /* (361) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (362) ccons ::= AS generated */ - -2, /* (363) conslist_opt ::= COMMA conslist */ - -3, /* (364) conslist ::= conslist tconscomma tcons */ - -1, /* (365) conslist ::= tcons */ - 0, /* (366) tconscomma ::= */ - -1, /* (367) defer_subclause_opt ::= defer_subclause */ - -1, /* (368) resolvetype ::= raisetype */ - -1, /* (369) selectnowith ::= oneselect */ - -1, /* (370) oneselect ::= values */ - -2, /* (371) sclp ::= selcollist COMMA */ - -1, /* (372) as ::= ID|STRING */ - 0, /* (373) returning ::= */ - -1, /* (374) expr ::= term */ - -1, /* (375) likeop ::= LIKE_KW|MATCH */ - -1, /* (376) exprlist ::= nexprlist */ - -1, /* (377) nmnum ::= plus_num */ - -1, /* (378) nmnum ::= nm */ - -1, /* (379) nmnum ::= ON */ - -1, /* (380) nmnum ::= DELETE */ - -1, /* (381) nmnum ::= DEFAULT */ - -1, /* (382) plus_num ::= INTEGER|FLOAT */ - 0, /* (383) foreach_clause ::= */ - -3, /* (384) foreach_clause ::= FOR EACH ROW */ - -1, /* (385) trnm ::= nm */ - 0, /* (386) tridxby ::= */ - -1, /* (387) database_kw_opt ::= DATABASE */ - 0, /* (388) database_kw_opt ::= */ - 0, /* (389) kwcolumn_opt ::= */ - -1, /* (390) kwcolumn_opt ::= COLUMNKW */ - -1, /* (391) vtabarglist ::= vtabarg */ - -3, /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (393) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (394) anylist ::= */ - -4, /* (395) anylist ::= anylist LP anylist RP */ - -2, /* (396) anylist ::= anylist ANY */ - 0, /* (397) with ::= */ + 0, /* (21) table_option_set ::= */ + -3, /* (22) table_option_set ::= table_option_set COMMA table_option */ + -2, /* (23) table_option ::= WITHOUT nm */ + -1, /* (24) table_option ::= nm */ + -2, /* (25) columnname ::= nm typetoken */ + 0, /* (26) typetoken ::= */ + -4, /* (27) typetoken ::= typename LP signed RP */ + -6, /* (28) typetoken ::= typename LP signed COMMA signed RP */ + -2, /* (29) typename ::= typename ID|STRING */ + 0, /* (30) scanpt ::= */ + 0, /* (31) scantok ::= */ + -2, /* (32) ccons ::= CONSTRAINT nm */ + -3, /* (33) ccons ::= DEFAULT scantok term */ + -4, /* (34) ccons ::= DEFAULT LP expr RP */ + -4, /* (35) ccons ::= DEFAULT PLUS scantok term */ + -4, /* (36) ccons ::= DEFAULT MINUS scantok term */ + -3, /* (37) ccons ::= DEFAULT scantok ID|INDEXED */ + -3, /* (38) ccons ::= NOT NULL onconf */ + -5, /* (39) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + -2, /* (40) ccons ::= UNIQUE onconf */ + -4, /* (41) ccons ::= CHECK LP expr RP */ + -4, /* (42) ccons ::= REFERENCES nm eidlist_opt refargs */ + -1, /* (43) ccons ::= defer_subclause */ + -2, /* (44) ccons ::= COLLATE ID|STRING */ + -3, /* (45) generated ::= LP expr RP */ + -4, /* (46) generated ::= LP expr RP ID */ + 0, /* (47) autoinc ::= */ + -1, /* (48) autoinc ::= AUTOINCR */ + 0, /* (49) refargs ::= */ + -2, /* (50) refargs ::= refargs refarg */ + -2, /* (51) refarg ::= MATCH nm */ + -3, /* (52) refarg ::= ON INSERT refact */ + -3, /* (53) refarg ::= ON DELETE refact */ + -3, /* (54) refarg ::= ON UPDATE refact */ + -2, /* (55) refact ::= SET NULL */ + -2, /* (56) refact ::= SET DEFAULT */ + -1, /* (57) refact ::= CASCADE */ + -1, /* (58) refact ::= RESTRICT */ + -2, /* (59) refact ::= NO ACTION */ + -3, /* (60) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + -2, /* (61) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 0, /* (62) init_deferred_pred_opt ::= */ + -2, /* (63) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + -2, /* (64) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 0, /* (65) conslist_opt ::= */ + -1, /* (66) tconscomma ::= COMMA */ + -2, /* (67) tcons ::= CONSTRAINT nm */ + -7, /* (68) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + -5, /* (69) tcons ::= UNIQUE LP sortlist RP onconf */ + -5, /* (70) tcons ::= CHECK LP expr RP onconf */ + -10, /* (71) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 0, /* (72) defer_subclause_opt ::= */ + 0, /* (73) onconf ::= */ + -3, /* (74) onconf ::= ON CONFLICT resolvetype */ + 0, /* (75) orconf ::= */ + -2, /* (76) orconf ::= OR resolvetype */ + -1, /* (77) resolvetype ::= IGNORE */ + -1, /* (78) resolvetype ::= REPLACE */ + -4, /* (79) cmd ::= DROP TABLE ifexists fullname */ + -2, /* (80) ifexists ::= IF EXISTS */ + 0, /* (81) ifexists ::= */ + -9, /* (82) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + -4, /* (83) cmd ::= DROP VIEW ifexists fullname */ + -1, /* (84) cmd ::= select */ + -3, /* (85) select ::= WITH wqlist selectnowith */ + -4, /* (86) select ::= WITH RECURSIVE wqlist selectnowith */ + -1, /* (87) select ::= selectnowith */ + -3, /* (88) selectnowith ::= selectnowith multiselect_op oneselect */ + -1, /* (89) multiselect_op ::= UNION */ + -2, /* (90) multiselect_op ::= UNION ALL */ + -1, /* (91) multiselect_op ::= EXCEPT|INTERSECT */ + -9, /* (92) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + -10, /* (93) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + -4, /* (94) values ::= VALUES LP nexprlist RP */ + -5, /* (95) values ::= values COMMA LP nexprlist RP */ + -1, /* (96) distinct ::= DISTINCT */ + -1, /* (97) distinct ::= ALL */ + 0, /* (98) distinct ::= */ + 0, /* (99) sclp ::= */ + -5, /* (100) selcollist ::= sclp scanpt expr scanpt as */ + -3, /* (101) selcollist ::= sclp scanpt STAR */ + -5, /* (102) selcollist ::= sclp scanpt nm DOT STAR */ + -2, /* (103) as ::= AS nm */ + 0, /* (104) as ::= */ + 0, /* (105) from ::= */ + -2, /* (106) from ::= FROM seltablist */ + -2, /* (107) stl_prefix ::= seltablist joinop */ + 0, /* (108) stl_prefix ::= */ + -7, /* (109) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + -9, /* (110) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + -7, /* (111) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + -7, /* (112) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 0, /* (113) dbnm ::= */ + -2, /* (114) dbnm ::= DOT nm */ + -1, /* (115) fullname ::= nm */ + -3, /* (116) fullname ::= nm DOT nm */ + -1, /* (117) xfullname ::= nm */ + -3, /* (118) xfullname ::= nm DOT nm */ + -5, /* (119) xfullname ::= nm DOT nm AS nm */ + -3, /* (120) xfullname ::= nm AS nm */ + -1, /* (121) joinop ::= COMMA|JOIN */ + -2, /* (122) joinop ::= JOIN_KW JOIN */ + -3, /* (123) joinop ::= JOIN_KW nm JOIN */ + -4, /* (124) joinop ::= JOIN_KW nm nm JOIN */ + -2, /* (125) on_opt ::= ON expr */ + 0, /* (126) on_opt ::= */ + 0, /* (127) indexed_opt ::= */ + -3, /* (128) indexed_opt ::= INDEXED BY nm */ + -2, /* (129) indexed_opt ::= NOT INDEXED */ + -4, /* (130) using_opt ::= USING LP idlist RP */ + 0, /* (131) using_opt ::= */ + 0, /* (132) orderby_opt ::= */ + -3, /* (133) orderby_opt ::= ORDER BY sortlist */ + -5, /* (134) sortlist ::= sortlist COMMA expr sortorder nulls */ + -3, /* (135) sortlist ::= expr sortorder nulls */ + -1, /* (136) sortorder ::= ASC */ + -1, /* (137) sortorder ::= DESC */ + 0, /* (138) sortorder ::= */ + -2, /* (139) nulls ::= NULLS FIRST */ + -2, /* (140) nulls ::= NULLS LAST */ + 0, /* (141) nulls ::= */ + 0, /* (142) groupby_opt ::= */ + -3, /* (143) groupby_opt ::= GROUP BY nexprlist */ + 0, /* (144) having_opt ::= */ + -2, /* (145) having_opt ::= HAVING expr */ + 0, /* (146) limit_opt ::= */ + -2, /* (147) limit_opt ::= LIMIT expr */ + -4, /* (148) limit_opt ::= LIMIT expr OFFSET expr */ + -4, /* (149) limit_opt ::= LIMIT expr COMMA expr */ + -6, /* (150) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 0, /* (151) where_opt ::= */ + -2, /* (152) where_opt ::= WHERE expr */ + 0, /* (153) where_opt_ret ::= */ + -2, /* (154) where_opt_ret ::= WHERE expr */ + -2, /* (155) where_opt_ret ::= RETURNING selcollist */ + -4, /* (156) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (157) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (158) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (159) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (160) setlist ::= nm EQ expr */ + -5, /* (161) setlist ::= LP idlist RP EQ expr */ + -7, /* (162) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (163) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (164) upsert ::= */ + -2, /* (165) upsert ::= RETURNING selcollist */ + -12, /* (166) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (167) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (168) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (169) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (170) returning ::= RETURNING selcollist */ + -2, /* (171) insert_cmd ::= INSERT orconf */ + -1, /* (172) insert_cmd ::= REPLACE */ + 0, /* (173) idlist_opt ::= */ + -3, /* (174) idlist_opt ::= LP idlist RP */ + -3, /* (175) idlist ::= idlist COMMA nm */ + -1, /* (176) idlist ::= nm */ + -3, /* (177) expr ::= LP expr RP */ + -1, /* (178) expr ::= ID|INDEXED */ + -1, /* (179) expr ::= JOIN_KW */ + -3, /* (180) expr ::= nm DOT nm */ + -5, /* (181) expr ::= nm DOT nm DOT nm */ + -1, /* (182) term ::= NULL|FLOAT|BLOB */ + -1, /* (183) term ::= STRING */ + -1, /* (184) term ::= INTEGER */ + -1, /* (185) expr ::= VARIABLE */ + -3, /* (186) expr ::= expr COLLATE ID|STRING */ + -6, /* (187) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (189) expr ::= ID|INDEXED LP STAR RP */ + -6, /* (190) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + -5, /* (191) expr ::= ID|INDEXED LP STAR RP filter_over */ + -1, /* (192) term ::= CTIME_KW */ + -5, /* (193) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (194) expr ::= expr AND expr */ + -3, /* (195) expr ::= expr OR expr */ + -3, /* (196) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (197) expr ::= expr EQ|NE expr */ + -3, /* (198) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (199) expr ::= expr PLUS|MINUS expr */ + -3, /* (200) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (201) expr ::= expr CONCAT expr */ + -2, /* (202) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (203) expr ::= expr likeop expr */ + -5, /* (204) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (205) expr ::= expr ISNULL|NOTNULL */ + -3, /* (206) expr ::= expr NOT NULL */ + -3, /* (207) expr ::= expr IS expr */ + -4, /* (208) expr ::= expr IS NOT expr */ + -2, /* (209) expr ::= NOT expr */ + -2, /* (210) expr ::= BITNOT expr */ + -2, /* (211) expr ::= PLUS|MINUS expr */ + -3, /* (212) expr ::= expr PTR expr */ + -1, /* (213) between_op ::= BETWEEN */ + -2, /* (214) between_op ::= NOT BETWEEN */ + -5, /* (215) expr ::= expr between_op expr AND expr */ + -1, /* (216) in_op ::= IN */ + -2, /* (217) in_op ::= NOT IN */ + -5, /* (218) expr ::= expr in_op LP exprlist RP */ + -3, /* (219) expr ::= LP select RP */ + -5, /* (220) expr ::= expr in_op LP select RP */ + -5, /* (221) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (222) expr ::= EXISTS LP select RP */ + -5, /* (223) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (224) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (225) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (226) case_else ::= ELSE expr */ + 0, /* (227) case_else ::= */ + -1, /* (228) case_operand ::= expr */ + 0, /* (229) case_operand ::= */ + 0, /* (230) exprlist ::= */ + -3, /* (231) nexprlist ::= nexprlist COMMA expr */ + -1, /* (232) nexprlist ::= expr */ + 0, /* (233) paren_exprlist ::= */ + -3, /* (234) paren_exprlist ::= LP exprlist RP */ + -12, /* (235) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (236) uniqueflag ::= UNIQUE */ + 0, /* (237) uniqueflag ::= */ + 0, /* (238) eidlist_opt ::= */ + -3, /* (239) eidlist_opt ::= LP eidlist RP */ + -5, /* (240) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (241) eidlist ::= nm collate sortorder */ + 0, /* (242) collate ::= */ + -2, /* (243) collate ::= COLLATE ID|STRING */ + -4, /* (244) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (245) cmd ::= VACUUM vinto */ + -3, /* (246) cmd ::= VACUUM nm vinto */ + -2, /* (247) vinto ::= INTO expr */ + 0, /* (248) vinto ::= */ + -3, /* (249) cmd ::= PRAGMA nm dbnm */ + -5, /* (250) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (251) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (252) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (253) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (254) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (255) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (256) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (257) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (258) trigger_time ::= BEFORE|AFTER */ + -2, /* (259) trigger_time ::= INSTEAD OF */ + 0, /* (260) trigger_time ::= */ + -1, /* (261) trigger_event ::= DELETE|INSERT */ + -1, /* (262) trigger_event ::= UPDATE */ + -3, /* (263) trigger_event ::= UPDATE OF idlist */ + 0, /* (264) when_clause ::= */ + -2, /* (265) when_clause ::= WHEN expr */ + -3, /* (266) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (267) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (268) trnm ::= nm DOT nm */ + -3, /* (269) tridxby ::= INDEXED BY nm */ + -2, /* (270) tridxby ::= NOT INDEXED */ + -9, /* (271) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (272) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (273) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (274) trigger_cmd ::= scanpt select scanpt */ + -4, /* (275) expr ::= RAISE LP IGNORE RP */ + -6, /* (276) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (277) raisetype ::= ROLLBACK */ + -1, /* (278) raisetype ::= ABORT */ + -1, /* (279) raisetype ::= FAIL */ + -4, /* (280) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (281) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (282) cmd ::= DETACH database_kw_opt expr */ + 0, /* (283) key_opt ::= */ + -2, /* (284) key_opt ::= KEY expr */ + -1, /* (285) cmd ::= REINDEX */ + -3, /* (286) cmd ::= REINDEX nm dbnm */ + -1, /* (287) cmd ::= ANALYZE */ + -3, /* (288) cmd ::= ANALYZE nm dbnm */ + -6, /* (289) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (290) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (291) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (292) add_column_fullname ::= fullname */ + -8, /* (293) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (294) cmd ::= create_vtab */ + -4, /* (295) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (296) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (297) vtabarg ::= */ + -1, /* (298) vtabargtoken ::= ANY */ + -3, /* (299) vtabargtoken ::= lp anylist RP */ + -1, /* (300) lp ::= LP */ + -2, /* (301) with ::= WITH wqlist */ + -3, /* (302) with ::= WITH RECURSIVE wqlist */ + -1, /* (303) wqas ::= AS */ + -2, /* (304) wqas ::= AS MATERIALIZED */ + -3, /* (305) wqas ::= AS NOT MATERIALIZED */ + -6, /* (306) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (307) wqlist ::= wqitem */ + -3, /* (308) wqlist ::= wqlist COMMA wqitem */ + -1, /* (309) windowdefn_list ::= windowdefn */ + -3, /* (310) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (311) windowdefn ::= nm AS LP window RP */ + -5, /* (312) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (313) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (314) window ::= ORDER BY sortlist frame_opt */ + -5, /* (315) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (316) window ::= frame_opt */ + -2, /* (317) window ::= nm frame_opt */ + 0, /* (318) frame_opt ::= */ + -3, /* (319) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (320) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (321) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (322) frame_bound_s ::= frame_bound */ + -2, /* (323) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (324) frame_bound_e ::= frame_bound */ + -2, /* (325) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (326) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (327) frame_bound ::= CURRENT ROW */ + 0, /* (328) frame_exclude_opt ::= */ + -2, /* (329) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (330) frame_exclude ::= NO OTHERS */ + -2, /* (331) frame_exclude ::= CURRENT ROW */ + -1, /* (332) frame_exclude ::= GROUP|TIES */ + -2, /* (333) window_clause ::= WINDOW windowdefn_list */ + -2, /* (334) filter_over ::= filter_clause over_clause */ + -1, /* (335) filter_over ::= over_clause */ + -1, /* (336) filter_over ::= filter_clause */ + -4, /* (337) over_clause ::= OVER LP window RP */ + -2, /* (338) over_clause ::= OVER nm */ + -5, /* (339) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (340) input ::= cmdlist */ + -2, /* (341) cmdlist ::= cmdlist ecmd */ + -1, /* (342) cmdlist ::= ecmd */ + -1, /* (343) ecmd ::= SEMI */ + -2, /* (344) ecmd ::= cmdx SEMI */ + -3, /* (345) ecmd ::= explain cmdx SEMI */ + 0, /* (346) trans_opt ::= */ + -1, /* (347) trans_opt ::= TRANSACTION */ + -2, /* (348) trans_opt ::= TRANSACTION nm */ + -1, /* (349) savepoint_opt ::= SAVEPOINT */ + 0, /* (350) savepoint_opt ::= */ + -2, /* (351) cmd ::= create_table create_table_args */ + -1, /* (352) table_option_set ::= table_option */ + -4, /* (353) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (354) columnlist ::= columnname carglist */ + -1, /* (355) nm ::= ID|INDEXED */ + -1, /* (356) nm ::= STRING */ + -1, /* (357) nm ::= JOIN_KW */ + -1, /* (358) typetoken ::= typename */ + -1, /* (359) typename ::= ID|STRING */ + -1, /* (360) signed ::= plus_num */ + -1, /* (361) signed ::= minus_num */ + -2, /* (362) carglist ::= carglist ccons */ + 0, /* (363) carglist ::= */ + -2, /* (364) ccons ::= NULL onconf */ + -4, /* (365) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (366) ccons ::= AS generated */ + -2, /* (367) conslist_opt ::= COMMA conslist */ + -3, /* (368) conslist ::= conslist tconscomma tcons */ + -1, /* (369) conslist ::= tcons */ + 0, /* (370) tconscomma ::= */ + -1, /* (371) defer_subclause_opt ::= defer_subclause */ + -1, /* (372) resolvetype ::= raisetype */ + -1, /* (373) selectnowith ::= oneselect */ + -1, /* (374) oneselect ::= values */ + -2, /* (375) sclp ::= selcollist COMMA */ + -1, /* (376) as ::= ID|STRING */ + 0, /* (377) returning ::= */ + -1, /* (378) expr ::= term */ + -1, /* (379) likeop ::= LIKE_KW|MATCH */ + -1, /* (380) exprlist ::= nexprlist */ + -1, /* (381) nmnum ::= plus_num */ + -1, /* (382) nmnum ::= nm */ + -1, /* (383) nmnum ::= ON */ + -1, /* (384) nmnum ::= DELETE */ + -1, /* (385) nmnum ::= DEFAULT */ + -1, /* (386) plus_num ::= INTEGER|FLOAT */ + 0, /* (387) foreach_clause ::= */ + -3, /* (388) foreach_clause ::= FOR EACH ROW */ + -1, /* (389) trnm ::= nm */ + 0, /* (390) tridxby ::= */ + -1, /* (391) database_kw_opt ::= DATABASE */ + 0, /* (392) database_kw_opt ::= */ + 0, /* (393) kwcolumn_opt ::= */ + -1, /* (394) kwcolumn_opt ::= COLUMNKW */ + -1, /* (395) vtabarglist ::= vtabarg */ + -3, /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (397) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (398) anylist ::= */ + -4, /* (399) anylist ::= anylist LP anylist RP */ + -2, /* (400) anylist ::= anylist ANY */ + 0, /* (401) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -161552,16 +164984,16 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy376);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy394);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy376 = TK_DEFERRED;} +{yymsp[1].minor.yy394 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 318: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==318); -{yymsp[0].minor.yy376 = yymsp[0].major; /*A-overwrites-X*/} + case 321: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==321); +{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -161584,7 +165016,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy376,0,0,yymsp[-2].minor.yy376); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy394,0,0,yymsp[-2].minor.yy394); } break; case 14: /* createkw ::= CREATE */ @@ -161592,95 +165024,112 @@ static YYACTIONTYPE yy_reduce( break; case 15: /* ifnotexists ::= */ case 18: /* temp ::= */ yytestcase(yyruleno==18); - case 21: /* table_options ::= */ yytestcase(yyruleno==21); - case 45: /* autoinc ::= */ yytestcase(yyruleno==45); - case 60: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==60); - case 70: /* defer_subclause_opt ::= */ yytestcase(yyruleno==70); - case 79: /* ifexists ::= */ yytestcase(yyruleno==79); - case 96: /* distinct ::= */ yytestcase(yyruleno==96); - case 239: /* collate ::= */ yytestcase(yyruleno==239); -{yymsp[1].minor.yy376 = 0;} + case 47: /* autoinc ::= */ yytestcase(yyruleno==47); + case 62: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==62); + case 72: /* defer_subclause_opt ::= */ yytestcase(yyruleno==72); + case 81: /* ifexists ::= */ yytestcase(yyruleno==81); + case 98: /* distinct ::= */ yytestcase(yyruleno==98); + case 242: /* collate ::= */ yytestcase(yyruleno==242); +{yymsp[1].minor.yy394 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy376 = 1;} +{yymsp[-2].minor.yy394 = 1;} break; case 17: /* temp ::= TEMP */ -{yymsp[0].minor.yy376 = pParse->db->init.busy==0;} +{yymsp[0].minor.yy394 = pParse->db->init.busy==0;} break; - case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ + case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_option_set */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy376,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy285,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy81); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy81); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy47); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); } break; - case 22: /* table_options ::= WITHOUT nm */ + case 21: /* table_option_set ::= */ +{yymsp[1].minor.yy285 = 0;} + break; + case 22: /* table_option_set ::= table_option_set COMMA table_option */ +{yylhsminor.yy285 = yymsp[-2].minor.yy285|yymsp[0].minor.yy285;} + yymsp[-2].minor.yy285 = yylhsminor.yy285; + break; + case 23: /* table_option ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy376 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy285 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy376 = 0; + yymsp[-1].minor.yy285 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } break; - case 23: /* columnname ::= nm typetoken */ -{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} + case 24: /* table_option ::= nm */ +{ + if( yymsp[0].minor.yy0.n==6 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"strict",6)==0 ){ + yylhsminor.yy285 = TF_Strict; + }else{ + yylhsminor.yy285 = 0; + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + } +} + yymsp[0].minor.yy285 = yylhsminor.yy285; break; - case 24: /* typetoken ::= */ - case 63: /* conslist_opt ::= */ yytestcase(yyruleno==63); - case 102: /* as ::= */ yytestcase(yyruleno==102); + case 25: /* columnname ::= nm typetoken */ +{sqlite3AddColumn(pParse,yymsp[-1].minor.yy0,yymsp[0].minor.yy0);} + break; + case 26: /* typetoken ::= */ + case 65: /* conslist_opt ::= */ yytestcase(yyruleno==65); + case 104: /* as ::= */ yytestcase(yyruleno==104); {yymsp[1].minor.yy0.n = 0; yymsp[1].minor.yy0.z = 0;} break; - case 25: /* typetoken ::= typename LP signed RP */ + case 27: /* typetoken ::= typename LP signed RP */ { yymsp[-3].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z); } break; - case 26: /* typetoken ::= typename LP signed COMMA signed RP */ + case 28: /* typetoken ::= typename LP signed COMMA signed RP */ { yymsp[-5].minor.yy0.n = (int)(&yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z); } break; - case 27: /* typename ::= typename ID|STRING */ + case 29: /* typename ::= typename ID|STRING */ {yymsp[-1].minor.yy0.n=yymsp[0].minor.yy0.n+(int)(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);} break; - case 28: /* scanpt ::= */ + case 30: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy504 = yyLookaheadToken.z; + yymsp[1].minor.yy522 = yyLookaheadToken.z; } break; - case 29: /* scantok ::= */ + case 31: /* scantok ::= */ { assert( yyLookahead!=YYNOCODE ); yymsp[1].minor.yy0 = yyLookaheadToken; } break; - case 30: /* ccons ::= CONSTRAINT nm */ - case 65: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==65); + case 32: /* ccons ::= CONSTRAINT nm */ + case 67: /* tcons ::= CONSTRAINT nm */ yytestcase(yyruleno==67); {pParse->constraintName = yymsp[0].minor.yy0;} break; - case 31: /* ccons ::= DEFAULT scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy404,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + case 33: /* ccons ::= DEFAULT scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; - case 32: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy404,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} + case 34: /* ccons ::= DEFAULT LP expr RP */ +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; - case 33: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy404,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} + case 35: /* ccons ::= DEFAULT PLUS scantok term */ +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy528,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; - case 34: /* ccons ::= DEFAULT MINUS scantok term */ + case 36: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy404, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy528, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; - case 35: /* ccons ::= DEFAULT scantok ID|INDEXED */ + case 37: /* ccons ::= DEFAULT scantok ID|INDEXED */ { Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0); if( p ){ @@ -161690,162 +165139,162 @@ static YYACTIONTYPE yy_reduce( sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); } break; - case 36: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy376);} + case 38: /* ccons ::= NOT NULL onconf */ +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy394);} break; - case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy376,yymsp[0].minor.yy376,yymsp[-2].minor.yy376);} + case 39: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy394,yymsp[0].minor.yy394,yymsp[-2].minor.yy394);} break; - case 38: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy376,0,0,0,0, + case 40: /* ccons ::= UNIQUE onconf */ +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy394,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; - case 39: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy404,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} + case 41: /* ccons ::= CHECK LP expr RP */ +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy528,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; - case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy70,yymsp[0].minor.yy376);} + case 42: /* ccons ::= REFERENCES nm eidlist_opt refargs */ +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy322,yymsp[0].minor.yy394);} break; - case 41: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy376);} + case 43: /* ccons ::= defer_subclause */ +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy394);} break; - case 42: /* ccons ::= COLLATE ID|STRING */ + case 44: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; - case 43: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy404,0);} + case 45: /* generated ::= LP expr RP */ +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy528,0);} break; - case 44: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy404,&yymsp[0].minor.yy0);} + case 46: /* generated ::= LP expr RP ID */ +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy528,&yymsp[0].minor.yy0);} break; - case 46: /* autoinc ::= AUTOINCR */ -{yymsp[0].minor.yy376 = 1;} + case 48: /* autoinc ::= AUTOINCR */ +{yymsp[0].minor.yy394 = 1;} break; - case 47: /* refargs ::= */ -{ yymsp[1].minor.yy376 = OE_None*0x0101; /* EV: R-19803-45884 */} + case 49: /* refargs ::= */ +{ yymsp[1].minor.yy394 = OE_None*0x0101; /* EV: R-19803-45884 */} break; - case 48: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy376 = (yymsp[-1].minor.yy376 & ~yymsp[0].minor.yy139.mask) | yymsp[0].minor.yy139.value; } + case 50: /* refargs ::= refargs refarg */ +{ yymsp[-1].minor.yy394 = (yymsp[-1].minor.yy394 & ~yymsp[0].minor.yy231.mask) | yymsp[0].minor.yy231.value; } break; - case 49: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy139.value = 0; yymsp[-1].minor.yy139.mask = 0x000000; } + case 51: /* refarg ::= MATCH nm */ +{ yymsp[-1].minor.yy231.value = 0; yymsp[-1].minor.yy231.mask = 0x000000; } break; - case 50: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy139.value = 0; yymsp[-2].minor.yy139.mask = 0x000000; } + case 52: /* refarg ::= ON INSERT refact */ +{ yymsp[-2].minor.yy231.value = 0; yymsp[-2].minor.yy231.mask = 0x000000; } break; - case 51: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy139.value = yymsp[0].minor.yy376; yymsp[-2].minor.yy139.mask = 0x0000ff; } + case 53: /* refarg ::= ON DELETE refact */ +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394; yymsp[-2].minor.yy231.mask = 0x0000ff; } break; - case 52: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy139.value = yymsp[0].minor.yy376<<8; yymsp[-2].minor.yy139.mask = 0x00ff00; } + case 54: /* refarg ::= ON UPDATE refact */ +{ yymsp[-2].minor.yy231.value = yymsp[0].minor.yy394<<8; yymsp[-2].minor.yy231.mask = 0x00ff00; } break; - case 53: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy376 = OE_SetNull; /* EV: R-33326-45252 */} + case 55: /* refact ::= SET NULL */ +{ yymsp[-1].minor.yy394 = OE_SetNull; /* EV: R-33326-45252 */} break; - case 54: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy376 = OE_SetDflt; /* EV: R-33326-45252 */} + case 56: /* refact ::= SET DEFAULT */ +{ yymsp[-1].minor.yy394 = OE_SetDflt; /* EV: R-33326-45252 */} break; - case 55: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy376 = OE_Cascade; /* EV: R-33326-45252 */} + case 57: /* refact ::= CASCADE */ +{ yymsp[0].minor.yy394 = OE_Cascade; /* EV: R-33326-45252 */} break; - case 56: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy376 = OE_Restrict; /* EV: R-33326-45252 */} + case 58: /* refact ::= RESTRICT */ +{ yymsp[0].minor.yy394 = OE_Restrict; /* EV: R-33326-45252 */} break; - case 57: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy376 = OE_None; /* EV: R-33326-45252 */} + case 59: /* refact ::= NO ACTION */ +{ yymsp[-1].minor.yy394 = OE_None; /* EV: R-33326-45252 */} break; - case 58: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy376 = 0;} + case 60: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ +{yymsp[-2].minor.yy394 = 0;} break; - case 59: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - case 74: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==74); - case 169: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==169); -{yymsp[-1].minor.yy376 = yymsp[0].minor.yy376;} + case 61: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + case 76: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==76); + case 171: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==171); +{yymsp[-1].minor.yy394 = yymsp[0].minor.yy394;} break; - case 61: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ - case 78: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==78); - case 211: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==211); - case 214: /* in_op ::= NOT IN */ yytestcase(yyruleno==214); - case 240: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==240); -{yymsp[-1].minor.yy376 = 1;} + case 63: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ + case 80: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==80); + case 214: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==214); + case 217: /* in_op ::= NOT IN */ yytestcase(yyruleno==217); + case 243: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==243); +{yymsp[-1].minor.yy394 = 1;} break; - case 62: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy376 = 0;} + case 64: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ +{yymsp[-1].minor.yy394 = 0;} break; - case 64: /* tconscomma ::= COMMA */ + case 66: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; - case 66: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy70,yymsp[0].minor.yy376,yymsp[-2].minor.yy376,0);} + case 68: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy322,yymsp[0].minor.yy394,yymsp[-2].minor.yy394,0);} break; - case 67: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy70,yymsp[0].minor.yy376,0,0,0,0, + case 69: /* tcons ::= UNIQUE LP sortlist RP onconf */ +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy322,yymsp[0].minor.yy394,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; - case 68: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy404,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} + case 70: /* tcons ::= CHECK LP expr RP onconf */ +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy528,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; - case 69: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + case 71: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy70, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy70, yymsp[-1].minor.yy376); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy376); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy322, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[-1].minor.yy394); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy394); } break; - case 71: /* onconf ::= */ - case 73: /* orconf ::= */ yytestcase(yyruleno==73); -{yymsp[1].minor.yy376 = OE_Default;} + case 73: /* onconf ::= */ + case 75: /* orconf ::= */ yytestcase(yyruleno==75); +{yymsp[1].minor.yy394 = OE_Default;} break; - case 72: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy376 = yymsp[0].minor.yy376;} + case 74: /* onconf ::= ON CONFLICT resolvetype */ +{yymsp[-2].minor.yy394 = yymsp[0].minor.yy394;} break; - case 75: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy376 = OE_Ignore;} + case 77: /* resolvetype ::= IGNORE */ +{yymsp[0].minor.yy394 = OE_Ignore;} break; - case 76: /* resolvetype ::= REPLACE */ - case 170: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==170); -{yymsp[0].minor.yy376 = OE_Replace;} + case 78: /* resolvetype ::= REPLACE */ + case 172: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==172); +{yymsp[0].minor.yy394 = OE_Replace;} break; - case 77: /* cmd ::= DROP TABLE ifexists fullname */ + case 79: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy153, 0, yymsp[-1].minor.yy376); + sqlite3DropTable(pParse, yymsp[0].minor.yy131, 0, yymsp[-1].minor.yy394); } break; - case 80: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + case 82: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy70, yymsp[0].minor.yy81, yymsp[-7].minor.yy376, yymsp[-5].minor.yy376); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy322, yymsp[0].minor.yy47, yymsp[-7].minor.yy394, yymsp[-5].minor.yy394); } break; - case 81: /* cmd ::= DROP VIEW ifexists fullname */ + case 83: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy153, 1, yymsp[-1].minor.yy376); + sqlite3DropTable(pParse, yymsp[0].minor.yy131, 1, yymsp[-1].minor.yy394); } break; - case 82: /* cmd ::= select */ + case 84: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy81, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy81); + sqlite3Select(pParse, yymsp[0].minor.yy47, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy47); } break; - case 83: /* select ::= WITH wqlist selectnowith */ -{yymsp[-2].minor.yy81 = attachWithToSelect(pParse,yymsp[0].minor.yy81,yymsp[-1].minor.yy103);} + case 85: /* select ::= WITH wqlist selectnowith */ +{yymsp[-2].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} break; - case 84: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{yymsp[-3].minor.yy81 = attachWithToSelect(pParse,yymsp[0].minor.yy81,yymsp[-1].minor.yy103);} + case 86: /* select ::= WITH RECURSIVE wqlist selectnowith */ +{yymsp[-3].minor.yy47 = attachWithToSelect(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy521);} break; - case 85: /* select ::= selectnowith */ + case 87: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy81; + Select *p = yymsp[0].minor.yy47; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy81 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy47 = p; /*A-overwrites-X*/ } break; - case 86: /* selectnowith ::= selectnowith multiselect_op oneselect */ + case 88: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy81; - Select *pLhs = yymsp[-2].minor.yy81; + Select *pRhs = yymsp[0].minor.yy47; + Select *pLhs = yymsp[-2].minor.yy47; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -161855,140 +165304,140 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy376; + pRhs->op = (u8)yymsp[-1].minor.yy394; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy376!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy394!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy81 = pRhs; + yymsp[-2].minor.yy47 = pRhs; } break; - case 87: /* multiselect_op ::= UNION */ - case 89: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==89); -{yymsp[0].minor.yy376 = yymsp[0].major; /*A-overwrites-OP*/} + case 89: /* multiselect_op ::= UNION */ + case 91: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==91); +{yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-OP*/} break; - case 88: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy376 = TK_ALL;} + case 90: /* multiselect_op ::= UNION ALL */ +{yymsp[-1].minor.yy394 = TK_ALL;} break; - case 90: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + case 92: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy81 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy70,yymsp[-5].minor.yy153,yymsp[-4].minor.yy404,yymsp[-3].minor.yy70,yymsp[-2].minor.yy404,yymsp[-1].minor.yy70,yymsp[-7].minor.yy376,yymsp[0].minor.yy404); + yymsp[-8].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy322,yymsp[-5].minor.yy131,yymsp[-4].minor.yy528,yymsp[-3].minor.yy322,yymsp[-2].minor.yy528,yymsp[-1].minor.yy322,yymsp[-7].minor.yy394,yymsp[0].minor.yy528); } break; - case 91: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + case 93: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy81 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy70,yymsp[-6].minor.yy153,yymsp[-5].minor.yy404,yymsp[-4].minor.yy70,yymsp[-3].minor.yy404,yymsp[-1].minor.yy70,yymsp[-8].minor.yy376,yymsp[0].minor.yy404); - if( yymsp[-9].minor.yy81 ){ - yymsp[-9].minor.yy81->pWinDefn = yymsp[-2].minor.yy49; + yymsp[-9].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy322,yymsp[-6].minor.yy131,yymsp[-5].minor.yy528,yymsp[-4].minor.yy322,yymsp[-3].minor.yy528,yymsp[-1].minor.yy322,yymsp[-8].minor.yy394,yymsp[0].minor.yy528); + if( yymsp[-9].minor.yy47 ){ + yymsp[-9].minor.yy47->pWinDefn = yymsp[-2].minor.yy41; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy49); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy41); } } break; - case 92: /* values ::= VALUES LP nexprlist RP */ + case 94: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy81 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy70,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy47 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values,0); } break; - case 93: /* values ::= values COMMA LP nexprlist RP */ + case 95: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy81; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy70,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy47; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy322,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pRight->pPrior = pLeft; - yymsp[-4].minor.yy81 = pRight; + yymsp[-4].minor.yy47 = pRight; }else{ - yymsp[-4].minor.yy81 = pLeft; + yymsp[-4].minor.yy47 = pLeft; } } break; - case 94: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy376 = SF_Distinct;} + case 96: /* distinct ::= DISTINCT */ +{yymsp[0].minor.yy394 = SF_Distinct;} break; - case 95: /* distinct ::= ALL */ -{yymsp[0].minor.yy376 = SF_All;} + case 97: /* distinct ::= ALL */ +{yymsp[0].minor.yy394 = SF_All;} break; - case 97: /* sclp ::= */ - case 130: /* orderby_opt ::= */ yytestcase(yyruleno==130); - case 140: /* groupby_opt ::= */ yytestcase(yyruleno==140); - case 227: /* exprlist ::= */ yytestcase(yyruleno==227); - case 230: /* paren_exprlist ::= */ yytestcase(yyruleno==230); - case 235: /* eidlist_opt ::= */ yytestcase(yyruleno==235); -{yymsp[1].minor.yy70 = 0;} + case 99: /* sclp ::= */ + case 132: /* orderby_opt ::= */ yytestcase(yyruleno==132); + case 142: /* groupby_opt ::= */ yytestcase(yyruleno==142); + case 230: /* exprlist ::= */ yytestcase(yyruleno==230); + case 233: /* paren_exprlist ::= */ yytestcase(yyruleno==233); + case 238: /* eidlist_opt ::= */ yytestcase(yyruleno==238); +{yymsp[1].minor.yy322 = 0;} break; - case 98: /* selcollist ::= sclp scanpt expr scanpt as */ + case 100: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy70, yymsp[-2].minor.yy404); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy70, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy70,yymsp[-3].minor.yy504,yymsp[-1].minor.yy504); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy322,yymsp[-3].minor.yy522,yymsp[-1].minor.yy522); } break; - case 99: /* selcollist ::= sclp scanpt STAR */ + case 101: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy70 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy70, p); + yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy322, p); } break; - case 100: /* selcollist ::= sclp scanpt nm DOT STAR */ + case 102: /* selcollist ::= sclp scanpt nm DOT STAR */ { Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); + Expr *pLeft = tokenExpr(pParse, TK_ID, yymsp[-2].minor.yy0); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70, pDot); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, pDot); } break; - case 101: /* as ::= AS nm */ - case 112: /* dbnm ::= DOT nm */ yytestcase(yyruleno==112); - case 251: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==251); - case 252: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==252); + case 103: /* as ::= AS nm */ + case 114: /* dbnm ::= DOT nm */ yytestcase(yyruleno==114); + case 254: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==254); + case 255: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==255); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; - case 103: /* from ::= */ - case 106: /* stl_prefix ::= */ yytestcase(yyruleno==106); -{yymsp[1].minor.yy153 = 0;} + case 105: /* from ::= */ + case 108: /* stl_prefix ::= */ yytestcase(yyruleno==108); +{yymsp[1].minor.yy131 = 0;} break; - case 104: /* from ::= FROM seltablist */ + case 106: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy153 = yymsp[0].minor.yy153; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy153); + yymsp[-1].minor.yy131 = yymsp[0].minor.yy131; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy131); } break; - case 105: /* stl_prefix ::= seltablist joinop */ + case 107: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy153 && yymsp[-1].minor.yy153->nSrc>0) ) yymsp[-1].minor.yy153->a[yymsp[-1].minor.yy153->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy376; + if( ALWAYS(yymsp[-1].minor.yy131 && yymsp[-1].minor.yy131->nSrc>0) ) yymsp[-1].minor.yy131->a[yymsp[-1].minor.yy131->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy394; } break; - case 107: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + case 109: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy153 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy153,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy404,yymsp[0].minor.yy436); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy153, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy131, &yymsp[-2].minor.yy0); } break; - case 108: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + case 110: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy153 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy153,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy404,yymsp[0].minor.yy436); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy153, yymsp[-4].minor.yy70); + yymsp[-8].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy131,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy131, yymsp[-4].minor.yy322); } break; - case 109: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + case 111: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy153 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy153,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy81,yymsp[-1].minor.yy404,yymsp[0].minor.yy436); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy47,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); } break; - case 110: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + case 112: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy153==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy404==0 && yymsp[0].minor.yy436==0 ){ - yymsp[-6].minor.yy153 = yymsp[-4].minor.yy153; - }else if( yymsp[-4].minor.yy153->nSrc==1 ){ - yymsp[-6].minor.yy153 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy153,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy404,yymsp[0].minor.yy436); - if( yymsp[-6].minor.yy153 ){ - SrcItem *pNew = &yymsp[-6].minor.yy153->a[yymsp[-6].minor.yy153->nSrc-1]; - SrcItem *pOld = yymsp[-4].minor.yy153->a; + if( yymsp[-6].minor.yy131==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy528==0 && yymsp[0].minor.yy254==0 ){ + yymsp[-6].minor.yy131 = yymsp[-4].minor.yy131; + }else if( yymsp[-4].minor.yy131->nSrc==1 ){ + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); + if( yymsp[-6].minor.yy131 ){ + SrcItem *pNew = &yymsp[-6].minor.yy131->a[yymsp[-6].minor.yy131->nSrc-1]; + SrcItem *pOld = yymsp[-4].minor.yy131->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -162001,267 +165450,263 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy153); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy131); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy153); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy153,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy153 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy153,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy404,yymsp[0].minor.yy436); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy131); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy131,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy131 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy131,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy528,yymsp[0].minor.yy254); } } break; - case 111: /* dbnm ::= */ - case 125: /* indexed_opt ::= */ yytestcase(yyruleno==125); + case 113: /* dbnm ::= */ + case 127: /* indexed_opt ::= */ yytestcase(yyruleno==127); {yymsp[1].minor.yy0.z=0; yymsp[1].minor.yy0.n=0;} break; - case 113: /* fullname ::= nm */ + case 115: /* fullname ::= nm */ { - yylhsminor.yy153 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy153 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy153->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy153 = yylhsminor.yy153; + yymsp[0].minor.yy131 = yylhsminor.yy131; break; - case 114: /* fullname ::= nm DOT nm */ + case 116: /* fullname ::= nm DOT nm */ { - yylhsminor.yy153 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy153 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy153->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy131 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy131->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy153 = yylhsminor.yy153; + yymsp[-2].minor.yy131 = yylhsminor.yy131; break; - case 115: /* xfullname ::= nm */ -{yymsp[0].minor.yy153 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} + case 117: /* xfullname ::= nm */ +{yymsp[0].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; - case 116: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy153 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 118: /* xfullname ::= nm DOT nm */ +{yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 117: /* xfullname ::= nm DOT nm AS nm */ + case 119: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy153 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy153 ) yymsp[-4].minor.yy153->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy131 ) yymsp[-4].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 118: /* xfullname ::= nm AS nm */ + case 120: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy153 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy153 ) yymsp[-2].minor.yy153->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy131 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy131 ) yymsp[-2].minor.yy131->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; - case 119: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy376 = JT_INNER; } + case 121: /* joinop ::= COMMA|JOIN */ +{ yymsp[0].minor.yy394 = JT_INNER; } break; - case 120: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy376 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} + case 122: /* joinop ::= JOIN_KW JOIN */ +{yymsp[-1].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; - case 121: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy376 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} + case 123: /* joinop ::= JOIN_KW nm JOIN */ +{yymsp[-2].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; - case 122: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy376 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} + case 124: /* joinop ::= JOIN_KW nm nm JOIN */ +{yymsp[-3].minor.yy394 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; - case 123: /* on_opt ::= ON expr */ - case 143: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==143); - case 150: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==150); - case 152: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==152); - case 223: /* case_else ::= ELSE expr */ yytestcase(yyruleno==223); - case 244: /* vinto ::= INTO expr */ yytestcase(yyruleno==244); -{yymsp[-1].minor.yy404 = yymsp[0].minor.yy404;} + case 125: /* on_opt ::= ON expr */ + case 145: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==145); + case 152: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==152); + case 154: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==154); + case 226: /* case_else ::= ELSE expr */ yytestcase(yyruleno==226); + case 247: /* vinto ::= INTO expr */ yytestcase(yyruleno==247); +{yymsp[-1].minor.yy528 = yymsp[0].minor.yy528;} break; - case 124: /* on_opt ::= */ - case 142: /* having_opt ::= */ yytestcase(yyruleno==142); - case 144: /* limit_opt ::= */ yytestcase(yyruleno==144); - case 149: /* where_opt ::= */ yytestcase(yyruleno==149); - case 151: /* where_opt_ret ::= */ yytestcase(yyruleno==151); - case 224: /* case_else ::= */ yytestcase(yyruleno==224); - case 226: /* case_operand ::= */ yytestcase(yyruleno==226); - case 245: /* vinto ::= */ yytestcase(yyruleno==245); -{yymsp[1].minor.yy404 = 0;} + case 126: /* on_opt ::= */ + case 144: /* having_opt ::= */ yytestcase(yyruleno==144); + case 146: /* limit_opt ::= */ yytestcase(yyruleno==146); + case 151: /* where_opt ::= */ yytestcase(yyruleno==151); + case 153: /* where_opt_ret ::= */ yytestcase(yyruleno==153); + case 227: /* case_else ::= */ yytestcase(yyruleno==227); + case 229: /* case_operand ::= */ yytestcase(yyruleno==229); + case 248: /* vinto ::= */ yytestcase(yyruleno==248); +{yymsp[1].minor.yy528 = 0;} break; - case 126: /* indexed_opt ::= INDEXED BY nm */ + case 128: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} break; - case 127: /* indexed_opt ::= NOT INDEXED */ + case 129: /* indexed_opt ::= NOT INDEXED */ {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; - case 128: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy436 = yymsp[-1].minor.yy436;} + case 130: /* using_opt ::= USING LP idlist RP */ +{yymsp[-3].minor.yy254 = yymsp[-1].minor.yy254;} break; - case 129: /* using_opt ::= */ - case 171: /* idlist_opt ::= */ yytestcase(yyruleno==171); -{yymsp[1].minor.yy436 = 0;} + case 131: /* using_opt ::= */ + case 173: /* idlist_opt ::= */ yytestcase(yyruleno==173); +{yymsp[1].minor.yy254 = 0;} break; - case 131: /* orderby_opt ::= ORDER BY sortlist */ - case 141: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==141); -{yymsp[-2].minor.yy70 = yymsp[0].minor.yy70;} + case 133: /* orderby_opt ::= ORDER BY sortlist */ + case 143: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==143); +{yymsp[-2].minor.yy322 = yymsp[0].minor.yy322;} break; - case 132: /* sortlist ::= sortlist COMMA expr sortorder nulls */ + case 134: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70,yymsp[-2].minor.yy404); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy70,yymsp[-1].minor.yy376,yymsp[0].minor.yy376); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322,yymsp[-2].minor.yy528); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); } break; - case 133: /* sortlist ::= expr sortorder nulls */ + case 135: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy70 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy404); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy70,yymsp[-1].minor.yy376,yymsp[0].minor.yy376); + yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy528); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy322,yymsp[-1].minor.yy394,yymsp[0].minor.yy394); } break; - case 134: /* sortorder ::= ASC */ -{yymsp[0].minor.yy376 = SQLITE_SO_ASC;} + case 136: /* sortorder ::= ASC */ +{yymsp[0].minor.yy394 = SQLITE_SO_ASC;} break; - case 135: /* sortorder ::= DESC */ -{yymsp[0].minor.yy376 = SQLITE_SO_DESC;} + case 137: /* sortorder ::= DESC */ +{yymsp[0].minor.yy394 = SQLITE_SO_DESC;} break; - case 136: /* sortorder ::= */ - case 139: /* nulls ::= */ yytestcase(yyruleno==139); -{yymsp[1].minor.yy376 = SQLITE_SO_UNDEFINED;} + case 138: /* sortorder ::= */ + case 141: /* nulls ::= */ yytestcase(yyruleno==141); +{yymsp[1].minor.yy394 = SQLITE_SO_UNDEFINED;} break; - case 137: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy376 = SQLITE_SO_ASC;} + case 139: /* nulls ::= NULLS FIRST */ +{yymsp[-1].minor.yy394 = SQLITE_SO_ASC;} break; - case 138: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy376 = SQLITE_SO_DESC;} + case 140: /* nulls ::= NULLS LAST */ +{yymsp[-1].minor.yy394 = SQLITE_SO_DESC;} break; - case 145: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy404 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy404,0);} + case 147: /* limit_opt ::= LIMIT expr */ +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,0);} break; - case 146: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy404 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy404,yymsp[0].minor.yy404);} + case 148: /* limit_opt ::= LIMIT expr OFFSET expr */ +{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 147: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy404 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy404,yymsp[-2].minor.yy404);} + case 149: /* limit_opt ::= LIMIT expr COMMA expr */ +{yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy528,yymsp[-2].minor.yy528);} break; - case 148: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + case 150: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy153, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy153,yymsp[0].minor.yy404,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy131, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy131,yymsp[0].minor.yy528,0,0); } break; - case 153: /* where_opt_ret ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy70); yymsp[-1].minor.yy404 = 0;} + case 155: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-1].minor.yy528 = 0;} break; - case 154: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy70); yymsp[-3].minor.yy404 = yymsp[-2].minor.yy404;} + case 156: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322); yymsp[-3].minor.yy528 = yymsp[-2].minor.yy528;} break; - case 155: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + case 157: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy153, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy70,"set list"); - yymsp[-5].minor.yy153 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy153, yymsp[-1].minor.yy153); - sqlite3Update(pParse,yymsp[-5].minor.yy153,yymsp[-2].minor.yy70,yymsp[0].minor.yy404,yymsp[-6].minor.yy376,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy131, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy322,"set list"); + yymsp[-5].minor.yy131 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy131, yymsp[-1].minor.yy131); + sqlite3Update(pParse,yymsp[-5].minor.yy131,yymsp[-2].minor.yy322,yymsp[0].minor.yy528,yymsp[-6].minor.yy394,0,0,0); } break; - case 156: /* setlist ::= setlist COMMA nm EQ expr */ + case 158: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy70, yymsp[0].minor.yy404); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy70, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy322, yymsp[0].minor.yy528); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, 1); } break; - case 157: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 159: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy70 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy70, yymsp[-3].minor.yy436, yymsp[0].minor.yy404); + yymsp[-6].minor.yy322 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy322, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); } break; - case 158: /* setlist ::= nm EQ expr */ + case 160: /* setlist ::= nm EQ expr */ { - yylhsminor.yy70 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy404); - sqlite3ExprListSetName(pParse, yylhsminor.yy70, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy322 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy528); + sqlite3ExprListSetName(pParse, yylhsminor.yy322, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy70 = yylhsminor.yy70; + yymsp[-2].minor.yy322 = yylhsminor.yy322; break; - case 159: /* setlist ::= LP idlist RP EQ expr */ + case 161: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy70 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy436, yymsp[0].minor.yy404); + yymsp[-4].minor.yy322 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy254, yymsp[0].minor.yy528); } break; - case 160: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 162: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy153, yymsp[-1].minor.yy81, yymsp[-2].minor.yy436, yymsp[-5].minor.yy376, yymsp[0].minor.yy190); + sqlite3Insert(pParse, yymsp[-3].minor.yy131, yymsp[-1].minor.yy47, yymsp[-2].minor.yy254, yymsp[-5].minor.yy394, yymsp[0].minor.yy444); } break; - case 161: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + case 163: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-4].minor.yy153, 0, yymsp[-3].minor.yy436, yymsp[-6].minor.yy376, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy131, 0, yymsp[-3].minor.yy254, yymsp[-6].minor.yy394, 0); } break; - case 162: /* upsert ::= */ -{ yymsp[1].minor.yy190 = 0; } + case 164: /* upsert ::= */ +{ yymsp[1].minor.yy444 = 0; } break; - case 163: /* upsert ::= RETURNING selcollist */ -{ yymsp[-1].minor.yy190 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy70); } + case 165: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy444 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy322); } break; - case 164: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ -{ yymsp[-11].minor.yy190 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy70,yymsp[-6].minor.yy404,yymsp[-2].minor.yy70,yymsp[-1].minor.yy404,yymsp[0].minor.yy190);} + case 166: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy322,yymsp[-6].minor.yy528,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,yymsp[0].minor.yy444);} break; - case 165: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ -{ yymsp[-8].minor.yy190 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy70,yymsp[-3].minor.yy404,0,0,yymsp[0].minor.yy190); } + case 167: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy444 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy322,yymsp[-3].minor.yy528,0,0,yymsp[0].minor.yy444); } break; - case 166: /* upsert ::= ON CONFLICT DO NOTHING returning */ -{ yymsp[-4].minor.yy190 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } + case 168: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; - case 167: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ -{ yymsp[-7].minor.yy190 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy70,yymsp[-1].minor.yy404,0);} + case 169: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy444 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528,0);} break; - case 168: /* returning ::= RETURNING selcollist */ -{sqlite3AddReturning(pParse,yymsp[0].minor.yy70);} + case 170: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy322);} break; - case 172: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy436 = yymsp[-1].minor.yy436;} + case 174: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy254 = yymsp[-1].minor.yy254;} break; - case 173: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy436 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy436,&yymsp[0].minor.yy0);} + case 175: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy254 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} break; - case 174: /* idlist ::= nm */ -{yymsp[0].minor.yy436 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 176: /* idlist ::= nm */ +{yymsp[0].minor.yy254 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; - case 175: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy404 = yymsp[-1].minor.yy404;} + case 177: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy528 = yymsp[-1].minor.yy528;} break; - case 176: /* expr ::= ID|INDEXED */ - case 177: /* expr ::= JOIN_KW */ yytestcase(yyruleno==177); -{yymsp[0].minor.yy404=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 178: /* expr ::= ID|INDEXED */ + case 179: /* expr ::= JOIN_KW */ yytestcase(yyruleno==179); +{yymsp[0].minor.yy528=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 178: /* expr ::= nm DOT nm */ + case 180: /* expr ::= nm DOT nm */ { - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); - sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); - } - yylhsminor.yy404 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy404 = yylhsminor.yy404; + yymsp[-2].minor.yy528 = yylhsminor.yy528; break; - case 179: /* expr ::= nm DOT nm DOT nm */ + case 181: /* expr ::= nm DOT nm DOT nm */ { - Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); - Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); + Expr *temp1 = tokenExpr(pParse,TK_ID,yymsp[-4].minor.yy0); + Expr *temp2 = tokenExpr(pParse,TK_ID,yymsp[-2].minor.yy0); + Expr *temp3 = tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); if( IN_RENAME_OBJECT ){ - sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); - sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); + sqlite3RenameTokenRemap(pParse, 0, temp1); } - yylhsminor.yy404 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy528 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy404 = yylhsminor.yy404; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 180: /* term ::= NULL|FLOAT|BLOB */ - case 181: /* term ::= STRING */ yytestcase(yyruleno==181); -{yymsp[0].minor.yy404=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 182: /* term ::= NULL|FLOAT|BLOB */ + case 183: /* term ::= STRING */ yytestcase(yyruleno==183); +{yymsp[0].minor.yy528=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 182: /* term ::= INTEGER */ + case 184: /* term ::= INTEGER */ { - yylhsminor.yy404 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy528 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + if( yylhsminor.yy528 ) yylhsminor.yy528->w.iOfst = (int)(yymsp[0].minor.yy0.z - pParse->zTail); } - yymsp[0].minor.yy404 = yylhsminor.yy404; + yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 183: /* expr ::= VARIABLE */ + case 185: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy404 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy404, n); + yymsp[0].minor.yy528 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy528, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -162270,159 +165715,167 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy404 = 0; + yymsp[0].minor.yy528 = 0; }else{ - yymsp[0].minor.yy404 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy404 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy404->iTable); + yymsp[0].minor.yy528 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy528 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy528->iTable); } } } break; - case 184: /* expr ::= expr COLLATE ID|STRING */ + case 186: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy404 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy404, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy528 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy528, &yymsp[0].minor.yy0, 1); } break; - case 185: /* expr ::= CAST LP expr AS typetoken RP */ + case 187: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy404 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy404, yymsp[-3].minor.yy404, 0); + yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy528, yymsp[-3].minor.yy528, 0); } break; - case 186: /* expr ::= ID|INDEXED LP distinct exprlist RP */ + case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy404 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy70, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy376); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy394); } - yymsp[-4].minor.yy404 = yylhsminor.yy404; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 187: /* expr ::= ID|INDEXED LP STAR RP */ + case 189: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy404 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy404 = yylhsminor.yy404; + yymsp[-3].minor.yy528 = yylhsminor.yy528; break; - case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + case 190: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { - yylhsminor.yy404 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy70, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy376); - sqlite3WindowAttach(pParse, yylhsminor.yy404, yymsp[0].minor.yy49); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy322, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy394); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } - yymsp[-5].minor.yy404 = yylhsminor.yy404; + yymsp[-5].minor.yy528 = yylhsminor.yy528; break; - case 189: /* expr ::= ID|INDEXED LP STAR RP filter_over */ + case 191: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { - yylhsminor.yy404 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy404, yymsp[0].minor.yy49); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy528, yymsp[0].minor.yy41); } - yymsp[-4].minor.yy404 = yylhsminor.yy404; + yymsp[-4].minor.yy528 = yylhsminor.yy528; break; - case 190: /* term ::= CTIME_KW */ + case 192: /* term ::= CTIME_KW */ { - yylhsminor.yy404 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy404 = yylhsminor.yy404; + yymsp[0].minor.yy528 = yylhsminor.yy528; break; - case 191: /* expr ::= LP nexprlist COMMA expr RP */ + case 193: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy70, yymsp[-1].minor.yy404); - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy404 ){ - yymsp[-4].minor.yy404->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy404->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy528->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 192: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy404=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy404,yymsp[0].minor.yy404);} + case 194: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy528=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 193: /* expr ::= expr OR expr */ - case 194: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==194); - case 195: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==195); - case 196: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==196); - case 197: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==197); - case 198: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==198); - case 199: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==199); -{yymsp[-2].minor.yy404=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy404,yymsp[0].minor.yy404);} + case 195: /* expr ::= expr OR expr */ + case 196: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==196); + case 197: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==199); + case 200: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==200); + case 201: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==201); +{yymsp[-2].minor.yy528=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy528,yymsp[0].minor.yy528);} break; - case 200: /* likeop ::= NOT LIKE_KW|MATCH */ + case 202: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 201: /* expr ::= expr likeop expr */ + case 203: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy404); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy404); - yymsp[-2].minor.yy404 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy404, 0); - if( yymsp[-2].minor.yy404 ) yymsp[-2].minor.yy404->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy528); + yymsp[-2].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy528, 0); + if( yymsp[-2].minor.yy528 ) yymsp[-2].minor.yy528->flags |= EP_InfixFunc; } break; - case 202: /* expr ::= expr likeop expr ESCAPE expr */ + case 204: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy404); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy404); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy404); - yymsp[-4].minor.yy404 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy404, 0); - if( yymsp[-4].minor.yy404 ) yymsp[-4].minor.yy404->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ) yymsp[-4].minor.yy528->flags |= EP_InfixFunc; } break; - case 203: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy404 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy404,0);} + case 205: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy528,0);} break; - case 204: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy404 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy404,0);} + case 206: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy528,0);} break; - case 205: /* expr ::= expr IS expr */ + case 207: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy404 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy404,yymsp[0].minor.yy404); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy404, yymsp[-2].minor.yy404, TK_ISNULL); + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-2].minor.yy528, TK_ISNULL); } break; - case 206: /* expr ::= expr IS NOT expr */ + case 208: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy404 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy404,yymsp[0].minor.yy404); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy404, yymsp[-3].minor.yy404, TK_NOTNULL); + yymsp[-3].minor.yy528 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy528,yymsp[0].minor.yy528); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy528, yymsp[-3].minor.yy528, TK_NOTNULL); } break; - case 207: /* expr ::= NOT expr */ - case 208: /* expr ::= BITNOT expr */ yytestcase(yyruleno==208); -{yymsp[-1].minor.yy404 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy404, 0);/*A-overwrites-B*/} + case 209: /* expr ::= NOT expr */ + case 210: /* expr ::= BITNOT expr */ yytestcase(yyruleno==210); +{yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy528, 0);/*A-overwrites-B*/} break; - case 209: /* expr ::= PLUS|MINUS expr */ + case 211: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy404 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy404, 0); + yymsp[-1].minor.yy528 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy528, 0); /*A-overwrites-B*/ } break; - case 210: /* between_op ::= BETWEEN */ - case 213: /* in_op ::= IN */ yytestcase(yyruleno==213); -{yymsp[0].minor.yy376 = 0;} - break; - case 212: /* expr ::= expr between_op expr AND expr */ + case 212: /* expr ::= expr PTR expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy404); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy404); - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy404, 0); - if( yymsp[-4].minor.yy404 ){ - yymsp[-4].minor.yy404->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, 0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse, pList, yymsp[0].minor.yy528); + yylhsminor.yy528 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); +} + yymsp[-2].minor.yy528 = yylhsminor.yy528; + break; + case 213: /* between_op ::= BETWEEN */ + case 216: /* in_op ::= IN */ yytestcase(yyruleno==216); +{yymsp[0].minor.yy394 = 0;} + break; + case 215: /* expr ::= expr between_op expr AND expr */ +{ + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy376 ) yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy404, 0); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 215: /* expr ::= expr in_op LP exprlist RP */ + case 218: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy70==0 ){ + if( yymsp[-1].minor.yy322==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -162431,197 +165884,205 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy404); - yymsp[-4].minor.yy404 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy376 ? "1" : "0"); - }else if( yymsp[-1].minor.yy70->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy70->a[0].pExpr) ){ - Expr *pRHS = yymsp[-1].minor.yy70->a[0].pExpr; - yymsp[-1].minor.yy70->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy70); - pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy404, pRHS); - if( yymsp[-3].minor.yy376 ) yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy404, 0); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy528); + yymsp[-4].minor.yy528 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy394 ? "1" : "0"); }else{ - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy404, 0); - if( yymsp[-4].minor.yy404 ){ - yymsp[-4].minor.yy404->x.pList = yymsp[-1].minor.yy70; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy404); + Expr *pRHS = yymsp[-1].minor.yy322->a[0].pExpr; + if( yymsp[-1].minor.yy322->nExpr==1 && sqlite3ExprIsConstant(pRHS) && yymsp[-4].minor.yy528->op!=TK_VECTOR ){ + yymsp[-1].minor.yy322->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy528, pRHS); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy70); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + if( yymsp[-4].minor.yy528==0 ){ + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy322); + }else if( yymsp[-4].minor.yy528->pLeft->op==TK_VECTOR ){ + int nExpr = yymsp[-4].minor.yy528->pLeft->x.pList->nExpr; + Select *pSelectRHS = sqlite3ExprListToValues(pParse, nExpr, yymsp[-1].minor.yy322); + if( pSelectRHS ){ + parserDoubleLinkSelect(pParse, pSelectRHS); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelectRHS); + } + }else{ + yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy322; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); + } } - if( yymsp[-3].minor.yy376 ) yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy404, 0); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } } break; - case 216: /* expr ::= LP select RP */ + case 219: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy404 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy404, yymsp[-1].minor.yy81); + yymsp[-2].minor.yy528 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy528, yymsp[-1].minor.yy47); } break; - case 217: /* expr ::= expr in_op LP select RP */ + case 220: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy404, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy404, yymsp[-1].minor.yy81); - if( yymsp[-3].minor.yy376 ) yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy404, 0); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, yymsp[-1].minor.yy47); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 218: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 221: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy70 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy70); - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy404, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy404, pSelect); - if( yymsp[-3].minor.yy376 ) yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy404, 0); + if( yymsp[0].minor.yy322 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy322); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy528, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy528, pSelect); + if( yymsp[-3].minor.yy394 ) yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy528, 0); } break; - case 219: /* expr ::= EXISTS LP select RP */ + case 222: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy404 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy81); + p = yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy47); } break; - case 220: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 223: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy404 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy404, 0); - if( yymsp[-4].minor.yy404 ){ - yymsp[-4].minor.yy404->x.pList = yymsp[-1].minor.yy404 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy70,yymsp[-1].minor.yy404) : yymsp[-2].minor.yy70; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy404); + yymsp[-4].minor.yy528 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy528, 0); + if( yymsp[-4].minor.yy528 ){ + yymsp[-4].minor.yy528->x.pList = yymsp[-1].minor.yy528 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[-1].minor.yy528) : yymsp[-2].minor.yy322; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy528); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy70); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy404); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy322); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); } } break; - case 221: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 224: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70, yymsp[-2].minor.yy404); - yymsp[-4].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy70, yymsp[0].minor.yy404); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[-2].minor.yy528); + yymsp[-4].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy322, yymsp[0].minor.yy528); } break; - case 222: /* case_exprlist ::= WHEN expr THEN expr */ + case 225: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy70 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy404); - yymsp[-3].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy70, yymsp[0].minor.yy404); + yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy528); + yymsp[-3].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy322, yymsp[0].minor.yy528); } break; - case 225: /* case_operand ::= expr */ -{yymsp[0].minor.yy404 = yymsp[0].minor.yy404; /*A-overwrites-X*/} + case 228: /* case_operand ::= expr */ +{yymsp[0].minor.yy528 = yymsp[0].minor.yy528; /*A-overwrites-X*/} break; - case 228: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy70 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy70,yymsp[0].minor.yy404);} + case 231: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy322 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy322,yymsp[0].minor.yy528);} break; - case 229: /* nexprlist ::= expr */ -{yymsp[0].minor.yy70 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy404); /*A-overwrites-Y*/} + case 232: /* nexprlist ::= expr */ +{yymsp[0].minor.yy322 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy528); /*A-overwrites-Y*/} break; - case 231: /* paren_exprlist ::= LP exprlist RP */ - case 236: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==236); -{yymsp[-2].minor.yy70 = yymsp[-1].minor.yy70;} + case 234: /* paren_exprlist ::= LP exprlist RP */ + case 239: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==239); +{yymsp[-2].minor.yy322 = yymsp[-1].minor.yy322;} break; - case 232: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 235: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy70, yymsp[-10].minor.yy376, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy404, SQLITE_SO_ASC, yymsp[-8].minor.yy376, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy322, yymsp[-10].minor.yy394, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy528, SQLITE_SO_ASC, yymsp[-8].minor.yy394, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 233: /* uniqueflag ::= UNIQUE */ - case 275: /* raisetype ::= ABORT */ yytestcase(yyruleno==275); -{yymsp[0].minor.yy376 = OE_Abort;} + case 236: /* uniqueflag ::= UNIQUE */ + case 278: /* raisetype ::= ABORT */ yytestcase(yyruleno==278); +{yymsp[0].minor.yy394 = OE_Abort;} break; - case 234: /* uniqueflag ::= */ -{yymsp[1].minor.yy376 = OE_None;} + case 237: /* uniqueflag ::= */ +{yymsp[1].minor.yy394 = OE_None;} break; - case 237: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 240: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy70 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy70, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy376, yymsp[0].minor.yy376); + yymsp[-4].minor.yy322 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy322, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); } break; - case 238: /* eidlist ::= nm collate sortorder */ + case 241: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy70 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy376, yymsp[0].minor.yy376); /*A-overwrites-Y*/ + yymsp[-2].minor.yy322 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy394, yymsp[0].minor.yy394); /*A-overwrites-Y*/ } break; - case 241: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy153, yymsp[-1].minor.yy376);} + case 244: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy131, yymsp[-1].minor.yy394);} break; - case 242: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy404);} + case 245: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy528);} break; - case 243: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy404);} + case 246: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy528);} break; - case 246: /* cmd ::= PRAGMA nm dbnm */ + case 249: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 247: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 250: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 248: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 249: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 252: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 250: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 253: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 253: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 256: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy157, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy33, &all); } break; - case 254: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 257: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy376, yymsp[-4].minor.yy262.a, yymsp[-4].minor.yy262.b, yymsp[-2].minor.yy153, yymsp[0].minor.yy404, yymsp[-10].minor.yy376, yymsp[-8].minor.yy376); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy394, yymsp[-4].minor.yy180.a, yymsp[-4].minor.yy180.b, yymsp[-2].minor.yy131, yymsp[0].minor.yy528, yymsp[-10].minor.yy394, yymsp[-8].minor.yy394); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 255: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy376 = yymsp[0].major; /*A-overwrites-X*/ } + case 258: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy394 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 256: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy376 = TK_INSTEAD;} + case 259: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy394 = TK_INSTEAD;} break; - case 257: /* trigger_time ::= */ -{ yymsp[1].minor.yy376 = TK_BEFORE; } + case 260: /* trigger_time ::= */ +{ yymsp[1].minor.yy394 = TK_BEFORE; } break; - case 258: /* trigger_event ::= DELETE|INSERT */ - case 259: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==259); -{yymsp[0].minor.yy262.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy262.b = 0;} + case 261: /* trigger_event ::= DELETE|INSERT */ + case 262: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==262); +{yymsp[0].minor.yy180.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy180.b = 0;} break; - case 260: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy262.a = TK_UPDATE; yymsp[-2].minor.yy262.b = yymsp[0].minor.yy436;} + case 263: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy180.a = TK_UPDATE; yymsp[-2].minor.yy180.b = yymsp[0].minor.yy254;} break; - case 261: /* when_clause ::= */ - case 280: /* key_opt ::= */ yytestcase(yyruleno==280); -{ yymsp[1].minor.yy404 = 0; } + case 264: /* when_clause ::= */ + case 283: /* key_opt ::= */ yytestcase(yyruleno==283); +{ yymsp[1].minor.yy528 = 0; } break; - case 262: /* when_clause ::= WHEN expr */ - case 281: /* key_opt ::= KEY expr */ yytestcase(yyruleno==281); -{ yymsp[-1].minor.yy404 = yymsp[0].minor.yy404; } + case 265: /* when_clause ::= WHEN expr */ + case 284: /* key_opt ::= KEY expr */ yytestcase(yyruleno==284); +{ yymsp[-1].minor.yy528 = yymsp[0].minor.yy528; } break; - case 263: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 266: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy157!=0 ); - yymsp[-2].minor.yy157->pLast->pNext = yymsp[-1].minor.yy157; - yymsp[-2].minor.yy157->pLast = yymsp[-1].minor.yy157; + assert( yymsp[-2].minor.yy33!=0 ); + yymsp[-2].minor.yy33->pLast->pNext = yymsp[-1].minor.yy33; + yymsp[-2].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 264: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 267: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy157!=0 ); - yymsp[-1].minor.yy157->pLast = yymsp[-1].minor.yy157; + assert( yymsp[-1].minor.yy33!=0 ); + yymsp[-1].minor.yy33->pLast = yymsp[-1].minor.yy33; } break; - case 265: /* trnm ::= nm DOT nm */ + case 268: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -162629,368 +166090,369 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 266: /* tridxby ::= INDEXED BY nm */ + case 269: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 267: /* tridxby ::= NOT INDEXED */ + case 270: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 268: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy157 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy153, yymsp[-3].minor.yy70, yymsp[-1].minor.yy404, yymsp[-7].minor.yy376, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy504);} - yymsp[-8].minor.yy157 = yylhsminor.yy157; + case 271: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy33 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy131, yymsp[-3].minor.yy322, yymsp[-1].minor.yy528, yymsp[-7].minor.yy394, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy522);} + yymsp[-8].minor.yy33 = yylhsminor.yy33; break; - case 269: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 272: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy157 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy436,yymsp[-2].minor.yy81,yymsp[-6].minor.yy376,yymsp[-1].minor.yy190,yymsp[-7].minor.yy504,yymsp[0].minor.yy504);/*yylhsminor.yy157-overwrites-yymsp[-6].minor.yy376*/ + yylhsminor.yy33 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy254,yymsp[-2].minor.yy47,yymsp[-6].minor.yy394,yymsp[-1].minor.yy444,yymsp[-7].minor.yy522,yymsp[0].minor.yy522);/*yylhsminor.yy33-overwrites-yymsp[-6].minor.yy394*/ } - yymsp[-7].minor.yy157 = yylhsminor.yy157; + yymsp[-7].minor.yy33 = yylhsminor.yy33; break; - case 270: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy157 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy404, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy504);} - yymsp[-5].minor.yy157 = yylhsminor.yy157; + case 273: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy33 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy528, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy522);} + yymsp[-5].minor.yy33 = yylhsminor.yy33; break; - case 271: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy157 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy81, yymsp[-2].minor.yy504, yymsp[0].minor.yy504); /*yylhsminor.yy157-overwrites-yymsp[-1].minor.yy81*/} - yymsp[-2].minor.yy157 = yylhsminor.yy157; + case 274: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy33 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy47, yymsp[-2].minor.yy522, yymsp[0].minor.yy522); /*yylhsminor.yy33-overwrites-yymsp[-1].minor.yy47*/} + yymsp[-2].minor.yy33 = yylhsminor.yy33; break; - case 272: /* expr ::= RAISE LP IGNORE RP */ + case 275: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy404 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy404 ){ - yymsp[-3].minor.yy404->affExpr = OE_Ignore; + yymsp[-3].minor.yy528 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy528 ){ + yymsp[-3].minor.yy528->affExpr = OE_Ignore; } } break; - case 273: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 276: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy404 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy404 ) { - yymsp[-5].minor.yy404->affExpr = (char)yymsp[-3].minor.yy376; + yymsp[-5].minor.yy528 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy528 ) { + yymsp[-5].minor.yy528->affExpr = (char)yymsp[-3].minor.yy394; } } break; - case 274: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy376 = OE_Rollback;} + case 277: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy394 = OE_Rollback;} break; - case 276: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy376 = OE_Fail;} + case 279: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy394 = OE_Fail;} break; - case 277: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 280: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy153,yymsp[-1].minor.yy376); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy131,yymsp[-1].minor.yy394); } break; - case 278: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 281: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy404, yymsp[-1].minor.yy404, yymsp[0].minor.yy404); + sqlite3Attach(pParse, yymsp[-3].minor.yy528, yymsp[-1].minor.yy528, yymsp[0].minor.yy528); } break; - case 279: /* cmd ::= DETACH database_kw_opt expr */ + case 282: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy404); + sqlite3Detach(pParse, yymsp[0].minor.yy528); } break; - case 282: /* cmd ::= REINDEX */ + case 285: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 283: /* cmd ::= REINDEX nm dbnm */ + case 286: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 284: /* cmd ::= ANALYZE */ + case 287: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 285: /* cmd ::= ANALYZE nm dbnm */ + case 288: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 286: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 289: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy153,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy131,&yymsp[0].minor.yy0); } break; - case 287: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 290: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 288: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + case 291: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ { - sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy153, &yymsp[0].minor.yy0); + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy131, &yymsp[0].minor.yy0); } break; - case 289: /* add_column_fullname ::= fullname */ + case 292: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy153); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy131); } break; - case 290: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 293: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy153, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy131, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 291: /* cmd ::= create_vtab */ + case 294: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 292: /* cmd ::= create_vtab LP vtabarglist RP */ + case 295: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 293: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 296: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy376); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy394); } break; - case 294: /* vtabarg ::= */ + case 297: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 295: /* vtabargtoken ::= ANY */ - case 296: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==296); - case 297: /* lp ::= LP */ yytestcase(yyruleno==297); + case 298: /* vtabargtoken ::= ANY */ + case 299: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==299); + case 300: /* lp ::= LP */ yytestcase(yyruleno==300); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 298: /* with ::= WITH wqlist */ - case 299: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==299); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy103, 1); } + case 301: /* with ::= WITH wqlist */ + case 302: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==302); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy521, 1); } break; - case 300: /* wqas ::= AS */ -{yymsp[0].minor.yy552 = M10d_Any;} + case 303: /* wqas ::= AS */ +{yymsp[0].minor.yy516 = M10d_Any;} break; - case 301: /* wqas ::= AS MATERIALIZED */ -{yymsp[-1].minor.yy552 = M10d_Yes;} + case 304: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy516 = M10d_Yes;} break; - case 302: /* wqas ::= AS NOT MATERIALIZED */ -{yymsp[-2].minor.yy552 = M10d_No;} + case 305: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy516 = M10d_No;} break; - case 303: /* wqitem ::= nm eidlist_opt wqas LP select RP */ + case 306: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { - yymsp[-5].minor.yy329 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy70, yymsp[-1].minor.yy81, yymsp[-3].minor.yy552); /*A-overwrites-X*/ + yymsp[-5].minor.yy385 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy322, yymsp[-1].minor.yy47, yymsp[-3].minor.yy516); /*A-overwrites-X*/ } break; - case 304: /* wqlist ::= wqitem */ + case 307: /* wqlist ::= wqitem */ { - yymsp[0].minor.yy103 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy329); /*A-overwrites-X*/ + yymsp[0].minor.yy521 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy385); /*A-overwrites-X*/ } break; - case 305: /* wqlist ::= wqlist COMMA wqitem */ + case 308: /* wqlist ::= wqlist COMMA wqitem */ { - yymsp[-2].minor.yy103 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy103, yymsp[0].minor.yy329); + yymsp[-2].minor.yy521 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy521, yymsp[0].minor.yy385); } break; - case 306: /* windowdefn_list ::= windowdefn */ -{ yylhsminor.yy49 = yymsp[0].minor.yy49; } - yymsp[0].minor.yy49 = yylhsminor.yy49; + case 309: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy41 = yymsp[0].minor.yy41; } + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 307: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 310: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy49!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy49, yymsp[-2].minor.yy49); - yymsp[0].minor.yy49->pNextWin = yymsp[-2].minor.yy49; - yylhsminor.yy49 = yymsp[0].minor.yy49; + assert( yymsp[0].minor.yy41!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy41); + yymsp[0].minor.yy41->pNextWin = yymsp[-2].minor.yy41; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[-2].minor.yy49 = yylhsminor.yy49; + yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 308: /* windowdefn ::= nm AS LP window RP */ + case 311: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy49) ){ - yymsp[-1].minor.yy49->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + if( ALWAYS(yymsp[-1].minor.yy41) ){ + yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy49 = yymsp[-1].minor.yy49; + yylhsminor.yy41 = yymsp[-1].minor.yy41; } - yymsp[-4].minor.yy49 = yylhsminor.yy49; + yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 309: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 312: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy49 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy49, yymsp[-2].minor.yy70, yymsp[-1].minor.yy70, 0); + yymsp[-4].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, 0); } break; - case 310: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 313: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy49 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy49, yymsp[-2].minor.yy70, yymsp[-1].minor.yy70, &yymsp[-5].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, yymsp[-2].minor.yy322, yymsp[-1].minor.yy322, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy49 = yylhsminor.yy49; + yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 311: /* window ::= ORDER BY sortlist frame_opt */ + case 314: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy49 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy49, 0, yymsp[-1].minor.yy70, 0); + yymsp[-3].minor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, 0); } break; - case 312: /* window ::= nm ORDER BY sortlist frame_opt */ + case 315: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy49 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy49, 0, yymsp[-1].minor.yy70, &yymsp[-4].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, yymsp[-1].minor.yy322, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy49 = yylhsminor.yy49; + yymsp[-4].minor.yy41 = yylhsminor.yy41; break; - case 313: /* window ::= frame_opt */ - case 332: /* filter_over ::= over_clause */ yytestcase(yyruleno==332); + case 316: /* window ::= frame_opt */ + case 335: /* filter_over ::= over_clause */ yytestcase(yyruleno==335); { - yylhsminor.yy49 = yymsp[0].minor.yy49; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[0].minor.yy49 = yylhsminor.yy49; + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 314: /* window ::= nm frame_opt */ + case 317: /* window ::= nm frame_opt */ { - yylhsminor.yy49 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy49, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy41 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy41, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy49 = yylhsminor.yy49; + yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 315: /* frame_opt ::= */ + case 318: /* frame_opt ::= */ { - yymsp[1].minor.yy49 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy41 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 316: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 319: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy49 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy376, yymsp[-1].minor.yy117.eType, yymsp[-1].minor.yy117.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy552); + yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy394, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy516); } - yymsp[-2].minor.yy49 = yylhsminor.yy49; + yymsp[-2].minor.yy41 = yylhsminor.yy41; break; - case 317: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 320: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { - yylhsminor.yy49 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy376, yymsp[-3].minor.yy117.eType, yymsp[-3].minor.yy117.pExpr, yymsp[-1].minor.yy117.eType, yymsp[-1].minor.yy117.pExpr, yymsp[0].minor.yy552); + yylhsminor.yy41 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy394, yymsp[-3].minor.yy595.eType, yymsp[-3].minor.yy595.pExpr, yymsp[-1].minor.yy595.eType, yymsp[-1].minor.yy595.pExpr, yymsp[0].minor.yy516); } - yymsp[-5].minor.yy49 = yylhsminor.yy49; + yymsp[-5].minor.yy41 = yylhsminor.yy41; break; - case 319: /* frame_bound_s ::= frame_bound */ - case 321: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==321); -{yylhsminor.yy117 = yymsp[0].minor.yy117;} - yymsp[0].minor.yy117 = yylhsminor.yy117; + case 322: /* frame_bound_s ::= frame_bound */ + case 324: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==324); +{yylhsminor.yy595 = yymsp[0].minor.yy595;} + yymsp[0].minor.yy595 = yylhsminor.yy595; break; - case 320: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 322: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==322); - case 324: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==324); -{yylhsminor.yy117.eType = yymsp[-1].major; yylhsminor.yy117.pExpr = 0;} - yymsp[-1].minor.yy117 = yylhsminor.yy117; + case 323: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 325: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==325); + case 327: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==327); +{yylhsminor.yy595.eType = yymsp[-1].major; yylhsminor.yy595.pExpr = 0;} + yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 323: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy117.eType = yymsp[0].major; yylhsminor.yy117.pExpr = yymsp[-1].minor.yy404;} - yymsp[-1].minor.yy117 = yylhsminor.yy117; + case 326: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy595.eType = yymsp[0].major; yylhsminor.yy595.pExpr = yymsp[-1].minor.yy528;} + yymsp[-1].minor.yy595 = yylhsminor.yy595; break; - case 325: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy552 = 0;} + case 328: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy516 = 0;} break; - case 326: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy552 = yymsp[0].minor.yy552;} + case 329: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy516 = yymsp[0].minor.yy516;} break; - case 327: /* frame_exclude ::= NO OTHERS */ - case 328: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==328); -{yymsp[-1].minor.yy552 = yymsp[-1].major; /*A-overwrites-X*/} + case 330: /* frame_exclude ::= NO OTHERS */ + case 331: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==331); +{yymsp[-1].minor.yy516 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 329: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy552 = yymsp[0].major; /*A-overwrites-X*/} + case 332: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy516 = yymsp[0].major; /*A-overwrites-X*/} break; - case 330: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy49 = yymsp[0].minor.yy49; } + case 333: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy41 = yymsp[0].minor.yy41; } break; - case 331: /* filter_over ::= filter_clause over_clause */ + case 334: /* filter_over ::= filter_clause over_clause */ { - if( yymsp[0].minor.yy49 ){ - yymsp[0].minor.yy49->pFilter = yymsp[-1].minor.yy404; + if( yymsp[0].minor.yy41 ){ + yymsp[0].minor.yy41->pFilter = yymsp[-1].minor.yy528; }else{ - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy404); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy528); } - yylhsminor.yy49 = yymsp[0].minor.yy49; + yylhsminor.yy41 = yymsp[0].minor.yy41; } - yymsp[-1].minor.yy49 = yylhsminor.yy49; + yymsp[-1].minor.yy41 = yylhsminor.yy41; break; - case 333: /* filter_over ::= filter_clause */ + case 336: /* filter_over ::= filter_clause */ { - yylhsminor.yy49 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy49 ){ - yylhsminor.yy49->eFrmType = TK_FILTER; - yylhsminor.yy49->pFilter = yymsp[0].minor.yy404; + yylhsminor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy41 ){ + yylhsminor.yy41->eFrmType = TK_FILTER; + yylhsminor.yy41->pFilter = yymsp[0].minor.yy528; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy404); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy528); } } - yymsp[0].minor.yy49 = yylhsminor.yy49; + yymsp[0].minor.yy41 = yylhsminor.yy41; break; - case 334: /* over_clause ::= OVER LP window RP */ + case 337: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy49 = yymsp[-1].minor.yy49; - assert( yymsp[-3].minor.yy49!=0 ); + yymsp[-3].minor.yy41 = yymsp[-1].minor.yy41; + assert( yymsp[-3].minor.yy41!=0 ); } break; - case 335: /* over_clause ::= OVER nm */ + case 338: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy49 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy49 ){ - yymsp[-1].minor.yy49->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy41 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy41 ){ + yymsp[-1].minor.yy41->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 336: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy404 = yymsp[-1].minor.yy404; } + case 339: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy528 = yymsp[-1].minor.yy528; } break; default: - /* (337) input ::= cmdlist */ yytestcase(yyruleno==337); - /* (338) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==338); - /* (339) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=339); - /* (340) ecmd ::= SEMI */ yytestcase(yyruleno==340); - /* (341) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==341); - /* (342) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=342); - /* (343) trans_opt ::= */ yytestcase(yyruleno==343); - /* (344) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==344); - /* (345) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==345); - /* (346) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==346); - /* (347) savepoint_opt ::= */ yytestcase(yyruleno==347); - /* (348) cmd ::= create_table create_table_args */ yytestcase(yyruleno==348); - /* (349) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==349); - /* (350) columnlist ::= columnname carglist */ yytestcase(yyruleno==350); - /* (351) nm ::= ID|INDEXED */ yytestcase(yyruleno==351); - /* (352) nm ::= STRING */ yytestcase(yyruleno==352); - /* (353) nm ::= JOIN_KW */ yytestcase(yyruleno==353); - /* (354) typetoken ::= typename */ yytestcase(yyruleno==354); - /* (355) typename ::= ID|STRING */ yytestcase(yyruleno==355); - /* (356) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=356); - /* (357) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=357); - /* (358) carglist ::= carglist ccons */ yytestcase(yyruleno==358); - /* (359) carglist ::= */ yytestcase(yyruleno==359); - /* (360) ccons ::= NULL onconf */ yytestcase(yyruleno==360); - /* (361) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==361); - /* (362) ccons ::= AS generated */ yytestcase(yyruleno==362); - /* (363) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==363); - /* (364) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==364); - /* (365) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=365); - /* (366) tconscomma ::= */ yytestcase(yyruleno==366); - /* (367) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=367); - /* (368) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=368); - /* (369) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=369); - /* (370) oneselect ::= values */ yytestcase(yyruleno==370); - /* (371) sclp ::= selcollist COMMA */ yytestcase(yyruleno==371); - /* (372) as ::= ID|STRING */ yytestcase(yyruleno==372); - /* (373) returning ::= */ yytestcase(yyruleno==373); - /* (374) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=374); - /* (375) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==375); - /* (376) exprlist ::= nexprlist */ yytestcase(yyruleno==376); - /* (377) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=377); - /* (378) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=378); - /* (379) nmnum ::= ON */ yytestcase(yyruleno==379); - /* (380) nmnum ::= DELETE */ yytestcase(yyruleno==380); - /* (381) nmnum ::= DEFAULT */ yytestcase(yyruleno==381); - /* (382) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==382); - /* (383) foreach_clause ::= */ yytestcase(yyruleno==383); - /* (384) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==384); - /* (385) trnm ::= nm */ yytestcase(yyruleno==385); - /* (386) tridxby ::= */ yytestcase(yyruleno==386); - /* (387) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==387); - /* (388) database_kw_opt ::= */ yytestcase(yyruleno==388); - /* (389) kwcolumn_opt ::= */ yytestcase(yyruleno==389); - /* (390) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==390); - /* (391) vtabarglist ::= vtabarg */ yytestcase(yyruleno==391); - /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==392); - /* (393) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==393); - /* (394) anylist ::= */ yytestcase(yyruleno==394); - /* (395) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==395); - /* (396) anylist ::= anylist ANY */ yytestcase(yyruleno==396); - /* (397) with ::= */ yytestcase(yyruleno==397); + /* (340) input ::= cmdlist */ yytestcase(yyruleno==340); + /* (341) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==341); + /* (342) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=342); + /* (343) ecmd ::= SEMI */ yytestcase(yyruleno==343); + /* (344) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==344); + /* (345) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=345); + /* (346) trans_opt ::= */ yytestcase(yyruleno==346); + /* (347) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==347); + /* (348) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==348); + /* (349) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==349); + /* (350) savepoint_opt ::= */ yytestcase(yyruleno==350); + /* (351) cmd ::= create_table create_table_args */ yytestcase(yyruleno==351); + /* (352) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=352); + /* (353) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==353); + /* (354) columnlist ::= columnname carglist */ yytestcase(yyruleno==354); + /* (355) nm ::= ID|INDEXED */ yytestcase(yyruleno==355); + /* (356) nm ::= STRING */ yytestcase(yyruleno==356); + /* (357) nm ::= JOIN_KW */ yytestcase(yyruleno==357); + /* (358) typetoken ::= typename */ yytestcase(yyruleno==358); + /* (359) typename ::= ID|STRING */ yytestcase(yyruleno==359); + /* (360) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=360); + /* (361) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=361); + /* (362) carglist ::= carglist ccons */ yytestcase(yyruleno==362); + /* (363) carglist ::= */ yytestcase(yyruleno==363); + /* (364) ccons ::= NULL onconf */ yytestcase(yyruleno==364); + /* (365) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==365); + /* (366) ccons ::= AS generated */ yytestcase(yyruleno==366); + /* (367) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==367); + /* (368) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==368); + /* (369) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=369); + /* (370) tconscomma ::= */ yytestcase(yyruleno==370); + /* (371) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=371); + /* (372) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=372); + /* (373) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=373); + /* (374) oneselect ::= values */ yytestcase(yyruleno==374); + /* (375) sclp ::= selcollist COMMA */ yytestcase(yyruleno==375); + /* (376) as ::= ID|STRING */ yytestcase(yyruleno==376); + /* (377) returning ::= */ yytestcase(yyruleno==377); + /* (378) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==379); + /* (380) exprlist ::= nexprlist */ yytestcase(yyruleno==380); + /* (381) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=381); + /* (382) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=382); + /* (383) nmnum ::= ON */ yytestcase(yyruleno==383); + /* (384) nmnum ::= DELETE */ yytestcase(yyruleno==384); + /* (385) nmnum ::= DEFAULT */ yytestcase(yyruleno==385); + /* (386) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==386); + /* (387) foreach_clause ::= */ yytestcase(yyruleno==387); + /* (388) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==388); + /* (389) trnm ::= nm */ yytestcase(yyruleno==389); + /* (390) tridxby ::= */ yytestcase(yyruleno==390); + /* (391) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==391); + /* (392) database_kw_opt ::= */ yytestcase(yyruleno==392); + /* (393) kwcolumn_opt ::= */ yytestcase(yyruleno==393); + /* (394) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==394); + /* (395) vtabarglist ::= vtabarg */ yytestcase(yyruleno==395); + /* (396) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==396); + /* (397) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==397); + /* (398) anylist ::= */ yytestcase(yyruleno==398); + /* (399) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==399); + /* (400) anylist ::= anylist ANY */ yytestcase(yyruleno==400); + /* (401) with ::= */ yytestcase(yyruleno==401); break; /********** End reduce actions ************************************************/ }; @@ -163148,8 +166610,8 @@ SQLITE_PRIVATE void sqlite3Parser( yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); #ifndef NDEBUG + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); if( yyTraceFILE ){ int yysize = yyRuleInfoNRhs[yyruleno]; if( yysize ){ @@ -163247,14 +166709,13 @@ SQLITE_PRIVATE void sqlite3Parser( yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion); yymajor = YYNOCODE; }else{ - while( yypParser->yytos >= yypParser->yystack - && (yyact = yy_find_reduce_action( - yypParser->yytos->stateno, - YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE - ){ + while( yypParser->yytos > yypParser->yystack ){ + yyact = yy_find_reduce_action(yypParser->yytos->stateno, + YYERRORSYMBOL); + if( yyact<=YY_MAX_SHIFTREDUCE ) break; yy_pop_parser_stack(yypParser); } - if( yypParser->yytos < yypParser->yystack || yymajor==0 ){ + if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion); yy_parse_failed(yypParser); #ifndef YYNOERRORRECOVERY @@ -164114,6 +167575,9 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ for(i=2; (c=z[i])!=0 && c!='\n'; i++){} *tokenType = TK_SPACE; /* IMP: R-22934-25134 */ return i; + }else if( z[1]=='>' ){ + *tokenType = TK_PTR; + return 2 + (z[2]=='>'); } *tokenType = TK_MINUS; return 1; @@ -164383,13 +167847,9 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ } /* -** Run the parser on the given SQL string. The parser structure is -** passed in. An SQLITE_ status code is returned. If an error occurs -** then an and attempt is made to write an error message into -** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that -** error message. +** Run the parser on the given SQL string. */ -SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ +SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){ int nErr = 0; /* Number of errors encountered */ void *pEngine; /* The LEMON-generated LALR(1) parser */ int n = 0; /* Length of the next token token */ @@ -164397,6 +167857,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr int lastTokenParsed = -1; /* type of the previous token */ sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ + Parse *pParentParse = 0; /* Outer parse context, if any */ #ifdef sqlite3Parser_ENGINEALWAYSONSTACK yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ #endif @@ -164409,7 +167870,6 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr } pParse->rc = SQLITE_OK; pParse->zTail = zSql; - assert( pzErrMsg!=0 ); #ifdef SQLITE_DEBUG if( db->flags & SQLITE_ParserTrace ){ printf("parser: [[[%s]]]\n", zSql); @@ -164432,7 +167892,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); assert( pParse->pVList==0 ); - pParse->pParentParse = db->pParse; + pParentParse = db->pParse; db->pParse = pParse; while( 1 ){ n = sqlite3GetToken((u8*)zSql, &tokenType); @@ -164452,6 +167912,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr #endif /* SQLITE_OMIT_WINDOWFUNC */ if( AtomicLoad(&db->u1.isInterrupted) ){ pParse->rc = SQLITE_INTERRUPT; + pParse->nErr++; break; } if( tokenType==TK_SPACE ){ @@ -164481,7 +167942,10 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ }else{ - sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); + Token x; + x.z = zSql; + x.n = n; + sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x); break; } } @@ -164509,46 +167973,30 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM_BKPT; } - if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ - pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); - } - assert( pzErrMsg!=0 ); - if( pParse->zErrMsg ){ - *pzErrMsg = pParse->zErrMsg; - sqlite3_log(pParse->rc, "%s in \"%s\"", - *pzErrMsg, pParse->zTail); - pParse->zErrMsg = 0; + if( pParse->zErrMsg || (pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE) ){ + if( pParse->zErrMsg==0 ){ + pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); + } + sqlite3_log(pParse->rc, "%s in \"%s\"", pParse->zErrMsg, pParse->zTail); nErr++; } pParse->zTail = zSql; - if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ - sqlite3VdbeDelete(pParse->pVdbe); - pParse->pVdbe = 0; - } -#ifndef SQLITE_OMIT_SHARED_CACHE - if( pParse->nested==0 ){ - sqlite3DbFree(db, pParse->aTableLock); - pParse->aTableLock = 0; - pParse->nTableLock = 0; - } -#endif #ifndef SQLITE_OMIT_VIRTUALTABLE sqlite3_free(pParse->apVtabLock); #endif - if( !IN_SPECIAL_PARSE ){ + if( pParse->pNewTable && !IN_SPECIAL_PARSE ){ /* If the pParse->declareVtab flag is set, do not delete any table ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, pParse->pNewTable); } - if( !IN_RENAME_OBJECT ){ + if( pParse->pNewTrigger && !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } sqlite3DbFree(db, pParse->pVList); - db->pParse = pParse->pParentParse; - pParse->pParentParse = 0; + db->pParse = pParentParse; assert( nErr==0 || pParse->rc!=SQLITE_OK ); return nErr; } @@ -165129,9 +168577,6 @@ SQLITE_PRIVATE int sqlite3Fts2Init(sqlite3*); #ifdef SQLITE_ENABLE_FTS5 SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); #endif -#ifdef SQLITE_ENABLE_JSON1 -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*); -#endif #ifdef SQLITE_ENABLE_STMTVTAB SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); #endif @@ -165166,8 +168611,8 @@ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { sqlite3DbstatRegister, #endif sqlite3TestExtInit, -#ifdef SQLITE_ENABLE_JSON1 - sqlite3Json1Init, +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) + sqlite3JsonTableFunctions, #endif #ifdef SQLITE_ENABLE_STMTVTAB sqlite3StmtVtabInit, @@ -166165,7 +169610,7 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3 *db, sqlite3_int64 iRowid) /* ** Return the number of changes in the most recent call to sqlite3_exec(). */ -SQLITE_API int sqlite3_changes(sqlite3 *db){ +SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -166174,11 +169619,14 @@ SQLITE_API int sqlite3_changes(sqlite3 *db){ #endif return db->nChange; } +SQLITE_API int sqlite3_changes(sqlite3 *db){ + return (int)sqlite3_changes64(db); +} /* ** Return the number of changes since the database handle was opened. */ -SQLITE_API int sqlite3_total_changes(sqlite3 *db){ +SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; @@ -166187,6 +169635,9 @@ SQLITE_API int sqlite3_total_changes(sqlite3 *db){ #endif return db->nTotalChange; } +SQLITE_API int sqlite3_total_changes(sqlite3 *db){ + return (int)sqlite3_total_changes64(db); +} /* ** Close all open savepoints. This function only manipulates fields of the @@ -166211,7 +169662,9 @@ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ ** with SQLITE_ANY as the encoding. */ static void functionDestroy(sqlite3 *db, FuncDef *p){ - FuncDestructor *pDestructor = p->u.pDestructor; + FuncDestructor *pDestructor; + assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 ); + pDestructor = p->u.pDestructor; if( pDestructor ){ pDestructor->nRef--; if( pDestructor->nRef==0 ){ @@ -166315,7 +169768,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){ /* Convert the connection into a zombie and then close it. */ - db->magic = SQLITE_MAGIC_ZOMBIE; + db->eOpenState = SQLITE_STATE_ZOMBIE; sqlite3LeaveMutexAndCloseZombie(db); return SQLITE_OK; } @@ -166379,7 +169832,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ ** or if the connection has not yet been closed by sqlite3_close_v2(), ** then just leave the mutex and return. */ - if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){ + if( db->eOpenState!=SQLITE_STATE_ZOMBIE || connectionIsBusy(db) ){ sqlite3_mutex_leave(db->mutex); return; } @@ -166465,7 +169918,7 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ sqlite3_free(db->auth.zAuthPW); #endif - db->magic = SQLITE_MAGIC_ERROR; + db->eOpenState = SQLITE_STATE_ERROR; /* The temp-database schema is allocated differently from the other schema ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). @@ -166474,8 +169927,11 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ ** structure? */ sqlite3DbFree(db, db->aDb[1].pSchema); + if( db->xAutovacDestr ){ + db->xAutovacDestr(db->pAutovacPagesArg); + } sqlite3_mutex_leave(db->mutex); - db->magic = SQLITE_MAGIC_CLOSED; + db->eOpenState = SQLITE_STATE_CLOSED; sqlite3_mutex_free(db->mutex); assert( sqlite3LookasideUsed(db,0)==0 ); if( db->lookaside.bMalloced ){ @@ -166528,7 +169984,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; db->nDeferredImmCons = 0; - db->flags &= ~(u64)SQLITE_DeferFKs; + db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly); /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ @@ -166863,7 +170319,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ */ SQLITE_API void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){ + if( !sqlite3SafetyCheckOk(db) && (db==0 || db->eOpenState!=SQLITE_STATE_ZOMBIE) ){ (void)SQLITE_MISUSE_BKPT; return; } @@ -166892,7 +170348,6 @@ SQLITE_PRIVATE int sqlite3CreateFunc( FuncDestructor *pDestructor ){ FuncDef *p; - int nName; int extraFlags; assert( sqlite3_mutex_held(db->mutex) ); @@ -166902,7 +170357,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc( || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) - || (255<(nName = sqlite3Strlen30( zFunctionName))) + || (255nRef==0 ){ - assert( rc!=SQLITE_OK ); + assert( rc!=SQLITE_OK || (xStep==0 && xFinal==0) ); xDestroy(p); sqlite3_free(pArg); } @@ -167365,6 +170831,34 @@ SQLITE_API void *sqlite3_preupdate_hook( } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +/* +** Register a function to be invoked prior to each autovacuum that +** determines the number of pages to vacuum. +*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, /* Attach the hook to this database */ + unsigned int (*xCallback)(void*,const char*,u32,u32,u32), + void *pArg, /* Argument to the function */ + void (*xDestructor)(void*) /* Destructor for pArg */ +){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ){ + if( xDestructor ) xDestructor(pArg); + return SQLITE_MISUSE_BKPT; + } +#endif + sqlite3_mutex_enter(db->mutex); + if( db->xAutovacDestr ){ + db->xAutovacDestr(db->pAutovacPagesArg); + } + db->xAutovacPages = xCallback; + db->pAutovacPagesArg = pArg; + db->xAutovacDestr = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + #ifndef SQLITE_OMIT_WAL /* ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). @@ -167627,6 +171121,19 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ return z; } +/* +** Return the byte offset of the most recent error +*/ +SQLITE_API int sqlite3_error_offset(sqlite3 *db){ + int iOffset = -1; + if( db && sqlite3SafetyCheckSickOrOk(db) && db->errCode ){ + sqlite3_mutex_enter(db->mutex); + iOffset = db->errByteOffset; + sqlite3_mutex_leave(db->mutex); + } + return iOffset; +} + #ifndef SQLITE_OMIT_UTF16 /* ** Return UTF-16 encoded English language explanation of the most recent @@ -167887,6 +171394,8 @@ SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ if( newLimit>=0 ){ /* IMP: R-52476-28732 */ if( newLimit>aHardLimit[limitId] ){ newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */ + }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){ + newLimit = 1; } db->aLimit[limitId] = newLimit; } @@ -168158,7 +171667,7 @@ SQLITE_PRIVATE int sqlite3ParseUri( */ static const char *uriParameter(const char *zFilename, const char *zParam){ zFilename += sqlite3Strlen30(zFilename) + 1; - while( zFilename[0] ){ + while( ALWAYS(zFilename!=0) && zFilename[0] ){ int x = strcmp(zFilename, zParam); zFilename += sqlite3Strlen30(zFilename) + 1; if( x==0 ) return zFilename; @@ -168218,8 +171727,8 @@ static int openDatabase( ** dealt with in the previous code block. Besides these, the only ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY, ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE, - ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask - ** off all other flags. + ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved + ** bits. Silently mask off all other flags. */ flags &= ~( SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_EXCLUSIVE | @@ -168254,9 +171763,9 @@ static int openDatabase( } } sqlite3_mutex_enter(db->mutex); - db->errMask = 0xff; + db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff; db->nDb = 2; - db->magic = SQLITE_MAGIC_BUSY; + db->eOpenState = SQLITE_STATE_BUSY; db->aDb = db->aDbStatic; db->lookaside.bDisable = 1; db->lookaside.sz = 0; @@ -168268,7 +171777,15 @@ static int openDatabase( db->nextAutovac = -1; db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; + db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ +#ifdef SQLITE_ENABLE_SORTER_MMAP + /* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map + ** the temporary files used to do external sorts (see code in vdbesort.c) + ** is disabled. It can still be used either by defining + ** SQLITE_ENABLE_SORTER_MMAP at compile time or by using the + ** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */ db->nMaxSorterMmap = 0x7FFFFFFF; +#endif db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_EnableView @@ -168416,7 +171933,7 @@ static int openDatabase( db->aDb[1].zDbSName = "temp"; db->aDb[1].safety_level = PAGER_SYNCHRONOUS_OFF; - db->magic = SQLITE_MAGIC_OPEN; + db->eOpenState = SQLITE_STATE_OPEN; if( db->mallocFailed ){ goto opendb_out; } @@ -168478,12 +171995,12 @@ opendb_out: sqlite3_mutex_leave(db->mutex); } rc = sqlite3_errcode(db); - assert( db!=0 || rc==SQLITE_NOMEM ); - if( rc==SQLITE_NOMEM ){ + assert( db!=0 || (rc&0xff)==SQLITE_NOMEM ); + if( (rc&0xff)==SQLITE_NOMEM ){ sqlite3_close(db); db = 0; }else if( rc!=SQLITE_OK ){ - db->magic = SQLITE_MAGIC_SICK; + db->eOpenState = SQLITE_STATE_SICK; } *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG @@ -168494,7 +172011,7 @@ opendb_out: } #endif sqlite3_free_filename(zOpen); - return rc & 0xff; + return rc; } @@ -168794,7 +172311,7 @@ SQLITE_API int sqlite3_table_column_metadata( /* Locate the table in question */ pTab = sqlite3FindTable(db, zTableName, zDbName); - if( !pTab || pTab->pSelect ){ + if( !pTab || IsView(pTab) ){ pTab = 0; goto error_out; } @@ -168805,7 +172322,7 @@ SQLITE_API int sqlite3_table_column_metadata( }else{ for(iCol=0; iColnCol; iCol++){ pCol = &pTab->aCol[iCol]; - if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ + if( 0==sqlite3StrICmp(pCol->zCnName, zColumnName) ){ break; } } @@ -168832,7 +172349,7 @@ SQLITE_API int sqlite3_table_column_metadata( */ if( pCol ){ zDataType = sqlite3ColumnType(pCol,0); - zCollSeq = pCol->zColl; + zCollSeq = sqlite3ColumnColl(pCol); notnull = pCol->notNull!=0; primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; @@ -169039,12 +172556,16 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** sqlite3_test_control(). */ case SQLITE_TESTCTRL_FAULT_INSTALL: { - /* MSVC is picky about pulling func ptrs from va lists. - ** http://support.microsoft.com/kb/47961 + /* A bug in MSVC prevents it from understanding pointers to functions + ** types in the second argument to va_arg(). Work around the problem + ** using a typedef. + ** http://support.microsoft.com/kb/47961 <-- dead hyperlink + ** Search at http://web.archive.org/ to find the 2015-03-16 archive + ** of the link above to see the original text. ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); */ - typedef int(*TESTCALLBACKFUNC_t)(int); - sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); + typedef int(*sqlite3FaultFuncType)(int); + sqlite3GlobalConfig.xTestCallback = va_arg(ap, sqlite3FaultFuncType); rc = sqlite3FaultSim(0); break; } @@ -169171,13 +172692,27 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } - /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, onoff, xAlt); ** - ** If parameter onoff is non-zero, subsequent calls to localtime() - ** and its variants fail. If onoff is zero, undo this setting. + ** If parameter onoff is 1, subsequent calls to localtime() fail. + ** If 2, then invoke xAlt() instead of localtime(). If 0, normal + ** processing. + ** + ** xAlt arguments are void pointers, but they really want to be: + ** + ** int xAlt(const time_t*, struct tm*); + ** + ** xAlt should write results in to struct tm object of its 2nd argument + ** and return zero on success, or return non-zero on failure. */ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + if( sqlite3GlobalConfig.bLocaltimeFault==2 ){ + typedef int(*sqlite3LocaltimeType)(const void*,void*); + sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType); + }else{ + sqlite3GlobalConfig.xAltLocaltime = 0; + } break; } @@ -169282,12 +172817,16 @@ SQLITE_API int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_IMPOSTER: { sqlite3 *db = va_arg(ap, sqlite3*); + int iDb; sqlite3_mutex_enter(db->mutex); - db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); - db->init.busy = db->init.imposterTable = va_arg(ap,int); - db->init.newTnum = va_arg(ap,int); - if( db->init.busy==0 && db->init.newTnum>0 ){ - sqlite3ResetAllSchemasOfConnection(db); + iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); + if( iDb>=0 ){ + db->init.iDb = iDb; + db->init.busy = db->init.imposterTable = va_arg(ap,int); + db->init.newTnum = va_arg(ap,int); + if( db->init.busy==0 && db->init.newTnum>0 ){ + sqlite3ResetAllSchemasOfConnection(db); + } } sqlite3_mutex_leave(db->mutex); break; @@ -169363,6 +172902,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } + /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST, + ** double fIn, // Input value + ** int *pLogEst, // sqlite3LogEstFromDouble(fIn) + ** u64 *pInt, // sqlite3LogEstToInt(*pLogEst) + ** int *pLogEst2 // sqlite3LogEst(*pInt) + ** ); + ** + ** Test access for the LogEst conversion routines. + */ + case SQLITE_TESTCTRL_LOGEST: { + double rIn = va_arg(ap, double); + LogEst rLogEst = sqlite3LogEstFromDouble(rIn); + u64 iInt = sqlite3LogEstToInt(rLogEst); + va_arg(ap, int*)[0] = rLogEst; + va_arg(ap, u64*)[0] = iInt; + va_arg(ap, int*)[0] = sqlite3LogEst(iInt); + break; + } + + #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) ** @@ -169499,7 +173058,7 @@ SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){ if( zFilename==0 || N<0 ) return 0; zFilename = databaseName(zFilename); zFilename += sqlite3Strlen30(zFilename) + 1; - while( zFilename[0] && (N--)>0 ){ + while( ALWAYS(zFilename) && zFilename[0] && (N--)>0 ){ zFilename += sqlite3Strlen30(zFilename) + 1; zFilename += sqlite3Strlen30(zFilename) + 1; } @@ -169542,12 +173101,14 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64( ** corruption. */ SQLITE_API const char *sqlite3_filename_database(const char *zFilename){ + if( zFilename==0 ) return 0; return databaseName(zFilename); } SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ + if( zFilename==0 ) return 0; zFilename = databaseName(zFilename); zFilename += sqlite3Strlen30(zFilename) + 1; - while( zFilename[0] ){ + while( ALWAYS(zFilename) && zFilename[0] ){ zFilename += sqlite3Strlen30(zFilename) + 1; zFilename += sqlite3Strlen30(zFilename) + 1; } @@ -169558,7 +173119,7 @@ SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){ return 0; #else zFilename = sqlite3_filename_journal(zFilename); - zFilename += sqlite3Strlen30(zFilename) + 1; + if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1; return zFilename; #endif } @@ -170851,17 +174412,18 @@ SQLITE_API extern int sqlite3_fts3_may_be_corrupt; ** Macros indicating that conditional expressions are always true or ** false. */ -#ifdef SQLITE_COVERAGE_TEST -# define ALWAYS(x) (1) -# define NEVER(X) (0) -#elif defined(SQLITE_DEBUG) -# define ALWAYS(x) sqlite3Fts3Always((x)!=0) -# define NEVER(x) sqlite3Fts3Never((x)!=0) -SQLITE_PRIVATE int sqlite3Fts3Always(int b); -SQLITE_PRIVATE int sqlite3Fts3Never(int b); +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) #else -# define ALWAYS(x) (x) -# define NEVER(x) (x) +# define ALWAYS(X) (X) +# define NEVER(X) (X) #endif /* @@ -171320,6 +174882,7 @@ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); #endif +SQLITE_PRIVATE void *sqlite3Fts3MallocZero(i64 nByte); SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, sqlite3_tokenizer_cursor ** @@ -171339,7 +174902,7 @@ SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *) SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); /* fts3_tokenize_vtab.c */ -SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *, void(*xDestroy)(void*)); /* fts3_unicode2.c (functions generated by parsing unicode text files) */ #ifndef SQLITE_DISABLE_FTS3_UNICODE @@ -171372,18 +174935,17 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); SQLITE_EXTENSION_INIT1 #endif +typedef struct Fts3HashWrapper Fts3HashWrapper; +struct Fts3HashWrapper { + Fts3Hash hash; /* Hash table */ + int nRef; /* Number of pointers to this object */ +}; + static int fts3EvalNext(Fts3Cursor *pCsr); static int fts3EvalStart(Fts3Cursor *pCsr); static int fts3TermSegReaderCursor( Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **); -#ifndef SQLITE_AMALGAMATION -# if defined(SQLITE_DEBUG) -SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; } -SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } -# endif -#endif - /* ** This variable is set to false when running tests for which the on disk ** structures should not be corrupt. Otherwise, true. If it is false, extra @@ -172243,7 +175805,7 @@ static int fts3InitVtab( sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ char **pzErr /* Write any error message here */ ){ - Fts3Hash *pHash = (Fts3Hash *)pAux; + Fts3Hash *pHash = &((Fts3HashWrapper*)pAux)->hash; Fts3Table *p = 0; /* Pointer to allocated vtab */ int rc = SQLITE_OK; /* Return code */ int i; /* Iterator variable */ @@ -175078,9 +178640,12 @@ static const sqlite3_module fts3Module = { ** allocated for the tokenizer hash table. */ static void hashDestroy(void *p){ - Fts3Hash *pHash = (Fts3Hash *)p; - sqlite3Fts3HashClear(pHash); - sqlite3_free(pHash); + Fts3HashWrapper *pHash = (Fts3HashWrapper *)p; + pHash->nRef--; + if( pHash->nRef<=0 ){ + sqlite3Fts3HashClear(&pHash->hash); + sqlite3_free(pHash); + } } /* @@ -175110,7 +178675,7 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const */ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ int rc = SQLITE_OK; - Fts3Hash *pHash = 0; + Fts3HashWrapper *pHash = 0; const sqlite3_tokenizer_module *pSimple = 0; const sqlite3_tokenizer_module *pPorter = 0; #ifndef SQLITE_DISABLE_FTS3_UNICODE @@ -175138,23 +178703,24 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ sqlite3Fts3PorterTokenizerModule(&pPorter); /* Allocate and initialize the hash-table used to store tokenizers. */ - pHash = sqlite3_malloc(sizeof(Fts3Hash)); + pHash = sqlite3_malloc(sizeof(Fts3HashWrapper)); if( !pHash ){ rc = SQLITE_NOMEM; }else{ - sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); + sqlite3Fts3HashInit(&pHash->hash, FTS3_HASH_STRING, 1); + pHash->nRef = 0; } /* Load the built-in tokenizers into the hash table */ if( rc==SQLITE_OK ){ - if( sqlite3Fts3HashInsert(pHash, "simple", 7, (void *)pSimple) - || sqlite3Fts3HashInsert(pHash, "porter", 7, (void *)pPorter) + if( sqlite3Fts3HashInsert(&pHash->hash, "simple", 7, (void *)pSimple) + || sqlite3Fts3HashInsert(&pHash->hash, "porter", 7, (void *)pPorter) #ifndef SQLITE_DISABLE_FTS3_UNICODE - || sqlite3Fts3HashInsert(pHash, "unicode61", 10, (void *)pUnicode) + || sqlite3Fts3HashInsert(&pHash->hash, "unicode61", 10, (void *)pUnicode) #endif #ifdef SQLITE_ENABLE_ICU - || (pIcu && sqlite3Fts3HashInsert(pHash, "icu", 4, (void *)pIcu)) + || (pIcu && sqlite3Fts3HashInsert(&pHash->hash, "icu", 4, (void *)pIcu)) #endif ){ rc = SQLITE_NOMEM; @@ -175163,7 +178729,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ #ifdef SQLITE_TEST if( rc==SQLITE_OK ){ - rc = sqlite3Fts3ExprInitTestInterface(db, pHash); + rc = sqlite3Fts3ExprInitTestInterface(db, &pHash->hash); } #endif @@ -175172,23 +178738,26 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ ** module with sqlite. */ if( SQLITE_OK==rc - && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer")) + && SQLITE_OK==(rc=sqlite3Fts3InitHashTable(db,&pHash->hash,"fts3_tokenizer")) && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) ){ + pHash->nRef++; rc = sqlite3_create_module_v2( db, "fts3", &fts3Module, (void *)pHash, hashDestroy ); if( rc==SQLITE_OK ){ + pHash->nRef++; rc = sqlite3_create_module_v2( - db, "fts4", &fts3Module, (void *)pHash, 0 + db, "fts4", &fts3Module, (void *)pHash, hashDestroy ); } if( rc==SQLITE_OK ){ - rc = sqlite3Fts3InitTok(db, (void *)pHash); + pHash->nRef++; + rc = sqlite3Fts3InitTok(db, (void *)pHash, hashDestroy); } return rc; } @@ -175197,7 +178766,7 @@ SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){ /* An error has occurred. Delete the hash table and return the error code. */ assert( rc!=SQLITE_OK ); if( pHash ){ - sqlite3Fts3HashClear(pHash); + sqlite3Fts3HashClear(&pHash->hash); sqlite3_free(pHash); } return rc; @@ -175544,7 +179113,7 @@ SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( assert( nDoclist>0 ); assert( *pbEof==0 ); - assert( p || *piDocid==0 ); + assert_fts3_nc( p || *piDocid==0 ); assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); if( p==0 ){ @@ -176408,8 +179977,8 @@ static void fts3EvalNextRow( Fts3Expr *pRight = pExpr->pRight; sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); - assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); - assert( pRight->bStart || pLeft->iDocid==pRight->iDocid ); + assert_fts3_nc( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); + assert_fts3_nc( pRight->bStart || pLeft->iDocid==pRight->iDocid ); if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){ fts3EvalNextRow(pCsr, pLeft, pRc); @@ -177047,6 +180616,9 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( if( bEofSave==0 && pNear->iDocid==iDocid ) break; } assert( rc!=SQLITE_OK || pPhrase->bIncr==0 ); + if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){ + rc = FTS_CORRUPT_VTAB; + } } if( bTreeEof ){ while( rc==SQLITE_OK && !pNear->bEof ){ @@ -177469,6 +181041,7 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM; memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat); iCol = 0; + rc = SQLITE_OK; while( iaStat[iCol+1].nDoc++; eState = 2; @@ -177520,7 +181097,6 @@ static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ } pCsr->iCol = 0; - rc = SQLITE_OK; }else{ pCsr->isEof = 1; } @@ -177849,7 +181425,7 @@ static int fts3isspace(char c){ ** zero the memory before returning a pointer to it. If unsuccessful, ** return NULL. */ -static void *fts3MallocZero(sqlite3_int64 nByte){ +SQLITE_PRIVATE void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){ void *pRet = sqlite3_malloc64(nByte); if( pRet ) memset(pRet, 0, nByte); return pRet; @@ -177930,7 +181506,7 @@ static int getNextToken( rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); if( rc==SQLITE_OK ){ nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken; - pRet = (Fts3Expr *)fts3MallocZero(nByte); + pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte); if( !pRet ){ rc = SQLITE_NOMEM; }else{ @@ -178185,7 +181761,7 @@ static int getNextNode( if( fts3isspace(cNext) || cNext=='"' || cNext=='(' || cNext==')' || cNext==0 ){ - pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr)); + pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr)); if( !pRet ){ return SQLITE_NOMEM; } @@ -178364,7 +181940,7 @@ static int fts3ExprParse( && p->eType==FTSQUERY_PHRASE && pParse->isNot ){ /* Create an implicit NOT operator. */ - Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); + Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr)); if( !pNot ){ sqlite3Fts3ExprFree(p); rc = SQLITE_NOMEM; @@ -178398,7 +181974,7 @@ static int fts3ExprParse( /* Insert an implicit AND operator. */ Fts3Expr *pAnd; assert( pRet && pPrev ); - pAnd = fts3MallocZero(sizeof(Fts3Expr)); + pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr)); if( !pAnd ){ sqlite3Fts3ExprFree(p); rc = SQLITE_NOMEM; @@ -181254,7 +184830,7 @@ static int fts3tokRowidMethod( ** Register the fts3tok module with database connection db. Return SQLITE_OK ** if successful or an error code if sqlite3_create_module() fails. */ -SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash, void(*xDestroy)(void*)){ static const sqlite3_module fts3tok_module = { 0, /* iVersion */ fts3tokConnectMethod, /* xCreate */ @@ -181283,7 +184859,9 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ }; int rc; /* Return code */ - rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); + rc = sqlite3_create_module_v2( + db, "fts3tokenize", &fts3tok_module, (void*)pHash, xDestroy + ); return rc; } @@ -182628,8 +186206,18 @@ static int fts3SegReaderNext( char *aCopy; PendingList *pList = (PendingList *)fts3HashData(pElem); int nCopy = pList->nData+1; - pReader->zTerm = (char *)fts3HashKey(pElem); - pReader->nTerm = fts3HashKeysize(pElem); + + int nTerm = fts3HashKeysize(pElem); + if( (nTerm+1)>pReader->nTermAlloc ){ + sqlite3_free(pReader->zTerm); + pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2); + if( !pReader->zTerm ) return SQLITE_NOMEM; + pReader->nTermAlloc = (nTerm+1)*2; + } + memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm); + pReader->zTerm[nTerm] = '\0'; + pReader->nTerm = nTerm; + aCopy = (char*)sqlite3_malloc(nCopy); if( !aCopy ) return SQLITE_NOMEM; memcpy(aCopy, pList->aData, nCopy); @@ -182882,9 +186470,7 @@ SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( */ SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ if( pReader ){ - if( !fts3SegReaderIsPending(pReader) ){ - sqlite3_free(pReader->zTerm); - } + sqlite3_free(pReader->zTerm); if( !fts3SegReaderIsRootOnly(pReader) ){ sqlite3_free(pReader->aNode); } @@ -185076,7 +188662,7 @@ static int nodeReaderNext(NodeReader *p){ return FTS_CORRUPT_VTAB; } blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc); - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){ memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix); p->term.n = nPrefix+nSuffix; p->iOff += nSuffix; @@ -185470,7 +189056,11 @@ static int fts3TermCmp( int nCmp = MIN(nLhs, nRhs); int res; - res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0); + if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){ + res = memcmp(zLhs, zRhs, nCmp); + }else{ + res = 0; + } if( res==0 ) res = nLhs - nRhs; return res; @@ -186114,7 +189704,7 @@ static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ if( aHint ){ blobGrowBuffer(pHint, nHint, &rc); if( rc==SQLITE_OK ){ - memcpy(pHint->a, aHint, nHint); + if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint); pHint->n = nHint; } } @@ -187231,9 +190821,8 @@ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ + sizeof(MatchinfoBuffer); sqlite3_int64 nStr = strlen(zMatchinfo); - pRet = sqlite3_malloc64(nByte + nStr+1); + pRet = sqlite3Fts3MallocZero(nByte + nStr+1); if( pRet ){ - memset(pRet, 0, nByte); pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*((int)nElem+1); @@ -187637,11 +191226,10 @@ static int fts3BestSnippet( ** the required space using malloc(). */ nByte = sizeof(SnippetPhrase) * nList; - sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte); + sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte); if( !sIter.aPhrase ){ return SQLITE_NOMEM; } - memset(sIter.aPhrase, 0, nByte); /* Initialize the contents of the SnippetIter object. Then iterate through ** the set of phrases in the expression to populate the aPhrase[] array. @@ -188205,10 +191793,12 @@ static int fts3MatchinfoLcsCb( ** position list for the next column. */ static int fts3LcsIteratorAdvance(LcsIterator *pIter){ - char *pRead = pIter->pRead; + char *pRead; sqlite3_int64 iRead; int rc = 0; + if( NEVER(pIter==0) ) return 1; + pRead = pIter->pRead; pRead += sqlite3Fts3GetVarint(pRead, &iRead); if( iRead==0 || iRead==1 ){ pRead = 0; @@ -188242,9 +191832,8 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ /* Allocate and populate the array of LcsIterator objects. The array ** contains one element for each matchable phrase in the query. **/ - aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase); + aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase); if( !aIter ) return SQLITE_NOMEM; - memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase); (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); for(i=0; inPhrase; i++){ @@ -188705,7 +192294,7 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( if( rc!=SQLITE_OK ) goto offsets_out; /* Allocate the array of TermOffset iterators. */ - sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken); + sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken); if( 0==sCtx.aTerm ){ rc = SQLITE_NOMEM; goto offsets_out; @@ -188726,13 +192315,13 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( const char *zDoc; int nDoc; - /* Initialize the contents of sCtx.aTerm[] for column iCol. There is - ** no way that this operation can fail, so the return code from - ** fts3ExprIterate() can be discarded. + /* Initialize the contents of sCtx.aTerm[] for column iCol. This + ** operation may fail if the database contains corrupt records. */ sCtx.iCol = iCol; sCtx.iTerm = 0; - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx); + rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx); + if( rc!=SQLITE_OK ) goto offsets_out; /* Retreive the text stored in column iCol. If an SQL NULL is stored ** in column iCol, jump immediately to the next iteration of the loop. @@ -189631,7 +193220,7 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ #endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */ /************** End of fts3_unicode2.c ***************************************/ -/************** Begin file json1.c *******************************************/ +/************** Begin file json.c ********************************************/ /* ** 2015-08-12 ** @@ -189644,10 +193233,10 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** ****************************************************************************** ** -** This SQLite extension implements JSON functions. The interface is -** modeled after MySQL JSON functions: +** This SQLite JSON functions. ** -** https://dev.mysql.com/doc/refman/5.7/en/json.html +** This file began as an extension in ext/misc/json1.c in 2015. That +** extension proved so useful that it has now been moved into the core. ** ** For the time being, all JSON is stored as pure text. (We might add ** a JSONB type in the future which stores a binary encoding of JSON in @@ -189655,48 +193244,8 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ ** This implementation parses JSON text at 250 MB/s, so it is hard to see ** how JSONB might improve on that.) */ -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) -#if !defined(SQLITEINT_H) -/* #include "sqlite3ext.h" */ -#endif -SQLITE_EXTENSION_INIT1 -/* #include */ -/* #include */ -/* #include */ -/* #include */ - -/* Mark a function parameter as unused, to suppress nuisance compiler -** warnings. */ -#ifndef UNUSED_PARAM -# define UNUSED_PARAM(X) (void)(X) -#endif - -#ifndef LARGEST_INT64 -# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) -#endif - -#ifndef deliberate_fall_through -# define deliberate_fall_through -#endif - -/* -** Versions of isspace(), isalnum() and isdigit() to which it is safe -** to pass signed char values. -*/ -#ifdef sqlite3Isdigit - /* Use the SQLite core versions if this routine is part of the - ** SQLite amalgamation */ -# define safe_isdigit(x) sqlite3Isdigit(x) -# define safe_isalnum(x) sqlite3Isalnum(x) -# define safe_isxdigit(x) sqlite3Isxdigit(x) -#else - /* Use the standard library for separate compilation */ -#include /* amalgamator: keep */ -# define safe_isdigit(x) isdigit((unsigned char)(x)) -# define safe_isalnum(x) isalnum((unsigned char)(x)) -# define safe_isxdigit(x) isxdigit((unsigned char)(x)) -#endif +#ifndef SQLITE_OMIT_JSON +/* #include "sqliteInt.h" */ /* ** Growing our own isspace() routine this way is twice as fast as @@ -189721,15 +193270,12 @@ static const char jsonIsSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -#define safe_isspace(x) (jsonIsSpace[(unsigned char)x]) +#define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) -#ifndef SQLITE_AMALGAMATION - /* Unsigned integer types. These are already defined in the sqliteInt.h, - ** but the definitions need to be repeated for separate compilation. */ - typedef sqlite3_uint64 u64; - typedef unsigned int u32; - typedef unsigned short int u16; - typedef unsigned char u8; +#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) +# define VVA(X) +#else +# define VVA(X) X #endif /* Objects */ @@ -189788,13 +193334,14 @@ static const char * const jsonType[] = { struct JsonNode { u8 eType; /* One of the JSON_ type values */ u8 jnFlags; /* JNODE flags */ + u8 eU; /* Which union element to use */ u32 n; /* Bytes of content, or number of sub-nodes */ union { - const char *zJContent; /* Content for INT, REAL, and STRING */ - u32 iAppend; /* More terms for ARRAY and OBJECT */ - u32 iKey; /* Key for ARRAY objects in json_tree() */ - u32 iReplace; /* Replacement content for JNODE_REPLACE */ - JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */ + const char *zJContent; /* 1: Content for INT, REAL, and STRING */ + u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ + u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ + u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */ + JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */ } u; }; @@ -190072,11 +193619,14 @@ static void jsonRenderNode( JsonString *pOut, /* Write JSON here */ sqlite3_value **aReplace /* Replacement values */ ){ + assert( pNode!=0 ); if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ - if( pNode->jnFlags & JNODE_REPLACE ){ + if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){ + assert( pNode->eU==4 ); jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); return; } + assert( pNode->eU==5 ); pNode = pNode->u.pPatch; } switch( pNode->eType ){ @@ -190095,6 +193645,7 @@ static void jsonRenderNode( } case JSON_STRING: { if( pNode->jnFlags & JNODE_RAW ){ + assert( pNode->eU==1 ); jsonAppendString(pOut, pNode->u.zJContent, pNode->n); break; } @@ -190102,6 +193653,7 @@ static void jsonRenderNode( } case JSON_REAL: case JSON_INT: { + assert( pNode->eU==1 ); jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); break; } @@ -190117,6 +193669,7 @@ static void jsonRenderNode( j += jsonNodeSize(&pNode[j]); } if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + assert( pNode->eU==2 ); pNode = &pNode[pNode->u.iAppend]; j = 1; } @@ -190137,6 +193690,7 @@ static void jsonRenderNode( j += 1 + jsonNodeSize(&pNode[j+1]); } if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + assert( pNode->eU==2 ); pNode = &pNode[pNode->u.iAppend]; j = 1; } @@ -190181,10 +193735,10 @@ static u8 jsonHexToInt(int h){ */ static u32 jsonHexToInt4(const char *z){ u32 v; - assert( safe_isxdigit(z[0]) ); - assert( safe_isxdigit(z[1]) ); - assert( safe_isxdigit(z[2]) ); - assert( safe_isxdigit(z[3]) ); + assert( sqlite3Isxdigit(z[0]) ); + assert( sqlite3Isxdigit(z[1]) ); + assert( sqlite3Isxdigit(z[2]) ); + assert( sqlite3Isxdigit(z[3]) ); v = (jsonHexToInt(z[0])<<12) + (jsonHexToInt(z[1])<<8) + (jsonHexToInt(z[2])<<4) @@ -190216,7 +193770,9 @@ static void jsonReturn( } case JSON_INT: { sqlite3_int64 i = 0; - const char *z = pNode->u.zJContent; + const char *z; + assert( pNode->eU==1 ); + z = pNode->u.zJContent; if( z[0]=='-' ){ z++; } while( z[0]>='0' && z[0]<='9' ){ unsigned v = *(z++) - '0'; @@ -190239,14 +193795,17 @@ static void jsonReturn( sqlite3_result_int64(pCtx, i); int_done: break; - int_as_real: i=0; /* no break */ deliberate_fall_through + int_as_real: ; /* no break */ deliberate_fall_through } case JSON_REAL: { double r; #ifdef SQLITE_AMALGAMATION - const char *z = pNode->u.zJContent; + const char *z; + assert( pNode->eU==1 ); + z = pNode->u.zJContent; sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); #else + assert( pNode->eU==1 ); r = strtod(pNode->u.zJContent, 0); #endif sqlite3_result_double(pCtx, r); @@ -190257,6 +193816,7 @@ static void jsonReturn( ** json_insert() and json_replace() and those routines do not ** call jsonReturn() */ if( pNode->jnFlags & JNODE_RAW ){ + assert( pNode->eU==1 ); sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, SQLITE_TRANSIENT); }else @@ -190264,15 +193824,18 @@ static void jsonReturn( assert( (pNode->jnFlags & JNODE_RAW)==0 ); if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ /* JSON formatted without any backslash-escapes */ + assert( pNode->eU==1 ); sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, SQLITE_TRANSIENT); }else{ /* Translate JSON formatted string into raw text */ u32 i; u32 n = pNode->n; - const char *z = pNode->u.zJContent; + const char *z; char *zOut; u32 j; + assert( pNode->eU==1 ); + z = pNode->u.zJContent; zOut = sqlite3_malloc( n+1 ); if( zOut==0 ){ sqlite3_result_error_nomem(pCtx); @@ -190393,12 +193956,13 @@ static int jsonParseAddNode( const char *zContent /* Content */ ){ JsonNode *p; - if( pParse->nNode>=pParse->nAlloc ){ + if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){ return jsonParseAddNodeExpand(pParse, eType, n, zContent); } p = &pParse->aNode[pParse->nNode]; p->eType = (u8)eType; p->jnFlags = 0; + VVA( p->eU = zContent ? 1 : 0 ); p->n = n; p->u.zJContent = zContent; return pParse->nNode++; @@ -190409,7 +193973,7 @@ static int jsonParseAddNode( */ static int jsonIs4Hex(const char *z){ int i; - for(i=0; i<4; i++) if( !safe_isxdigit(z[i]) ) return 0; + for(i=0; i<4; i++) if( !sqlite3Isxdigit(z[i]) ) return 0; return 1; } @@ -190428,13 +193992,13 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ int x; JsonNode *pNode; const char *z = pParse->zJson; - while( safe_isspace(z[i]) ){ i++; } + while( fast_isspace(z[i]) ){ i++; } if( (c = z[i])=='{' ){ /* Parse object */ iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); if( iThis<0 ) return -1; for(j=i+1;;j++){ - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); if( x<0 ){ @@ -190447,14 +194011,14 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ if( pNode->eType!=JSON_STRING ) return -1; pNode->jnFlags |= JNODE_LABEL; j = x; - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } if( z[j]!=':' ) return -1; j++; x = jsonParseValue(pParse, j); pParse->iDepth--; if( x<0 ) return -1; j = x; - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } c = z[j]; if( c==',' ) continue; if( c!='}' ) return -1; @@ -190466,8 +194030,9 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ /* Parse array */ iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); if( iThis<0 ) return -1; + memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u)); for(j=i+1;;j++){ - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1; x = jsonParseValue(pParse, j); pParse->iDepth--; @@ -190476,7 +194041,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ return -1; } j = x; - while( safe_isspace(z[j]) ){ j++; } + while( fast_isspace(z[j]) ){ j++; } c = z[j]; if( c==',' ) continue; if( c!=']' ) return -1; @@ -190513,17 +194078,17 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ return j+1; }else if( c=='n' && strncmp(z+i,"null",4)==0 - && !safe_isalnum(z[i+4]) ){ + && !sqlite3Isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_NULL, 0, 0); return i+4; }else if( c=='t' && strncmp(z+i,"true",4)==0 - && !safe_isalnum(z[i+4]) ){ + && !sqlite3Isalnum(z[i+4]) ){ jsonParseAddNode(pParse, JSON_TRUE, 0, 0); return i+4; }else if( c=='f' && strncmp(z+i,"false",5)==0 - && !safe_isalnum(z[i+5]) ){ + && !sqlite3Isalnum(z[i+5]) ){ jsonParseAddNode(pParse, JSON_FALSE, 0, 0); return i+5; }else if( c=='-' || (c>='0' && c<='9') ){ @@ -190594,7 +194159,7 @@ static int jsonParse( if( pParse->oom ) i = -1; if( i>0 ){ assert( pParse->iDepth==0 ); - while( safe_isspace(zJson[i]) ) i++; + while( fast_isspace(zJson[i]) ) i++; if( zJson[i] ) i = -1; } if( i<=0 ){ @@ -190730,6 +194295,7 @@ static JsonParse *jsonParseCached( ** a match. */ static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){ + assert( pNode->eU==1 ); if( pNode->jnFlags & JNODE_RAW ){ if( pNode->n!=nKey ) return 0; return strncmp(pNode->u.zJContent, zKey, nKey)==0; @@ -190776,14 +194342,15 @@ static JsonNode *jsonLookupStep( *pzErr = zPath; return 0; } + testcase( nKey==0 ); }else{ zKey = zPath; for(i=0; zPath[i] && zPath[i]!='.' && zPath[i]!='['; i++){} nKey = i; - } - if( nKey==0 ){ - *pzErr = zPath; - return 0; + if( nKey==0 ){ + *pzErr = zPath; + return 0; + } } j = 1; for(;;){ @@ -190795,6 +194362,7 @@ static JsonNode *jsonLookupStep( j += jsonNodeSize(&pRoot[j]); } if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + assert( pRoot->eU==2 ); iRoot += pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; j = 1; @@ -190809,8 +194377,10 @@ static JsonNode *jsonLookupStep( if( pParse->oom ) return 0; if( pNode ){ pRoot = &pParse->aNode[iRoot]; + assert( pRoot->eU==0 ); pRoot->u.iAppend = iStart - iRoot; pRoot->jnFlags |= JNODE_APPEND; + VVA( pRoot->eU = 2 ); pParse->aNode[iLabel].jnFlags |= JNODE_RAW; } return pNode; @@ -190818,7 +194388,7 @@ static JsonNode *jsonLookupStep( }else if( zPath[0]=='[' ){ i = 0; j = 1; - while( safe_isdigit(zPath[j]) ){ + while( sqlite3Isdigit(zPath[j]) ){ i = i*10 + zPath[j] - '0'; j++; } @@ -190833,18 +194403,19 @@ static JsonNode *jsonLookupStep( j += jsonNodeSize(&pBase[j]); } if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; + assert( pBase->eU==2 ); iBase += pBase->u.iAppend; pBase = &pParse->aNode[iBase]; j = 1; } j = 2; - if( zPath[2]=='-' && safe_isdigit(zPath[3]) ){ + if( zPath[2]=='-' && sqlite3Isdigit(zPath[3]) ){ unsigned int x = 0; j = 3; do{ x = x*10 + zPath[j] - '0'; j++; - }while( safe_isdigit(zPath[j]) ); + }while( sqlite3Isdigit(zPath[j]) ); if( x>i ) return 0; i -= x; } @@ -190866,6 +194437,7 @@ static JsonNode *jsonLookupStep( j += jsonNodeSize(&pRoot[j]); } if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + assert( pRoot->eU==2 ); iRoot += pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; j = 1; @@ -190881,8 +194453,10 @@ static JsonNode *jsonLookupStep( if( pParse->oom ) return 0; if( pNode ){ pRoot = &pParse->aNode[iRoot]; + assert( pRoot->eU==0 ); pRoot->u.iAppend = iStart - iRoot; pRoot->jnFlags |= JNODE_APPEND; + VVA( pRoot->eU = 2 ); } return pNode; } @@ -191036,9 +194610,13 @@ static void jsonParseFunc( } jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d", i, zType, x.aNode[i].n, x.aUp[i]); + assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 ); if( x.aNode[i].u.zJContent!=0 ){ + assert( x.aNode[i].eU==1 ); jsonAppendRaw(&s, " ", 1); jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n); + }else{ + assert( x.aNode[i].eU==0 ); } jsonAppendRaw(&s, "\n", 1); } @@ -191056,7 +194634,7 @@ static void jsonTest1Func( int argc, sqlite3_value **argv ){ - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); sqlite3_result_int(ctx, sqlite3_value_subtype(argv[0])==JSON_SUBTYPE); } #endif /* SQLITE_DEBUG */ @@ -191077,7 +194655,7 @@ static void jsonQuoteFunc( sqlite3_value **argv ){ JsonString jx; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); jsonInit(&jx, ctx); jsonAppendValue(&jx, argv[0]); @@ -191148,13 +194726,34 @@ static void jsonArrayLengthFunc( sqlite3_result_int64(ctx, n); } +/* +** Bit values for the flags passed into jsonExtractFunc() or +** jsonSetFunc() via the user-data value. +*/ +#define JSON_JSON 0x01 /* Result is always JSON */ +#define JSON_SQL 0x02 /* Result is always SQL */ +#define JSON_ABPATH 0x03 /* Allow abbreviated JSON path specs */ +#define JSON_ISSET 0x04 /* json_set(), not json_insert() */ + /* ** json_extract(JSON, PATH, ...) +** "->"(JSON,PATH) +** "->>"(JSON,PATH) ** -** Return the element described by PATH. Return NULL if there is no -** PATH element. If there are multiple PATHs, then return a JSON array -** with the result from each path. Throw an error if the JSON or any PATH -** is malformed. +** Return the element described by PATH. Return NULL if that PATH element +** is not found. +** +** If JSON_JSON is set or if more that one PATH argument is supplied then +** always return a JSON representation of the result. If JSON_SQL is set, +** then always return an SQL representation of the result. If neither flag +** is present and argc==2, then return JSON for objects and arrays and SQL +** for all other values. +** +** When multiple PATH arguments are supplied, the result is a JSON array +** containing the result of each PATH. +** +** Abbreviated JSON path expressions are allows if JSON_ABPATH, for +** compatibility with PG. */ static void jsonExtractFunc( sqlite3_context *ctx, @@ -191164,35 +194763,77 @@ static void jsonExtractFunc( JsonParse *p; /* The parse */ JsonNode *pNode; const char *zPath; + int flags = SQLITE_PTR_TO_INT(sqlite3_user_data(ctx)); JsonString jx; - int i; if( argc<2 ) return; p = jsonParseCached(ctx, argv, ctx); if( p==0 ) return; - jsonInit(&jx, ctx); - jsonAppendChar(&jx, '['); - for(i=1; inErr ) break; - if( argc>2 ){ + if( argc==2 ){ + /* With a single PATH argument */ + zPath = (const char*)sqlite3_value_text(argv[1]); + if( zPath==0 ) return; + if( flags & JSON_ABPATH ){ + if( zPath[0]!='$' ){ + /* The -> and ->> operators accept abbreviated PATH arguments. This + ** is mostly for compatibility with PostgreSQL, but also for + ** convenience. + ** + ** NUMBER ==> $[NUMBER] // PG compatible + ** LABEL ==> $.LABEL // PG compatible + ** [NUMBER] ==> $[NUMBER] // Not PG. Purely for convenience + */ + jsonInit(&jx, ctx); + if( sqlite3Isdigit(zPath[0]) ){ + jsonAppendRaw(&jx, "$[", 2); + jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); + jsonAppendRaw(&jx, "]", 2); + }else{ + jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='[')); + jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); + jsonAppendChar(&jx, 0); + } + pNode = jx.bErr ? 0 : jsonLookup(p, jx.zBuf, 0, ctx); + jsonReset(&jx); + }else{ + pNode = jsonLookup(p, zPath, 0, ctx); + } + if( pNode ){ + if( flags & JSON_JSON ){ + jsonReturnJson(pNode, ctx, 0); + }else{ + jsonReturn(pNode, ctx, 0); + sqlite3_result_subtype(ctx, 0); + } + } + }else{ + pNode = jsonLookup(p, zPath, 0, ctx); + if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); + } + }else{ + /* Two or more PATH arguments results in a JSON array with each + ** element of the array being the value selected by one of the PATHs */ + int i; + jsonInit(&jx, ctx); + jsonAppendChar(&jx, '['); + for(i=1; inErr ) break; jsonAppendSeparator(&jx); if( pNode ){ jsonRenderNode(pNode, &jx, 0); }else{ jsonAppendRaw(&jx, "null", 4); } - }else if( pNode ){ - jsonReturn(pNode, ctx, 0); } + if( i==argc ){ + jsonAppendChar(&jx, ']'); + jsonResult(&jx); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); + } + jsonReset(&jx); } - if( argc>2 && i==argc ){ - jsonAppendChar(&jx, ']'); - jsonResult(&jx); - sqlite3_result_subtype(ctx, JSON_SUBTYPE); - } - jsonReset(&jx); } /* This is the RFC 7396 MergePatch algorithm. @@ -191221,6 +194862,7 @@ static JsonNode *jsonMergePatch( const char *zKey; assert( pPatch[i].eType==JSON_STRING ); assert( pPatch[i].jnFlags & JNODE_LABEL ); + assert( pPatch[i].eU==1 ); nKey = pPatch[i].n; zKey = pPatch[i].u.zJContent; assert( (pPatch[i].jnFlags & JNODE_RAW)==0 ); @@ -191237,6 +194879,12 @@ static JsonNode *jsonMergePatch( if( pNew==0 ) return 0; pTarget = &pParse->aNode[iTarget]; if( pNew!=&pTarget[j+1] ){ + assert( pTarget[j+1].eU==0 + || pTarget[j+1].eU==1 + || pTarget[j+1].eU==2 ); + testcase( pTarget[j+1].eU==1 ); + testcase( pTarget[j+1].eU==2 ); + VVA( pTarget[j+1].eU = 5 ); pTarget[j+1].u.pPatch = pNew; pTarget[j+1].jnFlags |= JNODE_PATCH; } @@ -191252,9 +194900,14 @@ static JsonNode *jsonMergePatch( if( pParse->oom ) return 0; jsonRemoveAllNulls(pPatch); pTarget = &pParse->aNode[iTarget]; + assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 ); + testcase( pParse->aNode[iRoot].eU==2 ); pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; + VVA( pParse->aNode[iRoot].eU = 2 ); pParse->aNode[iRoot].u.iAppend = iStart - iRoot; iRoot = iStart; + assert( pParse->aNode[iPatch].eU==0 ); + VVA( pParse->aNode[iPatch].eU = 5 ); pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; } @@ -191276,7 +194929,7 @@ static void jsonPatchFunc( JsonParse y; /* The patch */ JsonNode *pResult; /* The result of the merge */ - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ jsonParseReset(&x); @@ -191396,11 +195049,15 @@ static void jsonReplaceFunc( pNode = jsonLookup(&x, zPath, 0, ctx); if( x.nErr ) goto replace_err; if( pNode ){ + assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 ); + testcase( pNode->eU!=0 && pNode->eU!=1 ); pNode->jnFlags |= (u8)JNODE_REPLACE; + VVA( pNode->eU = 4 ); pNode->u.iReplace = i + 1; } } if( x.aNode[0].jnFlags & JNODE_REPLACE ){ + assert( x.aNode[0].eU==4 ); sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); }else{ jsonReturnJson(x.aNode, ctx, argv); @@ -191409,6 +195066,7 @@ replace_err: jsonParseReset(&x); } + /* ** json_set(JSON, PATH, VALUE, ...) ** @@ -191431,7 +195089,7 @@ static void jsonSetFunc( const char *zPath; u32 i; int bApnd; - int bIsSet = *(int*)sqlite3_user_data(ctx); + int bIsSet = sqlite3_user_data(ctx)!=0; if( argc<1 ) return; if( (argc&1)==0 ) { @@ -191450,11 +195108,15 @@ static void jsonSetFunc( }else if( x.nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ + testcase( pNode->eU!=0 && pNode->eU!=1 ); + assert( pNode->eU!=3 && pNode->eU!=5 ); + VVA( pNode->eU = 4 ); pNode->jnFlags |= (u8)JNODE_REPLACE; pNode->u.iReplace = i + 1; } } if( x.aNode[0].jnFlags & JNODE_REPLACE ){ + assert( x.aNode[0].eU==4 ); sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); }else{ jsonReturnJson(x.aNode, ctx, argv); @@ -191467,8 +195129,8 @@ jsonSetDone: ** json_type(JSON) ** json_type(JSON, PATH) ** -** Return the top-level "type" of a JSON string. Throw an error if -** either the JSON or PATH inputs are not well-formed. +** Return the top-level "type" of a JSON string. json_type() raises an +** error if either the JSON or PATH inputs are not well-formed. */ static void jsonTypeFunc( sqlite3_context *ctx, @@ -191504,7 +195166,7 @@ static void jsonValidFunc( sqlite3_value **argv ){ JsonParse *p; /* The parse */ - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); p = jsonParseCached(ctx, argv, 0); sqlite3_result_int(ctx, p!=0); } @@ -191524,7 +195186,7 @@ static void jsonArrayStep( sqlite3_value **argv ){ JsonString *pStr; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ @@ -191584,8 +195246,8 @@ static void jsonGroupInverse( char *z; char c; JsonString *pStr; - UNUSED_PARAM(argc); - UNUSED_PARAM(argv); + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(argv); pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); #ifdef NEVER /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will @@ -191629,7 +195291,7 @@ static void jsonObjectStep( JsonString *pStr; const char *z; u32 n; - UNUSED_PARAM(argc); + UNUSED_PARAMETER(argc); pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ @@ -191720,10 +195382,10 @@ static int jsonEachConnect( #define JEACH_JSON 8 #define JEACH_ROOT 9 - UNUSED_PARAM(pzErr); - UNUSED_PARAM(argv); - UNUSED_PARAM(argc); - UNUSED_PARAM(pAux); + UNUSED_PARAMETER(pzErr); + UNUSED_PARAMETER(argv); + UNUSED_PARAMETER(argc); + UNUSED_PARAMETER(pAux); rc = sqlite3_declare_vtab(db, "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); @@ -191746,7 +195408,7 @@ static int jsonEachDisconnect(sqlite3_vtab *pVtab){ static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ JsonEachCursor *pCur; - UNUSED_PARAM(p); + UNUSED_PARAMETER(p); pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); @@ -191805,6 +195467,9 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ JsonNode *pUp = &p->sParse.aNode[iUp]; p->eType = pUp->eType; if( pUp->eType==JSON_ARRAY ){ + assert( pUp->eU==0 || pUp->eU==3 ); + testcase( pUp->eU==3 ); + VVA( pUp->eU = 3 ); if( iUp==p->i-1 ){ pUp->u.iKey = 0; }else{ @@ -191833,6 +195498,33 @@ static int jsonEachNext(sqlite3_vtab_cursor *cur){ return SQLITE_OK; } +/* Append an object label to the JSON Path being constructed +** in pStr. +*/ +static void jsonAppendObjectPathElement( + JsonString *pStr, + JsonNode *pNode +){ + int jj, nn; + const char *z; + assert( pNode->eType==JSON_STRING ); + assert( pNode->jnFlags & JNODE_LABEL ); + assert( pNode->eU==1 ); + z = pNode->u.zJContent; + nn = pNode->n; + assert( nn>=2 ); + assert( z[0]=='"' ); + assert( z[nn-1]=='"' ); + if( nn>2 && sqlite3Isalpha(z[1]) ){ + for(jj=2; jjsParse.aNode[i]; pUp = &p->sParse.aNode[iUp]; if( pUp->eType==JSON_ARRAY ){ + assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) ); + testcase( pUp->eU==0 ); jsonPrintf(30, pStr, "[%d]", pUp->u.iKey); }else{ assert( pUp->eType==JSON_OBJECT ); if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--; - assert( pNode->eType==JSON_STRING ); - assert( pNode->jnFlags & JNODE_LABEL ); - jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1); + jsonAppendObjectPathElement(pStr, pNode); } } @@ -191878,6 +195570,7 @@ static int jsonEachColumn( u32 iKey; if( p->bRecursive ){ if( p->iRowid==0 ) break; + assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 ); iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey; }else{ iKey = p->iRowid; @@ -191927,7 +195620,7 @@ static int jsonEachColumn( if( p->eType==JSON_ARRAY ){ jsonPrintf(30, &x, "[%d]", p->iRowid); }else if( p->eType==JSON_OBJECT ){ - jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1); + jsonAppendObjectPathElement(&x, pThis); } } jsonResult(&x); @@ -191985,7 +195678,7 @@ static int jsonEachBestIndex( /* This implementation assumes that JSON and ROOT are the last two ** columns in the table */ assert( JEACH_ROOT == JEACH_JSON+1 ); - UNUSED_PARAM(tab); + UNUSED_PARAMETER(tab); aIdx[0] = aIdx[1] = -1; pConstraint = pIdxInfo->aConstraint; for(i=0; inConstraint; i++, pConstraint++){ @@ -191994,6 +195687,7 @@ static int jsonEachBestIndex( if( pConstraint->iColumn < JEACH_JSON ) continue; iCol = pConstraint->iColumn - JEACH_JSON; assert( iCol==0 || iCol==1 ); + testcase( iCol==0 ); iMask = 1 << iCol; if( pConstraint->usable==0 ){ unusableMask |= iMask; @@ -192040,8 +195734,8 @@ static int jsonEachFilter( const char *zRoot = 0; sqlite3_int64 n; - UNUSED_PARAM(idxStr); - UNUSED_PARAM(argc); + UNUSED_PARAMETER(idxStr); + UNUSED_PARAMETER(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; z = (const char*)sqlite3_value_text(argv[0]); @@ -192091,6 +195785,8 @@ static int jsonEachFilter( p->iBegin = p->i = (int)(pNode - p->sParse.aNode); p->eType = pNode->eType; if( p->eType>=JSON_ARRAY ){ + assert( pNode->eU==0 ); + VVA( pNode->eU = 3 ); pNode->u.iKey = 0; p->iEnd = p->i + pNode->n + 1; if( p->bRecursive ){ @@ -192164,108 +195860,68 @@ static sqlite3_module jsonTreeModule = { 0 /* xShadowName */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ +#endif /* !defined(SQLITE_OMIT_JSON) */ -/**************************************************************************** -** The following routines are the only publically visible identifiers in this -** file. Call the following routines in order to register the various SQL -** functions and the virtual table implemented by this file. -****************************************************************************/ - -SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ - int rc = SQLITE_OK; - unsigned int i; - static const struct { - const char *zName; - int nArg; - int flag; - void (*xFunc)(sqlite3_context*,int,sqlite3_value**); - } aFunc[] = { - { "json", 1, 0, jsonRemoveFunc }, - { "json_array", -1, 0, jsonArrayFunc }, - { "json_array_length", 1, 0, jsonArrayLengthFunc }, - { "json_array_length", 2, 0, jsonArrayLengthFunc }, - { "json_extract", -1, 0, jsonExtractFunc }, - { "json_insert", -1, 0, jsonSetFunc }, - { "json_object", -1, 0, jsonObjectFunc }, - { "json_patch", 2, 0, jsonPatchFunc }, - { "json_quote", 1, 0, jsonQuoteFunc }, - { "json_remove", -1, 0, jsonRemoveFunc }, - { "json_replace", -1, 0, jsonReplaceFunc }, - { "json_set", -1, 1, jsonSetFunc }, - { "json_type", 1, 0, jsonTypeFunc }, - { "json_type", 2, 0, jsonTypeFunc }, - { "json_valid", 1, 0, jsonValidFunc }, - +/* +** Register JSON functions. +*/ +SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void){ +#ifndef SQLITE_OMIT_JSON + static FuncDef aJsonFunc[] = { + JFUNCTION(json, 1, 0, jsonRemoveFunc), + JFUNCTION(json_array, -1, 0, jsonArrayFunc), + JFUNCTION(json_array_length, 1, 0, jsonArrayLengthFunc), + JFUNCTION(json_array_length, 2, 0, jsonArrayLengthFunc), + JFUNCTION(json_extract, -1, 0, jsonExtractFunc), + JFUNCTION(->, 2, JSON_JSON, jsonExtractFunc), + JFUNCTION(->>, 2, JSON_SQL, jsonExtractFunc), + JFUNCTION(json_insert, -1, 0, jsonSetFunc), + JFUNCTION(json_object, -1, 0, jsonObjectFunc), + JFUNCTION(json_patch, 2, 0, jsonPatchFunc), + JFUNCTION(json_quote, 1, 0, jsonQuoteFunc), + JFUNCTION(json_remove, -1, 0, jsonRemoveFunc), + JFUNCTION(json_replace, -1, 0, jsonReplaceFunc), + JFUNCTION(json_set, -1, JSON_ISSET, jsonSetFunc), + JFUNCTION(json_type, 1, 0, jsonTypeFunc), + JFUNCTION(json_type, 2, 0, jsonTypeFunc), + JFUNCTION(json_valid, 1, 0, jsonValidFunc), #if SQLITE_DEBUG - /* DEBUG and TESTING functions */ - { "json_parse", 1, 0, jsonParseFunc }, - { "json_test1", 1, 0, jsonTest1Func }, + JFUNCTION(json_parse, 1, 0, jsonParseFunc), + JFUNCTION(json_test1, 1, 0, jsonTest1Func), #endif + WAGGREGATE(json_group_array, 1, 0, 0, + jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS), + WAGGREGATE(json_group_object, 2, 0, 0, + jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, + SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) }; + sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); +#endif +} + +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) +/* +** Register the JSON table-valued functions +*/ +SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){ + int rc = SQLITE_OK; static const struct { - const char *zName; - int nArg; - void (*xStep)(sqlite3_context*,int,sqlite3_value**); - void (*xFinal)(sqlite3_context*); - void (*xValue)(sqlite3_context*); - } aAgg[] = { - { "json_group_array", 1, - jsonArrayStep, jsonArrayFinal, jsonArrayValue }, - { "json_group_object", 2, - jsonObjectStep, jsonObjectFinal, jsonObjectValue }, - }; -#ifndef SQLITE_OMIT_VIRTUALTABLE - static const struct { - const char *zName; - sqlite3_module *pModule; + const char *zName; + sqlite3_module *pModule; } aMod[] = { { "json_each", &jsonEachModule }, { "json_tree", &jsonTreeModule }, }; -#endif - static const int enc = - SQLITE_UTF8 | - SQLITE_DETERMINISTIC | - SQLITE_INNOCUOUS; - for(i=0; i */ /* #include */ @@ -192404,7 +196077,9 @@ struct Rtree { u8 nBytesPerCell; /* Bytes consumed per cell */ u8 inWrTrans; /* True if inside write transaction */ u8 nAux; /* # of auxiliary columns in %_rowid */ +#ifdef SQLITE_ENABLE_GEOPOLY u8 nAuxNotNull; /* Number of initial not-null aux columns */ +#endif #ifdef SQLITE_DEBUG u8 bCorrupt; /* Shadow table corruption detected */ #endif @@ -192686,7 +196361,12 @@ struct RtreeMatchArg { ** it is not, make it a no-op. */ #ifndef SQLITE_AMALGAMATION -# define testcase(X) +# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) + unsigned int sqlite3RtreeTestcase = 0; +# define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; } +# else +# define testcase(X) +# endif #endif /* @@ -192935,18 +196615,6 @@ static void nodeBlobReset(Rtree *pRtree){ } } -/* -** Check to see if pNode is the same as pParent or any of the parents -** of pParent. -*/ -static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){ - do{ - if( pNode==pParent ) return 1; - pParent = pParent->pParent; - }while( pParent ); - return 0; -} - /* ** Obtain a reference to an r-tree node. */ @@ -192963,14 +196631,7 @@ static int nodeAcquire( ** increase its reference count and return it. */ if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){ - if( pParent && !pNode->pParent ){ - if( nodeInParentChain(pNode, pParent) ){ - RTREE_IS_CORRUPT(pRtree); - return SQLITE_CORRUPT_VTAB; - } - pParent->nRef++; - pNode->pParent = pParent; - }else if( pParent && pNode->pParent && pParent!=pNode->pParent ){ + if( pParent && pParent!=pNode->pParent ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -193028,7 +196689,7 @@ static int nodeAcquire( ** are the leaves, and so on. If the depth as specified on the root node ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt. */ - if( pNode && rc==SQLITE_OK && iNode==1 ){ + if( rc==SQLITE_OK && pNode && iNode==1 ){ pRtree->iDepth = readInt16(pNode->zData); if( pRtree->iDepth>RTREE_MAX_DEPTH ){ rc = SQLITE_CORRUPT_VTAB; @@ -193551,20 +197212,29 @@ static void rtreeNonleafConstraint( switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ - case RTREE_LE: - case RTREE_LT: case RTREE_EQ: + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the lower bound of the coordinate pair */ + if( p->u.rValue>=val ){ + pCellData += 4; + RTREE_DECODE_COORD(eInt, pCellData, val); + /* val now holds the upper bound of the coordinate pair */ + if( p->u.rValue<=val ) return; + } + break; + case RTREE_LE: + case RTREE_LT: RTREE_DECODE_COORD(eInt, pCellData, val); /* val now holds the lower bound of the coordinate pair */ if( p->u.rValue>=val ) return; - if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */ - /* Fall through for the RTREE_EQ case */ + break; - default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */ + default: pCellData += 4; RTREE_DECODE_COORD(eInt, pCellData, val); /* val now holds the upper bound of the coordinate pair */ if( p->u.rValue<=val ) return; + break; } *peWithin = NOT_WITHIN; } @@ -193634,11 +197304,12 @@ static int nodeRowidIndex( */ static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){ RtreeNode *pParent = pNode->pParent; - if( pParent ){ + if( ALWAYS(pParent) ){ return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex); + }else{ + *piIndex = -1; + return SQLITE_OK; } - *piIndex = -1; - return SQLITE_OK; } /* @@ -193761,7 +197432,8 @@ static RtreeSearchPoint *rtreeSearchPointNew( pNew = rtreeEnqueue(pCur, rScore, iLevel); if( pNew==0 ) return 0; ii = (int)(pNew - pCur->aPoint) + 1; - if( iiaNode[ii]==0 ); pCur->aNode[ii] = pCur->aNode[0]; }else{ @@ -193822,7 +197494,7 @@ static void rtreeSearchPointPop(RtreeCursor *p){ if( p->bPoint ){ p->anQueue[p->sPoint.iLevel]--; p->bPoint = 0; - }else if( p->nPoint ){ + }else if( ALWAYS(p->nPoint) ){ p->anQueue[p->aPoint[0].iLevel]--; n = --p->nPoint; p->aPoint[0] = p->aPoint[n]; @@ -193963,7 +197635,7 @@ static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); int rc = SQLITE_OK; RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); - if( rc==SQLITE_OK && p ){ + if( rc==SQLITE_OK && ALWAYS(p) ){ *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell); } return rc; @@ -193981,7 +197653,7 @@ static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc); if( rc ) return rc; - if( p==0 ) return SQLITE_OK; + if( NEVER(p==0) ) return SQLITE_OK; if( i==0 ){ sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); }else if( i<=pRtree->nDim2 ){ @@ -194180,8 +197852,11 @@ static int rtreeFilter( } if( rc==SQLITE_OK ){ RtreeSearchPoint *pNew; + assert( pCsr->bPoint==0 ); /* Due to the resetCursor() call above */ pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1)); - if( pNew==0 ) return SQLITE_NOMEM; + if( NEVER(pNew==0) ){ /* Because pCsr->bPoint was FALSE */ + return SQLITE_NOMEM; + } pNew->id = 1; pNew->iCell = 0; pNew->eWithin = PARTLY_WITHIN; @@ -194258,7 +197933,7 @@ static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( bMatch==0 && p->usable - && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ + && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ /* We have an equality constraint on the rowid. Use strategy 1. */ int jj; @@ -194464,7 +198139,7 @@ static int ChooseLeaf( int nCell = NCELL(pNode); RtreeCell cell; - RtreeNode *pChild; + RtreeNode *pChild = 0; RtreeCell *aCell = 0; @@ -194511,12 +198186,19 @@ static int AdjustTree( ){ RtreeNode *p = pNode; int cnt = 0; + int rc; while( p->pParent ){ RtreeNode *pParent = p->pParent; RtreeCell cell; int iCell; - if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell) ){ + cnt++; + if( NEVER(cnt>100) ){ + RTREE_IS_CORRUPT(pRtree); + return SQLITE_CORRUPT_VTAB; + } + rc = nodeParentIndex(pRtree, p, &iCell); + if( NEVER(rc!=SQLITE_OK) ){ RTREE_IS_CORRUPT(pRtree); return SQLITE_CORRUPT_VTAB; } @@ -194805,12 +198487,17 @@ static int updateMapping( xSetMapping = ((iHeight==0)?rowidWrite:parentWrite); if( iHeight>0 ){ RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); + RtreeNode *p; + for(p=pNode; p; p=p->pParent){ + if( p==pChild ) return SQLITE_CORRUPT_VTAB; + } if( pChild ){ nodeRelease(pRtree, pChild->pParent); nodeReference(pNode); pChild->pParent = pNode; } } + if( NEVER(pNode==0) ) return SQLITE_ERROR; return xSetMapping(pRtree, iRowid, pNode->iNode); } @@ -194900,11 +198587,12 @@ static int SplitNode( RtreeNode *pParent = pLeft->pParent; int iCell; rc = nodeParentIndex(pRtree, pLeft, &iCell); - if( rc==SQLITE_OK ){ + if( ALWAYS(rc==SQLITE_OK) ){ nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell); rc = AdjustTree(pRtree, pParent, &leftbbox); + assert( rc==SQLITE_OK ); } - if( rc!=SQLITE_OK ){ + if( NEVER(rc!=SQLITE_OK) ){ goto splitnode_out; } } @@ -194979,7 +198667,7 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ */ iNode = sqlite3_column_int64(pRtree->pReadParent, 0); for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); - if( !pTest ){ + if( pTest==0 ){ rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); } } @@ -195010,6 +198698,7 @@ static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ pParent = pNode->pParent; pNode->pParent = 0; rc = deleteCell(pRtree, pParent, iCell, iHeight+1); + testcase( rc!=SQLITE_OK ); } rc2 = nodeRelease(pRtree, pParent); if( rc==SQLITE_OK ){ @@ -195232,7 +198921,7 @@ static int rtreeInsertCell( } }else{ rc = AdjustTree(pRtree, pNode, pCell); - if( rc==SQLITE_OK ){ + if( ALWAYS(rc==SQLITE_OK) ){ if( iHeight==0 ){ rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode); }else{ @@ -195338,7 +199027,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ int rc2; RtreeNode *pChild = 0; i64 iChild = nodeGetRowid(pRtree, pRoot, 0); - rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); + rc = nodeAcquire(pRtree, iChild, pRoot, &pChild); /* tag-20210916a */ if( rc==SQLITE_OK ){ rc = removeNode(pRtree, pChild, pRtree->iDepth-1); } @@ -195673,7 +199362,7 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ char *zSql; sqlite3_stmt *p; int rc; - i64 nRow = 0; + i64 nRow = RTREE_MIN_ROWEST; rc = sqlite3_table_column_metadata( db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0 @@ -195690,20 +199379,10 @@ static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ if( rc==SQLITE_OK ){ if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); rc = sqlite3_finalize(p); - }else if( rc!=SQLITE_NOMEM ){ - rc = SQLITE_OK; - } - - if( rc==SQLITE_OK ){ - if( nRow==0 ){ - pRtree->nRowEst = RTREE_DEFAULT_ROWEST; - }else{ - pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); - } } sqlite3_free(zSql); } - + pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); return rc; } @@ -195853,9 +199532,12 @@ static int rtreeSqlInit( sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); for(ii=0; iinAux; ii++){ if( ii ) sqlite3_str_append(p, ",", 1); +#ifdef SQLITE_ENABLE_GEOPOLY if( iinAuxNotNull ){ sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); - }else{ + }else +#endif + { sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); } } @@ -196120,6 +199802,7 @@ static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ tree.nDim2 = tree.nDim*2; tree.nBytesPerCell = 8 + 8 * tree.nDim; node.zData = (u8 *)sqlite3_value_blob(apArg[1]); + if( node.zData==0 ) return; nData = sqlite3_value_bytes(apArg[1]); if( nData<4 ) return; if( nDataz[0]) ) p->z++; + while( fast_isspace(p->z[0]) ) p->z++; return p->z[0]; } @@ -196949,13 +200631,14 @@ static GeoPoly *geopolyFuncParam( ){ GeoPoly *p = 0; int nByte; + testcase( pCtx==0 ); if( sqlite3_value_type(pVal)==SQLITE_BLOB && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) ){ const unsigned char *a = sqlite3_value_blob(pVal); int nVertex; if( a==0 ){ - sqlite3_result_error_nomem(pCtx); + if( pCtx ) sqlite3_result_error_nomem(pCtx); return 0; } nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; @@ -197782,11 +201465,11 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ }else{ /* Remove a segment */ if( pActive==pThisEvent->pSeg ){ - pActive = pActive->pNext; + pActive = ALWAYS(pActive) ? pActive->pNext : 0; }else{ for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){ if( pSeg->pNext==pThisEvent->pSeg ){ - pSeg->pNext = pSeg->pNext->pNext; + pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0; break; } } @@ -198030,6 +201713,7 @@ static int geopolyFilter( RtreeCoord bbox[4]; RtreeConstraint *p; assert( argc==1 ); + assert( argv[0]!=0 ); geopolyBBox(0, argv[0], bbox, &rc); if( rc ){ goto geopoly_filter_end; @@ -198257,6 +201941,7 @@ static int geopolyUpdate( || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ || oldRowid!=newRowid) /* Rowid change */ ){ + assert( aData[2]!=0 ); geopolyBBox(0, aData[2], cell.aCoord, &rc); if( rc ){ if( rc==SQLITE_ERROR ){ @@ -198610,7 +202295,10 @@ SQLITE_API int sqlite3_rtree_query_callback( /* Allocate and populate the context object. */ pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); - if( !pGeomCtx ) return SQLITE_NOMEM; + if( !pGeomCtx ){ + if( xDestructor ) xDestructor(pContext); + return SQLITE_NOMEM; + } pGeomCtx->xGeom = 0; pGeomCtx->xQueryFunc = xQueryFunc; pGeomCtx->xDestructor = xDestructor; @@ -200181,6 +203869,13 @@ SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName); # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;} #endif +/* +** Name of the URI option that causes RBU to take an exclusive lock as +** part of the incremental checkpoint operation. +*/ +#define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint" + + /* ** The rbu_state table is used to save the state of a partially applied ** update so that it can be resumed later. The table consists of integer @@ -201265,7 +204960,9 @@ static void rbuTableType( assert( p->rc==SQLITE_OK ); p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, sqlite3_mprintf( - "SELECT (sql LIKE 'create virtual%%'), rootpage" + "SELECT " + " (sql COLLATE nocase BETWEEN 'CREATE VIRTUAL' AND 'CREATE VIRTUAM')," + " rootpage" " FROM sqlite_schema" " WHERE name=%Q", zTab )); @@ -201625,7 +205322,7 @@ static char *rbuVacuumTableStart( ** the caller has to use an OFFSET clause to extract only the required ** rows from the sourct table, just as it does for an RBU update operation. */ -char *rbuVacuumIndexStart( +static char *rbuVacuumIndexStart( sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter /* RBU iterator object */ ){ @@ -202798,7 +206495,7 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ break; case RBU_STATE_OALSZ: - pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); + pRet->iOalSz = sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_PHASEONESTEP: @@ -202825,13 +206522,19 @@ static RbuState *rbuLoadState(sqlite3rbu *p){ /* ** Open the database handle and attach the RBU database as "rbu". If an ** error occurs, leave an error code and message in the RBU handle. +** +** If argument dbMain is not NULL, then it is a database handle already +** open on the target database. Use this handle instead of opening a new +** one. */ -static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){ +static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){ assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); + assert( dbMain==0 || rbuIsVacuum(p)==0 ); /* Open the RBU database */ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); + p->dbMain = dbMain; if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); @@ -203197,15 +206900,31 @@ static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ /* -** Take an EXCLUSIVE lock on the database file. +** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if +** successful, or an SQLite error code otherwise. */ -static void rbuLockDatabase(sqlite3rbu *p){ - sqlite3_file *pReal = p->pTargetFd->pReal; - assert( p->rc==SQLITE_OK ); - p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED); - if( p->rc==SQLITE_OK ){ - p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE); +static int rbuLockDatabase(sqlite3 *db){ + int rc = SQLITE_OK; + sqlite3_file *fd = 0; + sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd); + + if( fd->pMethods ){ + rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED); + if( rc==SQLITE_OK ){ + rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE); + } } + return rc; +} + +/* +** Return true if the database handle passed as the only argument +** was opened with the rbu_exclusive_checkpoint=1 URI parameter +** specified. Or false otherwise. +*/ +static int rbuExclusiveCheckpoint(sqlite3 *db){ + const char *zUri = sqlite3_db_filename(db, 0); + return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0); } #if defined(_WIN32_WCE) @@ -203263,18 +206982,24 @@ static void rbuMoveOalFile(sqlite3rbu *p){ ** In order to ensure that there are no database readers, an EXCLUSIVE ** lock is obtained here before the *-oal is moved to *-wal. */ - rbuLockDatabase(p); + sqlite3 *dbMain = 0; + rbuFileSuffix3(zBase, zWal); + rbuFileSuffix3(zBase, zOal); + + /* Re-open the databases. */ + rbuObjIterFinalize(&p->objiter); + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); + p->dbMain = 0; + p->dbRbu = 0; + + dbMain = rbuOpenDbhandle(p, p->zTarget, 1); + if( dbMain ){ + assert( p->rc==SQLITE_OK ); + p->rc = rbuLockDatabase(dbMain); + } + if( p->rc==SQLITE_OK ){ - rbuFileSuffix3(zBase, zWal); - rbuFileSuffix3(zBase, zOal); - - /* Re-open the databases. */ - rbuObjIterFinalize(&p->objiter); - sqlite3_close(p->dbRbu); - sqlite3_close(p->dbMain); - p->dbMain = 0; - p->dbRbu = 0; - #if defined(_WIN32_WCE) { LPWSTR zWideOal; @@ -203301,11 +207026,19 @@ static void rbuMoveOalFile(sqlite3rbu *p){ #else p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK; #endif + } - if( p->rc==SQLITE_OK ){ - rbuOpenDatabase(p, 0); - rbuSetupCheckpoint(p, 0); - } + if( p->rc!=SQLITE_OK + || rbuIsVacuum(p) + || rbuExclusiveCheckpoint(dbMain)==0 + ){ + sqlite3_close(dbMain); + dbMain = 0; + } + + if( p->rc==SQLITE_OK ){ + rbuOpenDatabase(p, dbMain, 0); + rbuSetupCheckpoint(p, 0); } } @@ -204056,9 +207789,9 @@ static sqlite3rbu *openRbuHandle( ** If this is the case, it will have been checkpointed and deleted ** when the handle was closed and a second attempt to open the ** database may succeed. */ - rbuOpenDatabase(p, &bRetry); + rbuOpenDatabase(p, 0, &bRetry); if( bRetry ){ - rbuOpenDatabase(p, 0); + rbuOpenDatabase(p, 0, 0); } } @@ -204153,6 +207886,14 @@ static sqlite3rbu *openRbuHandle( }else if( p->eStage==RBU_STAGE_MOVE ){ /* no-op */ }else if( p->eStage==RBU_STAGE_CKPT ){ + if( !rbuIsVacuum(p) && rbuExclusiveCheckpoint(p->dbMain) ){ + /* If the rbu_exclusive_checkpoint=1 URI parameter was specified + ** and an incremental checkpoint is being resumed, attempt an + ** exclusive lock on the db file. If this fails, so be it. */ + p->eStage = RBU_STAGE_DONE; + rbuLockDatabase(p->dbMain); + p->eStage = RBU_STAGE_CKPT; + } rbuSetupCheckpoint(p, pState); }else if( p->eStage==RBU_STAGE_DONE ){ p->rc = SQLITE_DONE; @@ -204190,7 +207931,6 @@ SQLITE_API sqlite3rbu *sqlite3rbu_open( const char *zState ){ if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); } - /* TODO: Check that zTarget and zRbu are non-NULL */ return openRbuHandle(zTarget, zRbu, zState); } @@ -205393,6 +209133,15 @@ SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){ #if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \ && !defined(SQLITE_OMIT_VIRTUALTABLE) +/* +** The pager and btree modules arrange objects in memory so that there are +** always approximately 200 bytes of addressable memory following each page +** buffer. This way small buffer overreads caused by corrupt database pages +** do not cause undefined behaviour. This module pads each page buffer +** by the following number of bytes for the same purpose. +*/ +#define DBSTAT_PAGE_PADDING_BYTES 256 + /* ** Page paths: ** @@ -205460,9 +209209,8 @@ struct StatCell { /* Size information for a single btree page */ struct StatPage { u32 iPgno; /* Page number */ - DbPage *pPg; /* Page content */ + u8 *aPg; /* Page buffer from sqlite3_malloc() */ int iCell; /* Current cell */ - char *zPath; /* Path to this page */ /* Variables populated by statDecodePage(): */ @@ -205674,18 +209422,25 @@ static void statClearCells(StatPage *p){ } static void statClearPage(StatPage *p){ + u8 *aPg = p->aPg; statClearCells(p); - sqlite3PagerUnref(p->pPg); sqlite3_free(p->zPath); memset(p, 0, sizeof(StatPage)); + p->aPg = aPg; } static void statResetCsr(StatCursor *pCsr){ int i; - sqlite3_reset(pCsr->pStmt); + /* In some circumstances, specifically if an OOM has occurred, the call + ** to sqlite3_reset() may cause the pager to be reset (emptied). It is + ** important that statClearPage() is called to free any page refs before + ** this happens. dbsqlfuzz 9ed3e4e3816219d3509d711636c38542bf3f40b1. */ for(i=0; iaPage); i++){ statClearPage(&pCsr->aPage[i]); + sqlite3_free(pCsr->aPage[i].aPg); + pCsr->aPage[i].aPg = 0; } + sqlite3_reset(pCsr->pStmt); pCsr->iPage = 0; sqlite3_free(pCsr->zPath); pCsr->zPath = 0; @@ -205750,7 +209505,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ int isLeaf; int szPage; - u8 *aData = sqlite3PagerGetData(p->pPg); + u8 *aData = p->aPg; u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; p->flags = aHdr[0]; @@ -205821,7 +209576,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ if( nPayload>(u32)nLocal ){ int j; int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4); - if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){ + if( iOff+nLocal+4>nUsable || nPayload>0x7fffffff ){ goto statPageIsCorrupt; } pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); @@ -205880,6 +209635,38 @@ static void statSizeAndOffset(StatCursor *pCsr){ } } +/* +** Load a copy of the page data for page iPg into the buffer belonging +** to page object pPg. Allocate the buffer if necessary. Return SQLITE_OK +** if successful, or an SQLite error code otherwise. +*/ +static int statGetPage( + Btree *pBt, /* Load page from this b-tree */ + u32 iPg, /* Page number to load */ + StatPage *pPg /* Load page into this object */ +){ + int pgsz = sqlite3BtreeGetPageSize(pBt); + DbPage *pDbPage = 0; + int rc; + + if( pPg->aPg==0 ){ + pPg->aPg = (u8*)sqlite3_malloc(pgsz + DBSTAT_PAGE_PADDING_BYTES); + if( pPg->aPg==0 ){ + return SQLITE_NOMEM_BKPT; + } + memset(&pPg->aPg[pgsz], 0, DBSTAT_PAGE_PADDING_BYTES); + } + + rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPg, &pDbPage, 0); + if( rc==SQLITE_OK ){ + const u8 *a = sqlite3PagerGetData(pDbPage); + memcpy(pPg->aPg, a, pgsz); + sqlite3PagerUnref(pDbPage); + } + + return rc; +} + /* ** Move a DBSTAT cursor to the next entry. Normally, the next ** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0), @@ -205898,7 +209685,7 @@ static int statNext(sqlite3_vtab_cursor *pCursor){ pCsr->zPath = 0; statNextRestart: - if( pCsr->aPage[0].pPg==0 ){ + if( pCsr->iPage<0 ){ /* Start measuring space on the next btree */ statResetCounts(pCsr); rc = sqlite3_step(pCsr->pStmt); @@ -205910,7 +209697,7 @@ statNextRestart: pCsr->isEof = 1; return sqlite3_reset(pCsr->pStmt); } - rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0); + rc = statGetPage(pBt, iRoot, &pCsr->aPage[0]); pCsr->aPage[0].iPgno = iRoot; pCsr->aPage[0].iCell = 0; if( !pCsr->isAgg ){ @@ -205961,9 +209748,8 @@ statNextRestart: if( !p->iRightChildPg || p->iCell>p->nCell ){ statClearPage(p); - if( pCsr->iPage>0 ){ - pCsr->iPage--; - }else if( pCsr->isAgg ){ + pCsr->iPage--; + if( pCsr->isAgg && pCsr->iPage<0 ){ /* label-statNext-done: When computing aggregate space usage over ** an entire btree, this is the exit point from this function */ return SQLITE_OK; @@ -205982,7 +209768,7 @@ statNextRestart: }else{ p[1].iPgno = p->aCell[p->iCell].iChildPg; } - rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0); + rc = statGetPage(pBt, p[1].iPgno, &p[1]); pCsr->nPage++; p[1].iCell = 0; if( !pCsr->isAgg ){ @@ -206112,6 +209898,7 @@ static int statFilter( } if( rc==SQLITE_OK ){ + pCsr->iPage = -1; rc = statNext(pCursor); } return rc; @@ -206380,6 +210167,7 @@ static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ ){ pIdxInfo->orderByConsumed = 1; } + sqlite3VtabWriteAll(pIdxInfo); return SQLITE_OK; } @@ -207063,7 +210851,7 @@ static int sessionSerializeValue( if( aBuf ){ sessionVarintPut(&aBuf[1], n); - if( n ) memcpy(&aBuf[nVarint + 1], z, n); + if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n); } nByte = 1 + nVarint + n; @@ -207668,16 +211456,32 @@ static int sessionTableInfo( }else if( rc==SQLITE_ERROR ){ zPragma = sqlite3_mprintf(""); }else{ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; return rc; } }else{ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); } - if( !zPragma ) return SQLITE_NOMEM; + if( !zPragma ){ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; + return SQLITE_NOMEM; + } rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); sqlite3_free(zPragma); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; + return rc; + } nByte = nThis + 1; while( SQLITE_ROW==sqlite3_step(pStmt) ){ @@ -208095,7 +211899,11 @@ static int sessionFindTable( ){ rc = sqlite3session_attach(pSession, zName); if( rc==SQLITE_OK ){ - for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext); + pRet = pSession->pTable; + while( ALWAYS(pRet) && pRet->pNext ){ + pRet = pRet->pNext; + } + assert( pRet!=0 ); assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ); } } @@ -208868,6 +212676,7 @@ static int sessionAppendUpdate( int i; /* Used to iterate through columns */ u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */ + assert( abPK!=0 ); sessionAppendByte(pBuf, SQLITE_UPDATE, &rc); sessionAppendByte(pBuf, p->bIndirect, &rc); for(i=0; ipTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; - int nCol; /* Number of columns in table */ - u8 *abPK; /* Primary key array */ + int nCol = 0; /* Number of columns in table */ + u8 *abPK = 0; /* Primary key array */ const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ @@ -209230,6 +213041,7 @@ static int sessionGenerateChangeset( sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ + assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */ rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); } }else if( p->op!=SQLITE_INSERT ){ @@ -209290,7 +213102,10 @@ SQLITE_API int sqlite3session_changeset( int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ - int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); + int rc; + + if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE; + rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset); assert( rc || pnChangeset==0 || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize ); @@ -209305,6 +213120,7 @@ SQLITE_API int sqlite3session_changeset_strm( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ + if( xOutput==0 ) return SQLITE_MISUSE; return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0); } @@ -209316,6 +213132,7 @@ SQLITE_API int sqlite3session_patchset_strm( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ + if( xOutput==0 ) return SQLITE_MISUSE; return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0); } @@ -209331,6 +213148,7 @@ SQLITE_API int sqlite3session_patchset( int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ void **ppPatchset /* OUT: Buffer containing changeset */ ){ + if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE; return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset); } @@ -210294,11 +214112,11 @@ static int sessionChangesetInvert( } assert( rc==SQLITE_OK ); - if( pnInverted ){ + if( pnInverted && ALWAYS(ppInverted) ){ *pnInverted = sOut.nBuf; *ppInverted = sOut.aBuf; sOut.aBuf = 0; - }else if( sOut.nBuf>0 ){ + }else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); } @@ -210754,7 +214572,7 @@ static int sessionBindRow( for(i=0; rc==SQLITE_OK && i0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf); - }else{ + }else if( ppOut ){ *ppOut = buf.aBuf; - *pnOut = buf.nBuf; + if( pnOut ) *pnOut = buf.nBuf; buf.aBuf = 0; } } @@ -212299,7 +216117,7 @@ static int sessionRebase( if( sOut.nBuf>0 ){ rc = xOutput(pOut, sOut.aBuf, sOut.nBuf); } - }else{ + }else if( ppOut ){ *ppOut = (void*)sOut.aBuf; *pnOut = sOut.nBuf; sOut.aBuf = 0; @@ -213042,8 +216860,20 @@ typedef sqlite3_uint64 u64; #endif #define testcase(x) -#define ALWAYS(x) 1 -#define NEVER(x) 0 + +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST) +# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1 +#endif +#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS) +# define ALWAYS(X) (1) +# define NEVER(X) (0) +#elif !defined(NDEBUG) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) +#else +# define ALWAYS(X) (X) +# define NEVER(X) (X) +#endif #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #define MAX(x,y) (((x) > (y)) ? (x) : (y)) @@ -213103,7 +216933,7 @@ SQLITE_API extern int sqlite3_fts5_may_be_corrupt; ** A version of memcmp() that does not cause asan errors if one of the pointer ** parameters is NULL and the number of bytes to compare is zero. */ -#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n))) +#define fts5Memcmp(s1, s2, n) ((n)<=0 ? 0 : memcmp((s1), (s2), (n))) /* Mark a function parameter as unused, to suppress nuisance compiler ** warnings. */ @@ -213442,6 +217272,9 @@ static void sqlite3Fts5IndexCloseReader(Fts5Index*); */ static const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*); static int sqlite3Fts5IterNextScan(Fts5IndexIter*); +static void *sqlite3Fts5StructureRef(Fts5Index*); +static void sqlite3Fts5StructureRelease(void*); +static int sqlite3Fts5StructureTest(Fts5Index*, void*); /* @@ -214219,9 +218052,9 @@ struct fts5yyParser { }; typedef struct fts5yyParser fts5yyParser; +/* #include */ #ifndef NDEBUG /* #include */ -/* #include */ static FILE *fts5yyTraceFILE = 0; static char *fts5yyTracePrompt = 0; #endif /* NDEBUG */ @@ -215158,8 +218991,8 @@ static void sqlite3Fts5Parser( fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact); if( fts5yyact >= fts5YY_MIN_REDUCE ){ unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */ - assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); #ifndef NDEBUG + assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); if( fts5yyTraceFILE ){ int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; if( fts5yysize ){ @@ -215257,14 +219090,13 @@ static void sqlite3Fts5Parser( fts5yy_destructor(fts5yypParser, (fts5YYCODETYPE)fts5yymajor, &fts5yyminorunion); fts5yymajor = fts5YYNOCODE; }else{ - while( fts5yypParser->fts5yytos >= fts5yypParser->fts5yystack - && (fts5yyact = fts5yy_find_reduce_action( - fts5yypParser->fts5yytos->stateno, - fts5YYERRORSYMBOL)) > fts5YY_MAX_SHIFTREDUCE - ){ + while( fts5yypParser->fts5yytos > fts5yypParser->fts5yystack ){ + fts5yyact = fts5yy_find_reduce_action(fts5yypParser->fts5yytos->stateno, + fts5YYERRORSYMBOL); + if( fts5yyact<=fts5YY_MAX_SHIFTREDUCE ) break; fts5yy_pop_parser_stack(fts5yypParser); } - if( fts5yypParser->fts5yytos < fts5yypParser->fts5yystack || fts5yymajor==0 ){ + if( fts5yypParser->fts5yytos <= fts5yypParser->fts5yystack || fts5yymajor==0 ){ fts5yy_destructor(fts5yypParser,(fts5YYCODETYPE)fts5yymajor,&fts5yyminorunion); fts5yy_parse_failed(fts5yypParser); #ifndef fts5YYNOERRORRECOVERY @@ -216127,7 +219959,6 @@ static void sqlite3Fts5BufferAppendBlob( u32 nData, const u8 *pData ){ - assert_nc( *pRc || nData>=0 ); if( nData ){ if( fts5BufferGrow(pRc, pBuf, nData) ) return; memcpy(&pBuf->p[pBuf->n], pData, nData); @@ -216237,9 +220068,8 @@ static int sqlite3Fts5PoslistNext64( return 1; }else{ i64 iOff = *piOff; - int iVal; + u32 iVal; fts5FastGetVarint32(a, i, iVal); - assert( iVal>=0 ); if( iVal<=1 ){ if( iVal==0 ){ *pi = i; @@ -216247,6 +220077,7 @@ static int sqlite3Fts5PoslistNext64( } fts5FastGetVarint32(a, i, iVal); iOff = ((i64)iVal) << 32; + assert( iOff>=0 ); fts5FastGetVarint32(a, i, iVal); if( iVal<2 ){ /* This is a corrupt record. So stop parsing it here. */ @@ -216258,7 +220089,7 @@ static int sqlite3Fts5PoslistNext64( *piOff = (iOff & (i64)0x7FFFFFFF<<32)+((iOff + (iVal-2)) & 0x7FFFFFFF); } *pi = i; - assert( *piOff>=iOff ); + assert_nc( *piOff>=iOff ); return 0; } } @@ -217033,6 +220864,7 @@ static int sqlite3Fts5ConfigParse( z = fts5ConfigSkipWhitespace(z); if( z && *z=='=' ){ bOption = 1; + assert( zOne!=0 ); z++; if( bMustBeCol ) z = 0; } @@ -217049,7 +220881,11 @@ static int sqlite3Fts5ConfigParse( rc = SQLITE_ERROR; }else{ if( bOption ){ - rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr); + rc = fts5ConfigParseSpecial(pGlobal, pRet, + ALWAYS(zOne)?zOne:"", + zTwo?zTwo:"", + pzErr + ); }else{ rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr); zOne = 0; @@ -217567,6 +221403,7 @@ static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); if( pParse->rc==SQLITE_OK ){ + assert( pParse->zErr==0 ); pParse->zErr = sqlite3_vmprintf(zFmt, ap); pParse->rc = SQLITE_ERROR; } @@ -217865,6 +221702,7 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){ int bRetValid = 0; Fts5ExprTerm *p; + assert( pTerm ); assert( pTerm->pSynonym ); assert( bDesc==0 || bDesc==1 ); for(p=pTerm; p; p=p->pSynonym){ @@ -219305,7 +223143,7 @@ static int sqlite3Fts5ExprClonePhrase( sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){ /* All the allocations succeeded. Put the expression object together. */ pNew->pIndex = pExpr->pIndex; pNew->pConfig = pExpr->pConfig; @@ -219576,9 +223414,8 @@ static void sqlite3Fts5ParseSetColset( ){ Fts5Colset *pFree = pColset; if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){ - pParse->rc = SQLITE_ERROR; - pParse->zErr = sqlite3_mprintf( - "fts5: column queries are not supported (detail=none)" + sqlite3Fts5ParseError(pParse, + "fts5: column queries are not supported (detail=none)" ); }else{ fts5ParseSetColset(pParse, pExpr, pColset, &pFree); @@ -219752,13 +223589,10 @@ static Fts5ExprNode *sqlite3Fts5ParseNode( || pPhrase->nTerm>1 || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst) ){ - assert( pParse->rc==SQLITE_OK ); - pParse->rc = SQLITE_ERROR; - assert( pParse->zErr==0 ); - pParse->zErr = sqlite3_mprintf( + sqlite3Fts5ParseError(pParse, "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" - ); + ); sqlite3_free(pRet); pRet = 0; } @@ -220290,6 +224124,15 @@ struct Fts5PoslistPopulator { int bMiss; }; +/* +** Clear the position lists associated with all phrases in the expression +** passed as the first argument. Argument bLive is true if the expression +** might be pointing to a real entry, otherwise it has just been reset. +** +** At present this function is only used for detail=col and detail=none +** fts5 tables. This implies that all phrases must be at most 1 token +** in size, as phrase matches are not supported without detail=full. +*/ static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){ Fts5PoslistPopulator *pRet; pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); @@ -220299,7 +224142,7 @@ static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int b for(i=0; inPhrase; i++){ Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist; Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode; - assert( pExpr->apExprPhrase[i]->nTerm==1 ); + assert( pExpr->apExprPhrase[i]->nTerm<=1 ); if( bLive && (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof) ){ @@ -220850,7 +224693,7 @@ static int sqlite3Fts5HashWrite( p->bContent = 1; }else{ /* Append a new column value, if necessary */ - assert( iCol>=p->iCol ); + assert_nc( iCol>=p->iCol ); if( iCol!=p->iCol ){ if( pHash->eDetail==FTS5_DETAIL_FULL ){ pPtr[p->nData++] = 0x01; @@ -221655,8 +225498,11 @@ static int fts5BufferCompareBlob( ** res = *pLeft - *pRight */ static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){ - int nCmp = MIN(pLeft->n, pRight->n); - int res = fts5Memcmp(pLeft->p, pRight->p, nCmp); + int nCmp, res; + nCmp = MIN(pLeft->n, pRight->n); + assert( nCmp<=0 || pLeft->p!=0 ); + assert( nCmp<=0 || pRight->p!=0 ); + res = fts5Memcmp(pLeft->p, pRight->p, nCmp); return (res==0 ? (pLeft->n - pRight->n) : res); } @@ -221752,6 +225598,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ return pRet; } + /* ** Release a reference to data record returned by an earlier call to ** fts5DataRead(). @@ -221876,6 +225723,58 @@ static void fts5StructureRef(Fts5Structure *pStruct){ pStruct->nRef++; } +static void *sqlite3Fts5StructureRef(Fts5Index *p){ + fts5StructureRef(p->pStruct); + return (void*)p->pStruct; +} +static void sqlite3Fts5StructureRelease(void *p){ + if( p ){ + fts5StructureRelease((Fts5Structure*)p); + } +} +static int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){ + if( p->pStruct!=(Fts5Structure*)pStruct ){ + return SQLITE_ABORT; + } + return SQLITE_OK; +} + +/* +** Ensure that structure object (*pp) is writable. +** +** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If +** an error occurs, (*pRc) is set to an SQLite error code before returning. +*/ +static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){ + Fts5Structure *p = *pp; + if( *pRc==SQLITE_OK && p->nRef>1 ){ + i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel); + Fts5Structure *pNew; + pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte); + if( pNew ){ + int i; + memcpy(pNew, p, nByte); + for(i=0; inLevel; i++) pNew->aLevel[i].aSeg = 0; + for(i=0; inLevel; i++){ + Fts5StructureLevel *pLvl = &pNew->aLevel[i]; + nByte = sizeof(Fts5StructureSegment) * pNew->aLevel[i].nSeg; + pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(pRc, nByte); + if( pLvl->aSeg==0 ){ + for(i=0; inLevel; i++){ + sqlite3_free(pNew->aLevel[i].aSeg); + } + sqlite3_free(pNew); + return; + } + memcpy(pLvl->aSeg, p->aLevel[i].aSeg, nByte); + } + p->nRef--; + pNew->nRef = 1; + } + *pp = pNew; + } +} + /* ** Deserialize and return the structure record currently stored in serialized ** form within buffer pData/nData. @@ -221977,9 +225876,11 @@ static int fts5StructureDecode( } /* -** +** Add a level to the Fts5Structure.aLevel[] array of structure object +** (*ppStruct). */ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ + fts5StructureMakeWritable(pRc, ppStruct); if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; @@ -222773,6 +226674,7 @@ static void fts5SegIterInit( if( p->rc==SQLITE_OK ){ pIter->iLeafOffset = 4; + assert( pIter->pLeaf!=0 ); assert_nc( pIter->pLeaf->nn>4 ); assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 ); pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; @@ -222875,8 +226777,12 @@ static void fts5SegIterReverseNewPage(Fts5Index *p, Fts5SegIter *pIter){ int iRowidOff; iRowidOff = fts5LeafFirstRowidOff(pNew); if( iRowidOff ){ - pIter->pLeaf = pNew; - pIter->iLeafOffset = iRowidOff; + if( iRowidOff>=pNew->szLeaf ){ + p->rc = FTS5_CORRUPT; + }else{ + pIter->pLeaf = pNew; + pIter->iLeafOffset = iRowidOff; + } } } @@ -223156,7 +227062,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ if( pDlidx ){ int iSegid = pIter->pSeg->iSegid; pgnoLast = fts5DlidxIterPgno(pDlidx); - pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); + pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast)); }else{ Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */ @@ -223183,7 +227089,7 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ ** forward to find the page containing the last rowid. */ for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){ i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno); - Fts5Data *pNew = fts5DataRead(p, iAbs); + Fts5Data *pNew = fts5LeafRead(p, iAbs); if( pNew ){ int iRowid, bTermless; iRowid = fts5LeafFirstRowidOff(pNew); @@ -223214,6 +227120,10 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ pIter->pLeaf = pLast; pIter->iLeafPgno = pgnoLast; iOff = fts5LeafFirstRowidOff(pLast); + if( iOff>pLast->szLeaf ){ + p->rc = FTS5_CORRUPT; + return; + } iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid); pIter->iLeafOffset = iOff; @@ -223222,7 +227132,6 @@ static void fts5SegIterReverse(Fts5Index *p, Fts5SegIter *pIter){ }else{ pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast); } - } fts5SegIterReverseInitPage(p, pIter); @@ -223274,21 +227183,20 @@ static void fts5LeafSeek( Fts5SegIter *pIter, /* Iterator to seek */ const u8 *pTerm, int nTerm /* Term to search for */ ){ - int iOff; + u32 iOff; const u8 *a = pIter->pLeaf->p; - int szLeaf = pIter->pLeaf->szLeaf; - int n = pIter->pLeaf->nn; + u32 n = (u32)pIter->pLeaf->nn; u32 nMatch = 0; u32 nKeep = 0; u32 nNew = 0; u32 iTermOff; - int iPgidx; /* Current offset in pgidx */ + u32 iPgidx; /* Current offset in pgidx */ int bEndOfPage = 0; assert( p->rc==SQLITE_OK ); - iPgidx = szLeaf; + iPgidx = (u32)pIter->pLeaf->szLeaf; iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff); iOff = iTermOff; if( iOff>n ){ @@ -223354,15 +227262,15 @@ static void fts5LeafSeek( if( pIter->pLeaf==0 ) return; a = pIter->pLeaf->p; if( fts5LeafIsTermless(pIter->pLeaf)==0 ){ - iPgidx = pIter->pLeaf->szLeaf; + iPgidx = (u32)pIter->pLeaf->szLeaf; iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff); - if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){ + if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){ p->rc = FTS5_CORRUPT; return; }else{ nKeep = 0; iTermOff = iOff; - n = pIter->pLeaf->nn; + n = (u32)pIter->pLeaf->nn; iOff += fts5GetVarint32(&a[iOff], nNew); break; } @@ -223730,7 +227638,7 @@ static void fts5SegIterGotoPage( fts5SegIterNextPage(p, pIter); assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno ); - if( p->rc==SQLITE_OK ){ + if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){ int iOff; u8 *a = pIter->pLeaf->p; int n = pIter->pLeaf->szLeaf; @@ -224162,7 +228070,11 @@ static void fts5SegiterPoslist( Fts5Colset *pColset, Fts5Buffer *pBuf ){ + assert( pBuf!=0 ); + assert( pSeg!=0 ); if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){ + assert( pBuf->p!=0 ); + assert( pBuf->nSpace >= pBuf->n+pSeg->nPos+FTS5_DATA_ZERO_PADDING ); memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING); if( pColset==0 ){ fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback); @@ -224386,6 +228298,7 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ } static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ + assert( pIter!=0 || (*pRc)!=SQLITE_OK ); if( *pRc==SQLITE_OK ){ Fts5Config *pConfig = pIter->pIndex->pConfig; if( pConfig->eDetail==FTS5_DETAIL_NONE ){ @@ -224457,7 +228370,10 @@ static void fts5MultiIterNew( } } *ppOut = pNew = fts5MultiIterAlloc(p, nSeg); - if( pNew==0 ) return; + if( pNew==0 ){ + assert( p->rc!=SQLITE_OK ); + goto fts5MultiIterNew_post_check; + } pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC)); pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY)); pNew->pColset = pColset; @@ -224521,6 +228437,10 @@ static void fts5MultiIterNew( fts5MultiIterFree(pNew); *ppOut = 0; } + +fts5MultiIterNew_post_check: + assert( (*ppOut)!=0 || p->rc!=SQLITE_OK ); + return; } /* @@ -224568,7 +228488,8 @@ static void fts5MultiIterNew2( ** False otherwise. */ static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){ - assert( p->rc + assert( pIter!=0 || p->rc!=SQLITE_OK ); + assert( p->rc!=SQLITE_OK || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof ); return (p->rc || pIter->base.bEof); @@ -225372,6 +229293,7 @@ static void fts5IndexMergeLevel( ** and last leaf page number at the same time. */ fts5WriteFinish(p, &writer, &pSeg->pgnoLast); + assert( pIter!=0 || p->rc!=SQLITE_OK ); if( fts5MultiIterEof(p, pIter) ){ int i; @@ -225472,7 +229394,7 @@ static void fts5IndexAutomerge( Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */ int nLeaf /* Number of output leaves just written */ ){ - if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){ + if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 && ALWAYS((*ppStruct)!=0) ){ Fts5Structure *pStruct = *ppStruct; u64 nWrite; /* Initial value of write-counter */ int nWork; /* Number of work-quanta to perform */ @@ -226541,7 +230463,7 @@ static int sqlite3Fts5IndexQuery( if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ int iPrefixIdx = 0; /* +1 prefix index */ - if( nToken ) memcpy(&buf.p[1], pToken, nToken); + if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this ** is a prefix query for which there is no prefix index, set iIdx to @@ -226582,11 +230504,15 @@ static int sqlite3Fts5IndexQuery( /* Scan multiple terms in the main index */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); - assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); - fts5IterSetOutputCb(&p->rc, pRet); - if( p->rc==SQLITE_OK ){ - Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; - if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); + if( pRet==0 ){ + assert( p->rc!=SQLITE_OK ); + }else{ + assert( pRet->pColset==0 ); + fts5IterSetOutputCb(&p->rc, pRet); + if( p->rc==SQLITE_OK ){ + Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst]; + if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg); + } } } @@ -226834,7 +230760,7 @@ static int fts5QueryCksum( Fts5IndexIter *pIter = 0; int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); - while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){ + while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){ i64 rowid = pIter->iRowid; if( eDetail==FTS5_DETAIL_NONE ){ @@ -227199,6 +231125,7 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ Fts5Iter *pIter; /* Used to iterate through entire index */ Fts5Structure *pStruct; /* Index structure */ + int iLvl, iSeg; #ifdef SQLITE_DEBUG /* Used by extra internal tests only run if NDEBUG is not defined */ @@ -227209,15 +231136,16 @@ static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum, int bUseCksum /* Load the FTS index structure */ pStruct = fts5StructureRead(p); + if( pStruct==0 ){ + assert( p->rc!=SQLITE_OK ); + return fts5IndexReturn(p); + } /* Check that the internal nodes of each segment match the leaves */ - if( pStruct ){ - int iLvl, iSeg; - for(iLvl=0; iLvlnLevel; iLvl++){ - for(iSeg=0; iSegaLevel[iLvl].nSeg; iSeg++){ - Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; - fts5IndexIntegrityCheckSegment(p, pSeg); - } + for(iLvl=0; iLvlnLevel; iLvl++){ + for(iSeg=0; iSegaLevel[iLvl].nSeg; iSeg++){ + Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; + fts5IndexIntegrityCheckSegment(p, pSeg); } } @@ -228594,7 +232522,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){ rc = sqlite3_step(pSorter->pStmt); if( rc==SQLITE_DONE ){ rc = SQLITE_OK; - CsrFlagSet(pCsr, FTS5CSR_EOF); + CsrFlagSet(pCsr, FTS5CSR_EOF|FTS5CSR_REQUIRE_CONTENT); }else if( rc==SQLITE_ROW ){ const u8 *a; const u8 *aBlob; @@ -229164,7 +233092,8 @@ static int fts5FilterMethod( pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg ); if( rc==SQLITE_OK ){ - if( pCsr->ePlan==FTS5_PLAN_ROWID ){ + if( pRowidEq!=0 ){ + assert( pCsr->ePlan==FTS5_PLAN_ROWID ); sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); }else{ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); @@ -230582,7 +234511,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe", -1, SQLITE_TRANSIENT); } /* @@ -231133,12 +235062,16 @@ static int fts5StorageDeleteFromIndex( if( pConfig->abUnindexed[iCol-1]==0 ){ const char *zText; int nText; + assert( pSeek==0 || apVal==0 ); + assert( pSeek!=0 || apVal!=0 ); if( pSeek ){ zText = (const char*)sqlite3_column_text(pSeek, iCol); nText = sqlite3_column_bytes(pSeek, iCol); - }else{ + }else if( ALWAYS(apVal) ){ zText = (const char*)sqlite3_value_text(apVal[iCol-1]); nText = sqlite3_value_bytes(apVal[iCol-1]); + }else{ + continue; } ctx.szCol = 0; rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, @@ -231774,8 +235707,9 @@ static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){ assert( p->pConfig->bColumnsize ); rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); - if( rc==SQLITE_OK ){ + if( pLookup ){ int bCorrupt = 1; + assert( rc==SQLITE_OK ); sqlite3_bind_int64(pLookup, 1, iRowid); if( SQLITE_ROW==sqlite3_step(pLookup) ){ const u8 *aBlob = sqlite3_column_blob(pLookup, 0); @@ -231788,6 +235722,8 @@ static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){ if( bCorrupt && rc==SQLITE_OK ){ rc = FTS5_CORRUPT; } + }else{ + assert( rc!=SQLITE_OK ); } return rc; @@ -234478,6 +238414,7 @@ struct Fts5VocabCursor { int bEof; /* True if this cursor is at EOF */ Fts5IndexIter *pIter; /* Term/rowid iterator object */ + void *pStruct; /* From sqlite3Fts5StructureRef() */ int nLeTerm; /* Size of zLeTerm in bytes */ char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ @@ -234791,7 +238728,7 @@ static int fts5VocabOpenMethod( } if( rc==SQLITE_OK ){ - int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor); + i64 nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor); pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte); } @@ -234811,6 +238748,8 @@ static int fts5VocabOpenMethod( static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){ pCsr->rowid = 0; sqlite3Fts5IterClose(pCsr->pIter); + sqlite3Fts5StructureRelease(pCsr->pStruct); + pCsr->pStruct = 0; pCsr->pIter = 0; sqlite3_free(pCsr->zLeTerm); pCsr->nLeTerm = -1; @@ -234888,9 +238827,11 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; - int rc = SQLITE_OK; int nCol = pCsr->pFts5->pConfig->nCol; + int rc; + rc = sqlite3Fts5StructureTest(pCsr->pFts5->pIndex, pCsr->pStruct); + if( rc!=SQLITE_OK ) return rc; pCsr->rowid++; if( pTab->eType==FTS5_VOCAB_INSTANCE ){ @@ -235064,6 +239005,9 @@ static int fts5VocabFilterMethod( if( rc==SQLITE_OK ){ Fts5Index *pIndex = pCsr->pFts5->pIndex; rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); + if( rc==SQLITE_OK ){ + pCsr->pStruct = sqlite3Fts5StructureRef(pIndex); + } } if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){ rc = fts5VocabInstanceNewTerm(pCsr); @@ -235508,10 +239452,6 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=235511 -#undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafaalt2" -#endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } /************************** End of sqlite3.c ******************************/ diff --git a/Data/SQLite/src/sqlite3.h b/Data/SQLite/src/sqlite3.h index 3274bbe07..de393da9d 100644 --- a/Data/SQLite/src/sqlite3.h +++ b/Data/SQLite/src/sqlite3.h @@ -43,7 +43,30 @@ extern "C" { /* -** Provide the ability to override linkage features of the interface. +** Facilitate override of interface linkage and calling conventions. +** Be aware that these macros may not be used within this particular +** translation of the amalgamation and its associated header file. +** +** The SQLITE_EXTERN and SQLITE_API macros are used to instruct the +** compiler that the target identifier should have external linkage. +** +** The SQLITE_CDECL macro is used to set the calling convention for +** public functions that accept a variable number of arguments. +** +** The SQLITE_APICALL macro is used to set the calling convention for +** public functions that accept a fixed number of arguments. +** +** The SQLITE_STDCALL macro is no longer used and is now deprecated. +** +** The SQLITE_CALLBACK macro is used to set the calling convention for +** function pointers. +** +** The SQLITE_SYSAPI macro is used to set the calling convention for +** functions provided by the operating system. +** +** Currently, the SQLITE_CDECL, SQLITE_APICALL, SQLITE_CALLBACK, and +** SQLITE_SYSAPI macros are used only when building for environments +** that require non-default calling conventions. */ #ifndef SQLITE_EXTERN # define SQLITE_EXTERN extern @@ -123,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.36.0" -#define SQLITE_VERSION_NUMBER 3036000 -#define SQLITE_SOURCE_ID "2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5" +#define SQLITE_VERSION "3.38.5" +#define SQLITE_VERSION_NUMBER 3038005 +#define SQLITE_SOURCE_ID "2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -537,12 +560,13 @@ SQLITE_API int sqlite3_exec( #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8)) #define SQLITE_CONSTRAINT_ROWID (SQLITE_CONSTRAINT |(10<<8)) #define SQLITE_CONSTRAINT_PINNED (SQLITE_CONSTRAINT |(11<<8)) +#define SQLITE_CONSTRAINT_DATATYPE (SQLITE_CONSTRAINT |(12<<8)) #define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8)) #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8)) #define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8)) #define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8)) #define SQLITE_OK_LOAD_PERMANENTLY (SQLITE_OK | (1<<8)) -#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) +#define SQLITE_OK_SYMLINK (SQLITE_OK | (2<<8)) /* internal use only */ /* ** CAPI3REF: Flags For File Open Operations @@ -550,6 +574,19 @@ SQLITE_API int sqlite3_exec( ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. +** +** Only those flags marked as "Ok for sqlite3_open_v2()" may be +** used as the third argument to the [sqlite3_open_v2()] interface. +** The other flags have historically been ignored by sqlite3_open_v2(), +** though future versions of SQLite might change so that an error is +** raised if any of the disallowed bits are passed into sqlite3_open_v2(). +** Applications should not depend on the historical behavior. +** +** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into +** [sqlite3_open_v2()] does *not* cause the underlying database file +** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into +** [sqlite3_open_v2()] has historically be a no-op and might become an +** error in future versions of SQLite. */ #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ @@ -572,6 +609,7 @@ SQLITE_API int sqlite3_exec( #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */ /* Reserved: 0x00F00000 */ /* Legacy compatibility: */ @@ -2464,11 +2502,14 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** CAPI3REF: Count The Number Of Rows Modified ** METHOD: sqlite3 ** -** ^This function returns the number of rows modified, inserted or +** ^These functions return the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. -** ^Executing any other type of SQL statement does not modify the value -** returned by this function. +** The two functions are identical except for the type of the return value +** and that if the number of rows modified by the most recent INSERT, UPDATE +** or DELETE is greater than the maximum value supported by type "int", then +** the return value of sqlite3_changes() is undefined. ^Executing any other +** type of SQL statement does not modify the value returned by these functions. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are ** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], @@ -2517,16 +2558,21 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); ** */ SQLITE_API int sqlite3_changes(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_changes64(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified ** METHOD: sqlite3 ** -** ^This function returns the total number of rows inserted, modified or +** ^These functions return the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as -** part of trigger programs. ^Executing any other type of SQL statement -** does not affect the value returned by sqlite3_total_changes(). +** part of trigger programs. The two functions are identical except for the +** type of the return value and that if the number of rows modified by the +** connection exceeds the maximum value supported by type "int", then +** the return value of sqlite3_total_changes() is undefined. ^Executing +** any other type of SQL statement does not affect the value returned by +** sqlite3_total_changes(). ** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are @@ -2554,6 +2600,7 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** */ SQLITE_API int sqlite3_total_changes(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_total_changes64(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query @@ -3383,6 +3430,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** the default shared cache setting provided by ** [sqlite3_enable_shared_cache()].)^ ** +** [[OPEN_EXRESCODE]] ^(
[SQLITE_OPEN_EXRESCODE]
+**
The database connection comes up in "extended result code mode". +** In other words, the database behaves has if +** [sqlite3_extended_result_codes(db,1)] where called on the database +** connection as soon as the connection is created. In addition to setting +** the extended result code mode, this flag also causes [sqlite3_open_v2()] +** to return an extended result code.
+** ** [[OPEN_NOFOLLOW]] ^(
[SQLITE_OPEN_NOFOLLOW]
**
The database filename is not allowed to be a symbolic link
** )^ @@ -3390,7 +3445,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] -** then the behavior is undefined. +** then the behavior is undefined. Historic versions of SQLite +** have silently ignored surplus bits in the flags parameter to +** sqlite3_open_v2(), however that behavior might not be carried through +** into future versions of SQLite and so applications should not rely +** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op +** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause +** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE +** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not +** by sqlite3_open_v2(). ** ** ^The fourth parameter to sqlite3_open_v2() is the name of the ** [sqlite3_vfs] object that defines the operating system interface that @@ -3761,13 +3824,14 @@ SQLITE_API void sqlite3_free_filename(char*); ** sqlite3_extended_errcode() might change with each API call. ** Except, there are some interfaces that are guaranteed to never ** change the value of the error code. The error-code preserving -** interfaces are: +** interfaces include the following: ** **
    **
  • sqlite3_errcode() **
  • sqlite3_extended_errcode() **
  • sqlite3_errmsg() **
  • sqlite3_errmsg16() +**
  • sqlite3_error_offset() **
** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -3782,6 +3846,13 @@ SQLITE_API void sqlite3_free_filename(char*); ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. ** +** ^If the most recent error references a specific token in the input +** SQL, the sqlite3_error_offset() interface returns the byte offset +** of the start of that token. ^The byte offset returned by +** sqlite3_error_offset() assumes that the input SQL is UTF8. +** ^If the most recent error does not reference a specific token in the input +** SQL, then the sqlite3_error_offset() function returns -1. +** ** When the serialized [threading mode] is in use, it might be the ** case that a second error occurs on a separate thread in between ** the time of the first error and the call to these interfaces. @@ -3801,6 +3872,7 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); +SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Prepared Statement Object @@ -4158,12 +4230,17 @@ SQLITE_API int sqlite3_prepare16_v3( ** are managed by SQLite and are automatically freed when the prepared ** statement is finalized. ** ^The string returned by sqlite3_expanded_sql(P), on the other hand, -** is obtained from [sqlite3_malloc()] and must be free by the application +** is obtained from [sqlite3_malloc()] and must be freed by the application ** by passing it to [sqlite3_free()]. +** +** ^The sqlite3_normalized_sql() interface is only available if +** the [SQLITE_ENABLE_NORMALIZE] compile-time option is defined. */ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +#ifdef SQLITE_ENABLE_NORMALIZE SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); +#endif /* ** CAPI3REF: Determine If An SQL Statement Writes The Database @@ -4207,6 +4284,10 @@ SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a ** read-only no-op if the table already exists, but ** sqlite3_stmt_readonly() still returns false for such a statement. +** +** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] +** statement, then sqlite3_stmt_readonly(X) returns the same value as +** if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. */ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); @@ -4275,6 +4356,8 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); ** ** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. +** ^The sqlite3_value objects returned by [sqlite3_vtab_rhs_value()] +** are protected. ** ^The sqlite3_value object returned by ** [sqlite3_column_value()] is unprotected. ** Unprotected sqlite3_value objects may only be used as arguments @@ -4896,6 +4979,10 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** even empty strings, are always zero-terminated. ^The return ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. ** +** ^Strings returned by sqlite3_column_text16() always have the endianness +** which is native to the platform, regardless of the text encoding set +** for the database. +** ** Warning: ^The object returned by [sqlite3_column_value()] is an ** [unprotected sqlite3_value] object. In a multithreaded environment, ** an unprotected sqlite3_value object may only be used safely with @@ -4909,7 +4996,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** -** The these routines may attempt to convert the datatype of the result. +** These routines may attempt to convert the datatype of the result. ** ^For example, if the internal representation is FLOAT and a text result ** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions @@ -4934,7 +5021,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); ** TEXT BLOB No change ** BLOB INTEGER [CAST] to INTEGER ** BLOB FLOAT [CAST] to REAL -** BLOB TEXT Add a zero terminator if needed +** BLOB TEXT [CAST] to TEXT, ensure zero terminator ** ** )^ ** @@ -6347,6 +6434,72 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +/* +** CAPI3REF: Autovacuum Compaction Amount Callback +** METHOD: sqlite3 +** +** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback +** function C that is invoked prior to each autovacuum of the database +** file. ^The callback is passed a copy of the generic data pointer (P), +** the schema-name of the attached database that is being autovacuumed, +** the the size of the database file in pages, the number of free pages, +** and the number of bytes per page, respectively. The callback should +** return the number of free pages that should be removed by the +** autovacuum. ^If the callback returns zero, then no autovacuum happens. +** ^If the value returned is greater than or equal to the number of +** free pages, then a complete autovacuum happens. +** +**

^If there are multiple ATTACH-ed database files that are being +** modified as part of a transaction commit, then the autovacuum pages +** callback is invoked separately for each file. +** +**

The callback is not reentrant. The callback function should +** not attempt to invoke any other SQLite interface. If it does, bad +** things may happen, including segmentation faults and corrupt database +** files. The callback function should be a simple function that +** does some arithmetic on its input parameters and returns a result. +** +** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional +** destructor for the P parameter. ^If X is not NULL, then X(P) is +** invoked whenever the database connection closes or when the callback +** is overwritten by another invocation of sqlite3_autovacuum_pages(). +** +**

^There is only one autovacuum pages callback per database connection. +** ^Each call to the sqlite3_autovacuum_pages() interface overrides all +** previous invocations for that database connection. ^If the callback +** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, +** then the autovacuum steps callback is cancelled. The return value +** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might +** be some other error code if something goes wrong. The current +** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other +** return codes might be added in future releases. +** +**

If no autovacuum pages callback is specified (the usual case) or +** a NULL pointer is provided for the callback, +** then the default behavior is to vacuum all free pages. So, in other +** words, the default behavior is the same as if the callback function +** were something like this: +** +**

+**     unsigned int demonstration_autovac_pages_callback(
+**       void *pClientData,
+**       const char *zSchema,
+**       unsigned int nDbPage,
+**       unsigned int nFreePage,
+**       unsigned int nBytePerPage
+**     ){
+**       return nFreePage;
+**     }
+** 
+*/ +SQLITE_API int sqlite3_autovacuum_pages( + sqlite3 *db, + unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int), + void*, + void(*)(void*) +); + + /* ** CAPI3REF: Data Change Notification Callbacks ** METHOD: sqlite3 @@ -6988,24 +7141,56 @@ struct sqlite3_index_info { ** ** These macros define the allowed values for the ** [sqlite3_index_info].aConstraint[].op field. Each value represents -** an operator that is part of a constraint term in the wHERE clause of +** an operator that is part of a constraint term in the WHERE clause of ** a query that uses a [virtual table]. +** +** ^The left-hand operand of the operator is given by the corresponding +** aConstraint[].iColumn field. ^An iColumn of -1 indicates the left-hand +** operand is the rowid. +** The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET +** operators have no left-hand operand, and so for those operators the +** corresponding aConstraint[].iColumn is meaningless and should not be +** used. +** +** All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through +** value 255 are reserved to represent functions that are overloaded +** by the [xFindFunction|xFindFunction method] of the virtual table +** implementation. +** +** The right-hand operands for each constraint might be accessible using +** the [sqlite3_vtab_rhs_value()] interface. Usually the right-hand +** operand is only available if it appears as a single constant literal +** in the input SQL. If the right-hand operand is another column or an +** expression (even a constant expression) or a parameter, then the +** sqlite3_vtab_rhs_value() probably will not be able to extract it. +** ^The SQLITE_INDEX_CONSTRAINT_ISNULL and +** SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand +** and hence calls to sqlite3_vtab_rhs_value() for those operators will +** always return SQLITE_NOTFOUND. +** +** The collating sequence to be used for comparison can be found using +** the [sqlite3_vtab_collation()] interface. For most real-world virtual +** tables, the collating sequence of constraints does not matter (for example +** because the constraints are numeric) and so the sqlite3_vtab_collation() +** interface is no commonly needed. */ -#define SQLITE_INDEX_CONSTRAINT_EQ 2 -#define SQLITE_INDEX_CONSTRAINT_GT 4 -#define SQLITE_INDEX_CONSTRAINT_LE 8 -#define SQLITE_INDEX_CONSTRAINT_LT 16 -#define SQLITE_INDEX_CONSTRAINT_GE 32 -#define SQLITE_INDEX_CONSTRAINT_MATCH 64 -#define SQLITE_INDEX_CONSTRAINT_LIKE 65 -#define SQLITE_INDEX_CONSTRAINT_GLOB 66 -#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 -#define SQLITE_INDEX_CONSTRAINT_NE 68 -#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 -#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 -#define SQLITE_INDEX_CONSTRAINT_IS 72 -#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 +#define SQLITE_INDEX_CONSTRAINT_EQ 2 +#define SQLITE_INDEX_CONSTRAINT_GT 4 +#define SQLITE_INDEX_CONSTRAINT_LE 8 +#define SQLITE_INDEX_CONSTRAINT_LT 16 +#define SQLITE_INDEX_CONSTRAINT_GE 32 +#define SQLITE_INDEX_CONSTRAINT_MATCH 64 +#define SQLITE_INDEX_CONSTRAINT_LIKE 65 +#define SQLITE_INDEX_CONSTRAINT_GLOB 66 +#define SQLITE_INDEX_CONSTRAINT_REGEXP 67 +#define SQLITE_INDEX_CONSTRAINT_NE 68 +#define SQLITE_INDEX_CONSTRAINT_ISNOT 69 +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 +#define SQLITE_INDEX_CONSTRAINT_ISNULL 71 +#define SQLITE_INDEX_CONSTRAINT_IS 72 +#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 +#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* ** CAPI3REF: Register A Virtual Table Implementation @@ -7034,7 +7219,7 @@ struct sqlite3_index_info { ** destructor. ** ** ^If the third parameter (the pointer to the sqlite3_module object) is -** NULL then no new module is create and any existing modules with the +** NULL then no new module is created and any existing modules with the ** same name are dropped. ** ** See also: [sqlite3_drop_modules()] @@ -7810,7 +7995,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 -#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LOGEST 33 +#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -8333,6 +8519,16 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); ** The counter is incremented on the first [sqlite3_step()] call of each ** cycle. ** +** [[SQLITE_STMTSTATUS_FILTER_MISS]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] +**
SQLITE_STMTSTATUS_FILTER_HIT
+** SQLITE_STMTSTATUS_FILTER_MISS
+**
^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join +** step was bypassed because a Bloom filter returned not-found. The +** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of +** times that the Bloom filter returned a find, and thus the join step +** had to be processed as normal. +** ** [[SQLITE_STMTSTATUS_MEMUSED]]
SQLITE_STMTSTATUS_MEMUSED
**
^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually @@ -8347,6 +8543,8 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); #define SQLITE_STMTSTATUS_VM_STEP 4 #define SQLITE_STMTSTATUS_REPREPARE 5 #define SQLITE_STMTSTATUS_RUN 6 +#define SQLITE_STMTSTATUS_FILTER_MISS 7 +#define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99 /* @@ -9010,8 +9208,9 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); ** ** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any -** previously registered write-ahead log callback. ^Note that the -** [sqlite3_wal_autocheckpoint()] interface and the +** previously registered write-ahead log callback. ^The return value is +** a copy of the third parameter from the previous call, if any, or 0. +** ^Note that the [sqlite3_wal_autocheckpoint()] interface and the ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will ** overwrite any prior [sqlite3_wal_hook()] settings. */ @@ -9314,19 +9513,269 @@ SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint +** METHOD: sqlite3_index_info ** ** This function may only be called from within a call to the [xBestIndex] -** method of a [virtual table]. +** method of a [virtual table]. This function returns a pointer to a string +** that is the name of the appropriate collation sequence to use for text +** comparisons on the constraint identified by its arguments. ** -** The first argument must be the sqlite3_index_info object that is the -** first parameter to the xBestIndex() method. The second argument must be -** an index into the aConstraint[] array belonging to the sqlite3_index_info -** structure passed to xBestIndex. This function returns a pointer to a buffer -** containing the name of the collation sequence for the corresponding -** constraint. +** The first argument must be the pointer to the [sqlite3_index_info] object +** that is the first parameter to the xBestIndex() method. The second argument +** must be an index into the aConstraint[] array belonging to the +** sqlite3_index_info structure passed to xBestIndex. +** +** Important: +** The first parameter must be the same pointer that is passed into the +** xBestMethod() method. The first parameter may not be a pointer to a +** different [sqlite3_index_info] object, even an exact copy. +** +** The return value is computed as follows: +** +**
    +**
  1. If the constraint comes from a WHERE clause expression that contains +** a [COLLATE operator], then the name of the collation specified by +** that COLLATE operator is returned. +**

  2. If there is no COLLATE operator, but the column that is the subject +** of the constraint specifies an alternative collating sequence via +** a [COLLATE clause] on the column definition within the CREATE TABLE +** statement that was passed into [sqlite3_declare_vtab()], then the +** name of that alternative collating sequence is returned. +**

  3. Otherwise, "BINARY" is returned. +**

*/ SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +/* +** CAPI3REF: Determine if a virtual table query is DISTINCT +** METHOD: sqlite3_index_info +** +** This API may only be used from within an [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this +** interface from outside of xBestIndex() is undefined and probably harmful. +** +** ^The sqlite3_vtab_distinct() interface returns an integer that is +** either 0, 1, or 2. The integer returned by sqlite3_vtab_distinct() +** gives the virtual table additional information about how the query +** planner wants the output to be ordered. As long as the virtual table +** can meet the ordering requirements of the query planner, it may set +** the "orderByConsumed" flag. +** +**
  1. +** ^If the sqlite3_vtab_distinct() interface returns 0, that means +** that the query planner needs the virtual table to return all rows in the +** sort order defined by the "nOrderBy" and "aOrderBy" fields of the +** [sqlite3_index_info] object. This is the default expectation. If the +** virtual table outputs all rows in sorted order, then it is always safe for +** the xBestIndex method to set the "orderByConsumed" flag, regardless of +** the return value from sqlite3_vtab_distinct(). +**

  2. +** ^(If the sqlite3_vtab_distinct() interface returns 1, that means +** that the query planner does not need the rows to be returned in sorted order +** as long as all rows with the same values in all columns identified by the +** "aOrderBy" field are adjacent.)^ This mode is used when the query planner +** is doing a GROUP BY. +**

  3. +** ^(If the sqlite3_vtab_distinct() interface returns 2, that means +** that the query planner does not need the rows returned in any particular +** order, as long as rows with the same values in all "aOrderBy" columns +** are adjacent.)^ ^(Furthermore, only a single row for each particular +** combination of values in the columns identified by the "aOrderBy" field +** needs to be returned.)^ ^It is always ok for two or more rows with the same +** values in all "aOrderBy" columns to be returned, as long as all such rows +** are adjacent. ^The virtual table may, if it chooses, omit extra rows +** that have the same value for all columns identified by "aOrderBy". +** ^However omitting the extra rows is optional. +** This mode is used for a DISTINCT query. +**

+** +** ^For the purposes of comparing virtual table output values to see if the +** values are same value for sorting purposes, two NULL values are considered +** to be the same. In other words, the comparison operator is "IS" +** (or "IS NOT DISTINCT FROM") and not "==". +** +** If a virtual table implementation is unable to meet the requirements +** specified above, then it must not set the "orderByConsumed" flag in the +** [sqlite3_index_info] object or an incorrect answer may result. +** +** ^A virtual table implementation is always free to return rows in any order +** it wants, as long as the "orderByConsumed" flag is not set. ^When the +** the "orderByConsumed" flag is unset, the query planner will add extra +** [bytecode] to ensure that the final results returned by the SQL query are +** ordered correctly. The use of the "orderByConsumed" flag and the +** sqlite3_vtab_distinct() interface is merely an optimization. ^Careful +** use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" +** flag might help queries against a virtual table to run faster. Being +** overly aggressive and setting the "orderByConsumed" flag when it is not +** valid to do so, on the other hand, might cause SQLite to return incorrect +** results. +*/ +SQLITE_API int sqlite3_vtab_distinct(sqlite3_index_info*); + +/* +** CAPI3REF: Identify and handle IN constraints in xBestIndex +** +** This interface may only be used from within an +** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. +** The result of invoking this interface from any other context is +** undefined and probably harmful. +** +** ^(A constraint on a virtual table of the form +** "[IN operator|column IN (...)]" is +** communicated to the xBestIndex method as a +** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use +** this constraint, it must set the corresponding +** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under +** the usual mode of handling IN operators, SQLite generates [bytecode] +** that invokes the [xFilter|xFilter() method] once for each value +** on the right-hand side of the IN operator.)^ Thus the virtual table +** only sees a single value from the right-hand side of the IN operator +** at a time. +** +** In some cases, however, it would be advantageous for the virtual +** table to see all values on the right-hand of the IN operator all at +** once. The sqlite3_vtab_in() interfaces facilitates this in two ways: +** +**
    +**
  1. +** ^A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) +** if and only if the [sqlite3_index_info|P->aConstraint][N] constraint +** is an [IN operator] that can be processed all at once. ^In other words, +** sqlite3_vtab_in() with -1 in the third argument is a mechanism +** by which the virtual table can ask SQLite if all-at-once processing +** of the IN operator is even possible. +** +**

  2. +** ^A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates +** to SQLite that the virtual table does or does not want to process +** the IN operator all-at-once, respectively. ^Thus when the third +** parameter (F) is non-negative, this interface is the mechanism by +** which the virtual table tells SQLite how it wants to process the +** IN operator. +**

+** +** ^The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times +** within the same xBestIndex method call. ^For any given P,N pair, +** the return value from sqlite3_vtab_in(P,N,F) will always be the same +** within the same xBestIndex call. ^If the interface returns true +** (non-zero), that means that the constraint is an IN operator +** that can be processed all-at-once. ^If the constraint is not an IN +** operator or cannot be processed all-at-once, then the interface returns +** false. +** +** ^(All-at-once processing of the IN operator is selected if both of the +** following conditions are met: +** +**
    +**
  1. The P->aConstraintUsage[N].argvIndex value is set to a positive +** integer. This is how the virtual table tells SQLite that it wants to +** use the N-th constraint. +** +**

  2. The last call to sqlite3_vtab_in(P,N,F) for which F was +** non-negative had F>=1. +**

)^ +** +** ^If either or both of the conditions above are false, then SQLite uses +** the traditional one-at-a-time processing strategy for the IN constraint. +** ^If both conditions are true, then the argvIndex-th parameter to the +** xFilter method will be an [sqlite3_value] that appears to be NULL, +** but which can be passed to [sqlite3_vtab_in_first()] and +** [sqlite3_vtab_in_next()] to find all values on the right-hand side +** of the IN constraint. +*/ +SQLITE_API int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle); + +/* +** CAPI3REF: Find all elements on the right-hand side of an IN constraint. +** +** These interfaces are only useful from within the +** [xFilter|xFilter() method] of a [virtual table] implementation. +** The result of invoking these interfaces from any other context +** is undefined and probably harmful. +** +** The X parameter in a call to sqlite3_vtab_in_first(X,P) or +** sqlite3_vtab_in_next(X,P) must be one of the parameters to the +** xFilter method which invokes these routines, and specifically +** a parameter that was previously selected for all-at-once IN constraint +** processing use the [sqlite3_vtab_in()] interface in the +** [xBestIndex|xBestIndex method]. ^(If the X parameter is not +** an xFilter argument that was selected for all-at-once IN constraint +** processing, then these routines return [SQLITE_MISUSE])^ or perhaps +** exhibit some other undefined or harmful behavior. +** +** ^(Use these routines to access all values on the right-hand side +** of the IN constraint using code like the following: +** +**
+**    for(rc=sqlite3_vtab_in_first(pList, &pVal);
+**        rc==SQLITE_OK && pVal
+**        rc=sqlite3_vtab_in_next(pList, &pVal)
+**    ){
+**      // do something with pVal
+**    }
+**    if( rc!=SQLITE_OK ){
+**      // an error has occurred
+**    }
+** 
)^ +** +** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) +** routines return SQLITE_OK and set *P to point to the first or next value +** on the RHS of the IN constraint. ^If there are no more values on the +** right hand side of the IN constraint, then *P is set to NULL and these +** routines return [SQLITE_DONE]. ^The return value might be +** some other value, such as SQLITE_NOMEM, in the event of a malfunction. +** +** The *ppOut values returned by these routines are only valid until the +** next call to either of these routines or until the end of the xFilter +** method from which these routines were called. If the virtual table +** implementation needs to retain the *ppOut values for longer, it must make +** copies. The *ppOut values are [protected sqlite3_value|protected]. +*/ +SQLITE_API int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut); +SQLITE_API int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut); + +/* +** CAPI3REF: Constraint values in xBestIndex() +** METHOD: sqlite3_index_info +** +** This API may only be used from within the [xBestIndex|xBestIndex method] +** of a [virtual table] implementation. The result of calling this interface +** from outside of an xBestIndex method are undefined and probably harmful. +** +** ^When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within +** the [xBestIndex] method of a [virtual table] implementation, with P being +** a copy of the [sqlite3_index_info] object pointer passed into xBestIndex and +** J being a 0-based index into P->aConstraint[], then this routine +** attempts to set *V to the value of the right-hand operand of +** that constraint if the right-hand operand is known. ^If the +** right-hand operand is not known, then *V is set to a NULL pointer. +** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th +** constraint is not available. ^The sqlite3_vtab_rhs_value() interface +** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if +** something goes wrong. +** +** The sqlite3_vtab_rhs_value() interface is usually only successful if +** the right-hand operand of a constraint is a literal value in the original +** SQL statement. If the right-hand operand is an expression or a reference +** to some other column or a [host parameter], then sqlite3_vtab_rhs_value() +** will probably return [SQLITE_NOTFOUND]. +** +** ^(Some constraints, such as [SQLITE_INDEX_CONSTRAINT_ISNULL] and +** [SQLITE_INDEX_CONSTRAINT_ISNOTNULL], have no right-hand operand. For such +** constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.)^ +** +** ^The [sqlite3_value] object returned in *V is a protected sqlite3_value +** and remains valid for the duration of the xBestIndex method call. +** ^When xBestIndex returns, the sqlite3_value object returned by +** sqlite3_vtab_rhs_value() is automatically deallocated. +** +** The "_rhs_" in the name of this routine is an abbreviation for +** "Right-Hand Side". +*/ +SQLITE_API int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal); + /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} @@ -9878,6 +10327,10 @@ SQLITE_API unsigned char *sqlite3_serialize( ** database is currently in a read transaction or is involved in a backup ** operation. ** +** It is not possible to deserialized into the TEMP database. If the +** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the +** function returns SQLITE_ERROR. +** ** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. diff --git a/Data/SQLite/testsuite/TestSuite_vs170.vcxproj b/Data/SQLite/testsuite/TestSuite_vs170.vcxproj index db7e3a796..e96fb07f5 100644 --- a/Data/SQLite/testsuite/TestSuite_vs170.vcxproj +++ b/Data/SQLite/testsuite/TestSuite_vs170.vcxproj @@ -1,6 +1,10 @@ - + + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -51,6 +75,7 @@ + 17.0 TestSuite {45528A81-2523-48DD-AEB3-6B6BD73A2C5D} TestSuite @@ -87,6 +112,36 @@ MultiByte v143 + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + + + Application + MultiByte + v143 + Application MultiByte @@ -137,6 +192,24 @@ + + + + + + + + + + + + + + + + + + @@ -157,7 +230,13 @@ - <_ProjectFileVersion>15.0.28307.799 + <_ProjectFileVersion>17.0.32505.173 + TestSuited + TestSuited + TestSuited + TestSuite + TestSuite + TestSuite TestSuited TestSuited TestSuited @@ -171,6 +250,36 @@ TestSuite TestSuite + + binA64\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\ + objA64\TestSuite\$(Configuration)\ + false + + + binA64\static_mt\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\static_mt\ + objA64\TestSuite\$(Configuration)\ + false + + + binA64\static_md\ + objA64\TestSuite\$(Configuration)\ + true + + + binA64\static_md\ + objA64\TestSuite\$(Configuration)\ + false + bin\ obj\TestSuite\$(Configuration)\ @@ -231,6 +340,189 @@ obj64\TestSuite\$(Configuration)\ false + + + Disabled + ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitd.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\TestSuited.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + CppUnit.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\TestSuite.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitmtd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\TestSuited.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_mt\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + Level3 + + Default + true + + + CppUnitmt.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_mt\TestSuite.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + + + + Disabled + ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + Level3 + ProgramDatabase + Default + true + + + CppUnitmdd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\TestSuited.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + true + true + binA64\static_md\TestSuited.pdb + Console + MachineARM64 + + + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + ..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + Level3 + + Default + true + + + CppUnitmd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies) + binA64\static_md\TestSuite.exe + ..\..\..\libA64;%(AdditionalLibraryDirectories) + false + Console + true + true + MachineARM64 + + Disabled diff --git a/Data/SQLite/testsuite/src/SQLiteTest.cpp b/Data/SQLite/testsuite/src/SQLiteTest.cpp old mode 100644 new mode 100755 index deac5c2d4..931e00e4d --- a/Data/SQLite/testsuite/src/SQLiteTest.cpp +++ b/Data/SQLite/testsuite/src/SQLiteTest.cpp @@ -55,6 +55,7 @@ using Poco::Data::SQLChannel; using Poco::Data::LimitException; using Poco::Data::ConnectionFailedException; using Poco::Data::CLOB; +using Poco::Data::BLOB; using Poco::Data::Date; using Poco::Data::Time; using Poco::Data::Transaction; @@ -463,7 +464,7 @@ void SQLiteTest::testInsertCharPointer() pc = (const char*) std::calloc(9, sizeof(char)); poco_check_ptr (pc); - std::strncpy((char*) pc, "lastname", 8); + std::strncpy((char*) pc, "lastname", 9); Statement stmt = (tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :age)", bind(pc), bind("firstname"), @@ -1375,6 +1376,21 @@ void SQLiteTest::testEmptyDB() } +void SQLiteTest::testNonexistingDB() +{ + try + { + Session tmp (Poco::Data::SQLite::Connector::KEY, "foo/bar/nonexisting.db", 1); + fail("non-existing DB must throw"); + } + catch(ConnectionFailedException& ex) + { + return; + } + fail("non-existing DB must throw ConnectionFailedException"); +} + + void SQLiteTest::testCLOB() { std::string lastName("lastname"); @@ -1419,6 +1435,49 @@ void SQLiteTest::testCLOB() } +void SQLiteTest::testBLOB() +{ + std::string lastName("lastname"); + std::string firstName("firstname"); + std::string address("Address"); + Session tmp(Poco::Data::SQLite::Connector::KEY, "dummy.db"); + tmp << "DROP TABLE IF EXISTS Person", now; + tmp << "CREATE TABLE IF NOT EXISTS Person (LastName VARCHAR(30), FirstName VARCHAR, Address VARCHAR, Image BLOB)", now; + + struct DataStruct + { + int i = 0; + Poco::Int64 i64 = 1; + float f = 2.5; + double d = 3.5; + char c[16] = {0}; + }; + + DataStruct ds; + strcpy(ds.c, "123456789ABCDEF"); + BLOB img(reinterpret_cast(&ds), sizeof(ds)); + assertTrue(img.size() == sizeof(ds)); + int count = 0; + tmp << "INSERT INTO PERSON VALUES(:ln, :fn, :ad, :img)", use(lastName), use(firstName), use(address), use(img), now; + tmp << "SELECT COUNT(*) FROM PERSON", into(count), now; + assertTrue(count == 1); + BLOB res; + assertTrue(res.size() == 0); + + tmp << "SELECT Image FROM Person WHERE LastName == :ln", bind("lastname"), into(res), now; + assertTrue(res.size() == img.size()); + assertTrue(0 == std::memcmp(res.rawContent(), img.rawContent(), sizeof(img))); + assertTrue(0 == std::memcmp(res.rawContent(), &ds, sizeof(ds))); + DataStruct dsCopy; + std::memcpy(&dsCopy, res.rawContent(), sizeof(dsCopy)); + assertTrue(ds.i == dsCopy.i); + assertTrue(ds.i64 == dsCopy.i64); + assertTrue(ds.f == dsCopy.f); + assertTrue(ds.d == dsCopy.d); + assertTrue(std::string(ds.c) == std::string(dsCopy.c)); +} + + void SQLiteTest::testTuple10() { Session tmp (Poco::Data::SQLite::Connector::KEY, "dummy.db"); @@ -3161,7 +3220,8 @@ void SQLiteTest::testTransaction() std::string result; session.setTransactionIsolation(Session::TRANSACTION_READ_COMMITTED); - + session.setProperty(Poco::Data::SQLite::Utility::TRANSACTION_TYPE_PROPERTY_KEY, + Poco::Data::SQLite::TransactionType::EXCLUSIVE); { Transaction trans(session); assertTrue (trans.isActive()); @@ -3183,7 +3243,8 @@ void SQLiteTest::testTransaction() session << "SELECT count(*) FROM Person", into(count), now; assertTrue (0 == count); assertTrue (!session.isTransaction()); - + session.setProperty(Utility::TRANSACTION_TYPE_PROPERTY_KEY, + Poco::Data::SQLite::TransactionType::IMMEDIATE); { Transaction trans(session); session << "INSERT INTO Person VALUES (?,?,?,?)", use(lastNames), use(firstNames), use(addresses), use(ages), now; @@ -3392,6 +3453,19 @@ void SQLiteTest::testIllegalFilePath() } } +void SQLiteTest::testTransactionTypeProperty() +{ + try { + using namespace Poco::Data::SQLite; + + Session tmp(Connector::KEY, "dummy.db"); + tmp.setProperty(Utility::TRANSACTION_TYPE_PROPERTY_KEY, TransactionType::EXCLUSIVE); + Poco::Any property = tmp.getProperty(Utility::TRANSACTION_TYPE_PROPERTY_KEY); + TransactionType value = Poco::RefAnyCast(property); + assertTrue(value == TransactionType::EXCLUSIVE); + } catch (Poco::Exception&) {} +} + void SQLiteTest::setUp() { @@ -3447,7 +3521,9 @@ CppUnit::Test* SQLiteTest::suite() CppUnit_addTest(pSuite, SQLiteTest, testIllegalRange); CppUnit_addTest(pSuite, SQLiteTest, testSingleSelect); CppUnit_addTest(pSuite, SQLiteTest, testEmptyDB); + CppUnit_addTest(pSuite, SQLiteTest, testNonexistingDB); CppUnit_addTest(pSuite, SQLiteTest, testCLOB); + CppUnit_addTest(pSuite, SQLiteTest, testBLOB); CppUnit_addTest(pSuite, SQLiteTest, testTuple10); CppUnit_addTest(pSuite, SQLiteTest, testTupleVector10); CppUnit_addTest(pSuite, SQLiteTest, testTuple9); @@ -3495,6 +3571,7 @@ CppUnit::Test* SQLiteTest::suite() CppUnit_addTest(pSuite, SQLiteTest, testTransactor); CppUnit_addTest(pSuite, SQLiteTest, testFTS3); CppUnit_addTest(pSuite, SQLiteTest, testIllegalFilePath); + CppUnit_addTest(pSuite, SQLiteTest, testTransactionTypeProperty); return pSuite; } diff --git a/Data/SQLite/testsuite/src/SQLiteTest.h b/Data/SQLite/testsuite/src/SQLiteTest.h old mode 100644 new mode 100755 index a19fd85fe..6e4f911ea --- a/Data/SQLite/testsuite/src/SQLiteTest.h +++ b/Data/SQLite/testsuite/src/SQLiteTest.h @@ -74,8 +74,10 @@ public: void testIllegalRange(); void testSingleSelect(); void testEmptyDB(); + void testNonexistingDB(); void testCLOB(); + void testBLOB(); void testTuple1(); void testTupleVector1(); @@ -136,6 +138,7 @@ public: void testFTS3(); void testIllegalFilePath(); + void testTransactionTypeProperty(); void setUp(); void tearDown(); diff --git a/Data/SQLite/testsuite/src/WinCEDriver.cpp b/Data/SQLite/testsuite/src/WinCEDriver.cpp index b05045b15..8fd5bc023 100644 --- a/Data/SQLite/testsuite/src/WinCEDriver.cpp +++ b/Data/SQLite/testsuite/src/WinCEDriver.cpp @@ -24,7 +24,7 @@ int wmain(int argc, wchar_t* argv[]) std::wcstombs(buffer, argv[i], sizeof(buffer)); args.push_back(std::string(buffer)); } - CppUnit::TestRunner runner; + CppUnit::TestRunner runner; runner.addTest("SQLiteTestSuite", SQLiteTestSuite::suite()); return runner.run(args) ? 0 : 1; } diff --git a/Data/doc/00300-DataDeveloperManual.page b/Data/doc/00300-DataDeveloperManual.page index 5fdb7251e..abbbab862 100644 --- a/Data/doc/00300-DataDeveloperManual.page +++ b/Data/doc/00300-DataDeveloperManual.page @@ -11,25 +11,25 @@ Just implement the following interfaces: * Poco::Data::Connector * optional: Poco::Data::AbstractPreparation -It is recommended to implement the classes from top to down (ie. start with Binder and Extractor) and to use a +It is recommended to implement the classes from top to down (ie. start with Binder and Extractor) and to use a namespace that has <[ Poco::Data ]> as parent, e.g.<[ Poco::Data::SQLite ]>. !!!AbstractBinder -An <[AbstractBinder]> is a class that maps values to placeholders. It is also responsible to bind primitive C++ data types to database -data types. The constructor of the subclass should receive everything needed to bind variables to +An <[AbstractBinder]> is a class that maps values to placeholders. It is also responsible to bind primitive C++ data types to database +data types. The constructor of the subclass should receive everything needed to bind variables to placeholders by position. An example taken from the SQLite implementation would be: Binder::Binder(sqlite3_stmt* pStmt): _pStmt(pStmt) { } - + void Binder::bind(std::size_t pos, const Poco::Int32& val) { int rc = sqlite3_bind_int(_pStmt, (int)pos, val); checkReturn(rc); } - + void Binder::bind(std::size_t pos, const Poco::Int16& val) { Poco::Int32 tmp = val; @@ -43,55 +43,55 @@ All methods are public. AbstractBinder(); /// Creates the AbstractBinder. - + virtual ~AbstractBinder(); /// Destroys the AbstractBinder. - + virtual void bind(std::size_t pos, const Poco::Int8 &val) = 0; /// Binds an Int8. - + virtual void bind(std::size_t pos, const Poco::UInt8 &val) = 0; /// Binds an UInt8. - + virtual void bind(std::size_t pos, const Poco::Int16 &val) = 0; /// Binds an Int16. - + virtual void bind(std::size_t pos, const Poco::UInt16 &val) = 0; /// Binds an UInt16. - + virtual void bind(std::size_t pos, const Poco::Int32 &val) = 0; /// Binds an Int32. - + virtual void bind(std::size_t pos, const Poco::UInt32 &val) = 0; /// Binds an UInt32. - + virtual void bind(std::size_t pos, const Poco::Int64 &val) = 0; /// Binds an Int64. - + virtual void bind(std::size_t pos, const Poco::UInt64 &val) = 0; /// Binds an UInt64. - + virtual void bind(std::size_t pos, const bool &val) = 0; /// Binds a boolean. - + virtual void bind(std::size_t pos, const float &val) = 0; /// Binds a float. - + virtual void bind(std::size_t pos, const double &val) = 0; /// Binds a double. - + virtual void bind(std::size_t pos, const char &val) = 0; /// Binds a single character. - + virtual void bind(std::size_t pos, const char* const &pVal) = 0; /// Binds a const char ptr. - + virtual void bind(std::size_t pos, const std::string& val) = 0; /// Binds a string. - + virtual void bind(std::size_t pos, const BLOB& val) = 0; /// Binds a BLOB. - + virtual void reset() = 0; /// Resets the internal state, called before a rebind ---- @@ -105,7 +105,7 @@ the incoming value but will simply return false. An example taken from the SQLit _pStmt(pStmt) { } - + bool Extractor::extract(std::size_t pos, Poco::Int32& val) { if (isNull(pos<[ @@ -113,7 +113,7 @@ the incoming value but will simply return false. An example taken from the SQLit val = sqlite3_column_int(_pStmt, (int)pos); return true; } - + bool Extractor::extract(std::size_t pos, Poco::Int16& val) { if (isNull(pos<[ @@ -128,49 +128,49 @@ All methods are public. AbstractExtractor(); /// Creates the AbstractExtractor. - + virtual ~AbstractExtractor(); /// Destroys the AbstractExtractor. - + virtual bool extract(std::size_t pos, Poco::Int8& val) = 0; /// Extracts an Int8. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::UInt8& val) = 0; /// Extracts an UInt8. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::Int16& val) = 0; /// Extracts an Int16. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::UInt16& val) = 0; /// Extracts an UInt16. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::Int32& val) = 0; /// Extracts an Int32. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::UInt32& val) = 0; /// Extracts an UInt32. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::Int64& val) = 0; /// Extracts an Int64. Returns false if null was received. - + virtual bool extract(std::size_t pos, Poco::UInt64& val) = 0; /// Extracts an UInt64. Returns false if null was received. - + virtual bool extract(std::size_t pos, bool& val) = 0; /// Extracts a boolean. Returns false if null was received. - + virtual bool extract(std::size_t pos, float& val) = 0; /// Extracts a float. Returns false if null was received. - + virtual bool extract(std::size_t pos, double& val) = 0; /// Extracts a double. Returns false if null was received. - + virtual bool extract(std::size_t pos, char& val) = 0; /// Extracts a single character. Returns false if null was received. - + virtual bool extract(std::size_t pos, std::string& val) = 0; /// Extracts a string. Returns false if null was received. - + virtual bool extract(std::size_t pos, BLOB& val) = 0; /// Extracts a BLOB. Returns false if null was received. ---- @@ -196,7 +196,7 @@ The ODBC implementation is different: _myVec[pos] = Poco::Any a(val); int* i = AnyCast(&_myVec[pos]); //register int* i for output, Db specific - } + } ---- Extract now changes to: @@ -213,49 +213,49 @@ Extract now changes to: AbstractPreparation(); /// Creates the AbstractPreparation. - + virtual ~AbstractPreparation(); /// Destroys the AbstractPreparation. - + virtual void prepare(std::size_t pos, Poco::Int8) = 0; /// Prepares an Int8. - + virtual void prepare(std::size_t pos, Poco::UInt8) = 0; /// Prepares an UInt8. - + virtual void prepare(std::size_t pos, Poco::Int16) = 0; /// Prepares an Int16. - + virtual void prepare(std::size_t pos, Poco::UInt16) = 0; /// Prepares an UInt16. - + virtual void prepare(std::size_t pos, Poco::Int32) = 0; /// Prepares an Int32. - + virtual void prepare(std::size_t pos, Poco::UInt32) = 0; /// Prepares an UInt32. - + virtual void prepare(std::size_t pos, Poco::Int64) = 0; /// Prepares an Int64. - + virtual void prepare(std::size_t pos, Poco::UInt64) = 0; /// Prepares an UInt64. - + virtual void prepare(std::size_t pos, bool) = 0; /// Prepares a boolean. - + virtual void prepare(std::size_t pos, float) = 0; /// Prepares a float. - + virtual void prepare(std::size_t pos, double) = 0; /// Prepares a double. - + virtual void prepare(std::size_t pos, char) = 0; /// Prepares a single character. - + virtual void prepare(std::size_t pos, const std::string& ) = 0; /// Prepares a string. - + virtual void prepare(std::size_t pos, const BLOB&) = 0; ---- @@ -280,38 +280,38 @@ The interface it has to implement is given as: public: StatementImpl(); /// Creates the StatementImpl. - + virtual ~StatementImpl(); /// Destroys the StatementImpl. - + protected: virtual bool hasNext() = 0; - /// Returns true if a call to next() will return data. Note that the - /// implementation must support several consecutive calls to hasNext - /// without data getting lost, ie. hasNext(); hasNext(); next() must + /// Returns true if a call to next() will return data. Note that the + /// implementation must support several consecutive calls to hasNext + /// without data getting lost, ie. hasNext(); hasNext(); next() must /// be equal to hasNext(); next(); - + virtual void next() = 0; /// Retrieves the next row from the resultset. /// Will throw, if the resultset is empty. /// Expects the statement to be compiled and bound - + virtual bool canBind() const = 0; /// Returns if another bind is possible. - + virtual void compileImpl() = 0; /// Compiles the statement, doesn't bind yet. - /// From now on AbstractBinder and AbstractExtractor + /// From now on AbstractBinder and AbstractExtractor /// will be used - + virtual void bindImpl() = 0; /// Binds parameters. - + virtual AbstractExtractor& extractor() = 0; /// Returns the concrete extractor used by the statement. - + virtual AbstractBinder& binder() = 0; - /// Returns the concrete binder used by the statement. + /// Returns the concrete binder used by the statement. ---- The Extracting and Binding objects can be accessed via the calls to the super-class methods <*extractings()*> and <*bindings()*>. @@ -334,7 +334,7 @@ A high-level <*next*> implementation: if (!hasNext()) throw Poco::Data::DataException("No data received"); int nCol = countColumnsInResult...; - poco_assert (columnsHandled() == nCol); + poco_assert (columnsHandled() == nCol); Poco::Data::AbstractExtractingVec::iterator it = extractings().begin(); Poco::Data::AbstractExtractingVec::iterator itEnd = extractings().end(); std::size_t pos = 0; // sqlite starts with pos 0 for results! your DB maybe with 1 @@ -354,7 +354,7 @@ A high-level <*hasNext*> implementation: cacheResult disablehasNext() } - + return cachedResult; ---- @@ -362,13 +362,13 @@ A high-level <*compileImpl*>: if (compiled) return; - + std::string sqlStmt(toString()); if database expects placeholders in different format than ":name", parse and replace them compile statement; - + create Binder; create Extractor; ---- @@ -378,7 +378,7 @@ A high-level <*canBind*>: bool ret = false; if (!bindings().empty() && validCompiledStatement) ret = (*bindings().begin())->canBind(); - + return ret; ---- @@ -388,13 +388,13 @@ The connection is opened in the constructor, and closed in the destructor. Poco::Data::StatementImpl* createStatementImpl(); /// Returns an SQLite StatementImpl - + void begin(); /// Starts a transaction - + void commit(); /// Commits and ends a transaction - + void rollback(); /// Aborts a transaction ---- @@ -410,19 +410,19 @@ It should also have a static <*addToFactory()*> and a static <*removeFromFactory public: static const std::string KEY; /// Keyword for creating sessions - + Connector(); /// Creates the Connector. - + ~Connector(); /// Destroys the Connector. - + Poco::AutoPtr < Poco::Data::SessionImpl > createSession(const std::string& connectionString); /// Creates a SessionImpl object and initializes it with the given connectionString. - + static void registerConnector(); /// Registers the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory - + static void unregisterConnector(); /// Unregisters the Connector under the Keyword Connector::KEY at the Poco::Data::SessionFactory }; diff --git a/Data/include/Poco/Data/AbstractBinder.h b/Data/include/Poco/Data/AbstractBinder.h index f084ab843..48af1beaf 100644 --- a/Data/include/Poco/Data/AbstractBinder.h +++ b/Data/include/Poco/Data/AbstractBinder.h @@ -28,6 +28,7 @@ #include "Poco/Any.h" #include "Poco/Dynamic/Var.h" #include "Poco/UTFString.h" +#include "Poco/TextEncoding.h" #include #include #include @@ -39,7 +40,7 @@ namespace Data { using NullData = NullType; - +class Transcoder; namespace Keywords { @@ -64,7 +65,8 @@ public: PD_IN_OUT }; - AbstractBinder(); + AbstractBinder(Poco::TextEncoding::Ptr pFromEncoding = nullptr, + Poco::TextEncoding::Ptr pDBEncoding = nullptr); /// Creates the AbstractBinder. virtual ~AbstractBinder(); @@ -358,10 +360,16 @@ public: /// Returns true if direction is in bound; protected: + bool transcodeRequired() const; + void transcode(const std::string& from, std::string& to); + void reverseTranscode(const std::string& from, std::string& to); + const std::string& toString(const UUID& uuid); private: using StringList = std::vector; + + std::unique_ptr _pTranscoder; std::unique_ptr _pStrings; }; @@ -387,6 +395,12 @@ inline bool AbstractBinder::isInBound(Direction dir) } +inline bool AbstractBinder::transcodeRequired() const +{ + return _pTranscoder.operator bool(); +} + + } } // namespace Poco::Data diff --git a/Data/include/Poco/Data/AbstractBinding.h b/Data/include/Poco/Data/AbstractBinding.h index aaed3e6f8..4791d4b5e 100644 --- a/Data/include/Poco/Data/AbstractBinding.h +++ b/Data/include/Poco/Data/AbstractBinding.h @@ -68,7 +68,7 @@ public: virtual std::size_t numOfRowsHandled() const = 0; /// Returns the number of rows that the binding handles. /// - /// The trivial case will be one single row but + /// The trivial case will be one single row but /// for collection data types it can be larger. virtual bool canBind() const = 0; diff --git a/Data/include/Poco/Data/AbstractExtractor.h b/Data/include/Poco/Data/AbstractExtractor.h index 0ad868ab0..c08140ffe 100644 --- a/Data/include/Poco/Data/AbstractExtractor.h +++ b/Data/include/Poco/Data/AbstractExtractor.h @@ -23,6 +23,8 @@ #include "Poco/Data/LOB.h" #include "Poco/UUID.h" #include "Poco/UTFString.h" +#include "Poco/TextEncoding.h" +#include #include #include #include @@ -32,7 +34,6 @@ namespace Poco { - class DateTime; class Any; @@ -45,6 +46,7 @@ namespace Data { class Date; class Time; +class Transcoder; class Data_API AbstractExtractor @@ -54,7 +56,8 @@ class Data_API AbstractExtractor public: using Ptr = SharedPtr; - AbstractExtractor(); + AbstractExtractor(Poco::TextEncoding::Ptr pDBEncoding = nullptr, + Poco::TextEncoding::Ptr pToEncoding = nullptr); /// Creates the AbstractExtractor. virtual ~AbstractExtractor(); @@ -346,18 +349,33 @@ public: virtual void reset(); /// Resets any information internally cached by the extractor. + +protected: + bool transcodeRequired() const; + void transcode(const std::string& from, std::string& to); + void reverseTranscode(const std::string& from, std::string& to); + +private: + std::unique_ptr _pTranscoder; }; /// /// inlines /// + inline void AbstractExtractor::reset() { //default no-op } +inline bool AbstractExtractor::transcodeRequired() const +{ + return _pTranscoder.operator bool(); +} + + } } // namespace Poco::Data diff --git a/Data/include/Poco/Data/AbstractSessionImpl.h b/Data/include/Poco/Data/AbstractSessionImpl.h index d01f73d47..43a45fe72 100644 --- a/Data/include/Poco/Data/AbstractSessionImpl.h +++ b/Data/include/Poco/Data/AbstractSessionImpl.h @@ -40,13 +40,13 @@ class AbstractSessionImpl: public SessionImpl public: typedef void (C::*FeatureSetter)(const std::string&, bool); /// The setter method for a feature. - + typedef bool (C::*FeatureGetter)(const std::string&) const; /// The getter method for a feature. - + typedef void (C::*PropertySetter)(const std::string&, const Poco::Any&); /// The setter method for a property. - + typedef Poco::Any (C::*PropertyGetter)(const std::string&) const; /// The getter method for a property. @@ -57,28 +57,28 @@ public: _emptyStringIsNull(false), _forceEmptyString(false) /// Creates the AbstractSessionImpl. - /// - /// Adds "storage" property and sets the default internal storage container + /// + /// Adds "storage" property and sets the default internal storage container /// type to std::deque. - /// The storage is created by statements automatically whenever a query + /// The storage is created by statements automatically whenever a query /// returning results is executed but external storage is provided by the user. /// Storage type can be reconfigured at runtime both globally (for the - /// duration of the session) and locally (for a single statement execution only). + /// duration of the session) and locally (for a single statement execution only). /// See StatementImpl for details on how this property is used at runtime. - /// + /// /// Adds "handle" property which, if set by the back end, returns native handle /// for the back end DB. - /// + /// /// Adds "bulk" feature and sets it to false. /// Bulk feature determines whether the session is capable of bulk operations. - /// Connectors that are capable of it must set this feature prior to attempting + /// Connectors that are capable of it must set this feature prior to attempting /// bulk operations. /// /// Adds "emptyStringIsNull" feature and sets it to false. This feature should be /// set to true in order to modify the behavior of the databases that distinguish - /// between zero-length character strings as nulls. Setting this feature to true + /// between zero-length character strings as nulls. Setting this feature to true /// shall disregard any difference between empty character strings and nulls, - /// causing the framework to treat them the same (i.e. behave like Oracle). + /// causing the framework to treat them the same (i.e. behave like Oracle). /// /// Adds "forceEmptyString" feature and sets it to false. This feature should be set /// to true in order to force the databases that do not distinguish empty strings from @@ -89,23 +89,23 @@ public: /// resulting in default underlying database behavior. /// { - addProperty("storage", - &AbstractSessionImpl::setStorage, + addProperty("storage", + &AbstractSessionImpl::setStorage, &AbstractSessionImpl::getStorage); - addProperty("handle", + addProperty("handle", &AbstractSessionImpl::setHandle, &AbstractSessionImpl::getHandle); - addFeature("bulk", - &AbstractSessionImpl::setBulk, + addFeature("bulk", + &AbstractSessionImpl::setBulk, &AbstractSessionImpl::getBulk); - addFeature("emptyStringIsNull", + addFeature("emptyStringIsNull", &AbstractSessionImpl::setEmptyStringIsNull, &AbstractSessionImpl::getEmptyStringIsNull); - addFeature("forceEmptyString", + addFeature("forceEmptyString", &AbstractSessionImpl::setForceEmptyString, &AbstractSessionImpl::getForceEmptyString); } @@ -129,7 +129,7 @@ public: } else throw NotSupportedException(name); } - + bool getFeature(const std::string& name) /// Looks a feature up in the features map /// and calls the feature's getter, if there is one. @@ -144,7 +144,7 @@ public: } else throw NotSupportedException(name); } - + void setProperty(const std::string& name, const Poco::Any& value) /// Looks a property up in the properties map /// and calls the property's setter, if there is one. @@ -174,7 +174,7 @@ public: } else throw NotSupportedException(name); } - + void setStorage(const std::string& value) /// Sets the storage type. { @@ -186,7 +186,7 @@ public: { _storage = Poco::RefAnyCast(value); } - + Poco::Any getStorage(const std::string& name="") const /// Returns the storage type { @@ -194,13 +194,13 @@ public: } void setHandle(const std::string& name, const Poco::Any& handle) - /// Sets the native session handle. + /// Sets the native session handle. { _handle = handle; } - + Poco::Any getHandle(const std::string& name="") const - /// Returns the native session handle. + /// Returns the native session handle. { return _handle; } @@ -210,7 +210,7 @@ public: { _bulk = bulk; } - + bool getBulk(const std::string& name="") const /// Returns the execution type { @@ -228,7 +228,7 @@ public: _emptyStringIsNull = emptyStringIsNull; } - + bool getEmptyStringIsNull(const std::string& name="") const /// Returns the setting for the behavior regarding empty variable /// length strings. See setEmptyStringIsNull(const std::string&, bool) @@ -249,7 +249,7 @@ public: _forceEmptyString = forceEmptyString; } - + bool getForceEmptyString(const std::string& name="") const /// Returns the setting for the behavior regarding empty variable /// length strings. See setForceEmptyString(const std::string&, bool) @@ -270,7 +270,7 @@ protected: feature.getter = getter; _features[name] = feature; } - + void addProperty(const std::string& name, PropertySetter setter, PropertyGetter getter) /// Adds a property to the map of supported properties. /// @@ -289,16 +289,16 @@ private: FeatureSetter setter; FeatureGetter getter; }; - + struct Property { PropertySetter setter; PropertyGetter getter; }; - + using FeatureMap = std::map; using PropertyMap = std::map; - + FeatureMap _features; PropertyMap _properties; std::string _storage; diff --git a/Data/include/Poco/Data/ArchiveStrategy.h b/Data/include/Poco/Data/ArchiveStrategy.h index 2f4befac9..24116efec 100644 --- a/Data/include/Poco/Data/ArchiveStrategy.h +++ b/Data/include/Poco/Data/ArchiveStrategy.h @@ -36,9 +36,9 @@ class Data_API ArchiveStrategy public: static const std::string DEFAULT_ARCHIVE_DESTINATION; - ArchiveStrategy(const std::string& connector, - const std::string& connect, - const std::string& source, + ArchiveStrategy(const std::string& connector, + const std::string& connect, + const std::string& source, const std::string& destination = DEFAULT_ARCHIVE_DESTINATION); /// Creates archive strategy. @@ -83,7 +83,7 @@ protected: Statement& getDeleteStatement(); Statement& getCountStatement(); private: - + ArchiveStrategy(); ArchiveStrategy(const ArchiveStrategy&); ArchiveStrategy& operator = (const ArchiveStrategy&); @@ -177,11 +177,11 @@ class Data_API ArchiveByAgeStrategy: public ArchiveStrategy /// Archives rows scheduled for archiving. { public: - ArchiveByAgeStrategy(const std::string& connector, - const std::string& connect, - const std::string& sourceTable, + ArchiveByAgeStrategy(const std::string& connector, + const std::string& connect, + const std::string& sourceTable, const std::string& destinationTable = DEFAULT_ARCHIVE_DESTINATION); - + ~ArchiveByAgeStrategy(); void archive(); diff --git a/Data/include/Poco/Data/Binding.h b/Data/include/Poco/Data/Binding.h index 537543a7d..9585f85e4 100644 --- a/Data/include/Poco/Data/Binding.h +++ b/Data/include/Poco/Data/Binding.h @@ -40,14 +40,14 @@ namespace Data { template class Binding: public AbstractBinding /// Binding maps a value or multiple values (see Binding specializations for STL containers as - /// well as type handlers) to database column(s). Values to be bound can be either mapped + /// well as type handlers) to database column(s). Values to be bound can be either mapped /// directly (by reference) or a copy can be created, depending on the value of the copy argument. /// To pass a reference to a variable, it is recommended to pass it to the intermediate - /// utility function use(), which will create the proper binding. In cases when a reference + /// utility function use(), which will create the proper binding. In cases when a reference /// is passed to binding, the storage it refers to must be valid at the statement execution time. /// To pass a copy of a variable, constant or string literal, use utility function bind(). /// Variables can be passed as either copies or references (i.e. using either use() or bind()). - /// Constants, however, can only be passed as copies. this is best achieved using bind() utility + /// Constants, however, can only be passed as copies. This is best achieved using bind() utility /// function. An attempt to pass a constant by reference shall result in compile-time error. { public: @@ -57,10 +57,10 @@ public: using Ptr = SharedPtr; explicit Binding(T& val, - const std::string& name = "", - Direction direction = PD_IN): + const std::string& name = "", + Direction direction = PD_IN): AbstractBinding(name, direction), - _val(val), + _val(val), _bound(false) /// Creates the Binding using the passed reference as bound value. /// If copy is true, a copy of the value referred to is created. @@ -112,10 +112,10 @@ private: template class CopyBinding: public AbstractBinding /// Binding maps a value or multiple values (see Binding specializations for STL containers as - /// well as type handlers) to database column(s). Values to be bound can be either mapped + /// well as type handlers) to database column(s). Values to be bound can be either mapped /// directly (by reference) or a copy can be created, depending on the value of the copy argument. /// To pass a reference to a variable, it is recommended to pass it to the intermediate - /// utility function use(), which will create the proper binding. In cases when a reference + /// utility function use(), which will create the proper binding. In cases when a reference /// is passed to binding, the storage it refers to must be valid at the statement execution time. /// To pass a copy of a variable, constant or string literal, use utility function bind(). /// Variables can be passed as either copies or references (i.e. using either use() or bind()). @@ -127,8 +127,8 @@ public: using Ptr = SharedPtr; explicit CopyBinding(T& val, - const std::string& name = "", - Direction direction = PD_IN): + const std::string& name = "", + Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new T(val)), _bound(false) @@ -189,10 +189,10 @@ public: using Type = Binding; using Ptr = SharedPtr; - explicit Binding(const char* pVal, + explicit Binding(const char* pVal, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _val(pVal ? pVal : throw NullPointerException() ), _bound(false) /// Creates the Binding by copying the passed string. @@ -251,10 +251,10 @@ public: using Type = CopyBinding; using Ptr = SharedPtr; - explicit CopyBinding(const char* pVal, + explicit CopyBinding(const char* pVal, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _val(pVal ? pVal : throw NullPointerException() ), _bound(false) /// Creates the Binding by copying the passed string. @@ -312,12 +312,12 @@ public: using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; - explicit Binding(std::vector& val, - const std::string& name = "", - Direction direction = PD_IN): + explicit Binding(std::vector& val, + const std::string& name = "", + Direction direction = PD_IN): AbstractBinding(name, direction), - _val(val), - _begin(), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -350,7 +350,7 @@ public: { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); - + TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } @@ -373,18 +373,18 @@ class CopyBinding>: public AbstractBinding /// Specialization for std::vector. { public: - + using ValType = std::vector; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; - explicit CopyBinding(std::vector& val, - const std::string& name = "", - Direction direction = PD_IN): + explicit CopyBinding(std::vector& val, + const std::string& name = "", + Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::vector(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -417,7 +417,7 @@ public: { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); - + TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } @@ -439,14 +439,14 @@ template <> class Binding>: public AbstractBinding /// Specialization for std::vector. /// This specialization is necessary due to the nature of std::vector. - /// For details, see the standard library implementation of std::vector + /// For details, see the standard library implementation of std::vector /// or /// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001), /// Item 18: "Avoid using vector." - /// + /// /// The workaround employed here is using std::deque as an - /// internal replacement container. - /// + /// internal replacement container. + /// /// IMPORTANT: /// Only IN binding is supported. { @@ -456,13 +456,13 @@ public: using Ptr = SharedPtr>; using Iterator = ValType::const_iterator; - explicit Binding(const std::vector& val, - const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), + explicit Binding(const std::vector& val, + const std::string& name = "", + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), _deq(_val.begin(), _val.end()), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -520,14 +520,14 @@ template <> class CopyBinding>: public AbstractBinding /// Specialization for std::vector. /// This specialization is necessary due to the nature of std::vector. - /// For details, see the standard library implementation of std::vector + /// For details, see the standard library implementation of std::vector /// or /// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001), /// Item 18: "Avoid using vector." - /// + /// /// The workaround employed here is using std::deque as an - /// internal replacement container. - /// + /// internal replacement container. + /// /// IMPORTANT: /// Only IN binding is supported. { @@ -537,12 +537,12 @@ public: using Ptr = SharedPtr>; using Iterator = ValType::const_iterator; - explicit CopyBinding(const std::vector& val, - const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + explicit CopyBinding(const std::vector& val, + const std::string& name = "", + Direction direction = PD_IN): + AbstractBinding(name, direction), _deq(val.begin(), val.end()), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -608,10 +608,10 @@ public: explicit Binding(std::list& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), - _begin(), + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -673,10 +673,10 @@ public: explicit CopyBinding(ValType& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _pVal(new std::list(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -738,10 +738,10 @@ public: explicit Binding(std::deque& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), - _begin(), + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -803,10 +803,10 @@ public: explicit CopyBinding(std::deque& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _pVal(new std::deque(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -868,10 +868,10 @@ public: explicit Binding(std::set& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), - _begin(), + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -933,10 +933,10 @@ public: explicit CopyBinding(std::set& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _pVal(new std::set(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -998,10 +998,10 @@ public: explicit Binding(std::multiset& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), - _begin(), + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -1063,10 +1063,10 @@ public: explicit CopyBinding(std::multiset& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _pVal(new std::multiset(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -1128,10 +1128,10 @@ public: explicit Binding(std::map& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), - _begin(), + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -1193,10 +1193,10 @@ public: explicit CopyBinding(std::map& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _pVal(new std::map(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -1258,10 +1258,10 @@ public: explicit Binding(std::multimap& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), - _val(val), - _begin(), + Direction direction = PD_IN): + AbstractBinding(name, direction), + _val(val), + _begin(), _end() /// Creates the Binding. { @@ -1323,10 +1323,10 @@ public: explicit CopyBinding(std::multimap& val, const std::string& name = "", - Direction direction = PD_IN): - AbstractBinding(name, direction), + Direction direction = PD_IN): + AbstractBinding(name, direction), _pVal(new std::multimap(val)), - _begin(), + _begin(), _end() /// Creates the Binding. { @@ -1379,13 +1379,13 @@ private: namespace Keywords { -template +template inline AbstractBinding::Ptr use(T& t, const std::string& name = "") /// Convenience function for a more compact Binding creation. { // If this fails to compile, a const ref was passed to use(). // This can be resolved by either (a) using bind (which will copy the value), - // or (b) if the const ref is guaranteed to exist when execute is called + // or (b) if the const ref is guaranteed to exist when execute is called // (which can be much later!), by using the "useRef" keyword instead poco_static_assert (!IsConst::VALUE); return new Binding(t, name, AbstractBinding::PD_IN); @@ -1399,7 +1399,7 @@ inline AbstractBinding::Ptr use(const NullData& t, const std::string& name = "") } -template +template inline AbstractBinding::Ptr useRef(T& t, const std::string& name = "") /// Convenience function for a more compact Binding creation. { @@ -1407,7 +1407,7 @@ inline AbstractBinding::Ptr useRef(T& t, const std::string& name = "") } -template +template inline AbstractBinding::Ptr in(T& t, const std::string& name = "") /// Convenience function for a more compact Binding creation. { @@ -1422,7 +1422,7 @@ inline AbstractBinding::Ptr in(const NullData& t, const std::string& name = "") } -template +template inline AbstractBinding::Ptr out(T& t) /// Convenience function for a more compact Binding creation. { @@ -1431,7 +1431,7 @@ inline AbstractBinding::Ptr out(T& t) } -template +template inline AbstractBinding::Ptr io(T& t) /// Convenience function for a more compact Binding creation. { @@ -1468,7 +1468,7 @@ inline AbstractBindingVec& io(AbstractBindingVec& bv) } -template +template inline AbstractBinding::Ptr bind(T t, const std::string& name) /// Convenience function for a more compact Binding creation. /// This funtion differs from use() in its value copy semantics. @@ -1477,7 +1477,7 @@ inline AbstractBinding::Ptr bind(T t, const std::string& name) } -template +template inline AbstractBinding::Ptr bind(T t) /// Convenience function for a more compact Binding creation. /// This funtion differs from use() in its value copy semantics. diff --git a/Data/include/Poco/Data/Bulk.h b/Data/include/Poco/Data/Bulk.h index 7b30ae633..f55d4008c 100644 --- a/Data/include/Poco/Data/Bulk.h +++ b/Data/include/Poco/Data/Bulk.h @@ -42,9 +42,9 @@ public: /// Returns the limit asociated with this bulk object. Poco::UInt32 size() const; - /// Returns the value of the limit asociated with + /// Returns the value of the limit asociated with /// this bulk object. - + private: Bulk(); @@ -55,15 +55,15 @@ private: /// /// inlines /// -inline const Limit& Bulk::limit() const -{ - return _limit; +inline const Limit& Bulk::limit() const +{ + return _limit; } -inline Poco::UInt32 Bulk::size() const -{ - return _limit.value(); +inline Poco::UInt32 Bulk::size() const +{ + return _limit.value(); } diff --git a/Data/include/Poco/Data/BulkBinding.h b/Data/include/Poco/Data/BulkBinding.h index a1a4004b2..51637e6b4 100644 --- a/Data/include/Poco/Data/BulkBinding.h +++ b/Data/include/Poco/Data/BulkBinding.h @@ -35,13 +35,13 @@ namespace Data { template class BulkBinding: public AbstractBinding - /// A BulkBinding maps a value to a column. + /// A BulkBinding maps a value to a column. /// Bulk binding support is provided only for std::vector. { public: - BulkBinding(const T& val, Poco::UInt32 bulkSize, const std::string& name = "", Direction direction = PD_IN): - AbstractBinding(name, direction, bulkSize), - _val(val), + BulkBinding(const T& val, Poco::UInt32 bulkSize, const std::string& name = "", Direction direction = PD_IN): + AbstractBinding(name, direction, bulkSize), + _val(val), _bound(false) /// Creates the BulkBinding. { @@ -91,7 +91,7 @@ private: namespace Keywords { -template +template AbstractBinding::Ptr use(const std::vector& t, BulkFnType, const std::string& name = "") /// Convenience function for a more compact BulkBinding creation for std::vector. { @@ -99,7 +99,7 @@ AbstractBinding::Ptr use(const std::vector& t, BulkFnType, const std::string& } -template +template AbstractBinding::Ptr in(const std::vector& t, BulkFnType, const std::string& name = "") /// Convenience function for a more compact BulkBinding creation for std::vector. { @@ -107,7 +107,7 @@ AbstractBinding::Ptr in(const std::vector& t, BulkFnType, const std::string& } -template +template AbstractBinding::Ptr use(const std::deque& t, BulkFnType, const std::string& name = "") /// Convenience function for a more compact BulkBinding creation for std::deque. { @@ -115,7 +115,7 @@ AbstractBinding::Ptr use(const std::deque& t, BulkFnType, const std::string& } -template +template AbstractBinding::Ptr in(const std::deque& t, BulkFnType, const std::string& name = "") /// Convenience function for a more compact BulkBinding creation for std::deque. { @@ -123,7 +123,7 @@ AbstractBinding::Ptr in(const std::deque& t, BulkFnType, const std::string& n } -template +template AbstractBinding::Ptr use(const std::list& t, BulkFnType, const std::string& name = "") /// Convenience function for a more compact BulkBinding creation for std::list. { @@ -131,7 +131,7 @@ AbstractBinding::Ptr use(const std::list& t, BulkFnType, const std::string& n } -template +template AbstractBinding::Ptr in(const std::list& t, BulkFnType, const std::string& name = "") /// Convenience function for a more compact BulkBinding creation for std::list. { diff --git a/Data/include/Poco/Data/BulkExtraction.h b/Data/include/Poco/Data/BulkExtraction.h index bb61a1500..0ed297952 100644 --- a/Data/include/Poco/Data/BulkExtraction.h +++ b/Data/include/Poco/Data/BulkExtraction.h @@ -44,18 +44,18 @@ public: using Type = BulkExtraction; using Ptr = SharedPtr; - BulkExtraction(C& result, Poco::UInt32 limit, const Position& pos = Position(0)): + BulkExtraction(C& result, Poco::UInt32 limit, const Position& pos = Position(0)): AbstractExtraction(limit, pos.value(), true), - _rResult(result), + _rResult(result), _default() { if (static_cast(result.size()) != limit) result.resize(limit); } - BulkExtraction(C& result, const CValType& def, Poco::UInt32 limit, const Position& pos = Position(0)): + BulkExtraction(C& result, const CValType& def, Poco::UInt32 limit, const Position& pos = Position(0)): AbstractExtraction(limit, pos.value(), true), - _rResult(result), + _rResult(result), _default(def) { if (static_cast(result.size()) != limit) @@ -88,8 +88,8 @@ public: return _nulls.at(row); } catch (std::out_of_range& ex) - { - throw RangeException(ex.what()); + { + throw RangeException(ex.what()); } } @@ -137,7 +137,7 @@ template class InternalBulkExtraction: public BulkExtraction /// Container Data Type specialization extension for extraction of values from a query result set. /// - /// This class is intended for PocoData internal use - it is used by StatementImpl + /// This class is intended for PocoData internal use - it is used by StatementImpl /// to automaticaly create internal BulkExtraction in cases when statement returns data and no external storage /// was supplied. It is later used by RecordSet to retrieve the fetched data after statement execution. /// It takes ownership of the Column pointer supplied as constructor argument. Column object, in turn @@ -155,8 +155,8 @@ public: InternalBulkExtraction(C& result, Column* pColumn, Poco::UInt32 limit, - const Position& pos = Position(0)): - BulkExtraction(result, CValType(), limit, pos), + const Position& pos = Position(0)): + BulkExtraction(result, CValType(), limit, pos), _pColumn(pColumn) /// Creates InternalBulkExtraction. { @@ -171,17 +171,17 @@ public: void reset() { _pColumn->reset(); - } + } const CValType& value(int index) const { try - { - return BulkExtraction::result().at(index); + { + return BulkExtraction::result().at(index); } catch (std::out_of_range& ex) - { - throw RangeException(ex.what()); + { + throw RangeException(ex.what()); } } @@ -207,7 +207,7 @@ private: namespace Keywords { -template +template AbstractExtraction::Ptr into(std::vector& t, const Bulk& bulk, const Position& pos = Position(0)) /// Convenience function to allow for a more compact creation of an extraction object /// with std::vector bulk extraction support. @@ -216,7 +216,7 @@ AbstractExtraction::Ptr into(std::vector& t, const Bulk& bulk, const Position } -template +template AbstractExtraction::Ptr into(std::vector& t, BulkFnType, const Position& pos = Position(0)) /// Convenience function to allow for a more compact creation of an extraction object /// with std::vector bulk extraction support. @@ -227,7 +227,7 @@ AbstractExtraction::Ptr into(std::vector& t, BulkFnType, const Position& pos } -template +template AbstractExtraction::Ptr into(std::deque& t, const Bulk& bulk, const Position& pos = Position(0)) /// Convenience function to allow for a more compact creation of an extraction object /// with std::deque bulk extraction support. @@ -236,7 +236,7 @@ AbstractExtraction::Ptr into(std::deque& t, const Bulk& bulk, const Position& } -template +template AbstractExtraction::Ptr into(std::deque& t, BulkFnType, const Position& pos = Position(0)) /// Convenience function to allow for a more compact creation of an extraction object /// with std::deque bulk extraction support. @@ -247,7 +247,7 @@ AbstractExtraction::Ptr into(std::deque& t, BulkFnType, const Position& pos = } -template +template AbstractExtraction::Ptr into(std::list& t, const Bulk& bulk, const Position& pos = Position(0)) /// Convenience function to allow for a more compact creation of an extraction object /// with std::list bulk extraction support. @@ -256,7 +256,7 @@ AbstractExtraction::Ptr into(std::list& t, const Bulk& bulk, const Position& } -template +template AbstractExtraction::Ptr into(std::list& t, BulkFnType, const Position& pos = Position(0)) /// Convenience function to allow for a more compact creation of an extraction object /// with std::list bulk extraction support. diff --git a/Data/include/Poco/Data/Column.h b/Data/include/Poco/Data/Column.h index c6764b4c9..83469f225 100644 --- a/Data/include/Poco/Data/Column.h +++ b/Data/include/Poco/Data/Column.h @@ -34,7 +34,7 @@ namespace Data { template class Column /// Column class is column data container. - /// Data (a pointer to underlying STL container) is assigned to the class + /// Data (a pointer to underlying STL container) is assigned to the class /// at construction time. Construction with null pointer is not allowed. /// This class owns the data assigned to it and deletes the storage on destruction. { @@ -46,7 +46,7 @@ public: using Size = typename C::size_type; using Type = typename C::value_type; - Column(const MetaColumn& metaColumn, Container* pData): + Column(const MetaColumn& metaColumn, Container* pData): _metaColumn(metaColumn), _pData(pData) /// Creates the Column. @@ -55,15 +55,15 @@ public: throw NullPointerException("Container pointer must point to valid storage."); } - Column(const Column& col): - _metaColumn(col._metaColumn), + Column(const Column& col): + _metaColumn(col._metaColumn), _pData(col._pData) /// Creates the Column. { } - Column(Column&& col) noexcept: - _metaColumn(std::move(col._metaColumn)), + Column(Column&& col) noexcept: + _metaColumn(std::move(col._metaColumn)), _pData(std::move(col._pData)) /// Creates the Column. { @@ -90,7 +90,7 @@ public: return *this; } - void swap(Column& other) + void swap(Column& other) noexcept /// Swaps the column with another one. { using std::swap; @@ -112,8 +112,8 @@ public: return _pData->at(row); } catch (std::out_of_range& ex) - { - throw RangeException(ex.what()); + { + throw RangeException(ex.what()); } } @@ -189,13 +189,13 @@ private: template <> class Column> /// The std::vector specialization for the Column class. - /// + /// /// This specialization is necessary due to the nature of std::vector. - /// For details, see the standard library implementation of vector + /// For details, see the standard library implementation of vector /// or /// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001), /// Item 18: "Avoid using vector." - /// + /// /// The workaround employed here is using deque as an /// internal "companion" container kept in sync with the vector /// column data. @@ -207,8 +207,8 @@ public: using RIterator = Container::const_reverse_iterator; using Size = Container::size_type; - Column(const MetaColumn& metaColumn, Container* pData): - _metaColumn(metaColumn), + Column(const MetaColumn& metaColumn, Container* pData): + _metaColumn(metaColumn), _pData(pData) /// Creates the Column. { @@ -216,8 +216,8 @@ public: _deque.assign(_pData->begin(), _pData->end()); } - Column(const Column& col): - _metaColumn(col._metaColumn), + Column(const Column& col): + _metaColumn(col._metaColumn), _pData(col._pData) /// Creates the Column. { @@ -237,7 +237,7 @@ public: return *this; } - void swap(Column& other) + void swap(Column& other) noexcept /// Swaps the column with another one. { using std::swap; @@ -263,8 +263,8 @@ public: return _deque.at(row) = _pData->at(row); } catch (std::out_of_range& ex) - { - throw RangeException(ex.what()); + { + throw RangeException(ex.what()); } } @@ -350,8 +350,8 @@ public: using RIterator = typename Container::const_reverse_iterator; using Size = typename Container::size_type; - Column(const MetaColumn& metaColumn, std::list* pData): - _metaColumn(metaColumn), + Column(const MetaColumn& metaColumn, std::list* pData): + _metaColumn(metaColumn), _pData(pData) /// Creates the Column. { @@ -378,7 +378,7 @@ public: return *this; } - void swap(Column& other) + void swap(Column& other) noexcept /// Swaps the column with another one. { using std::swap; @@ -395,7 +395,7 @@ public: const T& value(std::size_t row) const /// Returns the field value in specified row. /// This is the std::list specialization and std::list - /// is not the optimal solution for cases where random + /// is not the optimal solution for cases where random /// access is needed. /// However, to allow for compatibility with other /// containers, this functionality is provided here. @@ -419,7 +419,7 @@ public: if (i == row) return *it; } - throw RangeException("Invalid row number."); + throw RangeException("Invalid row number."); } const T& operator [] (std::size_t row) const @@ -492,7 +492,7 @@ private: template -inline void swap(Column& c1, Column& c2) +inline void swap(Column& c1, Column& c2) noexcept { c1.swap(c2); } diff --git a/Data/include/Poco/Data/Date.h b/Data/include/Poco/Data/Date.h index 4ac234bb7..9340ef7cb 100644 --- a/Data/include/Poco/Data/Date.h +++ b/Data/include/Poco/Data/Date.h @@ -174,7 +174,7 @@ public: ~VarHolderImpl() { } - + const std::type_info& type() const { return typeid(Poco::Data::Date); @@ -207,7 +207,7 @@ public: { return cloneHolder(pVarHolder, _val); } - + const Poco::Data::Date& value() const { return _val; diff --git a/Data/include/Poco/Data/JSONRowFormatter.h b/Data/include/Poco/Data/JSONRowFormatter.h new file mode 100644 index 000000000..8308e9ab4 --- /dev/null +++ b/Data/include/Poco/Data/JSONRowFormatter.h @@ -0,0 +1,159 @@ +// +// JSONRowFormatter.h +// +// Library: Data +// Package: DataCore +// Module: JSONRowFormatter +// +// Definition of the JSONRowFormatter class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef Data_JSONRowFormatter_INCLUDED +#define Data_JSONRowFormatter_INCLUDED + + +#include "Poco/Data/RowFormatter.h" + + +namespace Poco { +namespace Data { + + +class Data_API JSONRowFormatter: public Poco::Data::RowFormatter + /// Class for JSON formatting of data rows. + /// + /// Formatter can be configured to operate in four modes (and + /// certain combinations thereof) : + /// + /// - small (condensed mode, only array of values) + /// + /// Example: + /// { + /// [["Simpson", "Bart", "Springfield", 12], + /// ["Simpson", "Lisa", "Springfield", 10]] + /// } + /// + /// - row count (total row count provided) + /// + /// Example: + /// { + /// "count":2, + /// [["Simpson", "Bart", "Springfield", 12], + /// ["Simpson", "Lisa", "Springfield", 10]] + /// } + /// + /// - column names (column names provided as a string array) + /// + /// Example: + /// { + /// "names":["LastName", "FirstName", "Address", "Age"], + /// [["Simpson", "Bart", "Springfield", 12], + /// ["Simpson", "Lisa", "Springfield", 10]] + /// } + /// + /// - full (total row count, column names provided in every row of data) + /// + /// Example: + /// { + /// "count":2, + /// [ + /// {"LastName": "Simpson", "FirstName": "Bart", "Address": "Springfield", "Age": 12}, + /// {"LastName": "Simpson", "FirstName": "Lisa", "Address": "Springfield", "Age": 10} + /// ] + /// } + /// + /// Total row count will be specified by the Poco::SQLRecordSet. Note, however, that this is + /// not possible to do accurately in case of result set paging. For those cases, there is + /// setTotalRowCount() member function, which allows to explicitly set the total row count. + /// If the total row count is preset on the formatter, the Data framework shall not interfere. +{ +public: + static const int JSON_FMT_MODE_SMALL = 1; + static const int JSON_FMT_MODE_ROW_COUNT = 2; + static const int JSON_FMT_MODE_COLUMN_NAMES = 4; + static const int JSON_FMT_MODE_FULL = 8; + + JSONRowFormatter(int mode = (JSON_FMT_MODE_COLUMN_NAMES | JSON_FMT_MODE_SMALL)); + /// Creates a new JSONRowFormatter. + + ~JSONRowFormatter(); + /// Destroys the JSONRowFormatter. + + std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames); + /// Formats names. + + std::string& formatValues(const ValueVec& vals, std::string& formattedValues); + // Formats values. + + void setJSONMode(int mode); + /// Sets the mode. Valid mode values are: + /// JSON_FMT_MODE_SMALL + /// JSON_FMT_MODE_ROW_COUNT + /// JSON_FMT_MODE_COLUMN_NAMES + /// JSON_FMT_MODE_FULL + + bool printRowCount() const; + /// Returns true if row count printing is enabled, + /// false otherwise. + + bool printColumnNames() const; + /// Returns true if column names printing is enabled, + /// false otherwise. + + bool isSmall() const; + /// Returns true if compact mode formatting is enabled, + /// false otherwise. + + bool isFull() const; + /// Returns true if full mode formatting is enabled, + /// false otherwise. + + +private: + void adjustPrefix() const; + + NameVecPtr _pNames; + int _mode; + bool _firstTime; +}; + + +// +// inlines +// + + +inline bool JSONRowFormatter::printRowCount() const +{ + return (_mode & JSON_FMT_MODE_ROW_COUNT) != 0; +} + + +inline bool JSONRowFormatter::printColumnNames() const +{ + return (_mode & JSON_FMT_MODE_COLUMN_NAMES) != 0; +} + + +inline bool JSONRowFormatter::isSmall() const +{ + return (_mode & JSON_FMT_MODE_SMALL) != 0; +} + + +inline bool JSONRowFormatter::isFull() const +{ + return (_mode & JSON_FMT_MODE_FULL) != 0; +} + + +} } // namespace Poco::Data + + +#endif // Data_JSONRowFormatter_INCLUDED diff --git a/Data/include/Poco/Data/LOB.h b/Data/include/Poco/Data/LOB.h index 3ca80463d..61b4b1a82 100644 --- a/Data/include/Poco/Data/LOB.h +++ b/Data/include/Poco/Data/LOB.h @@ -109,7 +109,7 @@ public: return *_pContent != *other._pContent; } - void swap(LOB& other) + void swap(LOB& other) noexcept /// Swaps the LOB with another one. { using std::swap; @@ -221,14 +221,14 @@ private: using BLOB = LOB; using CLOB = LOB; - +using JSON = std::string; // // inlines // template -inline void swap(LOB& b1, LOB& b2) +inline void swap(LOB& b1, LOB& b2) noexcept { b1.swap(b2); } diff --git a/Data/include/Poco/Data/LOBStream.h b/Data/include/Poco/Data/LOBStream.h index b3cbc5c34..a5f9ef701 100644 --- a/Data/include/Poco/Data/LOBStream.h +++ b/Data/include/Poco/Data/LOBStream.h @@ -33,7 +33,7 @@ template class LOBStreamBuf: public BasicUnbufferedStreamBuf> /// This is the streambuf class used for reading from and writing to a LOB. { -public: +public: LOBStreamBuf(LOB& lob): _lob(lob), _it(_lob.begin()) /// Creates LOBStreamBuf. { diff --git a/Data/include/Poco/Data/Limit.h b/Data/include/Poco/Data/Limit.h index 73bccf90b..80dcdc27c 100644 --- a/Data/include/Poco/Data/Limit.h +++ b/Data/include/Poco/Data/Limit.h @@ -35,9 +35,9 @@ public: { LIMIT_UNLIMITED = ~((SizeT) 0) }; - + Limit(SizeT value, bool hardLimit = false, bool isLowerLimit = false); - /// Creates the Limit. + /// Creates the Limit. /// /// Value contains the upper row hint, if hardLimit is set to true, the limit acts as a hard /// border, ie. every query must return exactly value rows, returning more than value objects will throw an exception! diff --git a/Data/include/Poco/Data/MetaColumn.h b/Data/include/Poco/Data/MetaColumn.h index 2952ed83d..99a1b0db1 100644 --- a/Data/include/Poco/Data/MetaColumn.h +++ b/Data/include/Poco/Data/MetaColumn.h @@ -51,6 +51,7 @@ public: FDT_TIME, FDT_TIMESTAMP, FDT_UUID, + FDT_JSON, FDT_UNKNOWN }; @@ -77,7 +78,7 @@ public: MetaColumn& operator = (MetaColumn&& other) noexcept; /// Assignment operator. - void swap(MetaColumn& other); + void swap(MetaColumn& other) noexcept; /// Swaps the contents with another instance. ~MetaColumn(); diff --git a/Data/include/Poco/Data/PooledSessionHolder.h b/Data/include/Poco/Data/PooledSessionHolder.h index 8924589fb..fbf2b70e3 100644 --- a/Data/include/Poco/Data/PooledSessionHolder.h +++ b/Data/include/Poco/Data/PooledSessionHolder.h @@ -80,7 +80,7 @@ inline SessionPool& PooledSessionHolder::owner() inline void PooledSessionHolder::access() { Poco::FastMutex::ScopedLock lock(_mutex); - + _lastUsed.update(); } diff --git a/Data/include/Poco/Data/PooledSessionImpl.h b/Data/include/Poco/Data/PooledSessionImpl.h index 90d234633..0d5edf578 100644 --- a/Data/include/Poco/Data/PooledSessionImpl.h +++ b/Data/include/Poco/Data/PooledSessionImpl.h @@ -62,11 +62,11 @@ public: bool hasTransactionIsolation(Poco::UInt32) const; bool isTransactionIsolation(Poco::UInt32) const; const std::string& connectorName() const; - void setFeature(const std::string& name, bool state); + void setFeature(const std::string& name, bool state); bool getFeature(const std::string& name); void setProperty(const std::string& name, const Poco::Any& value); Poco::Any getProperty(const std::string& name); - + protected: SessionImpl* access() const; /// Updates the last access timestamp, @@ -75,11 +75,11 @@ protected: /// /// Throws an SessionUnavailableException if the /// session is no longer valid. - + SessionImpl* impl() const; /// Returns a pointer to the SessionImpl. - -private: + +private: mutable Poco::AutoPtr _pHolder; }; diff --git a/Data/include/Poco/Data/Position.h b/Data/include/Poco/Data/Position.h index 727d27b74..19ba55543 100644 --- a/Data/include/Poco/Data/Position.h +++ b/Data/include/Poco/Data/Position.h @@ -38,7 +38,7 @@ public: Poco::UInt32 value() const; /// Returns the position value. - + private: Position(); @@ -49,9 +49,9 @@ private: /// /// inlines /// -inline Poco::UInt32 Position::value() const -{ - return _value; +inline Poco::UInt32 Position::value() const +{ + return _value; } diff --git a/Data/include/Poco/Data/Preparation.h b/Data/include/Poco/Data/Preparation.h index 6515063d9..870dfdcf2 100644 --- a/Data/include/Poco/Data/Preparation.h +++ b/Data/include/Poco/Data/Preparation.h @@ -34,9 +34,9 @@ class Preparation: public AbstractPreparation /// Class for calling the appropriate AbstractPreparator method. { public: - Preparation(AbstractPreparator::Ptr& pPreparator, std::size_t pos, T& val): - AbstractPreparation(pPreparator), - _pos(pos), + Preparation(AbstractPreparator::Ptr& pPreparator, std::size_t pos, T& val): + AbstractPreparation(pPreparator), + _pos(pos), _val(val) /// Creates the Preparation. { @@ -66,9 +66,9 @@ class Preparation>: public AbstractPreparation /// the whole vector preparation, rather than only individual contained values. { public: - Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::vector& val = std::vector()): - AbstractPreparation(pPreparator), - _pos(pos), + Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::vector& val = std::vector()): + AbstractPreparation(pPreparator), + _pos(pos), _val(val) /// Creates the Preparation. { @@ -98,9 +98,9 @@ class Preparation>: public AbstractPreparation /// the whole deque preparation, rather than only individual contained values. { public: - Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::deque& val = std::deque()): - AbstractPreparation(pPreparator), - _pos(pos), + Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::deque& val = std::deque()): + AbstractPreparation(pPreparator), + _pos(pos), _val(val) /// Creates the Preparation. { @@ -130,9 +130,9 @@ class Preparation>: public AbstractPreparation /// the whole list preparation, rather than only individual contained values. { public: - Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::list& val = std::list()): - AbstractPreparation(pPreparator), - _pos(pos), + Preparation(AbstractPreparator::Ptr pPreparator, std::size_t pos, std::list& val = std::list()): + AbstractPreparation(pPreparator), + _pos(pos), _val(val) /// Creates the Preparation. { diff --git a/Data/include/Poco/Data/Range.h b/Data/include/Poco/Data/Range.h index 8f0ab042e..08222a43c 100644 --- a/Data/include/Poco/Data/Range.h +++ b/Data/include/Poco/Data/Range.h @@ -66,7 +66,7 @@ inline const Limit& Range::upper() const namespace Keywords { -template +template Limit limit(T lim, bool hard = false) /// Creates an upperLimit { @@ -74,21 +74,21 @@ Limit limit(T lim, bool hard = false) } -template +template Limit upperLimit(T lim, bool hard = false) { return limit(lim, hard); } -template +template Limit lowerLimit(T lim) { return Limit(static_cast(lim), true, true); } -template +template Range range(T low, T upp, bool hard = false) { return Range(static_cast(low), static_cast(upp), hard); diff --git a/Data/include/Poco/Data/RecordSet.h b/Data/include/Poco/Data/RecordSet.h index d3733cfe2..603ed52da 100644 --- a/Data/include/Poco/Data/RecordSet.h +++ b/Data/include/Poco/Data/RecordSet.h @@ -44,7 +44,7 @@ class RowFilter; class Data_API RecordSet: private Statement /// RecordSet provides access to data returned from a query. /// Data access indices (row and column) are 0-based, as usual in C++. - /// + /// /// Recordset provides navigation methods to iterate through the /// recordset, retrieval methods to extract data, and methods /// to get metadata (type, etc.) about columns. @@ -64,7 +64,7 @@ class Data_API RecordSet: private Statement /// The third (optional) argument passed to the Recordset constructor is a RowFormatter /// implementation. The formatter is used in conjunction with << operator for recordset /// data formating. - /// + /// /// The number of rows in the RecordSet can be limited by specifying /// a limit for the Statement. { @@ -82,18 +82,18 @@ public: RowFormatter::Ptr pRowFormatter = 0); /// Creates the RecordSet. - RecordSet(Session& rSession, + RecordSet(Session& rSession, const std::string& query, RowFormatter::Ptr pRowFormatter = 0); /// Creates the RecordSet. - RecordSet(Session& rSession, + RecordSet(Session& rSession, const std::string& query, const RowFormatter& rowFormatter); /// Creates the RecordSet. template - RecordSet(Session& rSession, const std::string& query, const RF& rowFormatter): + RecordSet(Session& rSession, const std::string& query, const RF& rowFormatter): Statement((rSession << query, Keywords::now)), _currentRow(0), _pBegin(new RowIterator(this, 0 == rowsExtracted())), @@ -145,7 +145,7 @@ public: std::size_t getTotalRowCount() const; /// Returns the total number of rows in the RecordSet. /// The number of rows reported is independent of filtering. - /// If the total row count has not been set externally + /// If the total row count has not been set externally /// (either explicitly or implicitly through SQL), the value /// returned shall only be accurate if the statement limit /// is less or equal to the total row count. @@ -274,7 +274,7 @@ public: else return value(name, _currentRow); } - + template Poco::Dynamic::Var nvl(std::size_t index, const T& deflt = T()) const /// Returns the value in the given column of the current row @@ -378,11 +378,11 @@ public: void formatNames() const; /// Formats names using the current RowFormatter. - std::ostream& copyValues(std::ostream& os, - std::size_t offset = 0, + std::ostream& copyValues(std::ostream& os, + std::size_t offset = 0, std::size_t length = RowIterator::POSITION_END) const; /// Copies the data values to the supplied output stream. - /// The data set to be copied is starting at the specified offset + /// The data set to be copied is starting at the specified offset /// from the recordset beginning. The number of rows to be copied /// is specified by length argument. /// An invalid combination of offset/length arguments shall @@ -391,7 +391,7 @@ public: void formatValues(std::size_t offset, std::size_t length) const; /// Formats values using the current RowFormatter. - /// The data set to be formatted is starting at the specified offset + /// The data set to be formatted is starting at the specified offset /// from the recordset beginning. The number of rows to be copied /// is specified by length argument. /// An invalid combination of offset/length arguments shall @@ -421,7 +421,7 @@ private: const AbstractExtractionVec& rExtractions = extractions(); AbstractExtractionVec::const_iterator it = rExtractions.begin(); AbstractExtractionVec::const_iterator end = rExtractions.end(); - + for (; it != end; ++it) { ExtractionVecPtr pExtraction = dynamic_cast(it->get()); @@ -467,9 +467,9 @@ private: { return pExtraction->column(); } - else + else { - throw Poco::BadCastException(Poco::format("Type cast failed!\nColumn: %z\nTarget type:\t%s", + throw Poco::BadCastException(Poco::format("Type cast failed!\nColumn: %z\nTarget type:\t%s", pos, std::string(typeid(T).name()))); } diff --git a/Data/include/Poco/Data/Row.h b/Data/include/Poco/Data/Row.h index 110be6f0d..089d9ae87 100644 --- a/Data/include/Poco/Data/Row.h +++ b/Data/include/Poco/Data/Row.h @@ -41,12 +41,12 @@ class Data_API Row /// Rows are sortable. The sortability is maintained at all times (i.e. there /// is always at least one column specified as a sorting criteria) . /// The default and minimal sorting criteria is the first field (position 0). - /// The default sorting criteria can be replaced with any other field by + /// The default sorting criteria can be replaced with any other field by /// calling replaceSortField() member function. /// Additional fields can be added to sorting criteria, in which case the /// field precedence corresponds to addition order (i.e. later added fields /// have lower sorting precedence). - /// These features make Row suitable for use with standard sorted + /// These features make Row suitable for use with standard sorted /// containers and algorithms. The main constraint is that all the rows from /// a set that is being sorted must have the same sorting criteria (i.e., the same /// set of fields must be in sorting criteria in the same order). Since rows don't @@ -73,7 +73,7 @@ public: using SortMap = std::vector; /// The type for map holding fields used for sorting criteria. /// Fields are added sequentially and have precedence that - /// corresponds to field adding sequence order (rather than field's + /// corresponds to field adding sequence order (rather than field's /// position in the row). /// This requirement rules out use of std::map due to its sorted nature. using SortMapPtr = SharedPtr; @@ -111,7 +111,7 @@ public: _pNames->push_back(name); if (1 == _values.size()) addSortField(0); } - + template void set(std::size_t pos, const T& val) /// Assigns the value to the row. diff --git a/Data/include/Poco/Data/RowFilter.h b/Data/include/Poco/Data/RowFilter.h index 37d2c903d..4bec4c49e 100644 --- a/Data/include/Poco/Data/RowFilter.h +++ b/Data/include/Poco/Data/RowFilter.h @@ -167,7 +167,7 @@ private: RecordSet& recordSet() const; Comparison getComparison(const std::string& comp) const; - + void rewindRecordSet(); Comparisons _comparisons; diff --git a/Data/include/Poco/Data/RowFormatter.h b/Data/include/Poco/Data/RowFormatter.h index a56fe6646..e916d4f92 100644 --- a/Data/include/Poco/Data/RowFormatter.h +++ b/Data/include/Poco/Data/RowFormatter.h @@ -50,8 +50,8 @@ class Data_API RowFormatter /// it with rows through RecordSet. /// /// To accomodate for various formatting needs, a formatter can operate in two modes: - /// - /// - progressive: formatted individual row strings are gemerated and returned from each + /// + /// - progressive: formatted individual row strings are gemerated and returned from each /// call to formatValues; /// std::string& formatNames(const NameVecPtr, std::string&) and /// std::string& formatValues(const ValueVec&, std::string&) member calls should be @@ -106,7 +106,7 @@ public: /// The default implementation does nothing. virtual const std::string& toString(); - /// Throws NotImplementedException. Formatters operating in bulk mode should + /// Throws NotImplementedException. Formatters operating in bulk mode should /// implement this member function to return valid pointer to the formatted result. virtual int rowCount() const; @@ -139,7 +139,12 @@ public: protected: - void setPrefix(const std::string& prefix); + virtual void adjustPrefix() const; + /// Adjusts the prefix, if needed + /// (eg. to contain the total row count); + /// default no-op. + + void setPrefix(const std::string& prefix) const; /// Sets the prefix for the formatter. void setPostfix(const std::string& postfix); @@ -175,7 +180,7 @@ inline void RowFormatter::setTotalRowCount(int count) } -inline void RowFormatter::setPrefix(const std::string& prefix) +inline void RowFormatter::setPrefix(const std::string& prefix) const { _prefix = prefix; } @@ -189,6 +194,7 @@ inline void RowFormatter::setPostfix(const std::string& postfix) inline const std::string& RowFormatter::prefix() const { + adjustPrefix(); return _prefix; } diff --git a/Data/include/Poco/Data/RowIterator.h b/Data/include/Poco/Data/RowIterator.h index 88fe51d96..e1e32cb49 100644 --- a/Data/include/Poco/Data/RowIterator.h +++ b/Data/include/Poco/Data/RowIterator.h @@ -98,7 +98,7 @@ public: /// Returns a copy the RowIterator backed by diff positions. /// Throws RangeException if diff is larger than current position. - void swap(RowIterator& other); + void swap(RowIterator& other) noexcept; /// Swaps the RowIterator with another one. private: diff --git a/Data/include/Poco/Data/SessionFactory.h b/Data/include/Poco/Data/SessionFactory.h index 0185a8a38..3753cf3e1 100644 --- a/Data/include/Poco/Data/SessionFactory.h +++ b/Data/include/Poco/Data/SessionFactory.h @@ -32,16 +32,16 @@ namespace Data { class Data_API SessionFactory - /// A SessionFactory is a singleton class that stores Connectors and allows to + /// A SessionFactory is a singleton class that stores Connectors and allows to /// create Sessions of the required type: - /// + /// /// Session ses(SessionFactory::instance().create(connector, connectionString)); - /// + /// /// where the first param presents the type of session one wants to create (e.g. for SQLite one would choose "SQLite") /// and the second param is the connection string that the connector requires to connect to the database. /// /// A concrete example to open an SQLite database stored in the file "dummy.db" would be - /// + /// /// Session ses(SessionFactory::instance().create(SQLite::Connector::KEY, "dummy.db")); /// /// An even simpler way to create a session is to use the two argument constructor of Session, which @@ -50,7 +50,7 @@ class Data_API SessionFactory /// Session ses("SQLite", "dummy.db"); { public: - + static SessionFactory& instance(); /// returns the static instance of the singleton. @@ -71,7 +71,7 @@ public: Session create(const std::string& uri, std::size_t timeout = Session::LOGIN_TIMEOUT_DEFAULT); - /// Creates a Session for the given URI (must be in key:///connectionString format). + /// Creates a Session for the given URI (must be in key:///connectionString format). /// Throws a Poco:Data::UnknownDataBaseException if no Connector is registered for the key. private: @@ -86,7 +86,7 @@ private: Poco::SharedPtr ptrSI; SessionInfo(Connector* pSI); }; - + typedef std::map Connectors; Connectors _connectors; Poco::FastMutex _mutex; diff --git a/Data/include/Poco/Data/SessionPool.h b/Data/include/Poco/Data/SessionPool.h index 6994c331e..0c801c44b 100644 --- a/Data/include/Poco/Data/SessionPool.h +++ b/Data/include/Poco/Data/SessionPool.h @@ -40,7 +40,7 @@ class Data_API SessionPool: public RefCountedObject /// operation. Therefore it makes sense to reuse a session object /// once it is no longer needed. /// - /// A SessionPool manages a collection of SessionImpl objects + /// A SessionPool manages a collection of SessionImpl objects /// (decorated with a PooledSessionImpl). /// /// When a SessionImpl object is requested, the SessionPool first @@ -52,7 +52,7 @@ class Data_API SessionPool: public RefCountedObject /// can be set on the maximum number of objects. /// Sessions found not to be connected to the database are purged /// from the pool whenever one of the following events occurs: - /// + /// /// - JanitorTimer event /// - get() request /// - putBack() request @@ -67,11 +67,12 @@ class Data_API SessionPool: public RefCountedObject /// ... { public: - SessionPool(const std::string& connector, - const std::string& connectionString, - int minSessions = 1, - int maxSessions = 32, - int idleTime = 60); + SessionPool(const std::string& connector, + const std::string& connectionString, + int minSessions = 1, + int maxSessions = 32, + int idleTime = 60, + int connTimeout = 60); /// Creates the SessionPool for sessions with the given connector /// and connectionString. /// @@ -81,23 +82,23 @@ public: ~SessionPool(); /// Destroys the SessionPool. - + Session get(); /// Returns a Session. /// /// If there are unused sessions available, one of the /// unused sessions is recycled. Otherwise, a new session - /// is created. + /// is created. /// /// If the maximum number of sessions for this pool has /// already been created, a SessionPoolExhaustedException /// is thrown. - + template Session get(const std::string& name, const T& value) /// Returns a Session with requested property set. /// The property can be different from the default pool - /// value, in which case it is reset back to the pool + /// value, in which case it is reset back to the pool /// value when the session is reclaimed by the pool. { Session s = get(); @@ -111,24 +112,27 @@ public: Session get(const std::string& name, bool value); /// Returns a Session with requested feature set. /// The feature can be different from the default pool - /// value, in which case it is reset back to the pool + /// value, in which case it is reset back to the pool /// value when the session is reclaimed by the pool. int capacity() const; /// Returns the maximum number of sessions the SessionPool will manage. - + int used() const; /// Returns the number of sessions currently in use. - + int idle() const; /// Returns the number of idle sessions. - + + int connTimeout() const; + /// Returns the connection timeout. + int dead(); /// Returns the number of not connected active sessions. int allocated() const; /// Returns the number of allocated sessions. - + int available() const; /// Returns the number of available (idle + remaining capacity) sessions. @@ -177,14 +181,14 @@ protected: void onJanitorTimer(Poco::Timer&); private: - typedef std::pair PropertyPair; - typedef std::pair FeaturePair; + typedef std::pair PropertyPair; + typedef std::pair FeaturePair; typedef std::map AddPropertyMap; typedef std::map AddFeatureMap; SessionPool(const SessionPool&); SessionPool& operator = (const SessionPool&); - + void closeAll(SessionList& sessionList); std::string _connector; @@ -192,6 +196,7 @@ private: int _minSessions; int _maxSessions; int _idleTime; + int _connTimeout; int _nSessions; SessionList _idleSessions; SessionList _activeSessions; @@ -203,7 +208,7 @@ private: AddFeatureMap _addFeatureMap; mutable Poco::Mutex _mutex; - + friend class PooledSessionImpl; }; diff --git a/Data/include/Poco/Data/SessionPoolContainer.h b/Data/include/Poco/Data/SessionPoolContainer.h index 15c3e83b9..a1479b180 100644 --- a/Data/include/Poco/Data/SessionPoolContainer.h +++ b/Data/include/Poco/Data/SessionPoolContainer.h @@ -38,15 +38,15 @@ public: ~SessionPoolContainer(); /// Destroys the SessionPoolContainer. - + void add(SessionPool* pPool); /// Adds existing session pool to the container. /// Throws SessionPoolExistsException if pool already exists. - Session add(const std::string& sessionKey, + Session add(const std::string& sessionKey, const std::string& connectionString, - int minSessions = 1, - int maxSessions = 32, + int minSessions = 1, + int maxSessions = 32, int idleTime = 60); /// Adds a new session pool to the container and returns a Session from /// newly created pool. If pool already exists, request to add is silently @@ -58,7 +58,7 @@ public: bool isActive(const std::string& sessionKey, const std::string& connectionString = "") const; /// Returns true if the session is active (i.e. not shut down). - /// If connectionString is empty string, sessionKey must be a + /// If connectionString is empty string, sessionKey must be a /// fully qualified session name as registered with the pool /// container. @@ -72,7 +72,7 @@ public: void remove(const std::string& name); /// Removes a SessionPool. - + int count() const; /// Returns the number of session pols in the container. @@ -84,7 +84,7 @@ private: SessionPoolContainer(const SessionPoolContainer&); SessionPoolContainer& operator = (const SessionPoolContainer&); - + SessionPoolMap _sessionPools; Poco::FastMutex _mutex; }; diff --git a/Data/include/Poco/Data/SimpleRowFormatter.h b/Data/include/Poco/Data/SimpleRowFormatter.h index 67d82c6a8..0dcb43b0b 100644 --- a/Data/include/Poco/Data/SimpleRowFormatter.h +++ b/Data/include/Poco/Data/SimpleRowFormatter.h @@ -49,7 +49,7 @@ public: ~SimpleRowFormatter(); /// Destroys the SimpleRowFormatter. - void swap(SimpleRowFormatter& other); + void swap(SimpleRowFormatter& other) noexcept; /// Swaps the row formatter with another one. std::string& formatNames(const NameVecPtr pNames, std::string& formattedNames); @@ -66,7 +66,7 @@ public: std::streamsize getColumnWidth() const; /// Returns the column width. - + std::streamsize getSpacing() const; /// Returns the spacing. @@ -109,9 +109,13 @@ inline std::streamsize SimpleRowFormatter::getSpacing() const namespace std { + // Note: for an unknown reason, clang refuses to compile this function as noexcept template<> - inline void swap(Poco::Data::SimpleRowFormatter& s1, + inline void swap(Poco::Data::SimpleRowFormatter& s1, Poco::Data::SimpleRowFormatter& s2) +#ifndef POCO_COMPILER_CLANG + noexcept +#endif /// Full template specalization of std:::swap for SimpleRowFormatter { s1.swap(s2); diff --git a/Data/include/Poco/Data/Statement.h b/Data/include/Poco/Data/Statement.h index 610eead67..c3f30cce3 100644 --- a/Data/include/Poco/Data/Statement.h +++ b/Data/include/Poco/Data/Statement.h @@ -78,6 +78,7 @@ public: using ResultPtr = SharedPtr; using AsyncExecMethod = ActiveMethod; using AsyncExecMethodPtr = SharedPtr; + using State = StatementImpl::State; static const int WAIT_FOREVER = -1; @@ -124,7 +125,7 @@ public: Statement& operator = (Statement&& stmt) noexcept; /// Move assignment. - void swap(Statement& other); + void swap(Statement& other) noexcept; /// Swaps the statement with another one. template @@ -385,6 +386,9 @@ public: /// Sets the row formatter for this statement. /// Statement takes the ownership of the formatter. + State state() const; + /// Returns the statement state. + protected: using ImplPtr = StatementImpl::Ptr; @@ -791,6 +795,12 @@ inline bool Statement::isAsync() const } +inline Statement::State Statement::state() const +{ + return _pImpl->getState(); +} + + inline void Statement::setRowFormatter(RowFormatter::Ptr pRowFormatter) { _pRowFormatter = pRowFormatter; @@ -804,7 +814,7 @@ inline const RowFormatter::Ptr& Statement::getRowFormatter() } -inline void swap(Statement& s1, Statement& s2) +inline void swap(Statement& s1, Statement& s2) noexcept { s1.swap(s2); } diff --git a/Data/include/Poco/Data/StatementCreator.h b/Data/include/Poco/Data/StatementCreator.h index 635de7e1d..23ca43032 100644 --- a/Data/include/Poco/Data/StatementCreator.h +++ b/Data/include/Poco/Data/StatementCreator.h @@ -34,7 +34,7 @@ class Data_API StatementCreator public: StatementCreator(); /// Creates an unitialized StatementCreator. - + StatementCreator(Poco::AutoPtr ptrImpl); /// Creates a StatementCreator. @@ -52,10 +52,10 @@ public: StatementCreator& operator = (StatementCreator&& other) noexcept; /// Assignment operator. - - void swap(StatementCreator& other); - /// Swaps the StatementCreator with another one. - + + void swap(StatementCreator& other) noexcept; + /// Swaps the StatementCreator with another one. + template Statement operator << (const T& t) /// Creates a Statement. diff --git a/Data/include/Poco/Data/StatementImpl.h b/Data/include/Poco/Data/StatementImpl.h index 58e1d2d1f..fc2c9ffb9 100644 --- a/Data/include/Poco/Data/StatementImpl.h +++ b/Data/include/Poco/Data/StatementImpl.h @@ -432,7 +432,7 @@ private: using CountVec = std::vector; - State _state; + std::atomic _state; Limit _extrLimit; std::size_t _lowerLimit; std::vector _columnsExtracted; diff --git a/Data/include/Poco/Data/Time.h b/Data/include/Poco/Data/Time.h index 07116906b..80619a595 100644 --- a/Data/include/Poco/Data/Time.h +++ b/Data/include/Poco/Data/Time.h @@ -174,7 +174,7 @@ public: ~VarHolderImpl() { } - + const std::type_info& type() const { return typeid(Poco::Data::Time); @@ -211,7 +211,7 @@ public: { return cloneHolder(pVarHolder, _val); } - + const Poco::Data::Time& value() const { return _val; diff --git a/Data/include/Poco/Data/Transaction.h b/Data/include/Poco/Data/Transaction.h index a8fdc4699..caf3e7f85 100644 --- a/Data/include/Poco/Data/Transaction.h +++ b/Data/include/Poco/Data/Transaction.h @@ -44,22 +44,22 @@ public: /// Creates the Transaction, using the given database session. /// If start is true, transaction is started, otherwise begin() must be called /// to start the transaction. - + template - Transaction(Poco::Data::Session& rSession, T& t, Poco::Logger* pLogger = 0): + Transaction(Poco::Data::Session& rSession, T& t, Poco::Logger* pLogger = 0): _rSession(rSession), _pLogger(pLogger) /// Creates the Transaction, using the given database session, transactor and logger. - /// The transactor type must provide operator () overload taking non-const Session + /// The transactor type must provide operator () overload taking non-const Session /// reference as an argument. /// /// When transaction is created using this constructor, it is executed and /// commited automatically. If no error occurs, rollback is disabled and does /// not occur at destruction time. If an error occurs resulting in exception being /// thrown, the transaction is rolled back and exception propagated to calling code. - /// + /// /// Example usage: - /// + /// /// struct Transactor /// { /// void operator () (Session& session) const @@ -67,9 +67,9 @@ public: /// // do something ... /// } /// }; - /// + /// /// Transactor tr; - /// Transaction tn(session, tr); + /// Transaction tn(session, tr); { try { transact(t); } catch (...) @@ -86,7 +86,7 @@ public: /// (by calling commit()), or rolled back (by calling rollback()). /// /// If an exception is thrown during rollback, the exception is logged - /// and no further action is taken. + /// and no further action is taken. void setIsolation(Poco::UInt32 ti); /// Sets the transaction isolation level. @@ -116,7 +116,7 @@ public: template void transact(T& t) - /// Executes the transactor and, unless transactor throws an exception, + /// Executes the transactor and, unless transactor throws an exception, /// commits the transaction. { if (!isActive()) begin(); @@ -126,10 +126,10 @@ public: void commit(); /// Commits the current transaction. - + void rollback(); /// Rolls back the current transaction. - + bool isActive(); /// Returns false after the transaction has been committed or rolled back, /// true if the transaction is ongoing. @@ -142,7 +142,7 @@ private: Transaction(); Transaction(const Transaction&); Transaction& operator = (const Transaction&); - + void begin(); /// Begins the transaction if the session is already not in transaction. /// Otherwise does nothing. diff --git a/Data/include/Poco/Data/Transcoder.h b/Data/include/Poco/Data/Transcoder.h new file mode 100644 index 000000000..c9d5211ed --- /dev/null +++ b/Data/include/Poco/Data/Transcoder.h @@ -0,0 +1,97 @@ +// +// Transcoder.h +// +// Library: Data +// Package: DataCore +// Module: Transcoder +// +// Definition of the Transcoder class. +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#ifndef Data_Transcoder_INCLUDED +#define Data_Transcoder_INCLUDED + + +#include "Poco/Data/Data.h" +#include "Poco/TextConverter.h" +#include "Poco/TextEncoding.h" +#include +#include + + +namespace Poco { +namespace Data { + + +class Data_API Transcoder + /// Utility class used to convert string data encoding. + /// + /// The purpose of this class is to help with deciding + /// whether conversion is actually required, and to keep + /// the encodings lifetimes aligned with the converter lifetime. +{ +public: + using Ptr = std::unique_ptr; + using ConverterPtr = std::unique_ptr; + + virtual ~Transcoder(); + /// Destroys the Transcoder. + + static Ptr create(Poco::TextEncoding::Ptr pFromEncoding = nullptr, + Poco::TextEncoding::Ptr pToEncoding = nullptr); + /// Returns a unique pointer to Transcode instance; + /// if there is no need for transcoding, null pointer + /// is returned. + + std::string fromEncoding() const; + /// Returns "from" encoding canonical name. + + std::string toEncoding() const; + /// Returns "from" encoding canonical name. + + void transcode(const std::string& from, std::string& to); + /// Performs the conversion. Any prior content of the + /// destination string is cleared. + + void reverseTranscode(const std::string& from, std::string& to); + /// Performs the reverse conversion. Any prior content of the + /// destination string is cleared. + +private: + Transcoder(Poco::TextEncoding::Ptr pFromEncoding, + Poco::TextEncoding::Ptr pToEncoding); + /// Creates the Transcoder. + + Poco::TextEncoding::Ptr _pFromEncoding; + Poco::TextEncoding::Ptr _pToEncoding; + ConverterPtr _pConverter; + ConverterPtr _pReverseConverter; +}; + + +// +// inlines +// + +inline std::string Transcoder::fromEncoding() const +{ + return _pFromEncoding->canonicalName(); +} + + +inline std::string Transcoder::toEncoding() const +{ + return _pToEncoding->canonicalName(); +} + + +} } // namespace Poco::Data + + +#endif // Data_Transcoder_INCLUDED diff --git a/Data/include/Poco/Data/TypeHandler.h b/Data/include/Poco/Data/TypeHandler.h index 85684666e..235cbbb26 100644 --- a/Data/include/Poco/Data/TypeHandler.h +++ b/Data/include/Poco/Data/TypeHandler.h @@ -79,18 +79,18 @@ class TypeHandler: public AbstractTypeHandler /// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3)) /// // Note that we advance pos by the number of columns the datatype uses! For string/int this is one. /// poco_assert_dbg (!pBinder.isNull()); - /// TypeHandler::bind(pos++, obj.getLastName(), pBinder, dir); - /// TypeHandler::bind(pos++, obj.getFirstName(), pBinder, dir); - /// TypeHandler::bind(pos++, obj.getAge(), pBinder, dir); + /// TypeHandler::bind(pos++, obj.getLastName(), pBinder, dir); + /// TypeHandler::bind(pos++, obj.getFirstName(), pBinder, dir); + /// TypeHandler::bind(pos++, obj.getAge(), pBinder, dir); /// } /// /// static void prepare(std::size_t pos, const Person& obj, AbstractPreparator::Ptr pPreparator) /// { /// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3)) /// poco_assert_dbg (!pPreparator.isNull()); - /// TypeHandler::prepare(pos++, obj.getLastName(), pPreparator); - /// TypeHandler::prepare(pos++, obj.getFirstName(), pPreparator); - /// TypeHandler::prepare(pos++, obj.getAge(), pPreparator); + /// TypeHandler::prepare(pos++, obj.getLastName(), pPreparator); + /// TypeHandler::prepare(pos++, obj.getFirstName(), pPreparator); + /// TypeHandler::prepare(pos++, obj.getAge(), pPreparator); /// } /// /// static void extract(std::size_t pos, Person& obj, const Person& defVal, AbstractExtractor::Ptr pExt) @@ -102,9 +102,9 @@ class TypeHandler: public AbstractTypeHandler /// std::string firstName; /// int age = 0; /// // the table is defined as Person (LastName VARCHAR(30), FirstName VARCHAR, Age INTEGER(3)) - /// TypeHandler::extract(pos++, lastName, defVal.getLastName(), pExt); - /// TypeHandler::extract(pos++, firstName, defVal.getFirstName(), pExt); - /// TypeHandler::extract(pos++, age, defVal.getAge(), pExt); + /// TypeHandler::extract(pos++, lastName, defVal.getLastName(), pExt); + /// TypeHandler::extract(pos++, firstName, defVal.getFirstName(), pExt); + /// TypeHandler::extract(pos++, age, defVal.getAge(), pExt); /// obj.setLastName(lastName); /// obj.setFirstName(firstName); /// obj.setAge(age); @@ -343,6 +343,3670 @@ void tupleExtract(std::size_t& pos, TupleType tuple, DefValType defVal, Abstract } +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + +template +class TypeHandler> +{ + public: + using TupleConstRef = typename Poco::TypeWrapper>::CONSTREFTYPE; + using TupleRef = typename Poco::TypeWrapper>::REFTYPE; + + static void bind(std::size_t pos, TupleConstRef tuple, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) + { + poco_assert_dbg (!pBinder.isNull()); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + tupleBind(pos, tuple, pBinder, dir); + } + + static void prepare(std::size_t pos, TupleConstRef tuple, AbstractPreparator::Ptr pPreparator) + { + poco_assert_dbg (!pPreparator.isNull()); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + tuplePrepare(pos, tuple, pPreparator); + } + + static std::size_t size() + { + return TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); + } + + static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) + { + poco_assert_dbg (!pExt.isNull()); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + tupleExtract(pos, tuple, defVal, pExt); + } + + private: + TypeHandler(const TypeHandler&); + TypeHandler& operator=(const TypeHandler&); +}; + + template ::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -550,24 +4214,24 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -673,23 +4337,23 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -791,22 +4455,22 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -904,21 +4568,21 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1012,20 +4676,20 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1115,19 +4779,19 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1213,18 +4877,18 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1306,17 +4970,17 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1394,16 +5058,16 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1468,15 +5132,15 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1538,14 +5202,14 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1604,13 +5268,13 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1666,12 +5330,12 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1724,11 +5388,11 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1778,10 +5442,10 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1828,9 +5492,9 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1874,8 +5538,8 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size() + + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1916,7 +5580,7 @@ public: static std::size_t size() { return TypeHandler::size() + - TypeHandler::size(); + TypeHandler::size(); } static void extract(std::size_t pos, TupleRef tuple, TupleConstRef defVal, AbstractExtractor::Ptr pExt) @@ -1975,9 +5639,9 @@ class TypeHandler>: public AbstractTypeHandler public: static void bind(std::size_t pos, const std::pair& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) { - TypeHandler::bind(pos, obj.first, pBinder, dir); + TypeHandler::bind(pos, obj.first, pBinder, dir); pos += TypeHandler::size(); - TypeHandler::bind(pos, obj.second, pBinder, dir); + TypeHandler::bind(pos, obj.second, pBinder, dir); } static std::size_t size() @@ -1987,16 +5651,16 @@ public: static void extract(std::size_t pos, std::pair& obj, const std::pair& defVal, AbstractExtractor::Ptr pExt) { - TypeHandler::extract(pos, obj.first, defVal.first, pExt); + TypeHandler::extract(pos, obj.first, defVal.first, pExt); pos += TypeHandler::size(); - TypeHandler::extract(pos, obj.second, defVal.second, pExt); + TypeHandler::extract(pos, obj.second, defVal.second, pExt); } static void prepare(std::size_t pos, const std::pair& obj, AbstractPreparator::Ptr pPreparator) { - TypeHandler::prepare(pos, obj.first, pPreparator); + TypeHandler::prepare(pos, obj.first, pPreparator); pos += TypeHandler::size(); - TypeHandler::prepare(pos, obj.second, pPreparator); + TypeHandler::prepare(pos, obj.second, pPreparator); } private: @@ -2013,7 +5677,7 @@ public: static void bind(std::size_t pos, const Poco::AutoPtr& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) { // *obj will trigger a nullpointer exception if empty: this is on purpose - TypeHandler::bind(pos, *obj, pBinder, dir); + TypeHandler::bind(pos, *obj, pBinder, dir); } static std::size_t size() @@ -2027,15 +5691,15 @@ public: obj = Poco::AutoPtr(new T()); if (defVal) - TypeHandler::extract(pos, *obj, *defVal, pExt); + TypeHandler::extract(pos, *obj, *defVal, pExt); else - TypeHandler::extract(pos, *obj, *obj, pExt); + TypeHandler::extract(pos, *obj, *obj, pExt); } static void prepare(std::size_t pos, const Poco::AutoPtr&, AbstractPreparator::Ptr pPreparator) { poco_assert_dbg (!pPreparator.isNull()); - TypeHandler::prepare(pos, T(), pPreparator); + TypeHandler::prepare(pos, T(), pPreparator); } private: @@ -2053,7 +5717,7 @@ public: static void bind(std::size_t pos, const Poco::SharedPtr& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir) { // *obj will trigger a nullpointer exception if empty - TypeHandler::bind(pos, *obj, pBinder, dir); + TypeHandler::bind(pos, *obj, pBinder, dir); } static std::size_t size() @@ -2067,15 +5731,15 @@ public: obj = Poco::SharedPtr(new T()); if (defVal) - TypeHandler::extract(pos, *obj, *defVal, pExt); + TypeHandler::extract(pos, *obj, *defVal, pExt); else - TypeHandler::extract(pos, *obj, *obj, pExt); + TypeHandler::extract(pos, *obj, *obj, pExt); } static void prepare(std::size_t pos, const Poco::SharedPtr&, AbstractPreparator::Ptr pPreparator) { poco_assert_dbg (!pPreparator.isNull()); - TypeHandler::prepare(pos, T(), pPreparator); + TypeHandler::prepare(pos, T(), pPreparator); } private: diff --git a/Data/samples/Binding/src/Binding.cpp b/Data/samples/Binding/src/Binding.cpp index d80f9bc10..d17d96404 100644 --- a/Data/samples/Binding/src/Binding.cpp +++ b/Data/samples/Binding/src/Binding.cpp @@ -38,32 +38,32 @@ int main(int argc, char** argv) // drop sample table, if it exists session << "DROP TABLE IF EXISTS Person", now; - + // (re)create table session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; - + // insert some rows - Person person = + Person person = { "Bart Simpson", "Springfield", 12 }; - + Statement insert(session); insert << "INSERT INTO Person VALUES(?, ?, ?)", use(person.name), use(person.address), use(person.age); - + insert.execute(); - + person.name = "Lisa Simpson"; person.address = "Springfield"; person.age = 10; - + insert.execute(); - + // a simple query Statement select(session); select << "SELECT Name, Address, Age FROM Person", @@ -71,7 +71,7 @@ int main(int argc, char** argv) into(person.address), into(person.age), range(0, 1); // iterate over result set one row at a time - + while (!select.done()) { select.execute(); @@ -83,7 +83,7 @@ int main(int argc, char** argv) session << "SELECT Name FROM Person", into(names), now; - + for (std::vector::const_iterator it = names.begin(); it != names.end(); ++it) { std::cout << *it << std::endl; diff --git a/Data/samples/CMakeLists.txt b/Data/samples/CMakeLists.txt index 551d453cc..58727cd3c 100644 --- a/Data/samples/CMakeLists.txt +++ b/Data/samples/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory(RecordSet) add_subdirectory(RowFormatter) add_subdirectory(Tuple) add_subdirectory(TypeHandler) +add_subdirectory(WebNotifier) diff --git a/Data/samples/RecordSet/Makefile b/Data/samples/RecordSet/Makefile index e65ba747c..2f6a7b1b5 100644 --- a/Data/samples/RecordSet/Makefile +++ b/Data/samples/RecordSet/Makefile @@ -10,6 +10,6 @@ objects = RecordSet target = RecordSet target_version = 1 -target_libs = PocoDataSQLite PocoData PocoFoundation +target_libs = PocoDataSQLite PocoData PocoFoundation include $(POCO_BASE)/build/rules/exec diff --git a/Data/samples/RecordSet/src/RecordSet.cpp b/Data/samples/RecordSet/src/RecordSet.cpp index f5ac85e75..7d804e4c4 100644 --- a/Data/samples/RecordSet/src/RecordSet.cpp +++ b/Data/samples/RecordSet/src/RecordSet.cpp @@ -36,22 +36,22 @@ int main(int argc, char** argv) // drop sample table, if it exists session << "DROP TABLE IF EXISTS Person", now; - + // (re)create table session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3), Birthday DATE)", now; - + // insert some rows DateTime bd(1980, 4, 1); DateTime ld(1982, 5, 9); session << "INSERT INTO Person VALUES('Bart Simpson', 'Springfield', 12, ?)", use(bd), now; session << "INSERT INTO Person VALUES('Lisa Simpson', 'Springfield', 10, ?)", use(ld), now; - + // a simple query Statement select(session); select << "SELECT * FROM Person"; select.execute(); - // create a RecordSet + // create a RecordSet RecordSet rs(select); std::size_t cols = rs.columnCount(); // print all column names diff --git a/Data/samples/RowFormatter/Makefile b/Data/samples/RowFormatter/Makefile index 9e9306a31..b225bb0b7 100644 --- a/Data/samples/RowFormatter/Makefile +++ b/Data/samples/RowFormatter/Makefile @@ -10,6 +10,6 @@ objects = RowFormatter target = RowFormatter target_version = 1 -target_libs = PocoDataSQLite PocoData PocoFoundation +target_libs = PocoDataSQLite PocoData PocoFoundation include $(POCO_BASE)/build/rules/exec diff --git a/Data/samples/RowFormatter/src/RowFormatter.cpp b/Data/samples/RowFormatter/src/RowFormatter.cpp index 122dbd361..597a0a167 100644 --- a/Data/samples/RowFormatter/src/RowFormatter.cpp +++ b/Data/samples/RowFormatter/src/RowFormatter.cpp @@ -17,6 +17,7 @@ #include "Poco/Data/Statement.h" #include "Poco/Data/RecordSet.h" #include "Poco/Data/RowFormatter.h" +#include "Poco/Data/JSONRowFormatter.h" #include "Poco/Data/SQLite/Connector.h" #include @@ -27,6 +28,7 @@ using Poco::Data::Session; using Poco::Data::Statement; using Poco::Data::RecordSet; using Poco::Data::RowFormatter; +using Poco::Data::JSONRowFormatter; class HTMLTableFormatter : public RowFormatter @@ -37,7 +39,7 @@ public: std::ostringstream os; os << "" << std::endl; setPrefix(os.str()); - + os.str(""); os << "
" << std::endl; setPostfix(os.str()); @@ -65,9 +67,9 @@ public: ValueVec::const_iterator end = vals.end(); for (; it != end; ++it) { - if (it->isNumeric()) + if (it->isNumeric()) str << "\t\t"; - else + else str << "\t\t"; str << it->convert() << "" << std::endl; @@ -83,16 +85,16 @@ int main(int argc, char** argv) { // register SQLite connector Poco::Data::SQLite::Connector::registerConnector(); - + // create a session Session session("SQLite", "sample.db"); // drop sample table, if it exists session << "DROP TABLE IF EXISTS Simpsons", now; - + // (re)create table session << "CREATE TABLE Simpsons (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3), Birthday DATE)", now; - + // insert some rows DateTime hd(1956, 3, 1); session << "INSERT INTO Simpsons VALUES('Homer Simpson', 'Springfield', 42, ?)", use(hd), now; @@ -102,7 +104,7 @@ int main(int argc, char** argv) session << "INSERT INTO Simpsons VALUES('Bart Simpson', 'Springfield', 12, ?)", use(hd), now; hd.assign(1982, 5, 9); session << "INSERT INTO Simpsons VALUES('Lisa Simpson', 'Springfield', 10, ?)", use(hd), now; - + // create a statement and print the column names and data as HTML table HTMLTableFormatter tf; Statement stmt = (session << "SELECT * FROM Simpsons", format(tf), now); @@ -117,5 +119,11 @@ int main(int argc, char** argv) std::cout << std::endl << "Simple formatting:" << std::endl << std::endl; std::cout << RecordSet(session, "SELECT * FROM Simpsons"); + // JSON formatting example (uses the JSONRowFormatter provided by framework) + std::cout << std::endl << "JSON formatting:" << std::endl << std::endl; + JSONRowFormatter jsonRowFormatter; + jsonRowFormatter.setJSONMode((RowFormatter::Mode)(JSONRowFormatter::JSON_FMT_MODE_ROW_COUNT | JSONRowFormatter::JSON_FMT_MODE_COLUMN_NAMES)); + std::cout << RecordSet(session, "SELECT * FROM Simpsons", jsonRowFormatter); + return 0; } diff --git a/Data/samples/Tuple/Makefile b/Data/samples/Tuple/Makefile index c2b921217..4e8f28eb7 100644 --- a/Data/samples/Tuple/Makefile +++ b/Data/samples/Tuple/Makefile @@ -10,6 +10,6 @@ objects = Tuple target = Tuple target_version = 1 -target_libs = PocoDataSQLite PocoData PocoFoundation +target_libs = PocoDataSQLite PocoData PocoFoundation include $(POCO_BASE)/build/rules/exec diff --git a/Data/samples/Tuple/src/Tuple.cpp b/Data/samples/Tuple/src/Tuple.cpp index d269b26b8..dd01566fe 100644 --- a/Data/samples/Tuple/src/Tuple.cpp +++ b/Data/samples/Tuple/src/Tuple.cpp @@ -36,19 +36,19 @@ int main(int argc, char** argv) // drop sample table, if it exists session << "DROP TABLE IF EXISTS Person", now; - + // (re)create table session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3))", now; - + // insert some rows People people; people.push_back(Person("Bart Simpson", "Springfield", 12)); people.push_back(Person("Lisa Simpson", "Springfield", 10)); - + Statement insert(session); insert << "INSERT INTO Person VALUES(:name, :address, :age)", use(people), now; - + people.clear(); // a simple query @@ -56,11 +56,11 @@ int main(int argc, char** argv) select << "SELECT Name, Address, Age FROM Person", into(people), now; - + for (People::const_iterator it = people.begin(); it != people.end(); ++it) { - std::cout << "Name: " << it->get<0>() << - ", Address: " << it->get<1>() << + std::cout << "Name: " << it->get<0>() << + ", Address: " << it->get<1>() << ", Age: " << it->get<2>() <::bind(pos++, person.name, pBinder, dir); @@ -57,7 +57,7 @@ public: TypeHandler::bind(pos++, person.age, pBinder, dir); TypeHandler::bind(pos++, person.birthday, pBinder, dir); } - + static void extract(std::size_t pos, Person& person, const Person& deflt, AbstractExtractor::Ptr pExtr) { TypeHandler::extract(pos++, person.name, deflt.name, pExtr); @@ -65,7 +65,7 @@ public: TypeHandler::extract(pos++, person.age, deflt.age, pExtr); TypeHandler::extract(pos++, person.birthday, deflt.birthday, pExtr); } - + static void prepare(std::size_t pos, const Person& person, AbstractPreparator::Ptr pPrep) { TypeHandler::prepare(pos++, person.name, pPrep); @@ -89,62 +89,62 @@ int main(int argc, char** argv) // drop sample table, if it exists session << "DROP TABLE IF EXISTS Person", now; - + // (re)create table session << "CREATE TABLE Person (Name VARCHAR(30), Address VARCHAR, Age INTEGER(3), Birthday DATE)", now; - + // insert some rows - Person person = + Person person = { "Bart Simpson", "Springfield", 10, DateTime(1980, 4, 1) }; - + Statement insert(session); insert << "INSERT INTO Person VALUES(?, ?, ?, ?)", use(person); - + insert.execute(); - + person.name = "Lisa Simpson"; person.address = "Springfield"; person.age = 8; person.birthday = DateTime(1982, 5, 9); insert.execute(); - + // a simple query Statement select(session); select << "SELECT Name, Address, Age, Birthday FROM Person", into(person), range(0, 1); // iterate over result set one row at a time - + while (!select.done()) { select.execute(); std::cout << person.name << "\t" << person.address << "\t" << person.age << "\t" - << DateTimeFormatter::format(person.birthday, "%b %d %Y") + << DateTimeFormatter::format(person.birthday, "%b %d %Y") << std::endl; } - + // another query - store the result in a container std::vector persons; session << "SELECT Name, Address, Age, Birthday FROM Person", into(persons), now; - + for (std::vector::const_iterator it = persons.begin(); it != persons.end(); ++it) { std::cout << it->name << "\t" << it->address << "\t" << it->age << "\t" - << DateTimeFormatter::format(it->birthday, "%b %d %Y") + << DateTimeFormatter::format(it->birthday, "%b %d %Y") << std::endl; } - + return 0; } diff --git a/Data/samples/WebNotifier/WebNotifier.html b/Data/samples/WebNotifier/WebNotifier.html index 30b94c3dc..c826d3a27 100644 --- a/Data/samples/WebNotifier/WebNotifier.html +++ b/Data/samples/WebNotifier/WebNotifier.html @@ -8,10 +8,10 @@ var div = document.getElementById("output"); div.innerHTML = div.innerHTML + "
" + msg + "
"; } - + function WebSocketOpen() { - if ("WebSocket" in window) + if ("WebSocket" in window) { ws = new WebSocket("ws://localhost:9980/ws"); @@ -20,7 +20,7 @@ ws.send("Hello, world!"); log("WebSocket opened.", "green"); }; - + ws.onmessage = function(evt) { var arr = evt.data.split(","); @@ -32,7 +32,7 @@ else log("Unknown message received: " + evt.data, "red"); }; - + ws.onclose = function() { log("WebSocket closed.", "red"); @@ -43,22 +43,22 @@ log("This browser does not support WebSockets.", "red"); } } - + function WebSocketSend(msg) { ws.send("hello"); } - + function WebSocketClose() { ws.close(); } - + function updateTable(id, name, address, age) { var table = document.getElementById("dataTable"); - - + + if (table.rows.length > 1) { for (r = 1; r < table.rows.length; r++) @@ -72,18 +72,18 @@ } } } - + var row = table.insertRow(table.rows.length); - + var cell1 = row.insertCell(0); cell1.innerHTML = id; - + var cell2 = row.insertCell(1); cell2.innerHTML = name; - + var cell3 = row.insertCell(2); cell3.innerHTML = address; - + var cell4 = row.insertCell(3); cell4.innerHTML = age; } @@ -101,4 +101,4 @@
- \ No newline at end of file + diff --git a/Data/src/AbstractBinder.cpp b/Data/src/AbstractBinder.cpp index f3ac4edcf..d8397ea36 100644 --- a/Data/src/AbstractBinder.cpp +++ b/Data/src/AbstractBinder.cpp @@ -16,6 +16,7 @@ #include "Poco/Data/Date.h" #include "Poco/Data/Time.h" #include "Poco/Data/LOB.h" +#include "Poco/Data/Transcoder.h" #include "Poco/Data/DataException.h" #include "Poco/DateTime.h" #include "Poco/Any.h" @@ -26,7 +27,9 @@ namespace Poco { namespace Data { -AbstractBinder::AbstractBinder() +AbstractBinder::AbstractBinder(Poco::TextEncoding::Ptr pFromEncoding, + Poco::TextEncoding::Ptr pDBEncoding) : + _pTranscoder(Transcoder::create(pFromEncoding, pDBEncoding)) { } @@ -41,6 +44,20 @@ AbstractBinder::~AbstractBinder() } +void AbstractBinder::transcode(const std::string& from, std::string& to) +{ + if (_pTranscoder) + _pTranscoder->transcode(from, to); +} + + +void AbstractBinder::reverseTranscode(const std::string& from, std::string& to) +{ + if (_pTranscoder) + _pTranscoder->reverseTranscode(from, to); +} + + const std::string& AbstractBinder::toString(const UUID& uuid) { if (!_pStrings) _pStrings.reset(new StringList); diff --git a/Data/src/AbstractBinding.cpp b/Data/src/AbstractBinding.cpp index d30ccd1d8..be6fd363d 100644 --- a/Data/src/AbstractBinding.cpp +++ b/Data/src/AbstractBinding.cpp @@ -19,9 +19,9 @@ namespace Poco { namespace Data { -AbstractBinding::AbstractBinding(const std::string& name, - Direction direction, - Poco::UInt32 bulkSize): +AbstractBinding::AbstractBinding(const std::string& name, + Direction direction, + Poco::UInt32 bulkSize): _pBinder(0), _name(name), _direction(direction), diff --git a/Data/src/AbstractExtraction.cpp b/Data/src/AbstractExtraction.cpp index ac3f83927..94b394bdc 100644 --- a/Data/src/AbstractExtraction.cpp +++ b/Data/src/AbstractExtraction.cpp @@ -21,8 +21,8 @@ namespace Data { AbstractExtraction::AbstractExtraction(Poco::UInt32 limit, Poco::UInt32 position, - bool bulk): - _pExtractor(0), + bool bulk): + _pExtractor(0), _limit(limit), _position(position), _bulk(bulk), diff --git a/Data/src/AbstractExtractor.cpp b/Data/src/AbstractExtractor.cpp index b3ae3ae47..02e516f49 100644 --- a/Data/src/AbstractExtractor.cpp +++ b/Data/src/AbstractExtractor.cpp @@ -13,6 +13,7 @@ #include "Poco/Data/AbstractExtractor.h" +#include "Poco/Data/Transcoder.h" #include "Poco/Exception.h" @@ -20,7 +21,9 @@ namespace Poco { namespace Data { -AbstractExtractor::AbstractExtractor() +AbstractExtractor::AbstractExtractor(Poco::TextEncoding::Ptr pDBEncoding, + Poco::TextEncoding::Ptr pToEncoding): + _pTranscoder(Transcoder::create(pDBEncoding, pToEncoding)) { } @@ -30,6 +33,20 @@ AbstractExtractor::~AbstractExtractor() } +void AbstractExtractor::transcode(const std::string& from, std::string& to) +{ + if (_pTranscoder) + _pTranscoder->transcode(from, to); +} + + +void AbstractExtractor::reverseTranscode(const std::string& from, std::string& to) +{ + if (_pTranscoder) + _pTranscoder->reverseTranscode(from, to); +} + + bool AbstractExtractor::extract(std::size_t pos, std::vector& val) { throw NotImplementedException("std::vector extractor must be implemented."); diff --git a/Data/src/ArchiveStrategy.cpp b/Data/src/ArchiveStrategy.cpp index 2d8842ba2..c1cb8d995 100644 --- a/Data/src/ArchiveStrategy.cpp +++ b/Data/src/ArchiveStrategy.cpp @@ -30,8 +30,8 @@ const std::string ArchiveStrategy::DEFAULT_ARCHIVE_DESTINATION = "T_POCO_LOG_ARC ArchiveStrategy::ArchiveStrategy(const std::string& connector, - const std::string& connect, - const std::string& source, + const std::string& connect, + const std::string& source, const std::string& destination): _connector(connector), _connect(connect), @@ -61,9 +61,9 @@ void ArchiveStrategy::open() // -ArchiveByAgeStrategy::ArchiveByAgeStrategy(const std::string& connector, - const std::string& connect, - const std::string& sourceTable, +ArchiveByAgeStrategy::ArchiveByAgeStrategy(const std::string& connector, + const std::string& connect, + const std::string& sourceTable, const std::string& destinationTable): ArchiveStrategy(connector, connect, sourceTable, destinationTable) { @@ -124,7 +124,7 @@ void ArchiveByAgeStrategy::setThreshold(const std::string& age) while (it != end && Ascii::isSpace(*it)) ++it; std::string unit; while (it != end && Ascii::isAlpha(*it)) unit += *it++; - + Timespan::TimeDiff factor = Timespan::SECONDS; if (unit == "minutes") factor = Timespan::MINUTES; @@ -138,7 +138,7 @@ void ArchiveByAgeStrategy::setThreshold(const std::string& age) factor = 30*Timespan::DAYS; else if (unit != "seconds") throw InvalidArgumentException("setMaxAge", age); - + _maxAge = factor * n; } diff --git a/Data/src/Date.cpp b/Data/src/Date.cpp index 542d9a981..302b6a1d4 100644 --- a/Data/src/Date.cpp +++ b/Data/src/Date.cpp @@ -61,7 +61,7 @@ void Date::assign(int year, int month, int day) throw InvalidArgumentException("Month must be between 1 and 12"); if (day < 1 || day > DateTime::daysOfMonth(year, month)) - throw InvalidArgumentException("Month must be between 1 and " + + throw InvalidArgumentException("Month must be between 1 and " + NumberFormatter::format(DateTime::daysOfMonth(year, month))); _year = year; @@ -80,7 +80,7 @@ bool Date::operator < (const Date& date) const { int month = date.month(); if (_month < month) return true; - else + else if (_month > month) return false; else // months equal if (_day < date.day()) return true; diff --git a/Data/src/JSONRowFormatter.cpp b/Data/src/JSONRowFormatter.cpp new file mode 100644 index 000000000..3d5dc4fe2 --- /dev/null +++ b/Data/src/JSONRowFormatter.cpp @@ -0,0 +1,189 @@ +// +// JSONRowFormatter.cpp +// +// Library: Data +// Package: DataCore +// Module: JSONRowFormatter +// +// Copyright (c) 2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// SPDX-License-Identifier: BSL-1.0 +// + + +#include "Poco/Data/JSONRowFormatter.h" +#include "Poco/String.h" +#include "Poco/JSONString.h" +#include "Poco/Format.h" + + +using Poco::trimInPlace; +using Poco::format; +using Poco::toJSON; + + +namespace Poco { +namespace Data { + + +const int JSONRowFormatter::JSON_FMT_MODE_SMALL; +const int JSONRowFormatter::JSON_FMT_MODE_ROW_COUNT; +const int JSONRowFormatter::JSON_FMT_MODE_COLUMN_NAMES; +const int JSONRowFormatter::JSON_FMT_MODE_FULL; + + +JSONRowFormatter::JSONRowFormatter(int mode) : RowFormatter("{", "]}"), + _firstTime(true) +{ + if (mode == JSON_FMT_MODE_FULL) + { + mode |= JSON_FMT_MODE_ROW_COUNT; + mode |= JSON_FMT_MODE_COLUMN_NAMES; + } + + setJSONMode(mode); +} + + +JSONRowFormatter::~JSONRowFormatter() +{ +} + + +void JSONRowFormatter::adjustPrefix() const +{ + if (printRowCount()) + { + std::ostringstream ostr; + ostr << "{\"count\":" << getTotalRowCount() << ","; + if (_mode & JSON_FMT_MODE_FULL) + ostr << '['; + setPrefix(ostr.str()); + } +} + + +void JSONRowFormatter::setJSONMode(int mode) +{ + if (mode < JSON_FMT_MODE_SMALL || + mode > (JSON_FMT_MODE_SMALL | JSON_FMT_MODE_ROW_COUNT | JSON_FMT_MODE_COLUMN_NAMES | JSON_FMT_MODE_FULL)) + { + throw Poco::InvalidArgumentException( + Poco::format("JSONRowFormatter mode must be between " + "%d (JSON_FMT_MODE_SMALL) and %d (JSON_FMT_MODE_FULL)", + JSON_FMT_MODE_SMALL, + JSON_FMT_MODE_FULL)); + } + + _mode = mode; + if (!(_mode & JSON_FMT_MODE_SMALL) && !(_mode & JSON_FMT_MODE_FULL)) + _mode |= JSON_FMT_MODE_SMALL; + else if (_mode & JSON_FMT_MODE_FULL) + { + _mode |= JSON_FMT_MODE_ROW_COUNT; + } +} + + +std::string& JSONRowFormatter::formatValues(const ValueVec& vals, std::string& formattedValues) +{ + std::ostringstream str; + if (!_firstTime) str << ','; + if (isSmall()) + { + if (_firstTime) + { + if (printColumnNames()) + str << ",\"values\":"; + + str << '['; + } + + str << '['; + ValueVec::const_iterator it = vals.begin(); + ValueVec::const_iterator end = vals.end(); + for (; it != end;) + { + if (!it->isEmpty()) + { + if (it->isString() || it->isDate() || it->isTime()) + { + std::string val = it->convert(); + trimInPlace(val); + str << toJSON(val); + } + else + str << it->convert(); + } + else + str << "null"; + + if (++it == end) break; + + str << ','; + } + str << ']'; + } + else if (isFull()) + { + str << '{'; + ValueVec::const_iterator it = vals.begin(); + ValueVec::const_iterator end = vals.end(); + NameVec::iterator nIt = _pNames->begin(); + NameVec::iterator nEnd = _pNames->end(); + for (; it != end && nIt != nEnd; ++nIt) + { + if (!it->isEmpty()) + { + if (it->isString() || it->isDate() || it->isTime()) + { + std::string val = it->convert(); + trimInPlace(val); + str << '"' << *nIt << "\":" << toJSON(val); + } + else + str << '"' << *nIt << "\":" << it->convert(); + } + else + str << '"' << *nIt << "\":null"; + + if (++it != end) str << ','; + } + str << '}'; + } + + _firstTime = false; + return formattedValues = str.str(); +} + + +std::string& JSONRowFormatter::formatNames(const NameVecPtr pNames, std::string& formattedNames) +{ + //adjustPrefix(); + if (isFull()) + { + // names are used in formatValues + if (pNames && !_pNames) _pNames = pNames; + return formattedNames = ""; + } + else if (printColumnNames()) + { + std::ostringstream ostr; + ostr << "\"names\":["; + for (NameVec::const_iterator it = pNames->begin(), + end = pNames->end();;) + { + ostr << '"' << *it << '"'; + if (++it == end) break; + ostr << ','; + } + ostr << "]"; + return formattedNames = ostr.str(); + } + + return formattedNames = ""; +} + + +} }// namespace Poco::Data diff --git a/Data/src/MetaColumn.cpp b/Data/src/MetaColumn.cpp index d333164fe..cf1de736c 100644 --- a/Data/src/MetaColumn.cpp +++ b/Data/src/MetaColumn.cpp @@ -92,7 +92,7 @@ MetaColumn& MetaColumn::operator = (MetaColumn&& other) noexcept } -void MetaColumn::swap(MetaColumn& other) +void MetaColumn::swap(MetaColumn& other) noexcept { std::swap(_name, other._name); std::swap(_length, other._length); diff --git a/Data/src/RecordSet.cpp b/Data/src/RecordSet.cpp index a84c35fdf..20e978b0a 100644 --- a/Data/src/RecordSet.cpp +++ b/Data/src/RecordSet.cpp @@ -160,6 +160,7 @@ Poco::Dynamic::Var RecordSet::value(std::size_t col, std::size_t row, bool useFi case MetaColumn::FDT_TIME: return value
iphlpapi.lib;%(AdditionalDependencies) @@ -398,6 +399,7 @@ ProgramDatabase Default true + /Zc:__cplusplus %(AdditionalOptions) ..\lib64\PocoFoundationmtd.lib @@ -451,6 +453,7 @@ Default true + /Zc:__cplusplus %(AdditionalOptions) ..\lib64\PocoFoundationmt.lib @@ -500,6 +503,7 @@ ProgramDatabase Default true + /Zc:__cplusplus %(AdditionalOptions) ..\lib64\PocoFoundationmdd.lib @@ -557,6 +561,7 @@ Default true + /Zc:__cplusplus %(AdditionalOptions) @@ -1025,27 +1030,75 @@ true - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + true + true + true + true + true + + + @@ -1726,12 +1779,13 @@ - - - + + + + + - diff --git a/Foundation/Foundation_vs160.vcxproj.filters b/Foundation/Foundation_vs160.vcxproj.filters index c13fe7482..07fcc124b 100644 --- a/Foundation/Foundation_vs160.vcxproj.filters +++ b/Foundation/Foundation_vs160.vcxproj.filters @@ -52,18 +52,12 @@ {8d90af25-6c9f-45fb-8af0-7463fab03c44} - - {8bd7fdba-6cdf-4cc7-8ffd-e0eef416d7b5} - {3b04a0e6-f311-428b-af8f-c1a7a3d9fd10} {5f191b86-441f-4da7-8b2f-02513d443466} - - {f19826b3-7a4b-4d64-aaa3-eb1e084a71b2} - {f98d18b5-dfbc-4c35-8654-bf0c3fc815e9} @@ -187,6 +181,12 @@ {7df1fa35-122a-4152-b81f-35be1aabd290} + + {8bd7fdba-6cdf-4cc7-8ffd-e0eef416d7b5} + + + {f19826b3-7a4b-4d64-aaa3-eb1e084a71b2} + @@ -489,69 +489,6 @@ RegularExpression\Source Files - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - Logging\Source Files @@ -888,6 +825,96 @@ URI\Source Files + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + @@ -1322,18 +1349,6 @@ SharedLibrary\Header Files - - RegularExpression\PCRE Header Files - - - RegularExpression\PCRE Header Files - - - RegularExpression\PCRE Header Files - - - RegularExpression\PCRE Header Files - RegularExpression\Header Files @@ -1823,6 +1838,21 @@ URI\Header Files + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + diff --git a/Foundation/Foundation_vs170.sln b/Foundation/Foundation_vs170.sln index c17d01b3b..3371a9d6b 100644 --- a/Foundation/Foundation_vs170.sln +++ b/Foundation/Foundation_vs170.sln @@ -21,124 +21,178 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestLibrary", "testsuite\Te EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + debug_shared|ARM64 = debug_shared|ARM64 debug_shared|Win32 = debug_shared|Win32 debug_shared|x64 = debug_shared|x64 + debug_static_md|ARM64 = debug_static_md|ARM64 debug_static_md|Win32 = debug_static_md|Win32 debug_static_md|x64 = debug_static_md|x64 + debug_static_mt|ARM64 = debug_static_mt|ARM64 debug_static_mt|Win32 = debug_static_mt|Win32 debug_static_mt|x64 = debug_static_mt|x64 + release_shared|ARM64 = release_shared|ARM64 release_shared|Win32 = release_shared|Win32 release_shared|x64 = release_shared|x64 + release_static_md|ARM64 = release_static_md|ARM64 release_static_md|Win32 = release_static_md|Win32 release_static_md|x64 = release_static_md|x64 + release_static_mt|ARM64 = release_static_mt|ARM64 release_static_mt|Win32 = release_static_mt|Win32 release_static_mt|x64 = release_static_mt|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|Win32.Build.0 = debug_shared|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|x64.ActiveCfg = debug_shared|x64 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_shared|x64.Build.0 = debug_shared|x64 + {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 {B01196CC-B693-4548-8464-2FF60499E73F}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|ARM64.Build.0 = release_shared|ARM64 {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|Win32.ActiveCfg = release_shared|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|Win32.Build.0 = release_shared|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|Win32.Deploy.0 = release_shared|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|x64.ActiveCfg = release_shared|x64 {B01196CC-B693-4548-8464-2FF60499E73F}.release_shared|x64.Build.0 = release_shared|x64 + {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|Win32.Build.0 = release_static_md|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|x64.ActiveCfg = release_static_md|x64 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_md|x64.Build.0 = release_static_md|x64 + {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 {B01196CC-B693-4548-8464-2FF60499E73F}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|Win32.Build.0 = debug_shared|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|Win32.Deploy.0 = debug_shared|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|x64.ActiveCfg = debug_shared|x64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_shared|x64.Build.0 = debug_shared|x64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|Win32.Deploy.0 = debug_static_md|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|Win32.Deploy.0 = debug_static_mt|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|ARM64.Build.0 = release_shared|ARM64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|Win32.ActiveCfg = release_shared|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|Win32.Build.0 = release_shared|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|Win32.Deploy.0 = release_shared|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|x64.ActiveCfg = release_shared|x64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_shared|x64.Build.0 = release_shared|x64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|Win32.Build.0 = release_static_md|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|Win32.Deploy.0 = release_static_md|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|x64.ActiveCfg = release_static_md|x64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_md|x64.Build.0 = release_static_md|x64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|Win32.Deploy.0 = release_static_mt|Win32 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 {F1EE93DF-347F-4CB3-B191-C4E63F38E972}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_shared|Win32.Build.0 = debug_shared|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_shared|x64.ActiveCfg = debug_shared|x64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_shared|x64.Build.0 = debug_shared|x64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_md|ARM64.ActiveCfg = debug_static_md|ARM64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_md|ARM64.Build.0 = debug_static_md|ARM64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_md|Win32.ActiveCfg = debug_static_md|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_md|Win32.Build.0 = debug_static_md|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_md|x64.ActiveCfg = debug_static_md|x64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_md|x64.Build.0 = debug_static_md|x64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_mt|ARM64.ActiveCfg = debug_static_mt|ARM64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_mt|ARM64.Build.0 = debug_static_mt|ARM64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_mt|Win32.ActiveCfg = debug_static_mt|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_mt|Win32.Build.0 = debug_static_mt|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_mt|x64.ActiveCfg = debug_static_mt|x64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.debug_static_mt|x64.Build.0 = debug_static_mt|x64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_shared|ARM64.Build.0 = release_shared|ARM64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_shared|Win32.ActiveCfg = release_shared|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_shared|Win32.Build.0 = release_shared|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_shared|x64.ActiveCfg = release_shared|x64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_shared|x64.Build.0 = release_shared|x64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_md|ARM64.ActiveCfg = release_static_md|ARM64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_md|ARM64.Build.0 = release_static_md|ARM64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_md|Win32.ActiveCfg = release_static_md|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_md|Win32.Build.0 = release_static_md|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_md|x64.ActiveCfg = release_static_md|x64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_md|x64.Build.0 = release_static_md|x64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_mt|ARM64.ActiveCfg = release_static_mt|ARM64 + {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_mt|ARM64.Build.0 = release_static_mt|ARM64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_mt|Win32.ActiveCfg = release_static_mt|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_mt|Win32.Build.0 = release_static_mt|Win32 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_mt|x64.ActiveCfg = release_static_mt|x64 {6C41E55D-C0FC-4E01-AA8D-B7DA40E31D3A}.release_static_mt|x64.Build.0 = release_static_mt|x64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_shared|ARM64.ActiveCfg = debug_shared|ARM64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_shared|ARM64.Build.0 = debug_shared|ARM64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_shared|Win32.ActiveCfg = debug_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_shared|Win32.Build.0 = debug_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_shared|x64.ActiveCfg = debug_shared|x64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_shared|x64.Build.0 = debug_shared|x64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_md|ARM64.ActiveCfg = debug_shared|ARM64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_md|ARM64.Build.0 = debug_shared|ARM64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_md|Win32.ActiveCfg = debug_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_md|Win32.Build.0 = debug_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_md|x64.ActiveCfg = debug_shared|x64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_md|x64.Build.0 = debug_shared|x64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_mt|ARM64.ActiveCfg = debug_shared|ARM64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_mt|ARM64.Build.0 = debug_shared|ARM64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_mt|Win32.ActiveCfg = debug_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_mt|Win32.Build.0 = debug_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_mt|x64.ActiveCfg = debug_shared|x64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.debug_static_mt|x64.Build.0 = debug_shared|x64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_shared|ARM64.ActiveCfg = release_shared|ARM64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_shared|ARM64.Build.0 = release_shared|ARM64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_shared|Win32.ActiveCfg = release_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_shared|Win32.Build.0 = release_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_shared|x64.ActiveCfg = release_shared|x64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_shared|x64.Build.0 = release_shared|x64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_md|ARM64.ActiveCfg = release_shared|ARM64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_md|ARM64.Build.0 = release_shared|ARM64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_md|Win32.ActiveCfg = release_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_md|Win32.Build.0 = release_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_md|x64.ActiveCfg = release_shared|x64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_md|x64.Build.0 = release_shared|x64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_mt|ARM64.ActiveCfg = release_shared|ARM64 + {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_mt|ARM64.Build.0 = release_shared|ARM64 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_mt|Win32.ActiveCfg = release_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_mt|Win32.Build.0 = release_shared|Win32 {0955EB03-544B-4BD4-9C10-89CF38078F5F}.release_static_mt|x64.ActiveCfg = release_shared|x64 diff --git a/Foundation/Foundation_vs170.vcxproj b/Foundation/Foundation_vs170.vcxproj index e519f66ef..0223e151f 100644 --- a/Foundation/Foundation_vs170.vcxproj +++ b/Foundation/Foundation_vs170.vcxproj @@ -1,6 +1,10 @@  + + debug_shared + ARM64 + debug_shared Win32 @@ -9,6 +13,10 @@ debug_shared x64 + + debug_static_md + ARM64 + debug_static_md Win32 @@ -17,6 +25,10 @@ debug_static_md x64 + + debug_static_mt + ARM64 + debug_static_mt Win32 @@ -25,6 +37,10 @@ debug_static_mt x64 + + release_shared + ARM64 + release_shared Win32 @@ -33,6 +49,10 @@ release_shared x64 + + release_static_md + ARM64 + release_static_md Win32 @@ -41,6 +61,10 @@ release_static_md x64 + + release_static_mt + ARM64 + release_static_mt Win32 @@ -55,7 +79,6 @@ {B01196CC-B693-4548-8464-2FF60499E73F} Foundation Win32Proj - 8.1
@@ -68,6 +91,11 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + StaticLibrary MultiByte @@ -78,6 +106,11 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + StaticLibrary MultiByte @@ -88,6 +121,11 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + StaticLibrary MultiByte @@ -98,6 +136,11 @@ MultiByte v143 + + StaticLibrary + MultiByte + v143 + DynamicLibrary MultiByte @@ -108,6 +151,11 @@ MultiByte v143 + + DynamicLibrary + MultiByte + v143 + DynamicLibrary MultiByte @@ -118,6 +166,11 @@ MultiByte v143 + + DynamicLibrary + MultiByte + v143 + @@ -126,51 +179,75 @@ + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.25431.1 PocoFoundationd PocoFoundation64d + PocoFoundationA64d PocoFoundationmdd PocoFoundationmdd + PocoFoundationmdd PocoFoundationmtd PocoFoundationmtd + PocoFoundationmtd PocoFoundation PocoFoundation64 + PocoFoundationA64 PocoFoundationmd PocoFoundationmd + PocoFoundationmd PocoFoundationmt PocoFoundationmt + PocoFoundationmt ..\bin\ @@ -182,6 +259,9 @@ ..\bin64\ obj64\Foundation\$(Configuration)\ + + true + ..\bin\ obj\Foundation\$(Configuration)\ @@ -192,6 +272,9 @@ ..\bin64\ obj64\Foundation\$(Configuration)\ + + false + ..\lib\ obj\Foundation\$(Configuration)\ @@ -285,6 +368,36 @@ ..\lib64\PocoFoundationd.lib + + + Disabled + .\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;_USRDLL;Foundation_EXPORTS;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + + Level3 + ProgramDatabase + Default + true + + + iphlpapi.lib;%(AdditionalDependencies) + ..\binA64\PocoFoundation64d.dll + true + true + ..\binA64\PocoFoundation64d.pdb + ..\libA64;%(AdditionalLibraryDirectories) + Console + ..\libA64\PocoFoundationd.lib + + MaxSpeed @@ -354,6 +467,41 @@ ..\lib64\PocoFoundation.lib + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;_USRDLL;Foundation_EXPORTS;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + + Level3 + + + Default + true + + + iphlpapi.lib;%(AdditionalDependencies) + ..\binA64\PocoFoundation64.dll + true + false + ..\libA64;%(AdditionalLibraryDirectories) + Console + true + true + ..\libA64\PocoFoundation.lib + + Disabled @@ -403,6 +551,30 @@ ..\lib64\PocoFoundationmtd.lib + + + Disabled + .\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + true + true + true + + + ..\libA64\PocoFoundationmtd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\PocoFoundationmtd.lib + + MaxSpeed @@ -456,6 +628,33 @@ ..\lib64\PocoFoundationmt.lib + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreaded + false + true + true + true + + + Level3 + + + Default + true + + + ..\libA64\PocoFoundationmt.lib + + Disabled @@ -505,6 +704,30 @@ ..\lib64\PocoFoundationmdd.lib + + + Disabled + .\include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + true + true + + + ..\libA64\PocoFoundationmdd.pdb + Level3 + ProgramDatabase + Default + true + + + ..\libA64\PocoFoundationmdd.lib + + MaxSpeed @@ -564,6 +787,36 @@ ..\lib64\PocoFoundationmd.lib + + + MaxSpeed + OnlyExplicitInline + true + Speed + true + .\include;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + true + + + $(IntDir)$(ProjectName).pdb + Level3 + + + Default + true + + + + + ..\libA64\PocoFoundationmd.lib + + @@ -583,16 +836,22 @@ true true + true true true + true true true + true true true + true true true + true true true + true @@ -619,60 +878,84 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -683,30 +966,42 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -717,58 +1012,82 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -777,72 +1096,102 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -864,30 +1213,42 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -903,88 +1264,124 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -999,96 +1396,192 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + + + + + + + + + + + + + + + + + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + true + + + true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1096,30 +1589,42 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1132,59 +1637,83 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1192,101 +1721,143 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1299,32 +1870,44 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1342,30 +1925,42 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1375,30 +1970,42 @@ true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true true true + true @@ -1726,12 +2333,13 @@ - - - + + + + + - @@ -1741,55 +2349,79 @@ mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) + + mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) + %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) + + mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) + %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) + + mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) + %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) + + mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) + %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) + + mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) + %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) + + mc -h "%(RootDir)%(Directory)." -r "%(RootDir)%(Directory)." "%(FullPath) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) + %(RootDir)%(Directory)\pocomsg.rc;%(RootDir)%(Directory)\pocomsg.h;%(Outputs) false false + false true true + true true true + true false false + false true true + true true true + true diff --git a/Foundation/Foundation_vs170.vcxproj.filters b/Foundation/Foundation_vs170.vcxproj.filters index c13fe7482..fc8cd62ce 100644 --- a/Foundation/Foundation_vs170.vcxproj.filters +++ b/Foundation/Foundation_vs170.vcxproj.filters @@ -52,18 +52,12 @@ {8d90af25-6c9f-45fb-8af0-7463fab03c44} - - {8bd7fdba-6cdf-4cc7-8ffd-e0eef416d7b5} - {3b04a0e6-f311-428b-af8f-c1a7a3d9fd10} {5f191b86-441f-4da7-8b2f-02513d443466} - - {f19826b3-7a4b-4d64-aaa3-eb1e084a71b2} - {f98d18b5-dfbc-4c35-8654-bf0c3fc815e9} @@ -187,6 +181,12 @@ {7df1fa35-122a-4152-b81f-35be1aabd290} + + {8bd7fdba-6cdf-4cc7-8ffd-e0eef416d7b5} + + + {f19826b3-7a4b-4d64-aaa3-eb1e084a71b2} + @@ -489,69 +489,6 @@ RegularExpression\Source Files - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - - - RegularExpression\PCRE Source Files - Logging\Source Files @@ -888,6 +825,96 @@ URI\Source Files + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + + + RegularExpression\PCRE2 Source Files + @@ -1322,18 +1349,6 @@ SharedLibrary\Header Files - - RegularExpression\PCRE Header Files - - - RegularExpression\PCRE Header Files - - - RegularExpression\PCRE Header Files - - - RegularExpression\PCRE Header Files - RegularExpression\Header Files @@ -1823,6 +1838,21 @@ URI\Header Files + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + + + RegularExpression\PCRE2 Header Files + diff --git a/Foundation/Makefile b/Foundation/Makefile index 23d1243a0..c1949c051 100644 --- a/Foundation/Makefile +++ b/Foundation/Makefile @@ -35,15 +35,17 @@ objects = ArchiveStrategy Ascii ASCIIEncoding AsyncChannel \ zlib_objects = adler32 compress crc32 deflate \ infback inffast inflate inftrees trees zutil -pcre_objects = pcre_config pcre_chartables pcre_compile pcre_globals pcre_maketables \ - pcre_study pcre_byte_order pcre_valid_utf8 pcre_dfa_exec pcre_get pcre_jit_compile\ - pcre_exec pcre_ord2utf8 pcre_newline pcre_fullinfo pcre_xclass pcre_refcount pcre_string_utils \ - pcre_version +pcre_objects = pcre2_auto_possess pcre2_chartables pcre2_compile pcre2_config \ + pcre2_context pcre2_convert pcre2_dfa_match pcre2_error pcre2_extuni \ + pcre2_find_bracket pcre2_jit_compile pcre2_maketables pcre2_match \ + pcre2_match_data pcre2_newline pcre2_ord2utf pcre2_pattern_info \ + pcre2_script_run pcre2_serialize pcre2_string_utils pcre2_study pcre2_substitute \ + pcre2_substring pcre2_tables pcre2_ucd pcre2_valid_utf pcre2_xclass -pcre_utf8_objects = pcre_ucd pcre_tables +pcre_utf8_objects = pcre2_ucd pcre2_tables ifdef POCO_UNBUNDLED - SYSLIBS += -lpcre -lz + SYSLIBS += -lpcre2-8 -lz objects += $(pcre_utf8_objects) else objects += $(zlib_objects) $(pcre_objects) $(pcre_utf8_objects) diff --git a/Foundation/include/Poco/ASCIIEncoding.h b/Foundation/include/Poco/ASCIIEncoding.h index e47f61538..d839508db 100644 --- a/Foundation/include/Poco/ASCIIEncoding.h +++ b/Foundation/include/Poco/ASCIIEncoding.h @@ -38,7 +38,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/AbstractDelegate.h b/Foundation/include/Poco/AbstractDelegate.h index 9dea69a36..0a2b830f0 100644 --- a/Foundation/include/Poco/AbstractDelegate.h +++ b/Foundation/include/Poco/AbstractDelegate.h @@ -24,7 +24,7 @@ namespace Poco { -template +template class AbstractDelegate /// Base class for Delegate and Expire. { @@ -37,7 +37,7 @@ public: { } - virtual ~AbstractDelegate() + virtual ~AbstractDelegate() { } @@ -54,7 +54,7 @@ public: virtual void disable() = 0; /// Disables the delegate, which is done prior to removal. - + virtual const AbstractDelegate* unwrap() const /// Returns the unwrapped delegate. Must be overridden by decorators /// like Expire. @@ -64,7 +64,7 @@ public: }; -template <> +template <> class AbstractDelegate /// Base class for Delegate and Expire. { @@ -77,7 +77,7 @@ public: { } - virtual ~AbstractDelegate() + virtual ~AbstractDelegate() { } @@ -94,7 +94,7 @@ public: virtual void disable() = 0; /// Disables the delegate, which is done prior to removal. - + virtual const AbstractDelegate* unwrap() const /// Returns the unwrapped delegate. Must be overridden by decorators /// like Expire. diff --git a/Foundation/include/Poco/AbstractObserver.h b/Foundation/include/Poco/AbstractObserver.h old mode 100644 new mode 100755 index 6528660dd..7606878be --- a/Foundation/include/Poco/AbstractObserver.h +++ b/Foundation/include/Poco/AbstractObserver.h @@ -33,7 +33,7 @@ public: AbstractObserver(); AbstractObserver(const AbstractObserver& observer); virtual ~AbstractObserver(); - + AbstractObserver& operator = (const AbstractObserver& observer); virtual void notify(Notification* pNf) const = 0; diff --git a/Foundation/include/Poco/AbstractPriorityDelegate.h b/Foundation/include/Poco/AbstractPriorityDelegate.h index c27bc0c3f..dbe367a4e 100644 --- a/Foundation/include/Poco/AbstractPriorityDelegate.h +++ b/Foundation/include/Poco/AbstractPriorityDelegate.h @@ -25,7 +25,7 @@ namespace Poco { -template +template class AbstractPriorityDelegate: public AbstractDelegate /// Base class for PriorityDelegate and PriorityExpire. /// @@ -43,7 +43,7 @@ public: { } - virtual ~AbstractPriorityDelegate() + virtual ~AbstractPriorityDelegate() { } diff --git a/Foundation/include/Poco/AbstractStrategy.h b/Foundation/include/Poco/AbstractStrategy.h index 0bd8b548f..265804ac4 100644 --- a/Foundation/include/Poco/AbstractStrategy.h +++ b/Foundation/include/Poco/AbstractStrategy.h @@ -27,9 +27,9 @@ namespace Poco { -template +template class AbstractStrategy - /// An AbstractStrategy is the interface for all strategies. + /// An AbstractStrategy is the interface for all strategies. { public: AbstractStrategy() @@ -46,7 +46,7 @@ public: onRemove(pSender,args.key()); onAdd(pSender, args); } - + virtual void onAdd(const void* pSender, const KeyValueArgs & key) = 0; /// Adds the key to the strategy. /// If for the key already an entry exists, an exception will be thrown. diff --git a/Foundation/include/Poco/AccessExpirationDecorator.h b/Foundation/include/Poco/AccessExpirationDecorator.h index 9978185ff..ea0210675 100644 --- a/Foundation/include/Poco/AccessExpirationDecorator.h +++ b/Foundation/include/Poco/AccessExpirationDecorator.h @@ -55,7 +55,7 @@ public: ~AccessExpirationDecorator() { } - + const Poco::Timespan& getTimeout() const { return _span; diff --git a/Foundation/include/Poco/AccessExpireCache.h b/Foundation/include/Poco/AccessExpireCache.h index bb5c57152..f67d57bf9 100644 --- a/Foundation/include/Poco/AccessExpireCache.h +++ b/Foundation/include/Poco/AccessExpireCache.h @@ -26,11 +26,11 @@ namespace Poco { template < - class TKey, - class TValue, - class TMutex = FastMutex, + class TKey, + class TValue, + class TMutex = FastMutex, class TEventMutex = FastMutex -> +> class AccessExpireCache: public AbstractCache, TMutex, TEventMutex> /// An AccessExpireCache caches entries for a fixed time period (per default 10 minutes). /// Entries expire when they are not accessed with get() during this time period. Each access resets @@ -38,11 +38,11 @@ class AccessExpireCache: public AbstractCache, TMutex, TEventMutex>(AccessExpireStrategy(expire)) { } diff --git a/Foundation/include/Poco/AccessExpireLRUCache.h b/Foundation/include/Poco/AccessExpireLRUCache.h index 2833894b6..4618a353f 100644 --- a/Foundation/include/Poco/AccessExpireLRUCache.h +++ b/Foundation/include/Poco/AccessExpireLRUCache.h @@ -27,10 +27,10 @@ namespace Poco { -template < +template < class TKey, class TValue, - class TMutex = FastMutex, + class TMutex = FastMutex, class TEventMutex = FastMutex > class AccessExpireLRUCache: public AbstractCache, TMutex, TEventMutex> diff --git a/Foundation/include/Poco/ActiveDispatcher.h b/Foundation/include/Poco/ActiveDispatcher.h index 578a42087..81c5fbef1 100644 --- a/Foundation/include/Poco/ActiveDispatcher.h +++ b/Foundation/include/Poco/ActiveDispatcher.h @@ -21,6 +21,7 @@ #include "Poco/Foundation.h" #include "Poco/Runnable.h" #include "Poco/Thread.h" +#include "Poco/Event.h" #include "Poco/ActiveStarter.h" #include "Poco/ActiveRunnable.h" #include "Poco/NotificationQueue.h" @@ -35,7 +36,7 @@ class Foundation_API ActiveDispatcher: protected Runnable /// /// An active object, which is an ordinary object /// containing ActiveMethod members, executes all - /// active methods in their own thread. + /// active methods in their own thread. /// This behavior does not fit the "classic" /// definition of an active object, which serializes /// the execution of active methods (in other words, @@ -44,7 +45,7 @@ class Foundation_API ActiveDispatcher: protected Runnable /// /// Using this class as a base class, the serializing /// behavior for active objects can be implemented. - /// + /// /// The following example shows how this is done: /// /// class ActiveObject: public ActiveDispatcher @@ -86,7 +87,7 @@ public: void cancel(); /// Cancels all queued methods. - + protected: void run(); void stop(); diff --git a/Foundation/include/Poco/ActiveMethod.h b/Foundation/include/Poco/ActiveMethod.h index 8ab483572..fba154938 100644 --- a/Foundation/include/Poco/ActiveMethod.h +++ b/Foundation/include/Poco/ActiveMethod.h @@ -83,7 +83,7 @@ public: { poco_check_ptr (pOwner); } - + ActiveResultType operator () (const ArgType& arg) /// Invokes the ActiveMethod. { @@ -92,7 +92,7 @@ public: StarterType::start(_pOwner, pRunnable); return result; } - + ActiveMethod(const ActiveMethod& other): _pOwner(other._pOwner), _method(other._method) @@ -106,7 +106,7 @@ public: return *this; } - void swap(ActiveMethod& other) + void swap(ActiveMethod& other) noexcept { std::swap(_pOwner, other._pOwner); std::swap(_method, other._method); @@ -175,7 +175,7 @@ public: { poco_check_ptr (pOwner); } - + ActiveResultType operator () (void) /// Invokes the ActiveMethod. { @@ -184,7 +184,7 @@ public: StarterType::start(_pOwner, pRunnable); return result; } - + ActiveMethod(const ActiveMethod& other): _pOwner(other._pOwner), _method(other._method) @@ -198,7 +198,7 @@ public: return *this; } - void swap(ActiveMethod& other) + void swap(ActiveMethod& other) noexcept { std::swap(_pOwner, other._pOwner); std::swap(_method, other._method); diff --git a/Foundation/include/Poco/ActiveResult.h b/Foundation/include/Poco/ActiveResult.h index 04bd15304..640c55b96 100644 --- a/Foundation/include/Poco/ActiveResult.h +++ b/Foundation/include/Poco/ActiveResult.h @@ -33,7 +33,7 @@ template class ActiveResultHolder: public RefCountedObject /// This class holds the result of an asynchronous method /// invocation. It is used to pass the result from the - /// execution thread back to the invocation thread. + /// execution thread back to the invocation thread. /// The class uses reference counting for memory management. /// Do not use this class directly, use ActiveResult instead. { @@ -45,26 +45,26 @@ public: /// Creates an ActiveResultHolder. { } - + ResultType& data() /// Returns a reference to the actual result. { poco_check_ptr(_pData); return *_pData; } - + void data(ResultType* pData) { delete _pData; _pData = pData; } - + void wait() /// Pauses the caller until the result becomes available. { _event.wait(); } - + bool tryWait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Returns true if the result became @@ -72,7 +72,7 @@ public: { return _event.tryWait(milliseconds); } - + void wait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Throws a TimeoutException if the @@ -80,20 +80,20 @@ public: { _event.wait(milliseconds); } - + void notify() /// Notifies the invoking thread that the result became available. { _event.set(); } - + bool failed() const /// Returns true if the active method failed (and threw an exception). /// Information about the exception can be obtained by calling error(). { return _pExc != 0; } - + std::string error() const /// If the active method threw an exception, a textual representation /// of the exception is returned. An empty string is returned if the @@ -104,21 +104,21 @@ public: else return std::string(); } - + Exception* exception() const /// If the active method threw an exception, a clone of the exception /// object is returned, otherwise null. { return _pExc; } - + void error(const Exception& exc) /// Sets the exception. { delete _pExc; _pExc = exc.clone(); } - + void error(const std::string& msg) /// Sets the exception. { @@ -151,13 +151,13 @@ public: /// Creates an ActiveResultHolder. { } - + void wait() /// Pauses the caller until the result becomes available. { _event.wait(); } - + bool tryWait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Returns true if the result became @@ -165,7 +165,7 @@ public: { return _event.tryWait(milliseconds); } - + void wait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Throws a TimeoutException if the @@ -173,20 +173,20 @@ public: { _event.wait(milliseconds); } - + void notify() /// Notifies the invoking thread that the result became available. { _event.set(); } - + bool failed() const /// Returns true if the active method failed (and threw an exception). /// Information about the exception can be obtained by calling error(). { return _pExc != 0; } - + std::string error() const /// If the active method threw an exception, a textual representation /// of the exception is returned. An empty string is returned if the @@ -197,21 +197,21 @@ public: else return std::string(); } - + Exception* exception() const /// If the active method threw an exception, a clone of the exception /// object is returned, otherwise null. { return _pExc; } - + void error(const Exception& exc) /// Sets the exception. { delete _pExc; _pExc = exc.clone(); } - + void error(const std::string& msg) /// Sets the exception. { @@ -234,8 +234,8 @@ private: template class ActiveResult /// This class holds the result of an asynchronous method - /// invocation (see class ActiveMethod). It is used to pass the - /// result from the execution thread back to the invocation thread. + /// invocation (see class ActiveMethod). It is used to pass the + /// result from the execution thread back to the invocation thread. { public: typedef RT ResultType; @@ -247,20 +247,20 @@ public: { poco_check_ptr (pHolder); } - + ActiveResult(const ActiveResult& result) /// Copy constructor. { _pHolder = result._pHolder; _pHolder->duplicate(); } - + ~ActiveResult() /// Destroys the result. { _pHolder->release(); } - + ActiveResult& operator = (const ActiveResult& result) /// Assignment operator. { @@ -268,30 +268,30 @@ public: swap(tmp); return *this; } - - void swap(ActiveResult& result) + + void swap(ActiveResult& result) noexcept { using std::swap; swap(_pHolder, result._pHolder); } - + ResultType& data() const /// Returns a reference to the result data. { return _pHolder->data(); } - + void data(ResultType* pValue) { _pHolder->data(pValue); } - + void wait() /// Pauses the caller until the result becomes available. { _pHolder->wait(); } - + bool tryWait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Returns true if the result became @@ -299,7 +299,7 @@ public: { return _pHolder->tryWait(milliseconds); } - + void wait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Throws a TimeoutException if the @@ -307,20 +307,20 @@ public: { _pHolder->wait(milliseconds); } - + bool available() const /// Returns true if a result is available. { return _pHolder->tryWait(0); } - + bool failed() const /// Returns true if the active method failed (and threw an exception). /// Information about the exception can be obtained by calling error(). { return _pHolder->failed(); } - + std::string error() const /// If the active method threw an exception, a textual representation /// of the exception is returned. An empty string is returned if the @@ -342,14 +342,14 @@ public: { _pHolder->notify(); } - + ResultType& data() /// Returns a non-const reference to the result data. For internal /// use only. { return _pHolder->data(); } - + void error(const std::string& msg) /// Sets the failed flag and the exception message. { @@ -361,7 +361,7 @@ public: { _pHolder->error(exc); } - + private: ActiveResult(); @@ -373,8 +373,8 @@ private: template <> class ActiveResult /// This class holds the result of an asynchronous method - /// invocation (see class ActiveMethod). It is used to pass the - /// result from the execution thread back to the invocation thread. + /// invocation (see class ActiveMethod). It is used to pass the + /// result from the execution thread back to the invocation thread. { public: typedef ActiveResultHolder ActiveResultHolderType; @@ -385,20 +385,20 @@ public: { poco_check_ptr (pHolder); } - + ActiveResult(const ActiveResult& result) /// Copy constructor. { _pHolder = result._pHolder; _pHolder->duplicate(); } - + ~ActiveResult() /// Destroys the result. { _pHolder->release(); } - + ActiveResult& operator = (const ActiveResult& result) /// Assignment operator. { @@ -406,19 +406,19 @@ public: swap(tmp); return *this; } - - void swap(ActiveResult& result) + + void swap(ActiveResult& result) noexcept { using std::swap; swap(_pHolder, result._pHolder); } - + void wait() /// Pauses the caller until the result becomes available. { _pHolder->wait(); } - + bool tryWait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Returns true if the result became @@ -426,7 +426,7 @@ public: { return _pHolder->tryWait(milliseconds); } - + void wait(long milliseconds) /// Waits up to the specified interval for the result to /// become available. Throws a TimeoutException if the @@ -434,20 +434,20 @@ public: { _pHolder->wait(milliseconds); } - + bool available() const /// Returns true if a result is available. { return _pHolder->tryWait(0); } - + bool failed() const /// Returns true if the active method failed (and threw an exception). /// Information about the exception can be obtained by calling error(). { return _pHolder->failed(); } - + std::string error() const /// If the active method threw an exception, a textual representation /// of the exception is returned. An empty string is returned if the @@ -469,7 +469,7 @@ public: { _pHolder->notify(); } - + void error(const std::string& msg) /// Sets the failed flag and the exception message. { @@ -481,7 +481,7 @@ public: { _pHolder->error(exc); } - + private: ActiveResult(); diff --git a/Foundation/include/Poco/ActiveStarter.h b/Foundation/include/Poco/ActiveStarter.h index b79a31e8f..c1e211738 100644 --- a/Foundation/include/Poco/ActiveStarter.h +++ b/Foundation/include/Poco/ActiveStarter.h @@ -28,7 +28,7 @@ namespace Poco { template class ActiveStarter - /// The default implementation of the StarterType + /// The default implementation of the StarterType /// policy for ActiveMethod. It starts the method /// in its own thread, obtained from the default /// thread pool. diff --git a/Foundation/include/Poco/Activity.h b/Foundation/include/Poco/Activity.h index 8329e6d5c..9f5081625 100644 --- a/Foundation/include/Poco/Activity.h +++ b/Foundation/include/Poco/Activity.h @@ -42,24 +42,24 @@ class Activity: public Runnable /// be stopped at any time. However, to make stopping /// an activity work, the method implementing the /// activity has to check periodically whether it - /// has been requested to stop, and if so, return. + /// has been requested to stop, and if so, return. /// Activities are stopped before the object they belong to is /// destroyed. Methods implementing activities cannot have arguments - /// or return values. + /// or return values. /// /// Activity objects are used as follows: /// /// class ActiveObject /// { /// public: - /// ActiveObject(): + /// ActiveObject(): /// _activity(this, &ActiveObject::runActivity) /// { /// ... /// } - /// + /// /// ... - /// + /// /// protected: /// void runActivity() /// { @@ -88,7 +88,7 @@ public: { poco_check_ptr (pOwner); } - + ~Activity() /// Stops and destroys the activity. { @@ -102,7 +102,7 @@ public: poco_unexpected(); } } - + void start() /// Starts the activity by acquiring a /// thread for it from the default thread pool. @@ -113,7 +113,7 @@ public: void start(ThreadPool& pool) { FastMutex::ScopedLock lock(_mutex); - + if (!_running) { _done.reset(); @@ -130,19 +130,20 @@ public: } } } - + void stop() /// Requests to stop the activity. { _stopped = true; } - + void wait() /// Waits for the activity to complete. { if (_running) { _done.wait(); + _running = false; } } @@ -154,15 +155,16 @@ public: if (_running) { _done.wait(milliseconds); + _running = false; } } - + bool isStopped() const /// Returns true if the activity has been requested to stop. { return _stopped; } - + bool isRunning() const /// Returns true if the activity is running. { @@ -178,14 +180,12 @@ protected: } catch (...) { - _running = false; _done.set(); throw; } - _running = false; _done.set(); } - + private: Activity(); Activity(const Activity&); diff --git a/Foundation/include/Poco/Any.h b/Foundation/include/Poco/Any.h index ba6b71433..2321937ee 100644 --- a/Foundation/include/Poco/Any.h +++ b/Foundation/include/Poco/Any.h @@ -23,12 +23,13 @@ #include +#define poco_any_assert(cond) do { if (!(cond)) std::abort(); } while (0) + + namespace Poco { - class Any; - namespace Dynamic { class Var; @@ -38,7 +39,14 @@ template class VarHolderImpl; } -#ifndef POCO_NO_SOO +template +struct TypeSizeLE: + std::integral_constant{}; + + +template +struct TypeSizeGT: + std::integral_constant S)>{}; template @@ -51,6 +59,9 @@ union Placeholder /// (i.e. there will be no heap-allocation). The local buffer size is one byte /// larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating /// where the object was allocated (0 => heap, 1 => local). + /// + /// Important: for SOO builds, only same-type (or trivial both-empty no-op) + /// swap operation is allowed. { public: struct Size @@ -58,14 +69,38 @@ public: static const unsigned int value = SizeV; }; - Placeholder() + Placeholder(const Placeholder&) = delete; + Placeholder(Placeholder&&) = delete; + Placeholder& operator=(const Placeholder&) = delete; + Placeholder& operator=(Placeholder&&) = delete; + +#ifndef POCO_NO_SOO + + Placeholder(): pHolder(0) { - erase(); + std::memset(holder, 0, sizeof(Placeholder)); + } + + ~Placeholder() + { + destruct(false); + } + + void swap(Placeholder& other) noexcept + { + if (!isEmpty() || !other.isEmpty()) + std::swap(holder, other.holder); } void erase() { - std::memset(holder, 0, sizeof(Placeholder)); + destruct(true); + } + + bool isEmpty() const + { + static char buf[SizeV+1] = {}; + return 0 == std::memcmp(holder, buf, SizeV+1); } bool isLocal() const @@ -73,9 +108,24 @@ public: return holder[SizeV] != 0; } - void setLocal(bool local) const + template::value>::type* = nullptr> + PlaceholderT* assign(const V& value) { - holder[SizeV] = local ? 1 : 0; + erase(); + new (reinterpret_cast(holder)) T(value); + setLocal(true); + return reinterpret_cast(holder); + } + + template::value>::type* = nullptr> + PlaceholderT* assign(const V& value) + { + erase(); + pHolder = new T(value); + setLocal(false); + return pHolder; } PlaceholderT* content() const @@ -86,40 +136,67 @@ public: return pHolder; } -// MSVC71,80 won't extend friendship to nested class (Any::Holder) -#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80)) private: -#endif - typedef typename std::aligned_storage::type AlignerType; + typedef typename std::aligned_storage::type AlignerType; - PlaceholderT* pHolder; - mutable char holder[SizeV + 1]; - AlignerType aligner; - - friend class Any; - friend class Dynamic::Var; - friend class Dynamic::VarHolder; - template friend class Dynamic::VarHolderImpl; -}; - - -#else // !POCO_NO_SOO - - -template -union Placeholder - /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small - /// object optimization, when enabled). - /// - /// If Holder fits into POCO_SMALL_OBJECT_SIZE bytes of storage, - /// it will be placement-new-allocated into the local buffer - /// (i.e. there will be no heap-allocation). The local buffer size is one byte - /// larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating - /// where the object was allocated (0 => heap, 1 => local). -{ -public: - Placeholder () + void setLocal(bool local) const { + holder[SizeV] = local ? 1 : 0; + } + + void destruct(bool clear) + { + if (!isEmpty()) + { + if (!isLocal()) + delete pHolder; + else + reinterpret_cast(holder)->~PlaceholderT(); + + if (clear) std::memset(holder, 0, sizeof(Placeholder)); + } + } + + mutable unsigned char holder[SizeV+1]; + AlignerType aligner; + +#else // POCO_NO_SOO + + Placeholder(): pHolder(0) + { + } + + ~Placeholder() + { + delete pHolder; + } + + void swap(Placeholder& other) noexcept + { + std::swap(pHolder, other.pHolder); + } + + void erase() + { + delete pHolder; + pHolder = 0; + } + + bool isEmpty() const + { + return 0 == pHolder; + } + + bool isLocal() const + { + return false; + } + + template + PlaceholderT* assign(const V& value) + { + erase(); + return pHolder = new T(value); } PlaceholderT* content() const @@ -127,25 +204,14 @@ public: return pHolder; } -// MSVC71,80 won't extend friendship to nested class (Any::Holder) -#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80)) private: -#endif - +#endif // POCO_NO_SOO PlaceholderT* pHolder; - - friend class Any; - friend class Dynamic::Var; - friend class Dynamic::VarHolder; - template friend class Dynamic::VarHolderImpl; }; -#endif // POCO_NO_SOO - - class Any - /// An Any class represents a general type and is capable of storing any type, supporting type-safe extraction + /// Any class represents a general type and is capable of storing any type, supporting type-safe extraction /// of the internally stored data. /// /// Code taken from the Boost 1.33.1 library. Original copyright by Kevlin Henney. Modified for Poco @@ -156,8 +222,6 @@ class Any { public: -#ifndef POCO_NO_SOO - Any() /// Creates an empty any type. { @@ -185,41 +249,31 @@ public: /// Destructor. If Any is locally held, calls ValueHolder destructor; /// otherwise, deletes the placeholder from the heap. { - if (!empty()) - { - if (_valueHolder.isLocal()) - destruct(); - else - delete content(); - } } - Any& swap(Any& other) + Any& swap(Any& other) noexcept /// Swaps the content of the two Anys. /// - /// When small object optimization is enabled, swap only - /// has no-throw guarantee when both (*this and other) - /// objects are allocated on the heap. + /// If an exception occurs during swapping, the program + /// execution is aborted. { if (this == &other) return *this; if (!_valueHolder.isLocal() && !other._valueHolder.isLocal()) { - std::swap(_valueHolder.pHolder, other._valueHolder.pHolder); + _valueHolder.swap(other._valueHolder); } else { - Any tmp(*this); try { - if (_valueHolder.isLocal()) destruct(); + Any tmp(*this); construct(other); other = tmp; } catch (...) { - construct(tmp); - throw; + std::abort(); } } @@ -252,11 +306,10 @@ public: bool empty() const /// Returns true if the Any is empty. { - char buf[POCO_SMALL_OBJECT_SIZE] = { 0 }; - return 0 == std::memcmp(_valueHolder.holder, buf, POCO_SMALL_OBJECT_SIZE); + return _valueHolder.isEmpty(); } - const std::type_info & type() const + const std::type_info& type() const /// Returns the type information of the stored content. /// If the Any is empty typeid(void) is returned. /// It is recommended to always query an Any for its type info before @@ -265,6 +318,14 @@ public: return empty() ? typeid(void) : content()->type(); } + bool local() const + /// Returns true if data is held locally (ie. not allocated on the heap). + /// If POCO_NO_SOO is defined, it always return false. + /// The main purpose of this function is use for testing. + { + return _valueHolder.isLocal(); + } + private: class ValueHolder { @@ -283,28 +344,20 @@ private: { } - virtual const std::type_info & type() const + virtual const std::type_info& type() const { return typeid(ValueType); } virtual void clone(Placeholder* pPlaceholder) const { - if ((sizeof(Holder) <= POCO_SMALL_OBJECT_SIZE)) - { - new ((ValueHolder*) pPlaceholder->holder) Holder(_held); - pPlaceholder->setLocal(true); - } - else - { - pPlaceholder->pHolder = new Holder(_held); - pPlaceholder->setLocal(false); - } + pPlaceholder->assign, ValueType>(_held); } ValueType _held; private: + Holder & operator = (const Holder &); }; @@ -316,16 +369,7 @@ private: template void construct(const ValueType& value) { - if (sizeof(Holder) <= Placeholder::Size::value) - { - new (reinterpret_cast(_valueHolder.holder)) Holder(value); - _valueHolder.setLocal(true); - } - else - { - _valueHolder.pHolder = new Holder(value); - _valueHolder.setLocal(false); - } + _valueHolder.assign, ValueType>(value); } void construct(const Any& other) @@ -336,130 +380,8 @@ private: _valueHolder.erase(); } - void destruct() - { - content()->~ValueHolder(); - } - Placeholder _valueHolder; - -#else // if POCO_NO_SOO - - - Any(): _pHolder(0) - /// Creates an empty any type. - { - } - - template - Any(const ValueType& value): - _pHolder(new Holder(value)) - /// Creates an any which stores the init parameter inside. - /// - /// Example: - /// Any a(13); - /// Any a(string("12345")); - { - } - - Any(const Any& other): - _pHolder(other._pHolder ? other._pHolder->clone() : 0) - /// Copy constructor, works with both empty and initialized Any values. - { - } - - ~Any() - { - delete _pHolder; - } - - Any& swap(Any& rhs) - /// Swaps the content of the two Anys. - { - std::swap(_pHolder, rhs._pHolder); - return *this; - } - - template - Any& operator = (const ValueType& rhs) - /// Assignment operator for all types != Any. - /// - /// Example: - /// Any a = 13; - /// Any a = string("12345"); - { - Any(rhs).swap(*this); - return *this; - } - - Any& operator = (const Any& rhs) - /// Assignment operator for Any. - { - Any(rhs).swap(*this); - return *this; - } - - bool empty() const - /// Returns true if the Any is empty. - { - return !_pHolder; - } - - const std::type_info& type() const - /// Returns the type information of the stored content. - /// If the Any is empty typeid(void) is returned. - /// It is recommended to always query an Any for its type info before - /// trying to extract data via an AnyCast/RefAnyCast. - { - return _pHolder ? _pHolder->type() : typeid(void); - } - -private: - class ValueHolder - { - public: - virtual ~ValueHolder() = default; - - virtual const std::type_info& type() const = 0; - virtual ValueHolder* clone() const = 0; - }; - - template - class Holder: public ValueHolder - { - public: - Holder(const ValueType& value): - _held(value) - { - } - - virtual const std::type_info& type() const - { - return typeid(ValueType); - } - - virtual ValueHolder* clone() const - { - return new Holder(_held); - } - - ValueType _held; - - private: - Holder & operator = (const Holder &); - }; - - ValueHolder* content() const - { - return _pHolder; - } - -private: - ValueHolder* _pHolder; - -#endif // POCO_NO_SOO - template friend ValueType* AnyCast(Any*); @@ -522,10 +444,10 @@ ValueType AnyCast(Any& operand) if (!result) { std::string s = "RefAnyCast: Failed to convert between Any types "; - if (operand._pHolder) + if (operand.content()) { s.append(1, '('); - s.append(operand._pHolder->type().name()); + s.append(operand.content()->type().name()); s.append(" => "); s.append(typeid(ValueType).name()); s.append(1, ')'); @@ -564,10 +486,10 @@ const ValueType& RefAnyCast(const Any & operand) if (!result) { std::string s = "RefAnyCast: Failed to convert between Any types "; - if (operand._pHolder) + if (operand.content()) { s.append(1, '('); - s.append(operand._pHolder->type().name()); + s.append(operand.content()->type().name()); s.append(" => "); s.append(typeid(ValueType).name()); s.append(1, ')'); @@ -589,10 +511,10 @@ ValueType& RefAnyCast(Any& operand) if (!result) { std::string s = "RefAnyCast: Failed to convert between Any types "; - if (operand._pHolder) + if (operand.content()) { s.append(1, '('); - s.append(operand._pHolder->type().name()); + s.append(operand.content()->type().name()); s.append(" => "); s.append(typeid(ValueType).name()); s.append(1, ')'); diff --git a/Foundation/include/Poco/ArchiveStrategy.h b/Foundation/include/Poco/ArchiveStrategy.h index e04605f38..f3344573f 100644 --- a/Foundation/include/Poco/ArchiveStrategy.h +++ b/Foundation/include/Poco/ArchiveStrategy.h @@ -32,7 +32,7 @@ class ArchiveCompressor; class Foundation_API ArchiveStrategy - /// The ArchiveStrategy is used by FileChannel + /// The ArchiveStrategy is used by FileChannel /// to rename a rotated log file for archiving. /// /// Archived files can be automatically compressed, @@ -48,16 +48,16 @@ public: /// The given LogFile object is deleted. void compress(bool flag = true); - /// Enables or disables compression of archived files. + /// Enables or disables compression of archived files. protected: void moveFile(const std::string& oldName, const std::string& newName); bool exists(const std::string& name); - + private: ArchiveStrategy(const ArchiveStrategy&); ArchiveStrategy& operator = (const ArchiveStrategy&); - + bool _compress; ArchiveCompressor* _pCompressor; }; @@ -84,11 +84,11 @@ public: ArchiveByTimestampStrategy() { } - + ~ArchiveByTimestampStrategy() { } - + LogFile* archive(LogFile* pFile) /// Archives the file by appending the current timestamp to the /// file name. If the new file name exists, additionally a monotonic @@ -99,7 +99,7 @@ public: std::string archPath = path; archPath.append("."); DateTimeFormatter::append(archPath, DT().timestamp(), "%Y%m%d%H%M%S%i"); - + if (exists(archPath)) archiveByNumber(archPath); else moveFile(path, archPath); @@ -121,7 +121,7 @@ private: NumberFormatter::append(path, ++n); } while (exists(path)); - + while (n >= 0) { std::string oldPath = basePath; diff --git a/Foundation/include/Poco/Array.h b/Foundation/include/Poco/Array.h index eaae733c9..ff598b85f 100644 --- a/Foundation/include/Poco/Array.h +++ b/Foundation/include/Poco/Array.h @@ -159,7 +159,7 @@ public: enum { static_size = N }; - void swap (Array& y) + void swap (Array& y) noexcept { std::swap_ranges(begin(),end(),y.begin()); } @@ -246,7 +246,7 @@ bool operator>= (const Array& x, const Array& y) template -inline void swap (Array& x, Array& y) +inline void swap (Array& x, Array& y) noexcept /// global swap() { x.swap(y); diff --git a/Foundation/include/Poco/Ascii.h b/Foundation/include/Poco/Ascii.h index e7a8b855d..3556a322f 100644 --- a/Foundation/include/Poco/Ascii.h +++ b/Foundation/include/Poco/Ascii.h @@ -55,7 +55,7 @@ public: ACP_GRAPH = 0x0100, ACP_PRINT = 0x0200 }; - + static int properties(int ch); /// Return the ASCII character properties for the /// character with the given ASCII value. @@ -65,44 +65,44 @@ public: static bool hasSomeProperties(int ch, int properties); /// Returns true if the given character is - /// within the ASCII range and has at least one of + /// within the ASCII range and has at least one of /// the given properties. static bool hasProperties(int ch, int properties); /// Returns true if the given character is - /// within the ASCII range and has all of + /// within the ASCII range and has all of /// the given properties. static bool isAscii(int ch); /// Returns true iff the given character code is within /// the ASCII range (0 .. 127). - + static bool isSpace(int ch); /// Returns true iff the given character is a whitespace. - + static bool isDigit(int ch); /// Returns true iff the given character is a digit. static bool isHexDigit(int ch); /// Returns true iff the given character is a hexadecimal digit. - + static bool isPunct(int ch); /// Returns true iff the given character is a punctuation character. - + static bool isAlpha(int ch); - /// Returns true iff the given character is an alphabetic character. + /// Returns true iff the given character is an alphabetic character. static bool isAlphaNumeric(int ch); - /// Returns true iff the given character is an alphabetic character. - + /// Returns true iff the given character is an alphabetic character. + static bool isLower(int ch); /// Returns true iff the given character is a lowercase alphabetic /// character. - + static bool isUpper(int ch); /// Returns true iff the given character is an uppercase alphabetic /// character. - + static bool isPrintable(int ch); /// Returns true iff the given character is printable. @@ -115,7 +115,7 @@ public: /// If the given character is a lowercase character, /// return its uppercase counterpart, otherwise return /// the character. - + private: static const int CHARACTER_PROPERTIES[128]; }; @@ -126,7 +126,7 @@ private: // inline int Ascii::properties(int ch) { - if (isAscii(ch)) + if (isAscii(ch)) return CHARACTER_PROPERTIES[ch]; else return 0; diff --git a/Foundation/include/Poco/AsyncChannel.h b/Foundation/include/Poco/AsyncChannel.h index 700b7f3db..190bae7dd 100644 --- a/Foundation/include/Poco/AsyncChannel.h +++ b/Foundation/include/Poco/AsyncChannel.h @@ -25,6 +25,7 @@ #include "Poco/Runnable.h" #include "Poco/AutoPtr.h" #include "Poco/NotificationQueue.h" +#include namespace Poco { @@ -110,6 +111,7 @@ private: NotificationQueue _queue; std::size_t _queueSize = 0; std::size_t _dropCount = 0; + std::atomic _closed; }; diff --git a/Foundation/include/Poco/AutoPtr.h b/Foundation/include/Poco/AutoPtr.h index 8d6bbacd1..8251f4669 100644 --- a/Foundation/include/Poco/AutoPtr.h +++ b/Foundation/include/Poco/AutoPtr.h @@ -194,7 +194,7 @@ public: return assign(ptr); } - void swap(AutoPtr& ptr) + void swap(AutoPtr& ptr) noexcept { std::swap(_ptr, ptr._ptr); } @@ -398,7 +398,7 @@ private: template -inline void swap(AutoPtr& p1, AutoPtr& p2) +inline void swap(AutoPtr& p1, AutoPtr& p2) noexcept { p1.swap(p2); } diff --git a/Foundation/include/Poco/AutoReleasePool.h b/Foundation/include/Poco/AutoReleasePool.h index 42c8de7c4..80e11e558 100644 --- a/Foundation/include/Poco/AutoReleasePool.h +++ b/Foundation/include/Poco/AutoReleasePool.h @@ -27,10 +27,10 @@ namespace Poco { template class AutoReleasePool - /// An AutoReleasePool implements simple garbage collection for + /// An AutoReleasePool implements simple garbage collection for /// reference-counted objects. /// It temporarily takes ownership of reference-counted objects that - /// nobody else wants to take ownership of and releases them + /// nobody else wants to take ownership of and releases them /// at a later, appropriate point in time. /// /// Note: The correct way to add an object hold by an AutoPtr<> to @@ -46,14 +46,14 @@ public: /// Creates the AutoReleasePool. { } - + ~AutoReleasePool() /// Destroys the AutoReleasePool and releases /// all objects it currently holds. { release(); } - + void add(C* pObject) /// Adds the given object to the AutoReleasePool. /// The object's reference count is not modified @@ -61,7 +61,7 @@ public: if (pObject) _list.push_back(pObject); } - + void release() /// Releases all objects the AutoReleasePool currently holds /// by calling each object's release() method. @@ -72,10 +72,10 @@ public: _list.pop_front(); } } - + private: typedef std::list ObjectList; - + ObjectList _list; }; diff --git a/Foundation/include/Poco/Base32Decoder.h b/Foundation/include/Poco/Base32Decoder.h index c592e552c..bc87205d3 100644 --- a/Foundation/include/Poco/Base32Decoder.h +++ b/Foundation/include/Poco/Base32Decoder.h @@ -30,8 +30,8 @@ class Foundation_API Base32DecoderBuf: public UnbufferedStreamBuf /// This streambuf base32-decodes all data read /// from the istream connected to it. /// - /// Note: For performance reasons, the characters - /// are read directly from the given istream's + /// Note: For performance reasons, the characters + /// are read directly from the given istream's /// underlying streambuf, so the state /// of the istream will not reflect that of /// its streambuf. @@ -39,7 +39,7 @@ class Foundation_API Base32DecoderBuf: public UnbufferedStreamBuf public: Base32DecoderBuf(std::istream& istr); ~Base32DecoderBuf(); - + private: int readFromDevice(); int readOne(); @@ -48,10 +48,10 @@ private: int _groupLength; int _groupIndex; std::streambuf& _buf; - + static unsigned char IN_ENCODING[256]; static bool IN_ENCODING_INIT; - + private: Base32DecoderBuf(const Base32DecoderBuf&); Base32DecoderBuf& operator = (const Base32DecoderBuf&); @@ -71,7 +71,7 @@ public: protected: Base32DecoderBuf _buf; - + private: Base32DecoderIOS(const Base32DecoderIOS&); Base32DecoderIOS& operator = (const Base32DecoderIOS&); @@ -84,8 +84,8 @@ class Foundation_API Base32Decoder: public Base32DecoderIOS, public std::istream /// /// The class implements RFC 4648 - https://tools.ietf.org/html/rfc4648 /// - /// Note: For performance reasons, the characters - /// are read directly from the given istream's + /// Note: For performance reasons, the characters + /// are read directly from the given istream's /// underlying streambuf, so the state /// of the istream will not reflect that of /// its streambuf. diff --git a/Foundation/include/Poco/Base32Encoder.h b/Foundation/include/Poco/Base32Encoder.h index 47d2e1a11..f36eac89d 100644 --- a/Foundation/include/Poco/Base32Encoder.h +++ b/Foundation/include/Poco/Base32Encoder.h @@ -39,7 +39,7 @@ class Foundation_API Base32EncoderBuf: public UnbufferedStreamBuf public: Base32EncoderBuf(std::ostream& ostr, bool padding = true); ~Base32EncoderBuf(); - + int close(); /// Closes the stream buffer. @@ -50,9 +50,9 @@ private: int _groupLength; std::streambuf& _buf; bool _doPadding; - + static const unsigned char OUT_ENCODING[32]; - + friend class Base32DecoderBuf; Base32EncoderBuf(const Base32EncoderBuf&); diff --git a/Foundation/include/Poco/Base64Decoder.h b/Foundation/include/Poco/Base64Decoder.h index dbccc6f6c..678da50ec 100644 --- a/Foundation/include/Poco/Base64Decoder.h +++ b/Foundation/include/Poco/Base64Decoder.h @@ -30,8 +30,8 @@ class Foundation_API Base64DecoderBuf: public UnbufferedStreamBuf /// This streambuf base64-decodes all data read /// from the istream connected to it. /// - /// Note: For performance reasons, the characters - /// are read directly from the given istream's + /// Note: For performance reasons, the characters + /// are read directly from the given istream's /// underlying streambuf, so the state /// of the istream will not reflect that of /// its streambuf. @@ -88,8 +88,8 @@ class Foundation_API Base64Decoder: public Base64DecoderIOS, public std::istream /// /// The class implements RFC 4648 - https://tools.ietf.org/html/rfc4648 /// - /// Note: For performance reasons, the characters - /// are read directly from the given istream's + /// Note: For performance reasons, the characters + /// are read directly from the given istream's /// underlying streambuf, so the state /// of the istream will not reflect that of /// its streambuf. diff --git a/Foundation/include/Poco/Base64Encoder.h b/Foundation/include/Poco/Base64Encoder.h index 071b9018d..bc39d826b 100644 --- a/Foundation/include/Poco/Base64Encoder.h +++ b/Foundation/include/Poco/Base64Encoder.h @@ -59,7 +59,7 @@ public: void setLineLength(int lineLength); /// Specify the line length. /// - /// After the given number of characters have been written, + /// After the given number of characters have been written, /// a newline character will be written. /// /// Specify 0 for an unlimited line length. diff --git a/Foundation/include/Poco/BasicEvent.h b/Foundation/include/Poco/BasicEvent.h index 47e37dbde..a4b53101e 100644 --- a/Foundation/include/Poco/BasicEvent.h +++ b/Foundation/include/Poco/BasicEvent.h @@ -27,13 +27,13 @@ namespace Poco { -template -class BasicEvent: public AbstractEvent < +template +class BasicEvent: public AbstractEvent < TArgs, DefaultStrategy>, AbstractDelegate, TMutex > - /// A BasicEvent uses the DefaultStrategy which + /// A BasicEvent uses the DefaultStrategy which /// invokes delegates in the order they have been registered. /// /// Please see the AbstractEvent class template documentation diff --git a/Foundation/include/Poco/Buffer.h b/Foundation/include/Poco/Buffer.h index 87c59f166..34981e556 100644 --- a/Foundation/include/Poco/Buffer.h +++ b/Foundation/include/Poco/Buffer.h @@ -34,6 +34,21 @@ class Buffer /// /// This class is useful everywhere where a temporary buffer /// is needed. + /// + /// Note: A Buffer has both a size and a capacity, similar to + /// std::vector and std::string. However, upon creation of the + /// Buffer, the size always equals the capacity (provided via the + /// length argument of the constructor), as the Buffer is meant + /// to be filled by directly writing to its contents, + /// i.e., by passing the pointer to the first element + /// of the buffer obtained via begin() to a function expecting + /// a pointer to a buffer. + /// + /// Therefore, calling append() on a newly created Buffer will + /// always expand the buffer size and capacity. + /// If you need to create a Buffer and want to write data to it + /// by calling append(), the correct steps are to first create + /// the Buffer, then call resize(0), and then call append(). { public: Buffer(std::size_t length): @@ -248,7 +263,7 @@ public: return _capacity * sizeof(T); } - void swap(Buffer& other) + void swap(Buffer& other) noexcept /// Swaps the buffer with another one. { using std::swap; diff --git a/Foundation/include/Poco/BufferAllocator.h b/Foundation/include/Poco/BufferAllocator.h index c767fe4ad..9a3083eee 100644 --- a/Foundation/include/Poco/BufferAllocator.h +++ b/Foundation/include/Poco/BufferAllocator.h @@ -38,7 +38,7 @@ public: { return new char_type[static_cast(size)]; } - + static void deallocate(char_type* ptr, std::streamsize /*size*/) noexcept { delete [] ptr; diff --git a/Foundation/include/Poco/BufferedBidirectionalStreamBuf.h b/Foundation/include/Poco/BufferedBidirectionalStreamBuf.h index 5872c1289..bcb839fe8 100644 --- a/Foundation/include/Poco/BufferedBidirectionalStreamBuf.h +++ b/Foundation/include/Poco/BufferedBidirectionalStreamBuf.h @@ -29,9 +29,9 @@ namespace Poco { -template > +template > class BasicBufferedBidirectionalStreamBuf: public std::basic_streambuf - /// This is an implementation of a buffered bidirectional + /// This is an implementation of a buffered bidirectional /// streambuf that greatly simplifies the implementation of /// custom streambufs of various kinds. /// Derived classes only have to override the methods @@ -68,13 +68,13 @@ public: Allocator::deallocate(_pReadBuffer, _bufsize); Allocator::deallocate(_pWriteBuffer, _bufsize); } - + virtual int_type overflow(int_type c) { if (!(_mode & IOS::out)) return char_traits::eof(); if (flushBuffer() == std::streamsize(-1)) return char_traits::eof(); - if (c != char_traits::eof()) + if (c != char_traits::eof()) { *this->pptr() = char_traits::to_char_type(c); this->pbump(1); @@ -101,12 +101,12 @@ public: this->setg(_pReadBuffer + (4 - putback), _pReadBuffer + 4, _pReadBuffer + 4 + n); // return next character - return char_traits::to_int_type(*this->gptr()); + return char_traits::to_int_type(*this->gptr()); } virtual int sync() { - if (this->pptr() && this->pptr() > this->pbase()) + if (this->pptr() && this->pptr() > this->pbase()) { if (flushBuffer() == -1) return -1; } @@ -123,7 +123,7 @@ protected: { return _mode; } - + void resetBuffers() { this->setg(_pReadBuffer + 4, _pReadBuffer + 4, _pReadBuffer + 4); @@ -144,7 +144,7 @@ private: int flushBuffer() { int n = int(this->pptr() - this->pbase()); - if (writeToDevice(this->pbase(), n) == n) + if (writeToDevice(this->pbase(), n) == n) { this->pbump(-n); return n; @@ -169,7 +169,7 @@ private: // instantiation - to avoid duplicate symbols due to multiple // instantiations in different libraries. // -#if defined(_MSC_VER) && defined(POCO_DLL) && !defined(Foundation_EXPORTS) +#if defined(_MSC_VER) && defined(POCO_DLL) && !defined(Foundation_EXPORTS) template class Foundation_API BasicBufferedBidirectionalStreamBuf>; #endif typedef BasicBufferedBidirectionalStreamBuf> BufferedBidirectionalStreamBuf; diff --git a/Foundation/include/Poco/BufferedStreamBuf.h b/Foundation/include/Poco/BufferedStreamBuf.h index 80de74071..2c64a9f99 100644 --- a/Foundation/include/Poco/BufferedStreamBuf.h +++ b/Foundation/include/Poco/BufferedStreamBuf.h @@ -29,7 +29,7 @@ namespace Poco { -template > +template > class BasicBufferedStreamBuf: public std::basic_streambuf /// This is an implementation of a buffered streambuf /// that greatly simplifies the implementation of @@ -59,7 +59,7 @@ public: _pBuffer(Allocator::allocate(_bufsize)), _mode(mode) { - this->setg(_pBuffer + 4, _pBuffer + 4, _pBuffer + 4); + this->setg(_pBuffer + 4, _pBuffer + 4, _pBuffer + 4); this->setp(_pBuffer, _pBuffer + _bufsize); } @@ -68,7 +68,7 @@ public: try { Allocator::deallocate(_pBuffer, _bufsize); - } + } catch (...) { poco_unexpected(); @@ -80,7 +80,7 @@ public: if (!(_mode & IOS::out)) return char_traits::eof(); if (flushBuffer() == std::streamsize(-1)) return char_traits::eof(); - if (c != char_traits::eof()) + if (c != char_traits::eof()) { *this->pptr() = char_traits::to_char_type(c); this->pbump(1); @@ -107,12 +107,12 @@ public: this->setg(_pBuffer + (4 - putback), _pBuffer + 4, _pBuffer + 4 + n); // return next character - return char_traits::to_int_type(*this->gptr()); + return char_traits::to_int_type(*this->gptr()); } virtual int sync() { - if (this->pptr() && this->pptr() > this->pbase()) + if (this->pptr() && this->pptr() > this->pbase()) { if (flushBuffer() == -1) return -1; } @@ -124,7 +124,7 @@ protected: { _mode = mode; } - + openmode getMode() const { return _mode; @@ -144,7 +144,7 @@ private: int flushBuffer() { int n = int(this->pptr() - this->pbase()); - if (writeToDevice(this->pbase(), n) == n) + if (writeToDevice(this->pbase(), n) == n) { this->pbump(-n); return n; diff --git a/Foundation/include/Poco/Bugcheck.h b/Foundation/include/Poco/Bugcheck.h index ca475b887..6e1e4aae7 100644 --- a/Foundation/include/Poco/Bugcheck.h +++ b/Foundation/include/Poco/Bugcheck.h @@ -32,26 +32,26 @@ namespace Poco { class Foundation_API Bugcheck /// This class provides some static methods that are /// used by the - /// poco_assert_dbg(), poco_assert(), poco_check_ptr(), - /// poco_bugcheck() and poco_unexpected() macros. + /// poco_assert_dbg(), poco_assert(), poco_check_ptr(), + /// poco_bugcheck() and poco_unexpected() macros. /// You should not invoke these methods /// directly. Use the macros instead, as they /// automatically provide useful context information. { public: - static void assertion(const char* cond, const char* file, int line, const char* text = 0); + [[noreturn]] static void assertion(const char* cond, const char* file, int line, const char* text = 0); /// An assertion failed. Break into the debugger, if /// possible, then throw an AssertionViolationException. - static void nullPointer(const char* ptr, const char* file, int line); + [[noreturn]] static void nullPointer(const char* ptr, const char* file, int line); /// An null pointer was encountered. Break into the debugger, if /// possible, then throw an NullPointerException. - static void bugcheck(const char* file, int line); + [[noreturn]] static void bugcheck(const char* file, int line); /// An internal error was encountered. Break into the debugger, if /// possible, then throw an BugcheckException. - static void bugcheck(const char* msg, const char* file, int line); + [[noreturn]] static void bugcheck(const char* msg, const char* file, int line); /// An internal error was encountered. Break into the debugger, if /// possible, then throw an BugcheckException. @@ -186,7 +186,7 @@ struct POCO_STATIC_ASSERTION_FAILURE }; -template +template struct poco_static_assert_test { }; diff --git a/Foundation/include/Poco/ByteOrder.h b/Foundation/include/Poco/ByteOrder.h index a2f8735d1..04159cfbd 100644 --- a/Foundation/include/Poco/ByteOrder.h +++ b/Foundation/include/Poco/ByteOrder.h @@ -119,7 +119,7 @@ private: #if (POCO_MSVC_VERSION > 71) #define POCO_HAVE_MSC_BYTESWAP 1 #endif - #elif defined(__clang__) + #elif defined(__clang__) #if __has_builtin(__builtin_bswap32) #define POCO_HAVE_GCC_BYTESWAP 1 #endif diff --git a/Foundation/include/Poco/Channel.h b/Foundation/include/Poco/Channel.h index 94caf144d..8b97fc616 100644 --- a/Foundation/include/Poco/Channel.h +++ b/Foundation/include/Poco/Channel.h @@ -46,29 +46,29 @@ public: /// the reference count to one. virtual void open(); - /// Does whatever is necessary to open the channel. + /// Does whatever is necessary to open the channel. /// The default implementation does nothing. - + virtual void close(); /// Does whatever is necessary to close the channel. /// The default implementation does nothing. - + virtual void log(const Message& msg) = 0; /// Logs the given message to the channel. Must be /// overridden by subclasses. /// /// If the channel has not been opened yet, the log() /// method will open it. - + void setProperty(const std::string& name, const std::string& value); /// Throws a PropertyNotSupportedException. std::string getProperty(const std::string& name) const; /// Throws a PropertyNotSupportedException. - + protected: virtual ~Channel(); - + private: Channel(const Channel&); Channel& operator = (const Channel&); diff --git a/Foundation/include/Poco/Checksum.h b/Foundation/include/Poco/Checksum.h index 3961bb762..9a020f3cc 100644 --- a/Foundation/include/Poco/Checksum.h +++ b/Foundation/include/Poco/Checksum.h @@ -28,15 +28,15 @@ class Foundation_API Checksum /// This class calculates CRC-32 or Adler-32 checksums /// for arbitrary data. /// - /// A cyclic redundancy check (CRC) is a type of hash function, which is used to produce a - /// small, fixed-size checksum of a larger block of data, such as a packet of network + /// A cyclic redundancy check (CRC) is a type of hash function, which is used to produce a + /// small, fixed-size checksum of a larger block of data, such as a packet of network /// traffic or a computer file. CRC-32 is one of the most commonly used CRC algorithms. /// - /// Adler-32 is a checksum algorithm which was invented by Mark Adler. - /// It is almost as reliable as a 32-bit cyclic redundancy check for protecting against - /// accidental modification of data, such as distortions occurring during a transmission, + /// Adler-32 is a checksum algorithm which was invented by Mark Adler. + /// It is almost as reliable as a 32-bit cyclic redundancy check for protecting against + /// accidental modification of data, such as distortions occurring during a transmission, /// but is significantly faster to calculate in software. - + { public: enum Type diff --git a/Foundation/include/Poco/ClassLibrary.h b/Foundation/include/Poco/ClassLibrary.h index d2a54bdee..e10dbcbfb 100644 --- a/Foundation/include/Poco/ClassLibrary.h +++ b/Foundation/include/Poco/ClassLibrary.h @@ -40,7 +40,7 @@ extern "C" bool POCO_LIBRARY_API pocoBuildManifest(Poco::ManifestBase* pManifest); void POCO_LIBRARY_API pocoInitializeLibrary(); void POCO_LIBRARY_API pocoUninitializeLibrary(); -} +} // diff --git a/Foundation/include/Poco/ClassLoader.h b/Foundation/include/Poco/ClassLoader.h index 09f20bb6e..a55c63fdc 100644 --- a/Foundation/include/Poco/ClassLoader.h +++ b/Foundation/include/Poco/ClassLoader.h @@ -140,7 +140,7 @@ public: } void loadLibrary(const std::string& path, const std::string& manifest) - /// Loads a library from the given path, using the given manifest. + /// Loads a library from the given path, using the given manifest. /// Does nothing if the library is already loaded. /// Throws a LibraryLoadException if the library /// cannot be loaded or does not have a Manifest. @@ -208,9 +208,9 @@ public: { loadLibrary(path, ""); } - + void unloadLibrary(const std::string& path) - /// Unloads the given library. + /// Unloads the given library. /// Be extremely cautious when unloading shared libraries. /// If objects from the library are still referenced somewhere, /// a total crash is very likely. @@ -256,7 +256,7 @@ public: } return 0; } - + const Meta& classFor(const std::string& className) const /// Returns a reference to the MetaObject for the given /// class. Throws a NotFoundException if the class @@ -268,7 +268,7 @@ public: else throw NotFoundException(className); } - + Base* create(const std::string& className) const /// Creates an instance of the given class. /// Throws a NotFoundException if the class @@ -276,7 +276,7 @@ public: { return classFor(className).create(); } - + Base& instance(const std::string& className) const /// Returns a reference to the sole instance of /// the given class. The class must be a singleton, @@ -286,7 +286,7 @@ public: { return classFor(className).instance(); } - + bool canCreate(const std::string& className) const /// Returns true if create() can create new instances /// of the class. @@ -307,7 +307,7 @@ public: { return classFor(className).isAutoDelete(pObject); } - + const Manif* findManifest(const std::string& path) const /// Returns a pointer to the Manifest for the given /// library, or a null pointer if the library has not been loaded. @@ -320,7 +320,7 @@ public: else return 0; } - + const Manif& manifestFor(const std::string& path) const /// Returns a reference to the Manifest for the given library /// Throws a NotFoundException if the library has not been loaded. diff --git a/Foundation/include/Poco/Clock.h b/Foundation/include/Poco/Clock.h index 1a97851ce..570866c45 100644 --- a/Foundation/include/Poco/Clock.h +++ b/Foundation/include/Poco/Clock.h @@ -35,8 +35,8 @@ class Foundation_API Clock /// The monotonic() function can be used to check whether /// the system's clock is monotonic. /// - /// Monotonic Clock is available on Windows, Linux, OS X - /// and on POSIX platforms supporting clock_gettime() with CLOCK_MONOTONIC. + /// Monotonic Clock is available on Windows, Linux, OS X + /// and on POSIX platforms supporting clock_gettime() with CLOCK_MONOTONIC. /// /// Clock values are relative to a system-dependent epoch time /// (usually the system's startup time) and have no relation @@ -54,22 +54,22 @@ public: Clock(); /// Creates a Clock with the current system clock value. - + Clock(ClockVal tv); /// Creates a Clock from the given clock value. - + Clock(const Clock& other); /// Copy constructor. - + ~Clock(); /// Destroys the Clock. - + Clock& operator = (const Clock& other); Clock& operator = (ClockVal tv); - - void swap(Clock& clock); + + void swap(Clock& clock) noexcept; /// Swaps the Clock with another one. - + void update(); /// Updates the Clock with the current system clock. @@ -79,13 +79,13 @@ public: bool operator >= (const Clock& ts) const; bool operator < (const Clock& ts) const; bool operator <= (const Clock& ts) const; - + Clock operator + (ClockDiff d) const; Clock operator - (ClockDiff d) const; ClockDiff operator - (const Clock& ts) const; Clock& operator += (ClockDiff d); Clock& operator -= (ClockDiff d); - + ClockVal microseconds() const; /// Returns the clock value expressed in microseconds /// since the system-specific epoch time (usually system @@ -97,23 +97,23 @@ public: /// startup). /// /// Same as microseconds(). - + ClockDiff elapsed() const; /// Returns the time elapsed since the time denoted by /// the Clock instance. Equivalent to Clock() - *this. - + bool isElapsed(ClockDiff interval) const; /// Returns true iff the given interval has passed /// since the time denoted by the Clock instance. - + static ClockDiff resolution(); /// Returns the resolution in units per second. /// Since the Clock class has microsecond resolution, /// the returned value is always 1000000. - + static ClockDiff accuracy(); /// Returns the system's clock accuracy in microseconds. - + static bool monotonic(); /// Returns true iff the system's clock is monotonic. @@ -220,7 +220,7 @@ inline Clock::ClockDiff Clock::resolution() } -inline void swap(Clock& s1, Clock& s2) +inline void swap(Clock& s1, Clock& s2) noexcept { s1.swap(s2); } diff --git a/Foundation/include/Poco/Condition.h b/Foundation/include/Poco/Condition.h index 3340533df..35e73d779 100644 --- a/Foundation/include/Poco/Condition.h +++ b/Foundation/include/Poco/Condition.h @@ -30,8 +30,8 @@ namespace Poco { class Foundation_API Condition - /// A Condition is a synchronization object used to block a thread - /// until a particular condition is met. + /// A Condition is a synchronization object used to block a thread + /// until a particular condition is met. /// A Condition object is always used in conjunction with /// a Mutex (or FastMutex) object. /// @@ -43,16 +43,16 @@ class Foundation_API Condition public: Condition(); /// Creates the Condition. - + ~Condition(); /// Destroys the Condition. - + template void wait(Mtx& mutex) /// Unlocks the mutex (which must be locked upon calling /// wait()) and waits until the Condition is signalled. /// - /// The given mutex will be locked again upon + /// The given mutex will be locked again upon /// leaving the function, even in case of an exception. { ScopedUnlock unlock(mutex, false); @@ -64,13 +64,13 @@ public: } event.wait(); } - + template void wait(Mtx& mutex, long milliseconds) /// Unlocks the mutex (which must be locked upon calling /// wait()) and waits for the given time until the Condition is signalled. /// - /// The given mutex will be locked again upon successfully leaving the + /// The given mutex will be locked again upon successfully leaving the /// function, even in case of an exception. /// /// Throws a TimeoutException if the Condition is not signalled @@ -79,13 +79,13 @@ public: if (!tryWait(mutex, milliseconds)) throw TimeoutException(); } - + template bool tryWait(Mtx& mutex, long milliseconds) /// Unlocks the mutex (which must be locked upon calling /// tryWait()) and waits for the given time until the Condition is signalled. /// - /// The given mutex will be locked again upon leaving the + /// The given mutex will be locked again upon leaving the /// function, even in case of an exception. /// /// Returns true if the Condition has been signalled @@ -106,7 +106,7 @@ public: } return true; } - + void signal(); /// Signals the Condition and allows one waiting thread /// to continue execution. @@ -119,13 +119,13 @@ protected: void enqueue(Event& event); void dequeue(); void dequeue(Event& event); - + private: Condition(const Condition&); Condition& operator = (const Condition&); - + typedef std::deque WaitQueue; - + FastMutex _mutex; WaitQueue _waitQueue; }; diff --git a/Foundation/include/Poco/Config.h b/Foundation/include/Poco/Config.h index fb3cca8f4..8de4e610b 100644 --- a/Foundation/include/Poco/Config.h +++ b/Foundation/include/Poco/Config.h @@ -71,24 +71,15 @@ // cases when value holder fits into POCO_SMALL_OBJECT_SIZE // (see below). // -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// !!! NOTE: Any/Dynamic::Var SOO will NOT work reliably !!! -// !!! without C++11 (std::aligned_storage in particular). !!! -// !!! Only comment this out if your compiler has support !!! -// !!! for std::aligned_storage. !!! -// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -// -#ifndef POCO_ENABLE_SOO -#define POCO_NO_SOO -#endif +// #define POCO_NO_SOO // Small object size in bytes. When assigned to Any or Var, // objects larger than this value will be alocated on the heap, // while those smaller will be placement new-ed into an -// internal buffer. -#if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO) - #define POCO_SMALL_OBJECT_SIZE 32 +// internal stack-auto-allocated buffer. +#if !defined(POCO_SMALL_OBJECT_SIZE) + #define POCO_SMALL_OBJECT_SIZE 64 #endif @@ -96,7 +87,7 @@ // on platforms with no inotify. // #define POCO_NO_INOTIFY -// Define to force the use of PollingDirectoryWatcher +// Define to force the use of PollingDirectoryWatcher // #define POCO_DW_FORCE_POLLING @@ -151,6 +142,20 @@ // #define POCO_NET_NO_IPv6 +// No UNIX socket support +// Define to disable unix sockets +// #define POCO_NET_NO_UNIX_SOCKET + + +// Define to nonzero to enable move semantics +// on classes where it introduces a new state. +// For explanation, see: +// https://github.com/pocoproject/poco/wiki/Move-Semantics-in-POCO +#ifndef POCO_NEW_STATE_ON_MOVE +// #define POCO_NEW_STATE_ON_MOVE 1 +#endif + + // Windows CE has no locale support #if defined(_WIN32_WCE) #define POCO_NO_LOCALE @@ -185,7 +190,7 @@ // empty or other value: // Do not link any OpenSSL libraries automatically. You will have to edit the // Visual C++ project files for Crypto and NetSSL_OpenSSL. -#ifndef POCO_EXTERNAL_OPENSSL +#if !defined(POCO_EXTERNAL_OPENSSL) && defined(POCO_EXTERNAL_OPENSSL_SLPRO) #define POCO_EXTERNAL_OPENSSL POCO_EXTERNAL_OPENSSL_SLPRO #endif diff --git a/Foundation/include/Poco/Configurable.h b/Foundation/include/Poco/Configurable.h index cb260d382..6a5dd8fd5 100644 --- a/Foundation/include/Poco/Configurable.h +++ b/Foundation/include/Poco/Configurable.h @@ -48,15 +48,15 @@ class Foundation_API Configurable public: Configurable(); /// Creates the Configurable. - + virtual ~Configurable(); /// Destroys the Configurable. - + virtual void setProperty(const std::string& name, const std::string& value) = 0; /// Sets the property with the given name to the given value. /// If a property with the given name is not supported, a /// PropertyNotSupportedException is thrown. - + virtual std::string getProperty(const std::string& name) const = 0; /// Returns the value of the property with the given name. /// If a property with the given name is not supported, a diff --git a/Foundation/include/Poco/ConsoleChannel.h b/Foundation/include/Poco/ConsoleChannel.h index 0c133abe7..d02eb78a9 100644 --- a/Foundation/include/Poco/ConsoleChannel.h +++ b/Foundation/include/Poco/ConsoleChannel.h @@ -34,7 +34,7 @@ class Foundation_API ConsoleChannel: public Channel /// by a newline. /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is contained + /// appropriate Formatter to control what is contained /// in the text. /// /// Similar to StreamChannel, except that a static @@ -47,13 +47,13 @@ public: ConsoleChannel(); /// Creates the channel and attaches std::clog. - + ConsoleChannel(std::ostream& str); /// Creates the channel using the given stream. void log(const Message& msg); /// Logs the given message to the channel's stream. - + protected: ~ConsoleChannel(); @@ -77,7 +77,7 @@ class Foundation_API ColorConsoleChannel: public Channel /// property to true (default). Furthermore, colors can be /// configured by setting the following properties /// (default values are given in parenthesis): - /// + /// /// * traceColor (gray) /// * debugColor (gray) /// * informationColor (default) @@ -88,7 +88,7 @@ class Foundation_API ColorConsoleChannel: public Channel /// * fatalColor (lightRed) /// /// The following color values are supported: - /// + /// /// * default /// * black /// * red @@ -108,7 +108,7 @@ class Foundation_API ColorConsoleChannel: public Channel /// * white /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is contained + /// appropriate Formatter to control what is contained /// in the text. /// /// Similar to StreamChannel, except that a static @@ -116,19 +116,19 @@ class Foundation_API ColorConsoleChannel: public Channel /// console channels concurrently writing to the /// same stream. { -public: +public: ColorConsoleChannel(); /// Creates the channel and attaches std::clog. - + ColorConsoleChannel(std::ostream& str); /// Creates the channel using the given stream. void log(const Message& msg); /// Logs the given message to the channel's stream. - + void setProperty(const std::string& name, const std::string& value); - /// Sets the property with the given name. - /// + /// Sets the property with the given name. + /// /// The following properties are supported: /// * enableColors: Enable or disable colors. /// * traceColor: Specify color for trace messages. @@ -147,7 +147,7 @@ public: /// See setProperty() for a description of the supported /// properties. -protected: +protected: enum Color { CC_DEFAULT = 0x0027, diff --git a/Foundation/include/Poco/CountingStream.h b/Foundation/include/Poco/CountingStream.h index 730205dee..459d4f338 100644 --- a/Foundation/include/Poco/CountingStream.h +++ b/Foundation/include/Poco/CountingStream.h @@ -34,7 +34,7 @@ class Foundation_API CountingStreamBuf: public UnbufferedStreamBuf public: CountingStreamBuf(); /// Creates an unconnected CountingStreamBuf. - + CountingStreamBuf(std::istream& istr); /// Creates the CountingStreamBuf and connects it /// to the given input stream. @@ -45,34 +45,34 @@ public: ~CountingStreamBuf(); /// Destroys the CountingStream. - + std::streamsize chars() const; /// Returns the total number of characters. - + std::streamsize lines() const; /// Returns the total number of lines. - + std::streamsize pos() const; /// Returns the number of characters on the current line. - + void reset(); /// Resets all counters. - + void setCurrentLineNumber(std::streamsize line); /// Sets the current line number. /// /// This is mainly useful when parsing C/C++ /// preprocessed source code containing #line directives. - + std::streamsize getCurrentLineNumber() const; /// Returns the current line number (same as lines()). void addChars(std::streamsize chars); /// Add to the total number of characters. - + void addLines(std::streamsize lines); /// Add to the total number of lines. - + void addPos(std::streamsize pos); /// Add to the number of characters on the current line. @@ -127,16 +127,16 @@ public: /// /// This is mainly useful when parsing C/C++ /// preprocessed source code containing #line directives. - + std::streamsize getCurrentLineNumber() const; /// Returns the current line number (same as lines()). void addChars(std::streamsize chars); /// Add to the total number of characters. - + void addLines(std::streamsize lines); /// Add to the total number of lines. - + void addPos(std::streamsize pos); /// Add to the number of characters on the current line. @@ -170,7 +170,7 @@ class Foundation_API CountingOutputStream: public CountingIOS, public std::ostre public: CountingOutputStream(); /// Creates an unconnected CountingOutputStream. - + CountingOutputStream(std::ostream& ostr); /// Creates the CountingOutputStream and connects it /// to the given output stream. diff --git a/Foundation/include/Poco/DataURIStreamFactory.h b/Foundation/include/Poco/DataURIStreamFactory.h index 4c0a83b45..6297c59a0 100644 --- a/Foundation/include/Poco/DataURIStreamFactory.h +++ b/Foundation/include/Poco/DataURIStreamFactory.h @@ -36,7 +36,7 @@ public: ~DataURIStreamFactory(); /// Destroys the DataURIStreamFactory. - + std::istream* open(const URI& uri); /// Creates an input stream returning decoded data from the given data URI. /// diff --git a/Foundation/include/Poco/DateTime.h b/Foundation/include/Poco/DateTime.h index f0ee41b99..b95af9039 100644 --- a/Foundation/include/Poco/DateTime.h +++ b/Foundation/include/Poco/DateTime.h @@ -37,7 +37,7 @@ class Foundation_API DateTime /// UTC, Julian day and Gregorian calendar dates. /// /// The date and time stored in a DateTime is always in UTC - /// (Coordinated Universal Time) and thus independent of the + /// (Coordinated Universal Time) and thus independent of the /// timezone in effect on the system. /// /// Conversion calculations are based on algorithms @@ -45,7 +45,7 @@ class Foundation_API DateTime /// http://vsg.cape.com/~pbaum/date/date0.htm /// /// Internally, this class stores a date/time in two - /// forms (UTC and broken down) for performance reasons. Only use + /// forms (UTC and broken down) for performance reasons. Only use /// this class for conversions between date/time representations. /// Use the Timestamp class for everything else. /// @@ -77,7 +77,7 @@ public: NOVEMBER, DECEMBER }; - + enum DaysOfWeek /// Symbolic names for week day numbers (0 to 6). { @@ -99,7 +99,7 @@ public: DateTime(const Timestamp& timestamp); /// Creates a DateTime for the date and time given in /// a Timestamp. - + DateTime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0); /// Creates a DateTime for the given Gregorian date and time. /// * year is from 0 to 9999. @@ -129,7 +129,7 @@ public: DateTime& operator = (const DateTime& dateTime); /// Assigns another DateTime. - + DateTime& operator = (const Timestamp& timestamp); /// Assigns a Timestamp. @@ -149,66 +149,66 @@ public: /// /// Throws an InvalidArgumentException if an argument date is out of range. - void swap(DateTime& dateTime); + void swap(DateTime& dateTime) noexcept; /// Swaps the DateTime with another one. int year() const; /// Returns the year. - + int month() const; /// Returns the month (1 to 12). - + int week(int firstDayOfWeek = MONDAY) const; /// Returns the week number within the year. /// FirstDayOfWeek should be either SUNDAY (0) or MONDAY (1). - /// The returned week number will be from 0 to 53. Week number 1 is the week + /// The returned week number will be from 0 to 53. Week number 1 is the week /// containing January 4. This is in accordance to ISO 8601. - /// + /// /// The following example assumes that firstDayOfWeek is MONDAY. For 2005, which started /// on a Saturday, week 1 will be the week starting on Monday, January 3. /// January 1 and 2 will fall within week 0 (or the last week of the previous year). /// /// For 2007, which starts on a Monday, week 1 will be the week starting on Monday, January 1. /// There will be no week 0 in 2007. - + int day() const; /// Returns the day within the month (1 to 31). - + int dayOfWeek() const; /// Returns the weekday (0 to 6, where /// 0 = Sunday, 1 = Monday, ..., 6 = Saturday). - + int dayOfYear() const; /// Returns the number of the day in the year. /// January 1 is 1, February 1 is 32, etc. - + int hour() const; /// Returns the hour (0 to 23). - + int hourAMPM() const; /// Returns the hour (0 to 12). - + bool isAM() const; /// Returns true if hour < 12; bool isPM() const; /// Returns true if hour >= 12. - + int minute() const; /// Returns the minute (0 to 59). - + int second() const; /// Returns the second (0 to 59). - + int millisecond() const; /// Returns the millisecond (0 to 999) - + int microsecond() const; /// Returns the microsecond (0 to 999) - + double julianDay() const; /// Returns the julian day for the date and time. - + Timestamp timestamp() const; /// Returns the date and time expressed as a Timestamp. @@ -217,12 +217,12 @@ public: /// time. UTC base time is midnight, October 15, 1582. /// Resolution is 100 nanoseconds. - bool operator == (const DateTime& dateTime) const; - bool operator != (const DateTime& dateTime) const; - bool operator < (const DateTime& dateTime) const; - bool operator <= (const DateTime& dateTime) const; - bool operator > (const DateTime& dateTime) const; - bool operator >= (const DateTime& dateTime) const; + bool operator == (const DateTime& dateTime) const; + bool operator != (const DateTime& dateTime) const; + bool operator < (const DateTime& dateTime) const; + bool operator <= (const DateTime& dateTime) const; + bool operator > (const DateTime& dateTime) const; + bool operator >= (const DateTime& dateTime) const; DateTime operator + (const Timespan& span) const; DateTime operator - (const Timespan& span) const; @@ -256,14 +256,14 @@ public: protected: static double toJulianDay(Timestamp::UtcTimeVal utcTime); /// Computes the Julian day for an UTC time. - + static double toJulianDay(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0); /// Computes the Julian day for a Gregorian calendar date and time. /// See , section 2.3.1 for the algorithm. - + static Timestamp::UtcTimeVal toUtcTime(double julianDay); /// Computes the UTC time for a Julian day. - + void computeGregorian(double julianDay); /// Computes the Gregorian date for the given Julian day. /// See , section 3.3.1 for the algorithm. @@ -323,19 +323,19 @@ inline int DateTime::year() const return _year; } - + inline int DateTime::month() const { return _month; } - + inline int DateTime::day() const { return _day; } - + inline int DateTime::hour() const { return _hour; @@ -364,19 +364,19 @@ inline bool DateTime::isPM() const return _hour >= 12; } - + inline int DateTime::minute() const { return _minute; } - + inline int DateTime::second() const { return _second; } - + inline int DateTime::millisecond() const { return _millisecond; @@ -395,13 +395,13 @@ inline bool DateTime::operator == (const DateTime& dateTime) const } -inline bool DateTime::operator != (const DateTime& dateTime) const +inline bool DateTime::operator != (const DateTime& dateTime) const { return _utcTime != dateTime._utcTime; } -inline bool DateTime::operator < (const DateTime& dateTime) const +inline bool DateTime::operator < (const DateTime& dateTime) const { return _utcTime < dateTime._utcTime; } @@ -419,7 +419,7 @@ inline bool DateTime::operator > (const DateTime& dateTime) const } -inline bool DateTime::operator >= (const DateTime& dateTime) const +inline bool DateTime::operator >= (const DateTime& dateTime) const { return _utcTime >= dateTime._utcTime; } @@ -431,7 +431,7 @@ inline bool DateTime::isLeapYear(int year) } -inline void swap(DateTime& d1, DateTime& d2) +inline void swap(DateTime& d1, DateTime& d2) noexcept { d1.swap(d2); } diff --git a/Foundation/include/Poco/DateTimeFormat.h b/Foundation/include/Poco/DateTimeFormat.h index 8f222d091..d550b492f 100644 --- a/Foundation/include/Poco/DateTimeFormat.h +++ b/Foundation/include/Poco/DateTimeFormat.h @@ -33,7 +33,7 @@ public: static const std::string ISO8601_FORMAT; /// The date/time format defined in the ISO 8601 standard. /// - /// Examples: + /// Examples: /// 2005-01-01T12:00:00+01:00 /// 2005-01-01T11:00:00Z @@ -41,21 +41,21 @@ public: /// The date/time format defined in the ISO 8601 standard, /// with fractional seconds. /// - /// Examples: + /// Examples: /// 2005-01-01T12:00:00.000000+01:00 /// 2005-01-01T11:00:00.000000Z - + static const std::string RFC822_FORMAT; /// The date/time format defined in RFC 822 (obsoleted by RFC 1123). /// - /// Examples: + /// Examples: /// Sat, 1 Jan 05 12:00:00 +0100 /// Sat, 1 Jan 05 11:00:00 GMT static const std::string RFC1123_FORMAT; /// The date/time format defined in RFC 1123 (obsoletes RFC 822). /// - /// Examples: + /// Examples: /// Sat, 1 Jan 2005 12:00:00 +0100 /// Sat, 1 Jan 2005 11:00:00 GMT @@ -63,28 +63,28 @@ public: /// The date/time format defined in the HTTP specification (RFC 2616), /// which is basically a variant of RFC 1036 with a zero-padded day field. /// - /// Examples: + /// Examples: /// Sat, 01 Jan 2005 12:00:00 +0100 /// Sat, 01 Jan 2005 11:00:00 GMT static const std::string RFC850_FORMAT; /// The date/time format defined in RFC 850 (obsoleted by RFC 1036). /// - /// Examples: + /// Examples: /// Saturday, 1-Jan-05 12:00:00 +0100 /// Saturday, 1-Jan-05 11:00:00 GMT static const std::string RFC1036_FORMAT; /// The date/time format defined in RFC 1036 (obsoletes RFC 850). /// - /// Examples: + /// Examples: /// Saturday, 1 Jan 05 12:00:00 +0100 /// Saturday, 1 Jan 05 11:00:00 GMT static const std::string ASCTIME_FORMAT; /// The date/time format produced by the ANSI C asctime() function. /// - /// Example: + /// Example: /// Sat Jan 1 12:00:00 2005 static const std::string SORTABLE_FORMAT; @@ -97,9 +97,9 @@ public: // names used by formatter and parser static const std::string WEEKDAY_NAMES[7]; /// English names of week days (Sunday, Monday, Tuesday, ...). - + static const std::string MONTH_NAMES[12]; - /// English names of months (January, February, ...). + /// English names of months (January, February, ...). }; diff --git a/Foundation/include/Poco/DateTimeFormatter.h b/Foundation/include/Poco/DateTimeFormatter.h index 3d6e5ed80..0a6267d12 100644 --- a/Foundation/include/Poco/DateTimeFormatter.h +++ b/Foundation/include/Poco/DateTimeFormatter.h @@ -31,7 +31,7 @@ class Timespan; class Foundation_API DateTimeFormatter - /// This class converts dates and times into strings, supporting a + /// This class converts dates and times into strings, supporting a /// variety of standard and custom formats. /// /// There are two kind of static member functions: @@ -43,7 +43,7 @@ class Foundation_API DateTimeFormatter public: enum { - UTC = 0xFFFF /// Special value for timeZoneDifferential denoting UTC. + UTC = 0xFFFF /// Special value for timeZoneDifferential denoting UTC. }; static std::string format(const Timestamp& timestamp, const std::string& fmt, int timeZoneDifferential = UTC); @@ -130,7 +130,7 @@ public: /// Formats the given timezone differential in ISO format. /// If timeZoneDifferential is UTC, "Z" is returned, /// otherwise, +HH.MM (or -HH.MM) is returned. - + static std::string tzdRFC(int timeZoneDifferential); /// Formats the given timezone differential in RFC format. /// If timeZoneDifferential is UTC, "GMT" is returned, @@ -141,7 +141,7 @@ public: /// and appends it to the given string. /// If timeZoneDifferential is UTC, "Z" is returned, /// otherwise, +HH.MM (or -HH.MM) is returned. - + static void tzdRFC(std::string& str, int timeZoneDifferential); /// Formats the given timezone differential in RFC format /// and appends it to the given string. diff --git a/Foundation/include/Poco/DateTimeParser.h b/Foundation/include/Poco/DateTimeParser.h index bd8daf383..0459babe3 100644 --- a/Foundation/include/Poco/DateTimeParser.h +++ b/Foundation/include/Poco/DateTimeParser.h @@ -46,7 +46,7 @@ class Foundation_API DateTimeParser /// two or four digits. Years 69-00 are interpreted in the 20th century /// (1969-2000), years 01-68 in the 21th century (2001-2068). /// - /// Note that in the current implementation all characters other than format specifiers in + /// Note that in the current implementation all characters other than format specifiers in /// the format string are ignored/not matched against the date/time string. This may /// lead to non-error results even with nonsense input strings. /// This may change in a future version to a more strict behavior. @@ -66,13 +66,13 @@ public: /// Throws a SyntaxException if the string cannot be successfully parsed. /// Please see DateTimeFormatter::format() for a description of the format string. /// Class DateTimeFormat defines format strings for various standard date/time formats. - + static bool tryParse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential); /// Parses a date and time in the given format from the given string. /// Returns true if the string has been successfully parsed, false otherwise. /// Please see DateTimeFormatter::format() for a description of the format string. /// Class DateTimeFormat defines format strings for various standard date/time formats. - + static void parse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential); /// Parses a date and time from the given dateTime string. Before parsing, the method /// examines the dateTime string for a known date/time format. @@ -85,7 +85,7 @@ public: /// examines the dateTime string for a known date/time format. /// Please see DateTimeFormatter::format() for a description of the format string. /// Class DateTimeFormat defines format strings for various standard date/time formats. - + static bool tryParse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential); /// Parses a date and time from the given dateTime string. Before parsing, the method /// examines the dateTime string for a known date/time format. @@ -94,16 +94,16 @@ public: static int parseMonth(std::string::const_iterator& it, const std::string::const_iterator& end); /// Tries to interpret the given range as a month name. The range must be at least - /// three characters long. + /// three characters long. /// Returns the month number (1 .. 12) if the month name is valid. Otherwise throws /// a SyntaxException. static int parseDayOfWeek(std::string::const_iterator& it, const std::string::const_iterator& end); /// Tries to interpret the given range as a weekday name. The range must be at least - /// three characters long. + /// three characters long. /// Returns the weekday number (0 .. 6, where 0 = Sunday, 1 = Monday, etc.) if the /// weekday name is valid. Otherwise throws a SyntaxException. - + protected: static int parseTZD(std::string::const_iterator& it, const std::string::const_iterator& end); static int parseAMPM(std::string::const_iterator& it, const std::string::const_iterator& end, int hour); diff --git a/Foundation/include/Poco/DefaultStrategy.h b/Foundation/include/Poco/DefaultStrategy.h index 0291f3553..905acacc4 100644 --- a/Foundation/include/Poco/DefaultStrategy.h +++ b/Foundation/include/Poco/DefaultStrategy.h @@ -26,7 +26,7 @@ namespace Poco { -template +template class DefaultStrategy: public NotificationStrategy /// Default notification strategy. /// @@ -81,7 +81,7 @@ public: } } } - + void remove(DelegateHandle delegateHandle) { for (Iterator it = _delegates.begin(); it != _delegates.end(); ++it) diff --git a/Foundation/include/Poco/DeflatingStream.h b/Foundation/include/Poco/DeflatingStream.h index 8af593e02..d75570714 100644 --- a/Foundation/include/Poco/DeflatingStream.h +++ b/Foundation/include/Poco/DeflatingStream.h @@ -57,7 +57,7 @@ public: /// /// Please refer to the zlib documentation of deflateInit2() for a description /// of the windowBits parameter. - + DeflatingStreamBuf(std::ostream& ostr, StreamType type, int level); /// Creates a DeflatingStreamBuf for compressing data passed /// through and forwarding it to the given output stream. @@ -68,12 +68,12 @@ public: /// /// Please refer to the zlib documentation of deflateInit2() for a description /// of the windowBits parameter. - + ~DeflatingStreamBuf(); /// Destroys the DeflatingStreamBuf. - + int close(); - /// Finishes up the stream. + /// Finishes up the stream. /// /// Must be called when deflating to an output stream. @@ -83,7 +83,7 @@ protected: virtual int sync(); private: - enum + enum { STREAM_BUFFER_SIZE = 1024, DEFLATE_BUFFER_SIZE = 32768 @@ -128,10 +128,10 @@ public: ~DeflatingIOS(); /// Destroys the DeflatingIOS. - + DeflatingStreamBuf* rdbuf(); /// Returns a pointer to the underlying stream buffer. - + protected: DeflatingStreamBuf _buf; }; @@ -163,9 +163,9 @@ public: ~DeflatingOutputStream(); /// Destroys the DeflatingOutputStream. - + int close(); - /// Finishes up the stream. + /// Finishes up the stream. /// /// Must be called when deflating to an output stream. diff --git a/Foundation/include/Poco/DigestEngine.h b/Foundation/include/Poco/DigestEngine.h index 7ea34d564..e52167d2f 100644 --- a/Foundation/include/Poco/DigestEngine.h +++ b/Foundation/include/Poco/DigestEngine.h @@ -60,8 +60,11 @@ public: /// The returned reference is valid until the next /// time digest() is called, or the engine object is destroyed. - static std::string digestToHex(const Digest& bytes); + static std::string digestToHex(const Digest& bytes, std::size_t length = 0); /// Converts a message digest into a string of hexadecimal numbers. + /// If length is greater than zero, the output is truncated to length + /// bytes. If size is greater than the length of untruncated output, + /// InvalidArgumentException is thrown. static Digest digestFromHex(const std::string& digest); /// Converts a string created by digestToHex back to its Digest presentation diff --git a/Foundation/include/Poco/DigestStream.h b/Foundation/include/Poco/DigestStream.h index 6976e01aa..5d1de54c3 100644 --- a/Foundation/include/Poco/DigestStream.h +++ b/Foundation/include/Poco/DigestStream.h @@ -36,7 +36,7 @@ public: DigestBuf(DigestEngine& eng); DigestBuf(DigestEngine& eng, std::istream& istr); DigestBuf(DigestEngine& eng, std::ostream& ostr); - ~DigestBuf(); + ~DigestBuf(); int readFromDevice(char* buffer, std::streamsize length); int writeToDevice(const char* buffer, std::streamsize length); void close(); @@ -83,7 +83,7 @@ class Foundation_API DigestOutputStream: public DigestIOS, public std::ostream /// all the data passing through it, /// using a DigestEngine. /// To ensure that all data has been incorporated - /// into the digest, call close() or flush() before + /// into the digest, call close() or flush() before /// you obtain the digest from the digest engine. { public: diff --git a/Foundation/include/Poco/DirectoryIterator.h b/Foundation/include/Poco/DirectoryIterator.h index c3cedf3f4..fd8e89db1 100644 --- a/Foundation/include/Poco/DirectoryIterator.h +++ b/Foundation/include/Poco/DirectoryIterator.h @@ -40,19 +40,19 @@ class Foundation_API DirectoryIterator /// even is the original iterator has been advanced /// (all copies of an iterator share their state with /// the original iterator) - /// * because of this you should only use the prefix + /// * because of this you should only use the prefix /// increment operator { public: DirectoryIterator(); /// Creates the end iterator. - + DirectoryIterator(const std::string& path); /// Creates a directory iterator for the given path. DirectoryIterator(const DirectoryIterator& iterator); /// Creates a directory iterator for the given path. - + DirectoryIterator(const File& file); /// Creates a directory iterator for the given file. @@ -64,7 +64,7 @@ public: const std::string& name() const; /// Returns the current filename. - + const Path& path() const; /// Returns the current path. @@ -72,18 +72,18 @@ public: DirectoryIterator& operator = (const File& file); DirectoryIterator& operator = (const Path& path); DirectoryIterator& operator = (const std::string& path); - + virtual DirectoryIterator& operator ++ (); // prefix - + //@ deprecated DirectoryIterator operator ++ (int); // postfix /// Please use the prefix increment operator instead. - + const File& operator * () const; File& operator * (); const File* operator -> () const; File* operator -> (); - + bool operator == (const DirectoryIterator& iterator) const; bool operator != (const DirectoryIterator& iterator) const; @@ -104,7 +104,7 @@ inline const std::string& DirectoryIterator::name() const return _path.getFileName(); } - + inline const Path& DirectoryIterator::path() const { return _path; diff --git a/Foundation/include/Poco/DirectoryIterator_UNIX.h b/Foundation/include/Poco/DirectoryIterator_UNIX.h index d21f71192..c91c970c2 100644 --- a/Foundation/include/Poco/DirectoryIterator_UNIX.h +++ b/Foundation/include/Poco/DirectoryIterator_UNIX.h @@ -30,13 +30,13 @@ class Foundation_API DirectoryIteratorImpl public: DirectoryIteratorImpl(const std::string& path); ~DirectoryIteratorImpl(); - + void duplicate(); void release(); - + const std::string& get() const; const std::string& next(); - + private: DIR* _pDir; std::string _current; diff --git a/Foundation/include/Poco/DirectoryIterator_WIN32U.h b/Foundation/include/Poco/DirectoryIterator_WIN32U.h index 496842c7f..8035e0adf 100644 --- a/Foundation/include/Poco/DirectoryIterator_WIN32U.h +++ b/Foundation/include/Poco/DirectoryIterator_WIN32U.h @@ -30,13 +30,13 @@ class Foundation_API DirectoryIteratorImpl public: DirectoryIteratorImpl(const std::string& path); ~DirectoryIteratorImpl(); - + void duplicate(); void release(); - + const std::string& get() const; const std::string& next(); - + private: HANDLE _fh; WIN32_FIND_DATAW _fd; diff --git a/Foundation/include/Poco/DirectoryWatcher.h b/Foundation/include/Poco/DirectoryWatcher.h index 6e3a492fd..2de0c9f2a 100644 --- a/Foundation/include/Poco/DirectoryWatcher.h +++ b/Foundation/include/Poco/DirectoryWatcher.h @@ -45,7 +45,7 @@ class Foundation_API DirectoryWatcher: protected Runnable /// /// A thread will be created that watches the specified /// directory for changes. Events are reported in the context - /// of this thread. + /// of this thread. /// /// Note that changes to files in subdirectories of the watched /// directory are not reported. Separate DirectoryWatcher objects @@ -74,7 +74,7 @@ public: { DW_ITEM_ADDED = 1, /// A new item has been created and added to the directory. - + DW_ITEM_REMOVED = 2, /// An item has been removed from the directory. @@ -96,12 +96,12 @@ public: DW_FILTER_DISABLE_ALL = 0 /// Disables all event types. }; - + enum { DW_DEFAULT_SCAN_INTERVAL = 5 /// Default scan interval for platforms that don't provide a native notification mechanism. }; - + struct DirectoryEvent { DirectoryEvent(const File& f, DirectoryEventType ev): @@ -113,13 +113,13 @@ public: const File& item; /// The directory or file that has been changed. DirectoryEventType event; /// The kind of event. }; - + BasicEvent itemAdded; /// Fired when a file or directory has been created or added to the directory. - + BasicEvent itemRemoved; /// Fired when a file or directory has been removed from the directory. - + BasicEvent itemModified; /// Fired when a file or directory has been modified. @@ -128,10 +128,10 @@ public: BasicEvent itemMovedTo; /// Fired when a file or directory has been moved. This event delivers the new name. - + BasicEvent scanError; /// Fired when an error occurs while scanning for changes. - + DirectoryWatcher(const std::string& path, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL); /// Creates a DirectoryWatcher for the directory given in path. /// To enable only specific events, an eventMask can be specified by @@ -139,7 +139,7 @@ public: /// On platforms where no native filesystem notifications are available, /// scanInterval specifies the interval in seconds between scans /// of the directory. - + DirectoryWatcher(const File& directory, int eventMask = DW_FILTER_ENABLE_ALL, int scanInterval = DW_DEFAULT_SCAN_INTERVAL); /// Creates a DirectoryWatcher for the specified directory /// To enable only specific events, an eventMask can be specified by @@ -150,30 +150,30 @@ public: ~DirectoryWatcher(); /// Destroys the DirectoryWatcher. - + void suspendEvents(); /// Suspends sending of events. Can be called multiple times, but every /// call to suspendEvent() must be matched by a call to resumeEvents(). - + void resumeEvents(); /// Resumes events, after they have been suspended with a call to suspendEvents(). - + bool eventsSuspended() const; /// Returns true iff events are suspended. - + int eventMask() const; /// Returns the value of the eventMask passed to the constructor. - + int scanInterval() const; /// Returns the scan interval in seconds. - + const File& directory() const; /// Returns the directory being watched. - + bool supportsMoveEvents() const; /// Returns true iff the platform supports DW_ITEM_MOVED_FROM/itemMovedFrom and /// DW_ITEM_MOVED_TO/itemMovedTo events. - + protected: void init(); void stop(); diff --git a/Foundation/include/Poco/Dynamic/Pair.h b/Foundation/include/Poco/Dynamic/Pair.h index 580427533..166dc28a9 100644 --- a/Foundation/include/Poco/Dynamic/Pair.h +++ b/Foundation/include/Poco/Dynamic/Pair.h @@ -67,7 +67,7 @@ public: { } - Pair& swap(Pair& other) + Pair& swap(Pair& other) noexcept /// Swaps the content of the two Pairs. { std::swap(_data, other._data); diff --git a/Foundation/include/Poco/Dynamic/Struct.h b/Foundation/include/Poco/Dynamic/Struct.h index 60166cf03..317493f6e 100644 --- a/Foundation/include/Poco/Dynamic/Struct.h +++ b/Foundation/include/Poco/Dynamic/Struct.h @@ -173,7 +173,7 @@ public: _data.clear(); } - inline void swap(Struct& other) + inline void swap(Struct& other) noexcept /// Swap content of Struct with another Struct { _data.swap(other._data); diff --git a/Foundation/include/Poco/Dynamic/Var.h b/Foundation/include/Poco/Dynamic/Var.h index 9825ba2bb..2be0ed9b2 100644 --- a/Foundation/include/Poco/Dynamic/Var.h +++ b/Foundation/include/Poco/Dynamic/Var.h @@ -91,15 +91,9 @@ public: template Var(const T& val) /// Creates the Var from the given value. -#ifdef POCO_NO_SOO - : _pHolder(new VarHolderImpl(val)) - { - } -#else { construct(val); } -#endif Var(const char* pVal); // Convenience constructor for const char* which gets mapped to a std::string internally, i.e. pVal is deep-copied. @@ -231,12 +225,8 @@ public: Var& operator = (const T& other) /// Assignment operator for assigning POD to Var { -#ifdef POCO_NO_SOO - Var tmp(other); - swap(tmp); -#else + clear(); construct(other); -#endif return *this; } @@ -612,79 +602,34 @@ private: return pStr->operator[](n); } -#ifdef POCO_NO_SOO - - VarHolder* content() const - { - return _pHolder; - } - - void destruct() - { - if (!isEmpty()) delete content(); - } - - VarHolder* _pHolder; - -#else - VarHolder* content() const { return _placeholder.content(); } + void destruct() + { + } + template void construct(const ValueType& value) { - if (sizeof(VarHolderImpl) <= Placeholder::Size::value) - { - new (reinterpret_cast(_placeholder.holder)) VarHolderImpl(value); - _placeholder.setLocal(true); - } - else - { - _placeholder.pHolder = new VarHolderImpl(value); - _placeholder.setLocal(false); - } + _placeholder.assign, ValueType>(value); } void construct(const char* value) { std::string val(value); - if (sizeof(VarHolderImpl) <= Placeholder::Size::value) - { - new (reinterpret_cast(_placeholder.holder)) VarHolderImpl(val); - _placeholder.setLocal(true); - } - else - { - _placeholder.pHolder = new VarHolderImpl(val); - _placeholder.setLocal(false); - } + _placeholder.assign, std::string>(val); } void construct(const Var& other) { if (!other.isEmpty()) other.content()->clone(&_placeholder); - else - _placeholder.erase(); - } - - void destruct() - { - if (!isEmpty()) - { - if (_placeholder.isLocal()) - content()->~VarHolder(); - else - delete content(); - } } Placeholder _placeholder; - -#endif // POCO_NO_SOO }; @@ -699,24 +644,17 @@ private: inline void Var::swap(Var& other) { -#ifdef POCO_NO_SOO - - std::swap(_pHolder, other._pHolder); - -#else - if (this == &other) return; if (!_placeholder.isLocal() && !other._placeholder.isLocal()) { - std::swap(_placeholder.pHolder, other._placeholder.pHolder); + _placeholder.swap(other._placeholder); } else { Var tmp(*this); try { - if (_placeholder.isLocal()) destruct(); construct(other); other = tmp; } @@ -726,8 +664,6 @@ inline void Var::swap(Var& other) throw; } } - -#endif } diff --git a/Foundation/include/Poco/Dynamic/VarHolder.h b/Foundation/include/Poco/Dynamic/VarHolder.h index c1a17aecf..16b99d0a1 100644 --- a/Foundation/include/Poco/Dynamic/VarHolder.h +++ b/Foundation/include/Poco/Dynamic/VarHolder.h @@ -295,32 +295,18 @@ protected: template VarHolder* cloneHolder(Placeholder* pVarHolder, const T& val) const - /// Instantiates value holder wrapper. If size of the wrapper is - /// larger than POCO_SMALL_OBJECT_SIZE, holder is instantiated on + /// Instantiates value holder wrapper. + /// + /// Called from clone() member function of the implementation. + /// + /// When the smal object optimization is enabled (POCO_NO_SOO not + /// defined), if size of the wrapper is larger than + /// POCO_SMALL_OBJECT_SIZE, holder is instantiated on /// the heap, otherwise it is instantiated in-place (in the /// pre-allocated buffer inside the holder). - /// - /// Called from clone() member function of the implementation when - /// small object optimization is enabled. { -#ifdef POCO_NO_SOO - (void)pVarHolder; - return new VarHolderImpl(val); -#else poco_check_ptr (pVarHolder); - if ((sizeof(VarHolderImpl) <= Placeholder::Size::value)) - { - new ((VarHolder*) pVarHolder->holder) VarHolderImpl(val); - pVarHolder->setLocal(true); - return (VarHolder*) pVarHolder->holder; - } - else - { - pVarHolder->pHolder = new VarHolderImpl(val); - pVarHolder->setLocal(false); - return pVarHolder->pHolder; - } -#endif + return pVarHolder->assign, T>(val); } template @@ -420,41 +406,52 @@ protected: } private: + template void checkUpperLimit(const F& from) const - { - if ((sizeof(T) < sizeof(F)) && - (from > static_cast(std::numeric_limits::max()))) - { - throw RangeException("Value too large."); - } - else - if (from > std::numeric_limits::max()) - { - throw RangeException("Value too large."); - } - } - - template - void checkUpperLimitFloat(const F& from) const { if (from > std::numeric_limits::max()) throw RangeException("Value too large."); } - template - void checkLowerLimitFloat(const F& from) const - { - if (from < -std::numeric_limits::max()) - throw RangeException("Value too small."); - } - template void checkLowerLimit(const F& from) const { if (from < std::numeric_limits::min()) throw RangeException("Value too small."); } + + template + void checkUpperLimitFloat(const F& from) const + { + if (std::is_floating_point::value) + { + if (from > std::numeric_limits::max()) + throw RangeException("Value too large."); + } + else + { + // Avoid clang -Wimplicit-int-float-conversion warning with an explicit cast. + if (from > static_cast(std::numeric_limits::max())) + throw RangeException("Value too large."); + } + } + + template + void checkLowerLimitFloat(const F& from) const + { + if (std::is_floating_point::value) + { + if (from < -std::numeric_limits::max()) + throw RangeException("Value too small."); + } + else + { + // Avoid clang -Wimplicit-int-float-conversion warning with an explicit cast. + if (from < static_cast(std::numeric_limits::min())) + throw RangeException("Value too small."); + } + } }; diff --git a/Foundation/include/Poco/Dynamic/VarIterator.h b/Foundation/include/Poco/Dynamic/VarIterator.h index 038dfdb5c..eb9129fbc 100644 --- a/Foundation/include/Poco/Dynamic/VarIterator.h +++ b/Foundation/include/Poco/Dynamic/VarIterator.h @@ -79,11 +79,11 @@ public: /// Advances by one position and returns current position. VarIterator operator ++ (int) const; - /// Advances by one position and returns copy of the iterator with + /// Advances by one position and returns copy of the iterator with /// previous current position. const VarIterator& operator -- () const; - /// Goes back by one position and returns copy of the iterator with + /// Goes back by one position and returns copy of the iterator with /// previous current position. VarIterator operator -- (int) const; @@ -103,15 +103,15 @@ private: VarIterator(); void increment() const; - /// Increments the iterator position by one. + /// Increments the iterator position by one. /// Throws RangeException if position is out of range. void decrement() const; - /// Decrements the iterator position by one. + /// Decrements the iterator position by one. /// Throws RangeException if position is out of range. void setPosition(std::size_t pos) const; - /// Sets the iterator position. + /// Sets the iterator position. /// Throws RangeException if position is out of range. Var* _pVar; diff --git a/Foundation/include/Poco/Environment_UNIX.h b/Foundation/include/Poco/Environment_UNIX.h index d6ae543ff..1efb4ea15 100644 --- a/Foundation/include/Poco/Environment_UNIX.h +++ b/Foundation/include/Poco/Environment_UNIX.h @@ -31,8 +31,8 @@ class Foundation_API EnvironmentImpl public: typedef UInt8 NodeId[6]; /// Ethernet address. - static std::string getImpl(const std::string& name); - static bool hasImpl(const std::string& name); + static std::string getImpl(const std::string& name); + static bool hasImpl(const std::string& name); static void setImpl(const std::string& name, const std::string& value); static std::string osNameImpl(); static std::string osDisplayNameImpl(); @@ -44,7 +44,7 @@ public: private: typedef std::map StringMap; - + static StringMap _map; static FastMutex _mutex; }; diff --git a/Foundation/include/Poco/Environment_VX.h b/Foundation/include/Poco/Environment_VX.h index 8eb178d03..8feb6b9f0 100644 --- a/Foundation/include/Poco/Environment_VX.h +++ b/Foundation/include/Poco/Environment_VX.h @@ -31,8 +31,8 @@ class Foundation_API EnvironmentImpl public: typedef UInt8 NodeId[6]; /// Ethernet address. - static std::string getImpl(const std::string& name); - static bool hasImpl(const std::string& name); + static std::string getImpl(const std::string& name); + static bool hasImpl(const std::string& name); static void setImpl(const std::string& name, const std::string& value); static std::string osNameImpl(); static std::string osDisplayNameImpl(); @@ -44,7 +44,7 @@ public: private: typedef std::map StringMap; - + static StringMap _map; static FastMutex _mutex; }; diff --git a/Foundation/include/Poco/Environment_WIN32U.h b/Foundation/include/Poco/Environment_WIN32U.h index b54afb2e8..f7f5e793b 100644 --- a/Foundation/include/Poco/Environment_WIN32U.h +++ b/Foundation/include/Poco/Environment_WIN32U.h @@ -29,10 +29,10 @@ class Foundation_API EnvironmentImpl public: typedef UInt8 NodeId[6]; /// Ethernet address. - static std::string getImpl(const std::string& name); - static bool hasImpl(const std::string& name); + static std::string getImpl(const std::string& name); + static bool hasImpl(const std::string& name); static void setImpl(const std::string& name, const std::string& value); - static std::string osNameImpl(); + static std::string osNameImpl(); static std::string osDisplayNameImpl(); static std::string osVersionImpl(); static std::string osArchitectureImpl(); diff --git a/Foundation/include/Poco/Environment_WINCE.h b/Foundation/include/Poco/Environment_WINCE.h index 0c92bc540..b513682f6 100644 --- a/Foundation/include/Poco/Environment_WINCE.h +++ b/Foundation/include/Poco/Environment_WINCE.h @@ -29,27 +29,27 @@ class Foundation_API EnvironmentImpl public: typedef UInt8 NodeId[6]; /// Ethernet address. - static std::string getImpl(const std::string& name); - static bool hasImpl(const std::string& name); + static std::string getImpl(const std::string& name); + static bool hasImpl(const std::string& name); static void setImpl(const std::string& name, const std::string& value); - static std::string osNameImpl(); + static std::string osNameImpl(); static std::string osDisplayNameImpl(); static std::string osVersionImpl(); static std::string osArchitectureImpl(); static std::string nodeNameImpl(); static void nodeIdImpl(NodeId& id); static unsigned processorCountImpl(); - + private: static bool envVar(const std::string& name, std::string* value); - + static const std::string TEMP; static const std::string TMP; static const std::string HOMEPATH; static const std::string COMPUTERNAME; static const std::string OS; static const std::string NUMBER_OF_PROCESSORS; - static const std::string PROCESSOR_ARCHITECTURE; + static const std::string PROCESSOR_ARCHITECTURE; }; diff --git a/Foundation/include/Poco/ErrorHandler.h b/Foundation/include/Poco/ErrorHandler.h index a3eea3b14..bc5a6ae04 100644 --- a/Foundation/include/Poco/ErrorHandler.h +++ b/Foundation/include/Poco/ErrorHandler.h @@ -32,7 +32,7 @@ class Foundation_API ErrorHandler /// An unhandled exception that causes a thread to terminate is usually /// silently ignored, since the class library cannot do anything meaningful /// about it. - /// + /// /// The Thread class provides the possibility to register a /// global ErrorHandler that is invoked whenever a thread has /// been terminated by an unhandled exception. @@ -57,10 +57,10 @@ public: /// be silently ignored. /// /// The default implementation just breaks into the debugger. - + virtual void exception(const std::exception& exc); /// Called when a std::exception (or a subclass) - /// caused the thread to terminate. + /// caused the thread to terminate. /// /// This method should not throw any exception - it would /// be silently ignored. @@ -76,16 +76,16 @@ public: /// be silently ignored. /// /// The default implementation just breaks into the debugger. - + static void handle(const Exception& exc); /// Invokes the currently registered ErrorHandler. - + static void handle(const std::exception& exc); /// Invokes the currently registered ErrorHandler. - + static void handle(); /// Invokes the currently registered ErrorHandler. - + static ErrorHandler* set(ErrorHandler* pHandler); /// Registers the given handler as the current error handler. /// @@ -95,10 +95,10 @@ public: /// Returns a pointer to the currently registered /// ErrorHandler. -protected: +protected: static ErrorHandler* defaultHandler(); - /// Returns the default ErrorHandler. - + /// Returns the default ErrorHandler. + private: static ErrorHandler* _pHandler; static FastMutex _mutex; diff --git a/Foundation/include/Poco/Event.h b/Foundation/include/Poco/Event.h index 924961780..c59f29acd 100644 --- a/Foundation/include/Poco/Event.h +++ b/Foundation/include/Poco/Event.h @@ -54,7 +54,7 @@ public: /// Creates the event. If type is EVENT_AUTORESET, /// the event is automatically reset after /// a wait() successfully returns. - + //@ deprecated explicit Event(bool autoReset); /// Please use Event::Event(EventType) instead. @@ -64,7 +64,7 @@ public: void set(); /// Signals the event. If autoReset is true, - /// only one thread waiting for the event + /// only one thread waiting for the event /// can resume execution. /// If autoReset is false, all waiting threads /// can resume execution. @@ -86,7 +86,7 @@ public: void reset(); /// Resets the event to unsignalled state. - + private: Event(const Event&); Event& operator = (const Event&); diff --git a/Foundation/include/Poco/EventArgs.h b/Foundation/include/Poco/EventArgs.h index 006679070..a611995c8 100644 --- a/Foundation/include/Poco/EventArgs.h +++ b/Foundation/include/Poco/EventArgs.h @@ -34,7 +34,7 @@ class Foundation_API EventArgs { public: EventArgs(); - + virtual ~EventArgs(); }; diff --git a/Foundation/include/Poco/EventChannel.h b/Foundation/include/Poco/EventChannel.h index 47761ab3e..94a94cfb0 100644 --- a/Foundation/include/Poco/EventChannel.h +++ b/Foundation/include/Poco/EventChannel.h @@ -30,7 +30,7 @@ namespace Poco { class Foundation_API EventChannel: public Channel /// The EventChannel fires the messageLogged event for every log message /// received. This can be used to hook custom log message processing into - /// the logging framework. + /// the logging framework. { public: using Ptr = AutoPtr; diff --git a/Foundation/include/Poco/EventLogChannel.h b/Foundation/include/Poco/EventLogChannel.h index fcd18d363..c6f96932f 100644 --- a/Foundation/include/Poco/EventLogChannel.h +++ b/Foundation/include/Poco/EventLogChannel.h @@ -41,30 +41,30 @@ public: /// Creates the EventLogChannel. /// The name of the current application (or more correctly, /// the name of its executable) is taken as event source name. - + EventLogChannel(const std::string& name); /// Creates the EventLogChannel with the given event source name. - + EventLogChannel(const std::string& name, const std::string& host); /// Creates an EventLogChannel with the given event source /// name that routes messages to the given host. - + void open(); /// Opens the EventLogChannel. If necessary, the /// required registry entries to register a /// message resource DLL are made. - + void close(); /// Closes the EventLogChannel. - + void log(const Message& msg); /// Logs the given message to the Windows Event Log. /// /// The message type and priority are mapped to /// appropriate values for Event Log type and category. - + void setProperty(const std::string& name, const std::string& value); - /// Sets or changes a configuration property. + /// Sets or changes a configuration property. /// /// The following properties are supported: /// @@ -73,7 +73,7 @@ public: /// The default is "localhost". /// * host: same as host. /// * logfile: The name of the log file. The default is "Application". - + std::string getProperty(const std::string& name) const; /// Returns the value of the given property. diff --git a/Foundation/include/Poco/Event_POSIX.h b/Foundation/include/Poco/Event_POSIX.h index b7eb83aa6..93b64e67c 100644 --- a/Foundation/include/Poco/Event_POSIX.h +++ b/Foundation/include/Poco/Event_POSIX.h @@ -22,6 +22,7 @@ #include "Poco/Exception.h" #include #include +#include namespace Poco { @@ -30,18 +31,18 @@ namespace Poco { class Foundation_API EventImpl { protected: - EventImpl(bool autoReset); + EventImpl(bool autoReset); ~EventImpl(); void setImpl(); void waitImpl(); bool waitImpl(long milliseconds); void resetImpl(); - + private: - bool _auto; - volatile bool _state; - pthread_mutex_t _mutex; - pthread_cond_t _cond; + bool _auto; + std::atomic _state; + pthread_mutex_t _mutex; + pthread_cond_t _cond; }; @@ -50,7 +51,7 @@ private: // inline void EventImpl::setImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot signal event (lock)"); _state = true; if (pthread_cond_broadcast(&_cond)) @@ -64,7 +65,7 @@ inline void EventImpl::setImpl() inline void EventImpl::resetImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot reset event"); _state = false; pthread_mutex_unlock(&_mutex); diff --git a/Foundation/include/Poco/Event_VX.h b/Foundation/include/Poco/Event_VX.h index 9dd23c75e..81cc1be63 100644 --- a/Foundation/include/Poco/Event_VX.h +++ b/Foundation/include/Poco/Event_VX.h @@ -29,13 +29,13 @@ namespace Poco { class Foundation_API EventImpl { protected: - EventImpl(bool autoReset); + EventImpl(bool autoReset); ~EventImpl(); void setImpl(); void waitImpl(); bool waitImpl(long milliseconds); void resetImpl(); - + private: bool _auto; volatile bool _state; diff --git a/Foundation/include/Poco/Event_WIN32.h b/Foundation/include/Poco/Event_WIN32.h index 07fdb0984..2862887e6 100644 --- a/Foundation/include/Poco/Event_WIN32.h +++ b/Foundation/include/Poco/Event_WIN32.h @@ -21,7 +21,7 @@ #include "Poco/Foundation.h" #include "Poco/Exception.h" #include "Poco/UnWindows.h" - +#include namespace Poco { @@ -29,15 +29,15 @@ namespace Poco { class Foundation_API EventImpl { protected: - EventImpl(bool autoReset); + EventImpl(bool autoReset); ~EventImpl(); void setImpl(); void waitImpl(); bool waitImpl(long milliseconds); void resetImpl(); - + private: - HANDLE _event; + std::atomic _event; }; diff --git a/Foundation/include/Poco/Exception.h b/Foundation/include/Poco/Exception.h index c2d9c8db8..ce6d4d035 100644 --- a/Foundation/include/Poco/Exception.h +++ b/Foundation/include/Poco/Exception.h @@ -42,7 +42,7 @@ public: Exception(const Exception& exc); /// Copy constructor. - + ~Exception() noexcept; /// Destroys the exception and deletes the nested exception. @@ -51,25 +51,25 @@ public: virtual const char* name() const noexcept; /// Returns a static string describing the exception. - + virtual const char* className() const noexcept; /// Returns the name of the exception class. - + virtual const char* what() const noexcept; /// Returns a static string describing the exception. /// /// Same as name(), but for compatibility with std::exception. - + const Exception* nested() const; /// Returns a pointer to the nested exception, or /// null if no nested exception exists. - + const std::string& message() const; /// Returns the message text. - + int code() const; /// Returns the exception code if defined. - + std::string displayText() const; /// Returns a string consisting of the /// message name and the message text. @@ -79,7 +79,7 @@ public: /// /// The copy can later be thrown again by /// invoking rethrow() on it. - + virtual void rethrow() const; /// (Re)Throws the exception. /// @@ -96,7 +96,7 @@ protected: void extendedMessage(const std::string& arg); /// Sets the extended message for the exception. - + private: std::string _msg; Exception* _pNested; diff --git a/Foundation/include/Poco/ExpirationDecorator.h b/Foundation/include/Poco/ExpirationDecorator.h index 2e9d40a63..15c8e6a8f 100644 --- a/Foundation/include/Poco/ExpirationDecorator.h +++ b/Foundation/include/Poco/ExpirationDecorator.h @@ -64,7 +64,7 @@ public: ~ExpirationDecorator() { } - + const Poco::Timestamp& getExpiration() const { return _expiresAt; diff --git a/Foundation/include/Poco/Expire.h b/Foundation/include/Poco/Expire.h index 73f82b4b0..672ddfc02 100644 --- a/Foundation/include/Poco/Expire.h +++ b/Foundation/include/Poco/Expire.h @@ -28,12 +28,12 @@ namespace Poco { template class Expire: public AbstractDelegate - /// Decorator for AbstractDelegate adding automatic + /// Decorator for AbstractDelegate adding automatic /// expiration of registrations to AbstractDelegate's. { public: Expire(const AbstractDelegate& p, Timestamp::TimeDiff expireMillisecs): - _pDelegate(p.clone()), + _pDelegate(p.clone()), _expire(expireMillisecs*1000) { } @@ -50,7 +50,7 @@ public: { delete _pDelegate; } - + Expire& operator = (const Expire& expire) { if (&expire != this) @@ -81,7 +81,7 @@ public: { return new Expire(*this); } - + void disable() { _pDelegate->disable(); @@ -109,12 +109,12 @@ private: template <> class Expire: public AbstractDelegate - /// Decorator for AbstractDelegate adding automatic + /// Decorator for AbstractDelegate adding automatic /// expiration of registrations to AbstractDelegate's. { public: Expire(const AbstractDelegate& p, Timestamp::TimeDiff expireMillisecs): - _pDelegate(p.clone()), + _pDelegate(p.clone()), _expire(expireMillisecs*1000) { } @@ -131,7 +131,7 @@ public: { delete _pDelegate; } - + Expire& operator = (const Expire& expire) { if (&expire != this) @@ -162,7 +162,7 @@ public: { return new Expire(*this); } - + void disable() { _pDelegate->disable(); diff --git a/Foundation/include/Poco/ExpireCache.h b/Foundation/include/Poco/ExpireCache.h index 41f0482b3..5dd8ff720 100644 --- a/Foundation/include/Poco/ExpireCache.h +++ b/Foundation/include/Poco/ExpireCache.h @@ -26,11 +26,11 @@ namespace Poco { template < - class TKey, - class TValue, - class TMutex = FastMutex, + class TKey, + class TValue, + class TMutex = FastMutex, class TEventMutex = FastMutex -> +> class ExpireCache: public AbstractCache, TMutex, TEventMutex> /// An ExpireCache caches entries for a fixed time period (per default 10 minutes). /// Entries expire independently of the access pattern, i.e. after a constant time. @@ -40,11 +40,11 @@ class ExpireCache: public AbstractCache, TMutex, TEventMutex>(ExpireStrategy(expire)) { } diff --git a/Foundation/include/Poco/ExpireLRUCache.h b/Foundation/include/Poco/ExpireLRUCache.h index b58badcc5..492121262 100644 --- a/Foundation/include/Poco/ExpireLRUCache.h +++ b/Foundation/include/Poco/ExpireLRUCache.h @@ -27,10 +27,10 @@ namespace Poco { -template < +template < class TKey, class TValue, - class TMutex = FastMutex, + class TMutex = FastMutex, class TEventMutex = FastMutex > class ExpireLRUCache: public AbstractCache, TMutex, TEventMutex> diff --git a/Foundation/include/Poco/ExpireStrategy.h b/Foundation/include/Poco/ExpireStrategy.h index 27e471fd0..157286ada 100644 --- a/Foundation/include/Poco/ExpireStrategy.h +++ b/Foundation/include/Poco/ExpireStrategy.h @@ -31,7 +31,7 @@ namespace Poco { -template < +template < class TKey, class TValue > @@ -50,7 +50,7 @@ public: /// Create an expire strategy. Note that the smallest allowed caching time is 25ms. /// Anything lower than that is not useful with current operating systems. { - if (_expireTime < 25000) throw InvalidArgumentException("expireTime must be at least 25 ms"); + if (_expireTime < 25000) throw InvalidArgumentException("expireTime must be at least 25 ms"); } ~ExpireStrategy() diff --git a/Foundation/include/Poco/FIFOBuffer.h b/Foundation/include/Poco/FIFOBuffer.h index 7fc85ca7e..c1a6d9966 100644 --- a/Foundation/include/Poco/FIFOBuffer.h +++ b/Foundation/include/Poco/FIFOBuffer.h @@ -41,7 +41,7 @@ class BasicFIFOBuffer /// However, to achieve thread-safety in cases where multiple /// member function calls are involved and have to be atomic, /// the mutex must be locked externally. - /// + /// /// Buffer size, as well as amount of unread data and /// available space introspections are supported as well. /// @@ -55,12 +55,12 @@ public: /// Event indicating "writability" of the buffer, /// triggered as follows: /// - /// * when buffer transitions from non-full to full, - /// Writable event observers are notified, with + /// * when buffer transitions from non-full to full, + /// Writable event observers are notified, with /// false value as the argument /// /// * when buffer transitions from full to non-full, - /// Writable event observers are notified, with + /// Writable event observers are notified, with /// true value as the argument mutable Poco::BasicEvent readable; @@ -68,7 +68,7 @@ public: /// triggered as follows: /// /// * when buffer transitions from non-empty to empty, - /// Readable event observers are notified, with false + /// Readable event observers are notified, with false /// value as the argument /// /// * when FIFOBuffer transitions from empty to non-empty, @@ -112,7 +112,7 @@ public: /// Destroys the FIFOBuffer. { } - + void resize(std::size_t newSize, bool preserveContent = true) /// Resizes the buffer. If preserveContent is true, /// the content of the old buffer is preserved. @@ -126,22 +126,22 @@ public: if (preserveContent && (newSize < _used)) throw InvalidAccessException("Can not resize FIFO without data loss."); - + std::size_t usedBefore = _used; _buffer.resize(newSize, preserveContent); if (!preserveContent) _used = 0; if (_notify) notify(usedBefore); } - + std::size_t peek(T* pBuffer, std::size_t length) const /// Peeks into the data currently in the FIFO /// without actually extracting it. /// If length is zero, the return is immediate. /// If length is greater than used length, - /// it is substituted with the the current FIFO + /// it is substituted with the the current FIFO /// used length. - /// - /// Returns the number of elements copied in the + /// + /// Returns the number of elements copied in the /// supplied buffer. { if (0 == length) return 0; @@ -151,17 +151,17 @@ public: std::memcpy(pBuffer, _buffer.begin() + _begin, length * sizeof(T)); return length; } - + std::size_t peek(Poco::Buffer& buffer, std::size_t length = 0) const /// Peeks into the data currently in the FIFO /// without actually extracting it. /// Resizes the supplied buffer to the size of /// data written to it. If length is not - /// supplied by the caller or is greater than length - /// of currently used data, the current FIFO used + /// supplied by the caller or is greater than length + /// of currently used data, the current FIFO used /// data length is substituted for it. - /// - /// Returns the number of elements copied in the + /// + /// Returns the number of elements copied in the /// supplied buffer. { Mutex::ScopedLock lock(_mutex); @@ -170,13 +170,13 @@ public: buffer.resize(length); return peek(buffer.begin(), length); } - + std::size_t read(T* pBuffer, std::size_t length) /// Copies the data currently in the FIFO /// into the supplied buffer, which must be /// preallocated to at least the length size /// before calling this function. - /// + /// /// Returns the size of the copied data. { if (0 == length) return 0; @@ -193,13 +193,13 @@ public: return readLen; } - + std::size_t read(Poco::Buffer& buffer, std::size_t length = 0) /// Copies the data currently in the FIFO /// into the supplied buffer. /// Resizes the supplied buffer to the size of /// data written to it. - /// + /// /// Returns the size of the copied data. { Mutex::ScopedLock lock(_mutex); @@ -219,20 +219,20 @@ public: std::size_t write(const T* pBuffer, std::size_t length) /// Writes data from supplied buffer to the FIFO buffer. /// If there is no sufficient space for the whole - /// buffer to be written, data up to available + /// buffer to be written, data up to available /// length is written. /// The length of data to be written is determined from the /// length argument. Function does nothing and returns zero /// if length argument is equal to zero. - /// + /// /// Returns the length of data written. { if (0 == length) return 0; Mutex::ScopedLock lock(_mutex); - + if (!isWritable()) return 0; - + if (_buffer.size() - (_begin + _used) < length) { std::memmove(_buffer.begin(), begin(), _used * sizeof(T)); @@ -253,12 +253,12 @@ public: std::size_t write(const Buffer& buffer, std::size_t length = 0) /// Writes data from supplied buffer to the FIFO buffer. /// If there is no sufficient space for the whole - /// buffer to be written, data up to available + /// buffer to be written, data up to available /// length is written. /// The length of data to be written is determined from the /// length argument or buffer size (when length argument is /// default zero or greater than buffer size). - /// + /// /// Returns the length of data written. { if (length == 0 || length > buffer.size()) @@ -272,13 +272,13 @@ public: { return _buffer.size(); } - + std::size_t used() const /// Returns the size of the used portion of the buffer. { return _used; } - + std::size_t available() const /// Returns the size of the available portion of the buffer. { @@ -316,10 +316,10 @@ public: if (0 == length) return; Mutex::ScopedLock lock(_mutex); - + if (length > available()) throw Poco::InvalidAccessException("Cannot extend buffer."); - + if (!isWritable()) throw Poco::InvalidAccessException("Buffer not writable."); @@ -331,14 +331,15 @@ public: void advance(std::size_t length) /// Advances buffer by length elements. - /// Should be called AFTER the data + /// Should be called AFTER the data /// was copied into the buffer. { + if (0 == length) return; Mutex::ScopedLock lock(_mutex); if (length > available()) throw Poco::InvalidAccessException("Cannot extend buffer."); - + if (!isWritable()) throw Poco::InvalidAccessException("Buffer not writable."); @@ -377,7 +378,7 @@ public: T& operator [] (std::size_t index) /// Returns value at index position. - /// Throws InvalidAccessException if index is larger than + /// Throws InvalidAccessException if index is larger than /// the last valid (used) buffer position. { Mutex::ScopedLock lock(_mutex); @@ -389,7 +390,7 @@ public: const T& operator [] (std::size_t index) const /// Returns value at index position. - /// Throws InvalidAccessException if index is larger than + /// Throws InvalidAccessException if index is larger than /// the last valid (used) buffer position. { Mutex::ScopedLock lock(_mutex); @@ -404,12 +405,12 @@ public: { return _buffer; } - + void setError(bool error = true) /// Sets the error flag on the buffer and empties it. - /// If notifications are enabled, they will be triggered + /// If notifications are enabled, they will be triggered /// if appropriate. - /// + /// /// Setting error flag to true prevents reading and writing /// to the buffer; to re-enable FIFOBuffer for reading/writing, /// the error flag must be set to false. @@ -418,8 +419,8 @@ public: { bool f = false; Mutex::ScopedLock lock(_mutex); - if (error && isReadable() && _notify) readable.notify(this, f); - if (error && isWritable() && _notify) writable.notify(this, f); + if (isReadable() && _notify) readable.notify(this, f); + if (isWritable() && _notify) writable.notify(this, f); _error = error; _used = 0; } @@ -441,14 +442,14 @@ public: void setEOF(bool eof = true) /// Sets end-of-file flag on the buffer. - /// + /// /// Setting EOF flag to true prevents writing to the /// buffer; reading from the buffer will still be - /// allowed until all data present in the buffer at the - /// EOF set time is drained. After that, to re-enable + /// allowed until all data present in the buffer at the + /// EOF set time is drained. After that, to re-enable /// FIFOBuffer for reading/writing, EOF must be /// set to false. - /// + /// /// Setting EOF flag to false clears EOF state if it /// was previously set. If EOF was not set, it has no /// effect. @@ -523,7 +524,7 @@ private: readable.notify(this, t); else if (usedBefore > 0 && 0 == _used) readable.notify(this, f); - + if (usedBefore == _buffer.size() && _used < _buffer.size()) writable.notify(this, t); else if (usedBefore < _buffer.size() && _used == _buffer.size()) diff --git a/Foundation/include/Poco/FIFOBufferStream.h b/Foundation/include/Poco/FIFOBufferStream.h index 6c1e1eb78..08673a7ad 100644 --- a/Foundation/include/Poco/FIFOBufferStream.h +++ b/Foundation/include/Poco/FIFOBufferStream.h @@ -33,7 +33,7 @@ class Foundation_API FIFOBufferStreamBuf: public BufferedBidirectionalStreamBuf /// FIFOBuffer is enabled for emtpy/non-empty/full state transitions notifications. { public: - + FIFOBufferStreamBuf(); /// Creates a FIFOBufferStreamBuf. @@ -60,7 +60,7 @@ protected: int writeToDevice(const char* buffer, std::streamsize length); private: - enum + enum { STREAM_BUFFER_SIZE = 1024 }; @@ -89,15 +89,15 @@ public: explicit FIFOIOS(std::size_t length); /// Creates a FIFOIOS of the given length. - + ~FIFOIOS(); /// Destroys the FIFOIOS. /// /// Flushes the buffer. - + FIFOBufferStreamBuf* rdbuf(); /// Returns a pointer to the internal FIFOBufferStreamBuf. - + void close(); /// Flushes the stream. diff --git a/Foundation/include/Poco/FIFOEvent.h b/Foundation/include/Poco/FIFOEvent.h index b461d9631..f4c5007e7 100644 --- a/Foundation/include/Poco/FIFOEvent.h +++ b/Foundation/include/Poco/FIFOEvent.h @@ -27,9 +27,9 @@ namespace Poco { //@ deprecated -template -class FIFOEvent: public AbstractEvent < - TArgs, +template +class FIFOEvent: public AbstractEvent < + TArgs, FIFOStrategy>, AbstractDelegate, TMutex diff --git a/Foundation/include/Poco/FIFOStrategy.h b/Foundation/include/Poco/FIFOStrategy.h index 79c227604..b69ca6c9d 100644 --- a/Foundation/include/Poco/FIFOStrategy.h +++ b/Foundation/include/Poco/FIFOStrategy.h @@ -25,9 +25,9 @@ namespace Poco { //@ deprecated -template +template class FIFOStrategy: public DefaultStrategy - /// Note: As of release 1.4.2, DefaultStrategy already + /// Note: As of release 1.4.2, DefaultStrategy already /// implements FIFO behavior, so this class is provided /// for backwards compatibility only. { diff --git a/Foundation/include/Poco/FPEnvironment_DEC.h b/Foundation/include/Poco/FPEnvironment_DEC.h index b55794a51..932556e2c 100644 --- a/Foundation/include/Poco/FPEnvironment_DEC.h +++ b/Foundation/include/Poco/FPEnvironment_DEC.h @@ -59,18 +59,18 @@ protected: FPEnvironmentImpl(const FPEnvironmentImpl& env); ~FPEnvironmentImpl(); FPEnvironmentImpl& operator = (const FPEnvironmentImpl& env); - void keepCurrentImpl(); + void keepCurrentImpl(); static void clearFlagsImpl(); - static bool isFlagImpl(FlagImpl flag); + static bool isFlagImpl(FlagImpl flag); static void setRoundingModeImpl(RoundingModeImpl mode); static RoundingModeImpl getRoundingModeImpl(); - static bool isInfiniteImpl(float value); + static bool isInfiniteImpl(float value); static bool isInfiniteImpl(double value); static bool isInfiniteImpl(long double value); - static bool isNaNImpl(float value); + static bool isNaNImpl(float value); static bool isNaNImpl(double value); static bool isNaNImpl(long double value); - static float copySignImpl(float target, float source); + static float copySignImpl(float target, float source); static double copySignImpl(double target, double source); static long double copySignImpl(long double target, long double source); diff --git a/Foundation/include/Poco/FPEnvironment_QNX.h b/Foundation/include/Poco/FPEnvironment_QNX.h index 1eef8259d..ca16bd25e 100644 --- a/Foundation/include/Poco/FPEnvironment_QNX.h +++ b/Foundation/include/Poco/FPEnvironment_QNX.h @@ -48,18 +48,18 @@ protected: FPEnvironmentImpl(const FPEnvironmentImpl& env); ~FPEnvironmentImpl(); FPEnvironmentImpl& operator = (const FPEnvironmentImpl& env); - void keepCurrentImpl(); + void keepCurrentImpl(); static void clearFlagsImpl(); - static bool isFlagImpl(FlagImpl flag); + static bool isFlagImpl(FlagImpl flag); static void setRoundingModeImpl(RoundingModeImpl mode); static RoundingModeImpl getRoundingModeImpl(); - static bool isInfiniteImpl(float value); + static bool isInfiniteImpl(float value); static bool isInfiniteImpl(double value); static bool isInfiniteImpl(long double value); - static bool isNaNImpl(float value); + static bool isNaNImpl(float value); static bool isNaNImpl(double value); static bool isNaNImpl(long double value); - static float copySignImpl(float target, float source); + static float copySignImpl(float target, float source); static double copySignImpl(double target, double source); static long double copySignImpl(long double target, long double source); diff --git a/Foundation/include/Poco/FPEnvironment_SUN.h b/Foundation/include/Poco/FPEnvironment_SUN.h index d9755006d..b60c0bfa1 100644 --- a/Foundation/include/Poco/FPEnvironment_SUN.h +++ b/Foundation/include/Poco/FPEnvironment_SUN.h @@ -47,18 +47,18 @@ protected: FPEnvironmentImpl(const FPEnvironmentImpl& env); ~FPEnvironmentImpl(); FPEnvironmentImpl& operator = (const FPEnvironmentImpl& env); - void keepCurrentImpl(); + void keepCurrentImpl(); static void clearFlagsImpl(); - static bool isFlagImpl(FlagImpl flag); + static bool isFlagImpl(FlagImpl flag); static void setRoundingModeImpl(RoundingModeImpl mode); static RoundingModeImpl getRoundingModeImpl(); - static bool isInfiniteImpl(float value); + static bool isInfiniteImpl(float value); static bool isInfiniteImpl(double value); static bool isInfiniteImpl(long double value); - static bool isNaNImpl(float value); + static bool isNaNImpl(float value); static bool isNaNImpl(double value); static bool isNaNImpl(long double value); - static float copySignImpl(float target, float source); + static float copySignImpl(float target, float source); static double copySignImpl(double target, double source); static long double copySignImpl(long double target, long double source); diff --git a/Foundation/include/Poco/FPEnvironment_WIN32.h b/Foundation/include/Poco/FPEnvironment_WIN32.h index b5f20d806..79ab61761 100644 --- a/Foundation/include/Poco/FPEnvironment_WIN32.h +++ b/Foundation/include/Poco/FPEnvironment_WIN32.h @@ -106,8 +106,8 @@ inline bool FPEnvironmentImpl::isInfiniteImpl(double value) inline bool FPEnvironmentImpl::isInfiniteImpl(long double value) { - if (_isnan(value) != 0) return false; - return _finite(value) == 0; + if (_isnan(static_cast(value)) != 0) return false; + return _finite(static_cast(value)) == 0; } @@ -125,7 +125,7 @@ inline bool FPEnvironmentImpl::isNaNImpl(double value) inline bool FPEnvironmentImpl::isNaNImpl(long double value) { - return _isnan(value) != 0; + return _isnan(static_cast(value)) != 0; } diff --git a/Foundation/include/Poco/File.h b/Foundation/include/Poco/File.h index 26ee82ff6..2ba1e964c 100644 --- a/Foundation/include/Poco/File.h +++ b/Foundation/include/Poco/File.h @@ -23,7 +23,7 @@ #include -#if defined(POCO_OS_FAMILY_WINDOWS) +#if defined(POCO_OS_FAMILY_WINDOWS) #if defined(_WIN32_WCE) #include "File_WINCE.h" #else @@ -103,7 +103,7 @@ public: File& operator = (const Path& path); /// Assignment operator. - void swap(File& file); + void swap(File& file) noexcept; /// Swaps the file with another one. const std::string& path() const; @@ -312,7 +312,7 @@ inline bool File::operator >= (const File& file) const } -inline void swap(File& f1, File& f2) +inline void swap(File& f1, File& f2) noexcept { f1.swap(f2); } diff --git a/Foundation/include/Poco/FileChannel.h b/Foundation/include/Poco/FileChannel.h index 84348bca6..f3c8e1955 100644 --- a/Foundation/include/Poco/FileChannel.h +++ b/Foundation/include/Poco/FileChannel.h @@ -43,7 +43,7 @@ class Foundation_API FileChannel: public Channel /// by a newline. /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is in the text. + /// appropriate Formatter to control what is in the text. /// /// The FileChannel support log file rotation based /// on log file size or time intervals. @@ -66,7 +66,7 @@ class Foundation_API FileChannel: public Channel /// * daily: the file is rotated daily /// * weekly: the file is rotated every seven days /// * monthly: the file is rotated every 30 days - /// * minutes: the file is rotated every minutes, + /// * minutes: the file is rotated every minutes, /// where is an integer greater than zero. /// * hours: the file is rotated every hours, where /// is an integer greater than zero. @@ -128,7 +128,7 @@ class Foundation_API FileChannel: public Channel /// /// Archived log files can be automatically purged, either if /// they reach a certain age, or if the number of archived - /// log files reaches a given maximum number. This is + /// log files reaches a given maximum number. This is /// controlled by the purgeAge and purgeCount properties. /// /// The purgeAge property can have the following values: @@ -148,18 +148,18 @@ class Foundation_API FileChannel: public Channel /// The flush property specifies whether each log message is flushed /// immediately to the log file (which may hurt application performance, /// but ensures that everything is in the log in case of a system crash), - // or whether it's allowed to stay in the system's file buffer for some time. + // or whether it's allowed to stay in the system's file buffer for some time. /// Valid values are: /// /// * true: Every essages is immediately flushed to the log file (default). /// * false: Messages are not immediately flushed to the log file. /// - /// The rotateOnOpen property specifies whether an existing log file should be + /// The rotateOnOpen property specifies whether an existing log file should be /// rotated (and archived) when the channel is opened. Valid values are: /// /// * true: The log file is rotated (and archived) when the channel is opened. /// * false: Log messages will be appended to an existing log file, - /// if it exists (unless other conditions for a rotation are met). + /// if it exists (unless other conditions for a rotation are met). /// This is the default. /// /// For a more lightweight file channel class, see SimpleFileChannel. @@ -173,19 +173,19 @@ public: void open(); /// Opens the FileChannel and creates the log file if necessary. - + void close(); /// Closes the FileChannel. void log(const Message& msg); /// Logs the given message to the file. - + void setProperty(const std::string& name, const std::string& value); - /// Sets the property with the given name. - /// + /// Sets the property with the given name. + /// /// The following properties are supported: /// * path: The log file's path. - /// * rotation: The log file's rotation mode. See the + /// * rotation: The log file's rotation mode. See the /// FileChannel class for details. /// * archive: The log file's archive mode. See the /// FileChannel class for details. @@ -203,7 +203,7 @@ public: /// * flush: Specifies whether messages are immediately /// flushed to the log file. See the FileChannel class /// for details. - /// * rotateOnOpen: Specifies whether an existing log file should be + /// * rotateOnOpen: Specifies whether an existing log file should be /// rotated and archived when the channel is opened. std::string getProperty(const std::string& name) const; @@ -213,7 +213,7 @@ public: Timestamp creationDate() const; /// Returns the log file's creation date. - + UInt64 size() const; /// Returns the log file's current size in bytes. diff --git a/Foundation/include/Poco/FileStream.h b/Foundation/include/Poco/FileStream.h index ba1aa0a4f..7c76ad018 100644 --- a/Foundation/include/Poco/FileStream.h +++ b/Foundation/include/Poco/FileStream.h @@ -49,14 +49,14 @@ class Foundation_API FileIOS: public virtual std::ios public: FileIOS(std::ios::openmode defaultMode); /// Creates the basic stream. - + ~FileIOS(); /// Destroys the stream. void open(const std::string& path, std::ios::openmode mode); /// Opens the file specified by path, using the given mode. /// - /// Throws a FileException (or a similar exception) if the file + /// Throws a FileException (or a similar exception) if the file /// does not exist or is not accessible for other reasons and /// a new file cannot be created. @@ -90,7 +90,7 @@ class Foundation_API FileInputStream: public FileIOS, public std::istream public: FileInputStream(); /// Creates an unopened FileInputStream. - + FileInputStream(const std::string& path, std::ios::openmode mode = std::ios::in); /// Creates the FileInputStream for the file given by path, using /// the given mode. @@ -98,7 +98,7 @@ public: /// The std::ios::in flag is always set, regardless of the actual /// value specified for mode. /// - /// Throws a FileNotFoundException (or a similar exception) if the file + /// Throws a FileNotFoundException (or a similar exception) if the file /// does not exist or is not accessible for other reasons. ~FileInputStream(); @@ -120,15 +120,15 @@ class Foundation_API FileOutputStream: public FileIOS, public std::ostream public: FileOutputStream(); /// Creats an unopened FileOutputStream. - + FileOutputStream(const std::string& path, std::ios::openmode mode = std::ios::out | std::ios::trunc); /// Creates the FileOutputStream for the file given by path, using /// the given mode. /// - /// The std::ios::out is always set, regardless of the actual + /// The std::ios::out is always set, regardless of the actual /// value specified for mode. /// - /// Throws a FileException (or a similar exception) if the file + /// Throws a FileException (or a similar exception) if the file /// does not exist or is not accessible for other reasons and /// a new file cannot be created. @@ -147,7 +147,7 @@ class Foundation_API FileStream: public FileIOS, public std::iostream /// Use an InputLineEndingConverter or OutputLineEndingConverter /// if you require CR-LF translation. /// - /// A seek (seekg() or seekp()) operation will always set the + /// A seek (seekg() or seekp()) operation will always set the /// read position and the write position simultaneously to the /// same value. /// @@ -156,7 +156,7 @@ class Foundation_API FileStream: public FileIOS, public std::iostream public: FileStream(); /// Creats an unopened FileStream. - + FileStream(const std::string& path, std::ios::openmode mode = std::ios::out | std::ios::in); /// Creates the FileStream for the file given by path, using /// the given mode. diff --git a/Foundation/include/Poco/FileStreamFactory.h b/Foundation/include/Poco/FileStreamFactory.h index 01364cf1d..e82d2f3ac 100644 --- a/Foundation/include/Poco/FileStreamFactory.h +++ b/Foundation/include/Poco/FileStreamFactory.h @@ -38,7 +38,7 @@ public: ~FileStreamFactory(); /// Destroys the FileStreamFactory. - + std::istream* open(const URI& uri); /// Creates and opens a file stream in binary mode for the given URI. /// The URI must be either a file URI or a relative URI reference @@ -46,7 +46,7 @@ public: /// /// Throws an FileNotFound exception if the file cannot /// be opened. - + std::istream* open(const Path& path); /// Creates and opens a file stream in binary mode for the given path. /// diff --git a/Foundation/include/Poco/FileStream_POSIX.h b/Foundation/include/Poco/FileStream_POSIX.h index f5fa25cb8..3d19bdec2 100644 --- a/Foundation/include/Poco/FileStream_POSIX.h +++ b/Foundation/include/Poco/FileStream_POSIX.h @@ -33,7 +33,7 @@ class Foundation_API FileStreamBuf: public BufferedBidirectionalStreamBuf public: FileStreamBuf(); /// Creates a FileStreamBuf. - + ~FileStreamBuf(); /// Destroys the FileStream. diff --git a/Foundation/include/Poco/File_WIN32U.h b/Foundation/include/Poco/File_WIN32U.h index 7c2e0a935..c97cb2efa 100644 --- a/Foundation/include/Poco/File_WIN32U.h +++ b/Foundation/include/Poco/File_WIN32U.h @@ -28,7 +28,7 @@ namespace Poco { class Foundation_API FileImpl { protected: - enum Options + enum Options { OPT_FAIL_ON_OVERWRITE_IMPL = 0x01 }; diff --git a/Foundation/include/Poco/Format.h b/Foundation/include/Poco/Format.h index 780f4e4c5..515df47e9 100644 --- a/Foundation/include/Poco/Format.h +++ b/Foundation/include/Poco/Format.h @@ -116,6 +116,9 @@ void Foundation_API format(std::string& result, const std::string& fmt, const st template < typename T, +#ifdef __cpp_lib_remove_cvref + typename std::enable_if_t, std::vector>>, +#endif typename... Args> void format(std::string& result, const std::string& fmt, T arg1, Args... args) /// Appends the formatted string to result. @@ -130,6 +133,9 @@ void format(std::string& result, const std::string& fmt, T arg1, Args... args) template < typename T, +#ifdef __cpp_lib_remove_cvref + typename std::enable_if_t, std::vector>>, +#endif typename... Args> void format(std::string& result, const char* fmt, T arg1, Args... args) /// Appends the formatted string to result. @@ -144,6 +150,9 @@ void format(std::string& result, const char* fmt, T arg1, Args... args) template < typename T, +#ifdef __cpp_lib_remove_cvref + typename std::enable_if_t, std::vector>>, +#endif typename... Args> std::string format(const std::string& fmt, T arg1, Args... args) /// Returns the formatted string. @@ -160,6 +169,9 @@ std::string format(const std::string& fmt, T arg1, Args... args) template < typename T, +#ifdef __cpp_lib_remove_cvref + typename std::enable_if_t, std::vector>>, +#endif typename... Args> std::string format(const char* fmt, T arg1, Args... args) /// Returns the formatted string. diff --git a/Foundation/include/Poco/Formatter.h b/Foundation/include/Poco/Formatter.h index f638a5135..e05199289 100644 --- a/Foundation/include/Poco/Formatter.h +++ b/Foundation/include/Poco/Formatter.h @@ -44,8 +44,8 @@ class Foundation_API Formatter: public Configurable, public RefCountedObject /// The Formatter class supports the Configurable interface, /// so the behaviour of certain formatters is configurable. /// It also supports reference counting based garbage collection. - /// - /// Trivial implementations of of getProperty() and + /// + /// Trivial implementations of of getProperty() and /// setProperty() are provided. /// /// Subclasses must at least provide a format() method. @@ -55,14 +55,14 @@ public: Formatter(); /// Creates the formatter. - + virtual ~Formatter(); /// Destroys the formatter. virtual void format(const Message& msg, std::string& text) = 0; - /// Formats the message and places the result in text. + /// Formats the message and places the result in text. /// Subclasses must override this method. - + void setProperty(const std::string& name, const std::string& value); /// Throws a PropertyNotSupportedException. diff --git a/Foundation/include/Poco/FormattingChannel.h b/Foundation/include/Poco/FormattingChannel.h index 493e52b87..af9d0d6c2 100644 --- a/Foundation/include/Poco/FormattingChannel.h +++ b/Foundation/include/Poco/FormattingChannel.h @@ -40,31 +40,31 @@ public: FormattingChannel(); /// Creates a FormattingChannel. - + FormattingChannel(Formatter::Ptr pFormatter); /// Creates a FormattingChannel and attaches a Formatter. - + FormattingChannel(Formatter::Ptr pFormatter, Channel::Ptr pChannel); /// Creates a FormattingChannel and attaches a Formatter /// and a Channel. - + void setFormatter(Formatter::Ptr pFormatter); /// Sets the Formatter used to format the messages /// before they are passed on. If null, the message /// is passed on unmodified. - + Formatter::Ptr getFormatter() const; /// Returns the Formatter used to format messages, /// which may be null. void setChannel(Channel::Ptr pChannel); - /// Sets the destination channel to which the formatted + /// Sets the destination channel to which the formatted /// messages are passed on. - + Channel::Ptr getChannel() const; /// Returns the channel to which the formatted /// messages are passed on. - + void log(const Message& msg); /// Formats the given Message using the Formatter and /// passes the formatted message on to the destination @@ -81,7 +81,7 @@ public: void open(); /// Opens the attached channel. - + void close(); /// Closes the attached channel. diff --git a/Foundation/include/Poco/FunctionDelegate.h b/Foundation/include/Poco/FunctionDelegate.h index 9aec96d95..b5676a3b5 100644 --- a/Foundation/include/Poco/FunctionDelegate.h +++ b/Foundation/include/Poco/FunctionDelegate.h @@ -26,9 +26,9 @@ namespace Poco { -template +template class FunctionDelegate: public AbstractDelegate - /// Wraps a freestanding function or static member function + /// Wraps a freestanding function or static member function /// for use as a Delegate. { public: @@ -48,7 +48,7 @@ public: ~FunctionDelegate() { } - + FunctionDelegate& operator = (const FunctionDelegate& delegate) { if (&delegate != this) @@ -79,7 +79,7 @@ public: { return new FunctionDelegate(*this); } - + void disable() { Mutex::ScopedLock lock(_mutex); @@ -95,7 +95,7 @@ private: }; -template +template class FunctionDelegate: public AbstractDelegate { public: @@ -115,7 +115,7 @@ public: ~FunctionDelegate() { } - + FunctionDelegate& operator = (const FunctionDelegate& delegate) { if (&delegate != this) @@ -162,7 +162,7 @@ private: }; -template +template class FunctionDelegate: public AbstractDelegate { public: @@ -182,7 +182,7 @@ public: ~FunctionDelegate() { } - + FunctionDelegate& operator = (const FunctionDelegate& delegate) { if (&delegate != this) @@ -198,7 +198,7 @@ public: if (_function) { (*_function)(arguments); - return true; + return true; } else return false; } @@ -229,9 +229,9 @@ private: }; -template <> +template <> class FunctionDelegate: public AbstractDelegate - /// Wraps a freestanding function or static member function + /// Wraps a freestanding function or static member function /// for use as a Delegate. { public: @@ -251,7 +251,7 @@ public: ~FunctionDelegate() { } - + FunctionDelegate& operator = (const FunctionDelegate& delegate) { if (&delegate != this) @@ -282,7 +282,7 @@ public: { return new FunctionDelegate(*this); } - + void disable() { Mutex::ScopedLock lock(_mutex); @@ -298,7 +298,7 @@ private: }; -template <> +template <> class FunctionDelegate: public AbstractDelegate { public: @@ -318,7 +318,7 @@ public: ~FunctionDelegate() { } - + FunctionDelegate& operator = (const FunctionDelegate& delegate) { if (&delegate != this) @@ -365,7 +365,7 @@ private: }; -template +template class FunctionDelegate: public AbstractDelegate { public: @@ -385,7 +385,7 @@ public: ~FunctionDelegate() { } - + FunctionDelegate& operator = (const FunctionDelegate& delegate) { if (&delegate != this) @@ -401,7 +401,7 @@ public: if (_function) { (*_function)(); - return true; + return true; } else return false; } diff --git a/Foundation/include/Poco/FunctionPriorityDelegate.h b/Foundation/include/Poco/FunctionPriorityDelegate.h index 60e659204..a1b94b6b2 100644 --- a/Foundation/include/Poco/FunctionPriorityDelegate.h +++ b/Foundation/include/Poco/FunctionPriorityDelegate.h @@ -26,9 +26,9 @@ namespace Poco { -template +template class FunctionPriorityDelegate: public AbstractPriorityDelegate - /// Wraps a freestanding function or static member function + /// Wraps a freestanding function or static member function /// for use as a PriorityDelegate. { public: @@ -39,13 +39,13 @@ public: _function(function) { } - + FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), _function(delegate._function) { } - + FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate) { if (&delegate != this) @@ -97,7 +97,7 @@ private: }; -template +template class FunctionPriorityDelegate: public AbstractPriorityDelegate { public: @@ -108,13 +108,13 @@ public: _function(function) { } - + FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), _function(delegate._function) { } - + FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate) { if (&delegate != this) @@ -166,7 +166,7 @@ private: }; -template +template class FunctionPriorityDelegate: public AbstractPriorityDelegate { public: @@ -177,13 +177,13 @@ public: _function(function) { } - + FunctionPriorityDelegate(const FunctionPriorityDelegate& delegate): AbstractPriorityDelegate(delegate), _function(delegate._function) { } - + FunctionPriorityDelegate& operator = (const FunctionPriorityDelegate& delegate) { if (&delegate != this) diff --git a/Foundation/include/Poco/Glob.h b/Foundation/include/Poco/Glob.h index 0de6eaebe..e23e9b214 100644 --- a/Foundation/include/Poco/Glob.h +++ b/Foundation/include/Poco/Glob.h @@ -34,8 +34,8 @@ class Foundation_API Glob /// as known from Unix shells. /// /// In the pattern string, '*' matches any sequence of characters, - /// '?' matches any single character, [SET] matches any single character - /// in the specified set, [!SET] matches any character not in the + /// '?' matches any single character, [SET] matches any single character + /// in the specified set, [!SET] matches any character not in the /// specified set. /// /// A set is composed of characters or ranges; a range looks like @@ -58,23 +58,23 @@ public: GLOB_CASELESS = 0x04, /// ignore case when comparing characters GLOB_DIRS_ONLY = 0x80 /// only glob for directories (for internal use only) }; - + Glob(const std::string& pattern, int options = 0); /// Creates the Glob, using the given pattern. The pattern /// must not be an empty string. /// - /// If the GLOB_DOT_SPECIAL option is specified, '*' and '?' do + /// If the GLOB_DOT_SPECIAL option is specified, '*' and '?' do /// not match '.' at the beginning of a matched subject. This is useful for /// making dot-files invisible in good old Unix-style. ~Glob(); /// Destroys the Glob. - + bool match(const std::string& subject); /// Matches the given subject against the glob pattern. /// Returns true if the subject matches the pattern, false /// otherwise. - + static void glob(const std::string& pathPattern, std::set& files, int options = 0); /// Creates a set of files that match the given pathPattern. /// @@ -135,7 +135,7 @@ protected: bool matchSet(TextIterator& itp, const TextIterator& endp, int c); static void collect(const Path& pathPattern, const Path& base, const Path& current, const std::string& pattern, std::set& files, int options); static bool isDirectory(const Path& path, bool followSymlink); - + private: std::string _pattern; int _options; diff --git a/Foundation/include/Poco/HMACEngine.h b/Foundation/include/Poco/HMACEngine.h index 1e4d6c5ce..f37a11725 100644 --- a/Foundation/include/Poco/HMACEngine.h +++ b/Foundation/include/Poco/HMACEngine.h @@ -31,7 +31,7 @@ class HMACEngine: public DigestEngine /// This class implements the HMAC message /// authentication code algorithm, as specified /// in RFC 2104. The underlying DigestEngine - /// (MD5Engine, SHA1Engine, etc.) must be given as + /// (MD5Engine, SHA1Engine, etc.) must be given as /// template argument. /// Since the HMACEngine is a DigestEngine, it can /// be used with the DigestStream class to create @@ -43,19 +43,19 @@ public: BLOCK_SIZE = Engine::BLOCK_SIZE, DIGEST_SIZE = Engine::DIGEST_SIZE }; - + HMACEngine(const std::string& passphrase) { init(passphrase.data(), passphrase.length()); } - + HMACEngine(const char* passphrase, std::size_t length) { poco_check_ptr (passphrase); init(passphrase, length); } - + ~HMACEngine() { std::memset(_ipad, 0, BLOCK_SIZE); @@ -63,21 +63,22 @@ public: delete [] _ipad; delete [] _opad; } - + std::size_t digestLength() const { return DIGEST_SIZE; } - + void reset() { _engine.reset(); _engine.update(_ipad, BLOCK_SIZE); } - + const DigestEngine::Digest& digest() { const DigestEngine::Digest& d = _engine.digest(); + poco_assert (d.size() == DIGEST_SIZE); char db[DIGEST_SIZE]; char* pdb = db; for (auto v: d) *pdb++ = v; @@ -122,7 +123,7 @@ protected: } reset(); } - + void updateImpl(const void* data, std::size_t length) { _engine.update(data, length); diff --git a/Foundation/include/Poco/Hash.h b/Foundation/include/Poco/Hash.h index 7aafb66a6..99a9352dc 100644 --- a/Foundation/include/Poco/Hash.h +++ b/Foundation/include/Poco/Hash.h @@ -10,6 +10,9 @@ // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. // +// hashRange Copyright 2005-2014 Daniel James. +// (Extracted from Boost 1.75.0 lib and adapted for poco on 2021-03-31) +// // SPDX-License-Identifier: BSL-1.0 // @@ -19,9 +22,17 @@ #include "Poco/Foundation.h" +#include "Poco/Types.h" #include +#if defined(_MSC_VER) +# define POCO_HASH_ROTL32(x, r) _rotl(x,r) +#else +# define POCO_HASH_ROTL32(x, r) (x << r) | (x >> (32 - r)) +#endif + + namespace Poco { @@ -53,49 +64,133 @@ struct Hash // inline std::size_t hash(Int8 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(UInt8 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(Int16 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(UInt16 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(Int32 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(UInt32 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(Int64 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; } inline std::size_t hash(UInt64 n) { - return static_cast(n)*2654435761U; + return static_cast(n)*2654435761U; +} + + +namespace Impl { + + +template +inline void hashCombine(SizeT& seed, SizeT value) +{ + seed ^= value + 0x9e3779b9 + (seed<<6) + (seed>>2); +} + + +inline void hashCombine(Poco::UInt32& h1, Poco::UInt32 k1) +{ + const uint32_t c1 = 0xcc9e2d51; + const uint32_t c2 = 0x1b873593; + + k1 *= c1; + k1 = POCO_HASH_ROTL32(k1,15); + k1 *= c2; + + h1 ^= k1; + h1 = POCO_HASH_ROTL32(h1,13); + h1 = h1*5+0xe6546b64; +} + + +#if defined(POCO_PTR_IS_64_BIT) && !(defined(__GNUC__) && ULONG_MAX == 0xffffffff) + + +inline void hashCombine(Poco::UInt64& h, Poco::UInt64 k) +{ + const Poco::UInt64 m = UINT64_C(0xc6a4a7935bd1e995); + const int r = 47; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + + // Completely arbitrary number, to + // prevent zeros from hashing to 0. + h += 0xe6546b64; +} + + +#endif // POCO_PTR_IS_64_BIT + + +} // namespace Impl + + +template +inline void hashCombine(std::size_t& seed, T const& v) +{ + Hash hasher; + Impl::hashCombine(seed, hasher(v)); +} + + +template +inline std::size_t hashRange(It first, It last) +{ + std::size_t seed = 0; + + for(; first != last; ++first) + { + hashCombine::value_type>(seed, *first); + } + + return seed; +} + + +template +inline void hashRange(std::size_t& seed, It first, It last) +{ + for(; first != last; ++first) + { + hashCombine::value_type>(seed, *first); + } } diff --git a/Foundation/include/Poco/HashMap.h b/Foundation/include/Poco/HashMap.h index 70845b707..63def8bf9 100644 --- a/Foundation/include/Poco/HashMap.h +++ b/Foundation/include/Poco/HashMap.h @@ -33,13 +33,13 @@ struct HashMapEntry { Key first; Value second; - + HashMapEntry(): first(), second() { } - + HashMapEntry(const Key& key): first(key), second() @@ -51,7 +51,7 @@ struct HashMapEntry second(value) { } - + bool operator == (const HashMapEntry& entry) const { return first == entry.first; @@ -91,27 +91,27 @@ public: typedef const Mapped& ConstReference; typedef Mapped* Pointer; typedef const Mapped* ConstPointer; - + typedef HashMapEntry ValueType; typedef std::pair PairType; - + typedef HashMapEntryHash HashType; typedef LinearHashTable HashTable; - + typedef typename HashTable::Iterator Iterator; typedef typename HashTable::ConstIterator ConstIterator; - + HashMap() /// Creates an empty HashMap. { } - + HashMap(std::size_t initialReserve): _table(initialReserve) /// Creates the HashMap with room for initialReserve entries. { } - + HashMap& operator = (const HashMap& map) /// Assigns another HashMap. { @@ -119,33 +119,33 @@ public: swap(tmp); return *this; } - - void swap(HashMap& map) + + void swap(HashMap& map) noexcept /// Swaps the HashMap with another one. { _table.swap(map._table); } - + ConstIterator begin() const { return _table.begin(); } - + ConstIterator end() const { return _table.end(); } - + Iterator begin() { return _table.begin(); } - + Iterator end() { return _table.end(); } - + ConstIterator find(const KeyType& key) const { ValueType value(key); @@ -174,18 +174,18 @@ public: { return _table.insert(value); } - + void erase(Iterator it) { _table.erase(it); } - + void erase(const KeyType& key) { Iterator it = find(key); _table.erase(it); } - + void clear() { _table.clear(); diff --git a/Foundation/include/Poco/HashSet.h b/Foundation/include/Poco/HashSet.h index a0c080699..ee0dcb7ce 100644 --- a/Foundation/include/Poco/HashSet.h +++ b/Foundation/include/Poco/HashSet.h @@ -38,9 +38,9 @@ public: typedef Value* Pointer; typedef const Value* ConstPointer; typedef HashFunc Hash; - + typedef LinearHashTable HashTable; - + typedef typename HashTable::Iterator Iterator; typedef typename HashTable::ConstIterator ConstIterator; @@ -49,23 +49,23 @@ public: { } - HashSet(std::size_t initialReserve): + HashSet(std::size_t initialReserve): _table(initialReserve) /// Creates the HashSet, using the given initialReserve. { } - + HashSet(const HashSet& set): _table(set._table) /// Creates the HashSet by copying another one. { } - + ~HashSet() /// Destroys the HashSet. { } - + HashSet& operator = (const HashSet& table) /// Assigns another HashSet. { @@ -73,37 +73,37 @@ public: swap(tmp); return *this; } - - void swap(HashSet& set) + + void swap(HashSet& set) noexcept /// Swaps the HashSet with another one. { _table.swap(set._table); } - + ConstIterator begin() const /// Returns an iterator pointing to the first entry, if one exists. { return _table.begin(); } - + ConstIterator end() const /// Returns an iterator pointing to the end of the table. { return _table.end(); } - + Iterator begin() /// Returns an iterator pointing to the first entry, if one exists. { return _table.begin(); } - + Iterator end() /// Returns an iterator pointing to the end of the table. { return _table.end(); } - + ConstIterator find(const ValueType& value) const /// Finds an entry in the table. { @@ -115,51 +115,51 @@ public: { return _table.find(value); } - + std::size_t count(const ValueType& value) const /// Returns the number of elements with the given /// value, with is either 1 or 0. { return _table.count(value); } - + std::pair insert(const ValueType& value) /// Inserts an element into the set. /// /// If the element already exists in the set, - /// a pair(iterator, false) with iterator pointing to the + /// a pair(iterator, false) with iterator pointing to the /// existing element is returned. - /// Otherwise, the element is inserted an a + /// Otherwise, the element is inserted an a /// pair(iterator, true) with iterator /// pointing to the new element is returned. { return _table.insert(value); } - + void erase(Iterator it) /// Erases the element pointed to by it. { _table.erase(it); } - + void erase(const ValueType& value) /// Erases the element with the given value, if it exists. { _table.erase(value); } - + void clear() /// Erases all elements. { _table.clear(); } - + std::size_t size() const /// Returns the number of elements in the table. { return _table.size(); } - + bool empty() const /// Returns true iff the table is empty. { diff --git a/Foundation/include/Poco/HashStatistic.h b/Foundation/include/Poco/HashStatistic.h index ac413fb09..b2541ee23 100644 --- a/Foundation/include/Poco/HashStatistic.h +++ b/Foundation/include/Poco/HashStatistic.h @@ -31,10 +31,10 @@ class Foundation_API HashStatistic { public: HashStatistic( - UInt32 tableSize, - UInt32 numEntries, - UInt32 numZeroEntries, - UInt32 maxEntry, + UInt32 tableSize, + UInt32 numEntries, + UInt32 numZeroEntries, + UInt32 maxEntry, std::vector details = std::vector()); /// Creates the HashStatistic. diff --git a/Foundation/include/Poco/HashTable.h b/Foundation/include/Poco/HashTable.h index f2d8eb680..259ce8da3 100644 --- a/Foundation/include/Poco/HashTable.h +++ b/Foundation/include/Poco/HashTable.h @@ -51,9 +51,9 @@ public: typedef typename HashEntryMap::const_iterator ConstIterator; typedef typename HashEntryMap::iterator Iterator; - HashTable(UInt32 initialSize = 251): - _entries(0), - _size(0), + HashTable(UInt32 initialSize = 251): + _entries(0), + _size(0), _maxCapacity(initialSize) /// Creates the HashTable. { @@ -211,21 +211,21 @@ public: { return get(key); } - + Value& operator [] (const Key& key) { UInt32 hsh = hash(key); if (!_entries[hsh]) return insertRaw(key, hsh, Value()); - + ConstIterator it = _entries[hsh]->find(key); if (it == _entries[hsh]->end()) return insertRaw(key, hsh, Value()); return it->second; } - + const Key& getKeyRaw(const Key& key, UInt32 hsh) /// Throws an exception if the key does not exist. returns a reference to the internally /// stored key. Useful when someone does an insert and wants for performance reason only to store @@ -276,7 +276,7 @@ public: { return _size; } - + UInt32 maxCapacity() const { return _maxCapacity; diff --git a/Foundation/include/Poco/HexBinaryDecoder.h b/Foundation/include/Poco/HexBinaryDecoder.h index 7aab0f6cd..408e38d42 100644 --- a/Foundation/include/Poco/HexBinaryDecoder.h +++ b/Foundation/include/Poco/HexBinaryDecoder.h @@ -29,13 +29,13 @@ namespace Poco { class Foundation_API HexBinaryDecoderBuf: public UnbufferedStreamBuf /// This streambuf decodes all hexBinary-encoded data read /// from the istream connected to it. - /// In hexBinary encoding, each binary octet is encoded as a character tuple, + /// In hexBinary encoding, each binary octet is encoded as a character tuple, /// consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code. /// See also: XML Schema Part 2: Datatypes (http://www.w3.org/TR/xmlschema-2/), /// section 3.2.15. /// - /// Note: For performance reasons, the characters - /// are read directly from the given istream's + /// Note: For performance reasons, the characters + /// are read directly from the given istream's /// underlying streambuf, so the state /// of the istream will not reflect that of /// its streambuf. @@ -43,7 +43,7 @@ class Foundation_API HexBinaryDecoderBuf: public UnbufferedStreamBuf public: HexBinaryDecoderBuf(std::istream& istr); ~HexBinaryDecoderBuf(); - + private: int readFromDevice(); int readOne(); @@ -71,13 +71,13 @@ protected: class Foundation_API HexBinaryDecoder: public HexBinaryDecoderIOS, public std::istream /// This istream decodes all hexBinary-encoded data read /// from the istream connected to it. - /// In hexBinary encoding, each binary octet is encoded as a character tuple, + /// In hexBinary encoding, each binary octet is encoded as a character tuple, /// consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code. /// See also: XML Schema Part 2: Datatypes (http://www.w3.org/TR/xmlschema-2/), /// section 3.2.15. /// - /// Note: For performance reasons, the characters - /// are read directly from the given istream's + /// Note: For performance reasons, the characters + /// are read directly from the given istream's /// underlying streambuf, so the state /// of the istream will not reflect that of /// its streambuf. diff --git a/Foundation/include/Poco/HexBinaryEncoder.h b/Foundation/include/Poco/HexBinaryEncoder.h index 453c3cd82..bd7653982 100644 --- a/Foundation/include/Poco/HexBinaryEncoder.h +++ b/Foundation/include/Poco/HexBinaryEncoder.h @@ -29,8 +29,8 @@ namespace Poco { class Foundation_API HexBinaryEncoderBuf: public UnbufferedStreamBuf /// This streambuf encodes all data written /// to it in hexBinary encoding and forwards it to a connected - /// ostream. - /// In hexBinary encoding, each binary octet is encoded as a character tuple, + /// ostream. + /// In hexBinary encoding, each binary octet is encoded as a character tuple, /// consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code. /// See also: XML Schema Part 2: Datatypes (http://www.w3.org/TR/xmlschema-2/), /// section 3.2.15. @@ -43,24 +43,24 @@ class Foundation_API HexBinaryEncoderBuf: public UnbufferedStreamBuf public: HexBinaryEncoderBuf(std::ostream& ostr); ~HexBinaryEncoderBuf(); - + int close(); /// Closes the stream buffer. - + void setLineLength(int lineLength); /// Specify the line length. /// - /// After the given number of characters have been written, + /// After the given number of characters have been written, /// a newline character will be written. /// /// Specify 0 for an unlimited line length. - + int getLineLength() const; /// Returns the currently set line length. - + void setUppercase(bool flag = true); /// Specify whether hex digits a-f are written in upper or lower case. - + private: int writeToDevice(char c); @@ -95,7 +95,7 @@ class Foundation_API HexBinaryEncoder: public HexBinaryEncoderIOS, public std::o /// Always call close() when done /// writing data, to ensure proper /// completion of the encoding operation. - /// In hexBinary encoding, each binary octet is encoded as a character tuple, + /// In hexBinary encoding, each binary octet is encoded as a character tuple, /// consisting of two hexadecimal digits ([0-9a-fA-F]) representing the octet code. /// See also: XML Schema Part 2: Datatypes (http://www.w3.org/TR/xmlschema-2/), /// section 3.2.15. diff --git a/Foundation/include/Poco/InflatingStream.h b/Foundation/include/Poco/InflatingStream.h index 6e66faf6b..61064dc87 100644 --- a/Foundation/include/Poco/InflatingStream.h +++ b/Foundation/include/Poco/InflatingStream.h @@ -71,27 +71,27 @@ public: ~InflatingStreamBuf(); /// Destroys the InflatingStreamBuf. - + int close(); - /// Finishes up the stream. + /// Finishes up the stream. /// /// Must be called when inflating to an output stream. - + void reset(); /// Resets the stream buffer. - + protected: int readFromDevice(char* buffer, std::streamsize length); int writeToDevice(const char* buffer, std::streamsize length); int sync(); private: - enum + enum { STREAM_BUFFER_SIZE = 1024, INFLATE_BUFFER_SIZE = 32768 }; - + std::istream* _pIstr; std::ostream* _pOstr; char* _buffer; @@ -111,7 +111,7 @@ public: InflatingIOS(std::ostream& ostr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB); /// Creates an InflatingIOS for expanding the compressed data passed through /// and forwarding it to the given output stream. - + InflatingIOS(std::ostream& ostr, int windowBits); /// Creates an InflatingIOS for expanding the compressed data passed through /// and forwarding it to the given output stream. @@ -120,11 +120,11 @@ public: /// of the windowBits parameter. InflatingIOS(std::istream& istr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB); - /// Creates an InflatingIOS for expanding the compressed data read from + /// Creates an InflatingIOS for expanding the compressed data read from /// the given input stream. InflatingIOS(std::istream& istr, int windowBits); - /// Creates an InflatingIOS for expanding the compressed data read from + /// Creates an InflatingIOS for expanding the compressed data read from /// the given input stream. /// /// Please refer to the zlib documentation of inflateInit2() for a description @@ -132,10 +132,10 @@ public: ~InflatingIOS(); /// Destroys the InflatingIOS. - + InflatingStreamBuf* rdbuf(); /// Returns a pointer to the underlying stream buffer. - + protected: InflatingStreamBuf _buf; }; @@ -152,7 +152,7 @@ public: InflatingOutputStream(std::ostream& ostr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB); /// Creates an InflatingOutputStream for expanding the compressed data passed through /// and forwarding it to the given output stream. - + InflatingOutputStream(std::ostream& ostr, int windowBits); /// Creates an InflatingOutputStream for expanding the compressed data passed through /// and forwarding it to the given output stream. @@ -162,9 +162,9 @@ public: ~InflatingOutputStream(); /// Destroys the InflatingOutputStream. - + int close(); - /// Finishes up the stream. + /// Finishes up the stream. /// /// Must be called to ensure all data is properly written to /// the target output stream. @@ -186,11 +186,11 @@ class Foundation_API InflatingInputStream: public std::istream, public Inflating { public: InflatingInputStream(std::istream& istr, InflatingStreamBuf::StreamType type = InflatingStreamBuf::STREAM_ZLIB); - /// Creates an InflatingInputStream for expanding the compressed data read from + /// Creates an InflatingInputStream for expanding the compressed data read from /// the given input stream. InflatingInputStream(std::istream& istr, int windowBits); - /// Creates an InflatingInputStream for expanding the compressed data read from + /// Creates an InflatingInputStream for expanding the compressed data read from /// the given input stream. /// /// Please refer to the zlib documentation of inflateInit2() for a description @@ -198,7 +198,7 @@ public: ~InflatingInputStream(); /// Destroys the InflatingInputStream. - + void reset(); /// Resets the zlib machinery so that another zlib stream can be read from /// the same underlying input stream. diff --git a/Foundation/include/Poco/Instantiator.h b/Foundation/include/Poco/Instantiator.h index ce21ebc12..323a523e0 100644 --- a/Foundation/include/Poco/Instantiator.h +++ b/Foundation/include/Poco/Instantiator.h @@ -34,14 +34,14 @@ public: /// Creates the AbstractInstantiator. { } - + virtual ~AbstractInstantiator() /// Destroys the AbstractInstantiator. { } - + virtual Base* createInstance() const = 0; - /// Creates an instance of a concrete subclass of Base. + /// Creates an instance of a concrete subclass of Base. private: AbstractInstantiator(const AbstractInstantiator&); @@ -51,8 +51,8 @@ private: template class Instantiator: public AbstractInstantiator - /// A template class for the easy instantiation of - /// instantiators. + /// A template class for the easy instantiation of + /// instantiators. /// /// For the Instantiator to work, the class of which /// instances are to be instantiated must have a no-argument @@ -63,7 +63,7 @@ public: /// Creates the Instantiator. { } - + virtual ~Instantiator() /// Destroys the Instantiator. { diff --git a/Foundation/include/Poco/KeyValueArgs.h b/Foundation/include/Poco/KeyValueArgs.h index cdcc4e1ce..6c3009da1 100644 --- a/Foundation/include/Poco/KeyValueArgs.h +++ b/Foundation/include/Poco/KeyValueArgs.h @@ -24,20 +24,20 @@ namespace Poco { -template +template class KeyValueArgs /// Simply event arguments class to transfer a key and a value via an event call. /// Note that key and value are *NOT* copied, only references to them are stored. { public: - KeyValueArgs(const TKey& aKey, const TValue& aVal): - _key(aKey), + KeyValueArgs(const TKey& aKey, const TValue& aVal): + _key(aKey), _value(aVal) { } KeyValueArgs(const KeyValueArgs& args): - _key(args._key), + _key(args._key), _value(args._value) { } diff --git a/Foundation/include/Poco/LRUCache.h b/Foundation/include/Poco/LRUCache.h index 9c7bfcad7..d73bbf046 100644 --- a/Foundation/include/Poco/LRUCache.h +++ b/Foundation/include/Poco/LRUCache.h @@ -26,11 +26,11 @@ namespace Poco { template < - class TKey, + class TKey, class TValue, - class TMutex = FastMutex, + class TMutex = FastMutex, class TEventMutex = FastMutex -> +> class LRUCache: public AbstractCache, TMutex, TEventMutex> /// An LRUCache implements Least Recently Used caching. The default size for a cache is 1024 entries. { diff --git a/Foundation/include/Poco/LRUStrategy.h b/Foundation/include/Poco/LRUStrategy.h index c7180bd88..6bb274443 100644 --- a/Foundation/include/Poco/LRUStrategy.h +++ b/Foundation/include/Poco/LRUStrategy.h @@ -44,7 +44,7 @@ public: typedef typename KeyIndex::const_iterator ConstIndexIterator; public: - LRUStrategy(std::size_t size): + LRUStrategy(std::size_t size): _size(size) { if (_size < 1) throw InvalidArgumentException("size must be > 0"); @@ -117,7 +117,7 @@ public: Iterator it = --_keys.end(); //--keys can never be invoked on an empty list due to the minSize==1 requirement of LRU std::size_t i = 0; - while (i++ < diff) + while (i++ < diff) { elemsToRemove.insert(*it); if (it != _keys.begin()) diff --git a/Foundation/include/Poco/Latin1Encoding.h b/Foundation/include/Poco/Latin1Encoding.h index b1b987e0a..532da2b9d 100644 --- a/Foundation/include/Poco/Latin1Encoding.h +++ b/Foundation/include/Poco/Latin1Encoding.h @@ -38,7 +38,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/Latin2Encoding.h b/Foundation/include/Poco/Latin2Encoding.h index ac1cfecde..b82475596 100644 --- a/Foundation/include/Poco/Latin2Encoding.h +++ b/Foundation/include/Poco/Latin2Encoding.h @@ -41,7 +41,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/Latin9Encoding.h b/Foundation/include/Poco/Latin9Encoding.h index d2b7a1ca7..0eac73349 100644 --- a/Foundation/include/Poco/Latin9Encoding.h +++ b/Foundation/include/Poco/Latin9Encoding.h @@ -41,7 +41,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/LineEndingConverter.h b/Foundation/include/Poco/LineEndingConverter.h index d23414c35..b519b51ec 100644 --- a/Foundation/include/Poco/LineEndingConverter.h +++ b/Foundation/include/Poco/LineEndingConverter.h @@ -41,7 +41,7 @@ public: class Foundation_API LineEndingConverterStreamBuf: public UnbufferedStreamBuf /// This stream buffer performs line ending conversion - /// on text streams. The converter can convert from and to + /// on text streams. The converter can convert from and to /// the Unix (LF), Mac (CR) and DOS/Windows/Network (CF-LF) endings. /// /// Any newline sequence in the source will be replaced by the @@ -58,7 +58,7 @@ public: ~LineEndingConverterStreamBuf(); /// Destroys the LineEndingConverterStream. - + void setNewLine(const std::string& newLineCharacters); /// Sets the target line ending for the converter. /// @@ -90,7 +90,7 @@ private: class Foundation_API LineEndingConverterIOS: public virtual std::ios /// The base class for InputLineEndingConverter and OutputLineEndingConverter. /// - /// This class provides common methods and is also needed to ensure + /// This class provides common methods and is also needed to ensure /// the correct initialization order of the stream buffer and base classes. { public: @@ -133,7 +133,7 @@ protected: class Foundation_API InputLineEndingConverter: public LineEndingConverterIOS, public std::istream /// InputLineEndingConverter performs line ending conversion - /// on text input streams. The converter can convert from and to + /// on text input streams. The converter can convert from and to /// the Unix (LF), Mac (CR) and DOS/Windows/Network (CF-LF) endings. /// /// Any newline sequence in the source will be replaced by the @@ -155,7 +155,7 @@ public: class Foundation_API OutputLineEndingConverter: public LineEndingConverterIOS, public std::ostream /// OutputLineEndingConverter performs line ending conversion - /// on text output streams. The converter can convert from and to + /// on text output streams. The converter can convert from and to /// the Unix (LF), Mac (CR) and DOS/Windows/Network (CF-LF) endings. /// /// Any newline sequence in the source will be replaced by the diff --git a/Foundation/include/Poco/LinearHashTable.h b/Foundation/include/Poco/LinearHashTable.h index 1db5b0088..7883387ad 100644 --- a/Foundation/include/Poco/LinearHashTable.h +++ b/Foundation/include/Poco/LinearHashTable.h @@ -73,7 +73,7 @@ public: ConstIterator(): _initialized(false) { } - + ConstIterator(const BucketVecIterator& vecIt, const BucketVecIterator& endIt, const BucketIterator& buckIt): _vecIt(vecIt), _endIt(endIt), @@ -90,15 +90,15 @@ public: { } - + ConstIterator& operator = (const ConstIterator& it) { ConstIterator tmp(it); swap(tmp); return *this; } - - void swap(ConstIterator& it) + + void swap(ConstIterator& it) noexcept { using std::swap; // uninitialized iterators crash when swapped @@ -109,7 +109,7 @@ public: swap(_buckIt, it._buckIt); swap(_initialized, it._initialized); } - else + else { _vecIt = it._vecIt; _endIt = it._endIt; @@ -117,7 +117,7 @@ public: _initialized = it._initialized; } } - + bool operator == (const ConstIterator& it) const { return _vecIt == it._vecIt && (_vecIt == _endIt || _buckIt == it._buckIt); @@ -127,7 +127,7 @@ public: { return _vecIt != it._vecIt || (_vecIt != _endIt && _buckIt != it._buckIt); } - + const typename Bucket::value_type& operator * () const { return *_buckIt; @@ -137,7 +137,7 @@ public: { return &*_buckIt; } - + ConstIterator& operator ++ () // prefix { if (_vecIt != _endIt) @@ -151,30 +151,30 @@ public: } return *this; } - + ConstIterator operator ++ (int) // postfix { ConstIterator tmp(*this); ++*this; return tmp; } - + protected: BucketVecIterator _vecIt; BucketVecIterator _endIt; BucketIterator _buckIt; bool _initialized; - + friend class LinearHashTable; }; - + class Iterator: public ConstIterator { public: Iterator() { } - + Iterator(const BucketVecIterator& vecIt, const BucketVecIterator& endIt, const BucketIterator& buckIt): ConstIterator(vecIt, endIt, buckIt) { @@ -184,19 +184,19 @@ public: ConstIterator(it) { } - + Iterator& operator = (const Iterator& it) { Iterator tmp(it); ConstIterator::swap(tmp); return *this; } - - void swap(Iterator& it) + + void swap(Iterator& it) noexcept { ConstIterator::swap(it); } - + typename Bucket::value_type& operator * () { return *this->_buckIt; @@ -216,13 +216,13 @@ public: { return &*this->_buckIt; } - + Iterator& operator ++ () // prefix { ConstIterator::operator ++ (); return *this; } - + Iterator operator ++ (int) // postfix { Iterator tmp(*this); @@ -232,8 +232,8 @@ public: friend class LinearHashTable; }; - - LinearHashTable(std::size_t initialReserve = 64): + + LinearHashTable(std::size_t initialReserve = 64): _split(0), _front(1), _size(0) @@ -242,7 +242,7 @@ public: _buckets.reserve(calcSize(initialReserve)); _buckets.push_back(Bucket()); } - + LinearHashTable(const LinearHashTable& table): _buckets(table._buckets), _split(table._split), @@ -251,12 +251,12 @@ public: /// Creates the LinearHashTable by copying another one. { } - + ~LinearHashTable() /// Destroys the LinearHashTable. { } - + LinearHashTable& operator = (const LinearHashTable& table) /// Assigns another LinearHashTable. { @@ -264,8 +264,8 @@ public: swap(tmp); return *this; } - - void swap(LinearHashTable& table) + + void swap(LinearHashTable& table) noexcept /// Swaps the LinearHashTable with another one. { using std::swap; @@ -274,7 +274,7 @@ public: swap(_front, table._front); swap(_size, table._size); } - + ConstIterator begin() const /// Returns an iterator pointing to the first entry, if one exists. { @@ -289,13 +289,13 @@ public: else return ConstIterator(it, itEnd, it->begin()); } - + ConstIterator end() const /// Returns an iterator pointing to the end of the table. { return ConstIterator(_buckets.end(), _buckets.end(), _buckets.front().end()); } - + Iterator begin() /// Returns an iterator pointing to the first entry, if one exists. { @@ -310,13 +310,13 @@ public: else return Iterator(it, itEnd, it->begin()); } - + Iterator end() /// Returns an iterator pointing to the end of the table. { return Iterator(_buckets.end(), _buckets.end(), _buckets.front().end()); } - + ConstIterator find(const Value& value) const /// Finds an entry in the table. { @@ -340,21 +340,21 @@ public: else return end(); } - + std::size_t count(const Value& value) const /// Returns the number of elements with the given /// value, with is either 1 or 0. { return find(value) != end() ? 1 : 0; } - + std::pair insert(const Value& value) /// Inserts an element into the table. /// /// If the element already exists in the table, - /// a pair(iterator, false) with iterator pointing to the + /// a pair(iterator, false) with iterator pointing to the /// existing element is returned. - /// Otherwise, the element is inserted an a + /// Otherwise, the element is inserted an a /// pair(iterator, true) with iterator /// pointing to the new element is returned. { @@ -376,7 +376,7 @@ public: return std::make_pair(Iterator(it, _buckets.end(), buckIt), false); } } - + void erase(Iterator it) /// Erases the element pointed to by it. { @@ -387,39 +387,39 @@ public: merge(); } } - + void erase(const Value& value) /// Erases the element with the given value, if it exists. { Iterator it = find(value); erase(it); } - + void clear() /// Erases all elements. { LinearHashTable emptyTable; swap(emptyTable); } - + std::size_t size() const /// Returns the number of elements in the table. { return _size; } - + bool empty() const /// Returns true iff the table is empty. { return _size == 0; } - + std::size_t buckets() const /// Returns the number of allocated buckets. { return _buckets.size(); } - + protected: std::size_t bucketAddress(const Value& value) const { @@ -429,7 +429,7 @@ protected: else return n % (2*_front); } - + std::size_t bucketAddressForHash(std::size_t hash) { if (hash % _front >= _split) @@ -437,7 +437,7 @@ protected: else return hash % (2*_front); } - + void split() { if (_split == _front) @@ -458,7 +458,7 @@ protected: swap(*it, _buckets[addr].back()); } } - + void merge() { if (_split == 0) @@ -478,16 +478,16 @@ protected: swap(*it, _buckets[addr].back()); } } - + static std::size_t calcSize(std::size_t initialSize) { std::size_t size = 32; while (size < initialSize) size *= 2; return size; } - + private: - // Evil hack: _buckets must be mutable because both ConstIterator and Iterator hold + // Evil hack: _buckets must be mutable because both ConstIterator and Iterator hold // ordinary iterator's (not const_iterator's). mutable BucketVec _buckets; std::size_t _split; diff --git a/Foundation/include/Poco/ListMap.h b/Foundation/include/Poco/ListMap.h index 51844d7f1..2e41af0a3 100644 --- a/Foundation/include/Poco/ListMap.h +++ b/Foundation/include/Poco/ListMap.h @@ -35,7 +35,7 @@ class ListMap /// ordering of elements is not desirable. Naturally, this container will /// have inferior data retrieval performance and it is not recommended for /// use with large datasets. The main purpose within POCO is for Internet - /// messages (email message, http headers etc), to prevent automatic + /// messages (email message, http headers etc), to prevent automatic /// header entry reordering. { public: @@ -45,17 +45,17 @@ public: using ConstReference = const Mapped&; using Pointer = Mapped*; using ConstPointer = const Mapped*; - + using ValueType = typename Container::value_type; using SizeType = typename Container::size_type; using Iterator = typename Container::iterator; using ConstIterator = typename Container::const_iterator; - + ListMap() /// Creates an empty ListMap. { } - + explicit ListMap(std::size_t initialReserve): _container(initialReserve) /// Creates the ListMap with room for initialReserve entries. @@ -71,7 +71,7 @@ public: _container(std::move(other._container)) { } - + ListMap& operator = (const ListMap& map) /// Assigns another ListMap. { @@ -79,44 +79,44 @@ public: swap(tmp); return *this; } - + ListMap& operator = (ListMap&& map) noexcept /// Assigns another ListMap. { _container = std::move(map._container); return *this; } - - void swap(ListMap& map) + + void swap(ListMap& map) noexcept /// Swaps the ListMap with another one. { _container.swap(map._container); } - + ConstIterator begin() const /// Returns the beginning of the map. { return _container.begin(); } - + ConstIterator end() const /// Returns the end of the map. { return _container.end(); } - + Iterator begin() /// Returns the beginning of the map. { return _container.begin(); } - + Iterator end() /// Returns the end of the map. { return _container.end(); } - + ConstIterator find(const KeyType& key) const /// Finds the first occurrence of the key and /// returns iterator pointing to the found entry @@ -148,22 +148,22 @@ public: } Iterator insert(const ValueType& val) - /// Inserts the value into the map. If one or more values - /// already exist, new value is inserted at the end of the + /// Inserts the value into the map. If one or more values + /// already exist, new value is inserted at the end of the /// block. Thus, all the equal value entries are located /// sequentially at all times. - /// Returns iterator pointing to the newly inserted value + /// Returns iterator pointing to the newly inserted value { Iterator it = find(val.first); while (it != _container.end() && isEqual(it->first, val.first)) ++it; return _container.insert(it, val); } - + void erase(Iterator it) { _container.erase(it); } - + SizeType erase(const KeyType& key) { SizeType count = 0; @@ -185,7 +185,7 @@ public: } return count; } - + void clear() { _container.clear(); diff --git a/Foundation/include/Poco/LocalDateTime.h b/Foundation/include/Poco/LocalDateTime.h index 47206671a..5562309fe 100644 --- a/Foundation/include/Poco/LocalDateTime.h +++ b/Foundation/include/Poco/LocalDateTime.h @@ -27,11 +27,11 @@ namespace Poco { class Foundation_API LocalDateTime /// This class represents an instant in local time - /// (as opposed to UTC), expressed in years, months, days, - /// hours, minutes, seconds and milliseconds based on the + /// (as opposed to UTC), expressed in years, months, days, + /// hours, minutes, seconds and milliseconds based on the /// Gregorian calendar. /// - /// In addition to the date and time, the class also + /// In addition to the date and time, the class also /// maintains a time zone differential, which denotes /// the difference in seconds from UTC to local time, /// i.e. UTC = local time - time zone differential. @@ -53,7 +53,7 @@ class Foundation_API LocalDateTime { public: LocalDateTime(); - /// Creates a LocalDateTime with the current date/time + /// Creates a LocalDateTime with the current date/time /// for the current time zone. LocalDateTime(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microsecond = 0); @@ -94,7 +94,7 @@ public: //@ deprecated LocalDateTime(int tzd, const DateTime& dateTime, bool adjust); /// Creates a LocalDateTime from the UTC time given in dateTime, - /// using the given time zone differential. If adjust is true, + /// using the given time zone differential. If adjust is true, /// adjusts dateTime for the given time zone differential. LocalDateTime(double julianDay); @@ -107,19 +107,19 @@ public: LocalDateTime(const LocalDateTime& dateTime); /// Copy constructor. Creates the LocalDateTime from another one. - + ~LocalDateTime(); /// Destroys the LocalDateTime. - + LocalDateTime& operator = (const LocalDateTime& dateTime); /// Assigns another LocalDateTime. - + LocalDateTime& operator = (const Timestamp& timestamp); /// Assigns a timestamp LocalDateTime& operator = (double julianDay); /// Assigns a Julian day in the local time zone. - + LocalDateTime& assign(int year, int month, int day, int hour = 0, int minute = 0, int second = 0, int millisecond = 0, int microseconds = 0); /// Assigns a Gregorian local date and time. /// * year is from 0 to 9999. @@ -155,64 +155,64 @@ public: int year() const; /// Returns the year. - + int month() const; /// Returns the month (1 to 12). - + int week(int firstDayOfWeek = DateTime::MONDAY) const; /// Returns the week number within the year. /// FirstDayOfWeek should be either SUNDAY (0) or MONDAY (1). - /// The returned week number will be from 0 to 53. Week number 1 is the week + /// The returned week number will be from 0 to 53. Week number 1 is the week /// containing January 4. This is in accordance to ISO 8601. - /// + /// /// The following example assumes that firstDayOfWeek is MONDAY. For 2005, which started /// on a Saturday, week 1 will be the week starting on Monday, January 3. /// January 1 and 2 will fall within week 0 (or the last week of the previous year). /// /// For 2007, which starts on a Monday, week 1 will be the week starting on Monday, January 1. /// There will be no week 0 in 2007. - + int day() const; /// Returns the day within the month (1 to 31). - + int dayOfWeek() const; /// Returns the weekday (0 to 6, where /// 0 = Sunday, 1 = Monday, ..., 6 = Saturday). - + int dayOfYear() const; /// Returns the number of the day in the year. /// January 1 is 1, February 1 is 32, etc. - + int hour() const; /// Returns the hour (0 to 23). - + int hourAMPM() const; /// Returns the hour (0 to 12). - + bool isAM() const; /// Returns true if hour < 12; bool isPM() const; /// Returns true if hour >= 12. - + int minute() const; /// Returns the minute (0 to 59). - + int second() const; /// Returns the second (0 to 59). - + int millisecond() const; /// Returns the millisecond (0 to 999) - + int microsecond() const; /// Returns the microsecond (0 to 999) - + double julianDay() const; /// Returns the Julian day for the date. int tzd() const; /// Returns the time zone differential. - + DateTime utc() const; /// Returns the UTC equivalent for the local date and time. @@ -222,12 +222,12 @@ public: Timestamp::UtcTimeVal utcTime() const; /// Returns the UTC equivalent for the local date and time. - bool operator == (const LocalDateTime& dateTime) const; - bool operator != (const LocalDateTime& dateTime) const; - bool operator < (const LocalDateTime& dateTime) const; - bool operator <= (const LocalDateTime& dateTime) const; - bool operator > (const LocalDateTime& dateTime) const; - bool operator >= (const LocalDateTime& dateTime) const; + bool operator == (const LocalDateTime& dateTime) const; + bool operator != (const LocalDateTime& dateTime) const; + bool operator < (const LocalDateTime& dateTime) const; + bool operator <= (const LocalDateTime& dateTime) const; + bool operator > (const LocalDateTime& dateTime) const; + bool operator >= (const LocalDateTime& dateTime) const; LocalDateTime operator + (const Timespan& span) const; LocalDateTime operator - (const Timespan& span) const; @@ -237,23 +237,23 @@ public: protected: LocalDateTime(Timestamp::UtcTimeVal utcTime, Timestamp::TimeDiff diff, int tzd); - + void determineTzd(bool adjust = false); /// Recalculate the tzd based on the _dateTime member based /// on the current timezone using the Standard C runtime functions. /// If adjust is true, then adjustForTzd() is called after the /// differential is calculated. - + void adjustForTzd(); /// Adjust the _dateTime member based on the _tzd member. - + std::time_t dstOffset(int& dstOffset) const; /// Determine the DST offset for the current date/time. - + private: DateTime _dateTime; int _tzd; - + friend class DateTimeFormatter; friend class DateTimeParser; }; @@ -285,7 +285,7 @@ inline int LocalDateTime::day() const return _dateTime.day(); } - + inline int LocalDateTime::dayOfWeek() const { return _dateTime.dayOfWeek(); @@ -303,7 +303,7 @@ inline int LocalDateTime::hour() const return _dateTime.hour(); } - + inline int LocalDateTime::hourAMPM() const { return _dateTime.hourAMPM(); @@ -321,19 +321,19 @@ inline bool LocalDateTime::isPM() const return _dateTime.isPM(); } - + inline int LocalDateTime::minute() const { return _dateTime.minute(); } - + inline int LocalDateTime::second() const { return _dateTime.second(); } - + inline int LocalDateTime::millisecond() const { return _dateTime.millisecond(); @@ -376,7 +376,7 @@ inline void LocalDateTime::adjustForTzd() } -inline void swap(LocalDateTime& d1, LocalDateTime& d2) +inline void swap(LocalDateTime& d1, LocalDateTime& d2) noexcept { d1.swap(d2); } diff --git a/Foundation/include/Poco/LogFile_STD.h b/Foundation/include/Poco/LogFile_STD.h index 0e8feda2b..a178cb0ba 100644 --- a/Foundation/include/Poco/LogFile_STD.h +++ b/Foundation/include/Poco/LogFile_STD.h @@ -43,6 +43,7 @@ private: std::string _path; mutable Poco::FileOutputStream _str; Timestamp _creationDate; + UInt64 _size; }; diff --git a/Foundation/include/Poco/LoggingRegistry.h b/Foundation/include/Poco/LoggingRegistry.h index 2d4ca3647..397b81993 100644 --- a/Foundation/include/Poco/LoggingRegistry.h +++ b/Foundation/include/Poco/LoggingRegistry.h @@ -58,7 +58,7 @@ public: /// Registers a channel under a given name. /// It is okay to re-register a different channel under an /// already existing name. - + void registerFormatter(const std::string& name, Formatter::Ptr pFormatter); /// Registers a formatter under a given name. /// It is okay to re-register a different formatter under an @@ -86,7 +86,7 @@ private: typedef AutoPtr FormatterPtr; typedef std::map ChannelMap; typedef std::map FormatterMap; - + ChannelMap _channelMap; FormatterMap _formatterMap; mutable FastMutex _mutex; diff --git a/Foundation/include/Poco/MD4Engine.h b/Foundation/include/Poco/MD4Engine.h index c243e7851..291c561f6 100644 --- a/Foundation/include/Poco/MD4Engine.h +++ b/Foundation/include/Poco/MD4Engine.h @@ -61,7 +61,7 @@ public: MD4Engine(); ~MD4Engine(); - + std::size_t digestLength() const; void reset(); const DigestEngine::Digest& digest(); diff --git a/Foundation/include/Poco/MD5Engine.h b/Foundation/include/Poco/MD5Engine.h index ec3e80df7..e67b10a99 100644 --- a/Foundation/include/Poco/MD5Engine.h +++ b/Foundation/include/Poco/MD5Engine.h @@ -16,7 +16,7 @@ // MD5 (RFC 1321) algorithm: // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All // rights reserved. -// +// // License to copy and use this software is granted provided that it // is identified as the "RSA Data Security, Inc. MD5 Message-Digest // Algorithm" in all material mentioning or referencing this software @@ -61,7 +61,7 @@ public: MD5Engine(); ~MD5Engine(); - + std::size_t digestLength() const; void reset(); const DigestEngine::Digest& digest(); diff --git a/Foundation/include/Poco/Manifest.h b/Foundation/include/Poco/Manifest.h index b3db242c6..11e3470ea 100644 --- a/Foundation/include/Poco/Manifest.h +++ b/Foundation/include/Poco/Manifest.h @@ -100,7 +100,7 @@ public: { return _it->second; } - + private: typename MetaMap::const_iterator _it; }; diff --git a/Foundation/include/Poco/MemoryStream.h b/Foundation/include/Poco/MemoryStream.h index e168c8a03..1db3a2c23 100644 --- a/Foundation/include/Poco/MemoryStream.h +++ b/Foundation/include/Poco/MemoryStream.h @@ -31,9 +31,9 @@ namespace Poco { -template +template class BasicMemoryStreamBuf: public std::basic_streambuf - /// BasicMemoryStreamBuf is a simple implementation of a + /// BasicMemoryStreamBuf is a simple implementation of a /// stream buffer for reading and writing from a memory area. /// /// This streambuf only supports unidirectional streams. @@ -145,7 +145,7 @@ public: { return 0; } - + std::streamsize charsWritten() const { return static_cast(this->pptr() - this->pbase()); @@ -158,7 +158,7 @@ public: this->setg(_pBuffer, _pBuffer, _pBuffer + _bufferSize); this->setp(_pBuffer, _pBuffer + _bufferSize); } - + private: char_type* _pBuffer; std::streamsize _bufferSize; @@ -184,13 +184,13 @@ class Foundation_API MemoryIOS: public virtual std::ios public: MemoryIOS(char* pBuffer, std::streamsize bufferSize); /// Creates the basic stream. - + ~MemoryIOS(); /// Destroys the stream. MemoryStreamBuf* rdbuf(); /// Returns a pointer to the underlying streambuf. - + protected: MemoryStreamBuf _buf; }; @@ -203,7 +203,7 @@ public: MemoryInputStream(const char* pBuffer, std::streamsize bufferSize); /// Creates a MemoryInputStream for the given memory area, /// ready for reading. - + ~MemoryInputStream(); /// Destroys the MemoryInputStream. }; @@ -216,7 +216,7 @@ public: MemoryOutputStream(char* pBuffer, std::streamsize bufferSize); /// Creates a MemoryOutputStream for the given memory area, /// ready for writing. - + ~MemoryOutputStream(); /// Destroys the MemoryInputStream. diff --git a/Foundation/include/Poco/Message.h b/Foundation/include/Poco/Message.h index 9779f0de7..fd3262caf 100644 --- a/Foundation/include/Poco/Message.h +++ b/Foundation/include/Poco/Message.h @@ -43,6 +43,8 @@ class Foundation_API Message /// caused the message. { public: + typedef std::map StringMap; + enum Priority { PRIO_FATAL = 1, /// A fatal error. The application will most likely terminate. This is the highest priority. @@ -132,6 +134,9 @@ public: long getTid() const; /// Returns the numeric thread identifier for the message. + long getOsTid() const; + /// Returns the numeric thread identifier for the message. + void setPid(long pid); /// Sets the process identifier for the message. @@ -175,6 +180,9 @@ public: /// with the given name. If the parameter with the given name /// does not exist, then defaultValue is returned. + const StringMap& getAll() const; + /// Returns a const reference to all the values + void set(const std::string& param, const std::string& value); /// Sets the value for a parameter. If the parameter does /// not exist, then it is created. @@ -192,7 +200,6 @@ public: protected: void init(); - typedef std::map StringMap; private: std::string _source; @@ -200,6 +207,7 @@ private: Priority _prio; Timestamp _time; long _tid; + long _ostid; std::string _thread; long _pid; const char* _file; @@ -246,6 +254,10 @@ inline long Message::getTid() const return _tid; } +inline long Message::getOsTid() const +{ + return _ostid; +} inline long Message::getPid() const { @@ -265,7 +277,7 @@ inline int Message::getSourceLine() const } -inline void swap(Message& m1, Message& m2) +inline void swap(Message& m1, Message& m2) noexcept { m1.swap(m2); } diff --git a/Foundation/include/Poco/MetaObject.h b/Foundation/include/Poco/MetaObject.h index a3e574da9..907c9d73d 100644 --- a/Foundation/include/Poco/MetaObject.h +++ b/Foundation/include/Poco/MetaObject.h @@ -58,7 +58,7 @@ public: virtual B* create() const = 0; /// Create a new instance of a class. /// Cannot be used for singletons. - + virtual B& instance() const = 0; /// Returns a reference to the only instance /// of the class. Used for singletons only. @@ -74,7 +74,7 @@ public: /// and the object is deleted. { typename ObjectSet::iterator it = _deleteSet.find(pObject); - + if (it != _deleteSet.end()) { _deleteSet.erase(pObject); @@ -115,7 +115,7 @@ private: AbstractMetaObject& operator = (const AbstractMetaObject&); typedef std::set ObjectSet; - + const char* _name; mutable ObjectSet _deleteSet; }; @@ -142,12 +142,12 @@ public: { return new C; } - + B& instance() const { throw InvalidAccessException("Not a singleton. Use create() to create instances of", this->name()); } - + bool canCreate() const { return true; @@ -155,26 +155,26 @@ public: }; -template -class MetaSingleton: public AbstractMetaObject +template +class MetaSingleton: public AbstractMetaObject /// A SingletonMetaObject disables the create() method /// and instead offers an instance() method to access - /// the single instance of its class. -{ -public: - MetaSingleton(const char* name): AbstractMetaObject(name) + /// the single instance of its class. +{ +public: + MetaSingleton(const char* name): AbstractMetaObject(name) { } - - ~MetaSingleton() + + ~MetaSingleton() { } - + B* create() const { throw InvalidAccessException("Cannot create instances of a singleton class. Use instance() to obtain a", this->name()); } - + bool canCreate() const { return false; @@ -190,9 +190,9 @@ public: return true; } -private: - mutable SingletonHolder _object; -}; +private: + mutable SingletonHolder _object; +}; } // namespace Poco diff --git a/Foundation/include/Poco/MetaProgramming.h b/Foundation/include/Poco/MetaProgramming.h index ba68fe054..620d77dea 100644 --- a/Foundation/include/Poco/MetaProgramming.h +++ b/Foundation/include/Poco/MetaProgramming.h @@ -38,7 +38,7 @@ struct IsReference template struct IsReference { - enum + enum { VALUE = 1 }; @@ -48,7 +48,7 @@ struct IsReference template struct IsReference { - enum + enum { VALUE = 1 }; @@ -69,7 +69,7 @@ struct IsConst template struct IsConst { - enum + enum { VALUE = 1 }; @@ -79,7 +79,7 @@ struct IsConst template struct IsConst { - enum + enum { VALUE = 1 }; diff --git a/Foundation/include/Poco/Mutex.h b/Foundation/include/Poco/Mutex.h index c10946846..5070ab37a 100644 --- a/Foundation/include/Poco/Mutex.h +++ b/Foundation/include/Poco/Mutex.h @@ -51,10 +51,10 @@ namespace Poco { class Foundation_API Mutex: private MutexImpl - /// A Mutex (mutual exclusion) is a synchronization + /// A Mutex (mutual exclusion) is a synchronization /// mechanism used to control access to a shared resource /// in a concurrent (multithreaded) scenario. - /// Mutexes are recursive, that is, the same mutex can be + /// Mutexes are recursive, that is, the same mutex can be /// locked multiple times by the same thread (but, of course, /// not by other threads). /// Using the ScopedLock class is the preferred way to automatically @@ -62,23 +62,23 @@ class Foundation_API Mutex: private MutexImpl { public: using ScopedLock = Poco::ScopedLock; - + Mutex(); /// creates the Mutex. - + ~Mutex(); /// destroys the Mutex. void lock(); /// Locks the mutex. Blocks if the mutex /// is held by another thread. - + void lock(long milliseconds); /// Locks the mutex. Blocks up to the given number of milliseconds /// if the mutex is held by another thread. Throws a TimeoutException /// if the mutex can not be locked within the given timeout. /// - /// Performance Note: On most platforms (including Windows), this member function is + /// Performance Note: On most platforms (including Windows), this member function is /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep(). /// On POSIX platforms that support pthread_mutex_timedlock(), this is used. @@ -92,14 +92,14 @@ public: /// if the mutex is held by another thread. /// Returns true if the mutex was successfully locked. /// - /// Performance Note: On most platforms (including Windows), this member function is + /// Performance Note: On most platforms (including Windows), this member function is /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep(). /// On POSIX platforms that support pthread_mutex_timedlock(), this is used. void unlock(); /// Unlocks the mutex so that it can be acquired by /// other threads. - + private: Mutex(const Mutex&); Mutex& operator = (const Mutex&); @@ -120,7 +120,7 @@ public: FastMutex(); /// creates the Mutex. - + ~FastMutex(); /// destroys the Mutex. @@ -133,7 +133,7 @@ public: /// if the mutex is held by another thread. Throws a TimeoutException /// if the mutex can not be locked within the given timeout. /// - /// Performance Note: On most platforms (including Windows), this member function is + /// Performance Note: On most platforms (including Windows), this member function is /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep(). /// On POSIX platforms that support pthread_mutex_timedlock(), this is used. @@ -147,14 +147,14 @@ public: /// if the mutex is held by another thread. /// Returns true if the mutex was successfully locked. /// - /// Performance Note: On most platforms (including Windows), this member function is + /// Performance Note: On most platforms (including Windows), this member function is /// implemented using a loop calling (the equivalent of) tryLock() and Thread::sleep(). /// On POSIX platforms that support pthread_mutex_timedlock(), this is used. void unlock(); /// Unlocks the mutex so that it can be acquired by /// other threads. - + private: FastMutex(const FastMutex&); FastMutex& operator = (const FastMutex&); @@ -222,12 +222,12 @@ class Foundation_API NullMutex { public: using ScopedLock = Poco::ScopedLock; - + NullMutex() /// Creates the NullMutex. { } - + ~NullMutex() /// Destroys the NullMutex. { @@ -237,7 +237,7 @@ public: /// Does nothing. { } - + void lock(long) /// Does nothing. { diff --git a/Foundation/include/Poco/Mutex_POSIX.h b/Foundation/include/Poco/Mutex_POSIX.h index 12f61dd68..6e6c42a52 100644 --- a/Foundation/include/Poco/Mutex_POSIX.h +++ b/Foundation/include/Poco/Mutex_POSIX.h @@ -37,7 +37,7 @@ protected: bool tryLockImpl(); bool tryLockImpl(long milliseconds); void unlockImpl(); - + private: pthread_mutex_t _mutex; }; @@ -56,7 +56,7 @@ protected: // inline void MutexImpl::lockImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot lock mutex"); } diff --git a/Foundation/include/Poco/Mutex_VX.h b/Foundation/include/Poco/Mutex_VX.h index f0f43eac3..7d9f24df2 100644 --- a/Foundation/include/Poco/Mutex_VX.h +++ b/Foundation/include/Poco/Mutex_VX.h @@ -37,7 +37,7 @@ protected: bool tryLockImpl(); bool tryLockImpl(long milliseconds); void unlockImpl(); - + private: SEM_ID _sem; }; diff --git a/Foundation/include/Poco/Mutex_WIN32.h b/Foundation/include/Poco/Mutex_WIN32.h index 8e18c527e..b99981b20 100644 --- a/Foundation/include/Poco/Mutex_WIN32.h +++ b/Foundation/include/Poco/Mutex_WIN32.h @@ -35,7 +35,7 @@ protected: bool tryLockImpl(); bool tryLockImpl(long milliseconds); void unlockImpl(); - + private: CRITICAL_SECTION _cs; }; diff --git a/Foundation/include/Poco/Mutex_WINCE.h b/Foundation/include/Poco/Mutex_WINCE.h index 27200680f..27f93a72a 100644 --- a/Foundation/include/Poco/Mutex_WINCE.h +++ b/Foundation/include/Poco/Mutex_WINCE.h @@ -35,7 +35,7 @@ protected: bool tryLockImpl(); bool tryLockImpl(long milliseconds); void unlockImpl(); - + private: HANDLE _mutex; }; diff --git a/Foundation/include/Poco/NObserver.h b/Foundation/include/Poco/NObserver.h old mode 100644 new mode 100755 index 4231dc183..95b61fabd --- a/Foundation/include/Poco/NObserver.h +++ b/Foundation/include/Poco/NObserver.h @@ -30,7 +30,7 @@ template class NObserver: public AbstractObserver /// This template class implements an adapter that sits between /// a NotificationCenter and an object receiving notifications - /// from it. It is quite similar in concept to the + /// from it. It is quite similar in concept to the /// RunnableAdapter, but provides some NotificationCenter /// specific additional methods. /// See the NotificationCenter class for information on how @@ -38,7 +38,7 @@ class NObserver: public AbstractObserver /// /// This class template is quite similar to the Observer class /// template. The only difference is that the NObserver - /// expects the callback function to accept a const AutoPtr& + /// expects the callback function to accept a const AutoPtr& /// instead of a plain pointer as argument, thus simplifying memory /// management. { @@ -46,23 +46,23 @@ public: typedef AutoPtr NotificationPtr; typedef void (C::*Callback)(const NotificationPtr&); - NObserver(C& object, Callback method): - _pObject(&object), + NObserver(C& object, Callback method): + _pObject(&object), _method(method) { } - + NObserver(const NObserver& observer): AbstractObserver(observer), - _pObject(observer._pObject), + _pObject(observer._pObject), _method(observer._method) { } - + ~NObserver() { } - + NObserver& operator = (const NObserver& observer) { if (&observer != this) @@ -72,7 +72,7 @@ public: } return *this; } - + void notify(Notification* pNf) const { Poco::Mutex::ScopedLock lock(_mutex); @@ -87,7 +87,7 @@ public: } } } - + bool equals(const AbstractObserver& abstractObserver) const { const NObserver* pObs = dynamic_cast(&abstractObserver); @@ -98,16 +98,16 @@ public: { return dynamic_cast(pNf) && (!pName || pNf->name() == pName); } - + AbstractObserver* clone() const { return new NObserver(*this); } - + void disable() { Poco::Mutex::ScopedLock lock(_mutex); - + _pObject = 0; } diff --git a/Foundation/include/Poco/NamedEvent.h b/Foundation/include/Poco/NamedEvent.h index 5ef42bb1e..93c4b27f7 100644 --- a/Foundation/include/Poco/NamedEvent.h +++ b/Foundation/include/Poco/NamedEvent.h @@ -21,7 +21,7 @@ #include "Poco/Foundation.h" -#if defined(POCO_OS_FAMILY_WINDOWS) +#if defined(POCO_OS_FAMILY_WINDOWS) #include "Poco/NamedEvent_WIN32U.h" #elif POCO_OS == POCO_OS_ANDROID #include "Poco/NamedEvent_Android.h" diff --git a/Foundation/include/Poco/NamedEvent_Android.h b/Foundation/include/Poco/NamedEvent_Android.h index 910c8a46e..27c9bca82 100644 --- a/Foundation/include/Poco/NamedEvent_Android.h +++ b/Foundation/include/Poco/NamedEvent_Android.h @@ -27,7 +27,7 @@ namespace Poco { class Foundation_API NamedEventImpl { protected: - NamedEventImpl(const std::string& name); + NamedEventImpl(const std::string& name); ~NamedEventImpl(); void setImpl(); void waitImpl(); diff --git a/Foundation/include/Poco/NamedEvent_UNIX.h b/Foundation/include/Poco/NamedEvent_UNIX.h index e593790d6..22cb31dc9 100644 --- a/Foundation/include/Poco/NamedEvent_UNIX.h +++ b/Foundation/include/Poco/NamedEvent_UNIX.h @@ -30,11 +30,11 @@ namespace Poco { class Foundation_API NamedEventImpl { protected: - NamedEventImpl(const std::string& name); + NamedEventImpl(const std::string& name); ~NamedEventImpl(); void setImpl(); void waitImpl(); - + private: std::string getFileName(); diff --git a/Foundation/include/Poco/NamedEvent_WIN32U.h b/Foundation/include/Poco/NamedEvent_WIN32U.h index b2936c416..35f5d45fe 100644 --- a/Foundation/include/Poco/NamedEvent_WIN32U.h +++ b/Foundation/include/Poco/NamedEvent_WIN32U.h @@ -28,15 +28,15 @@ namespace Poco { class Foundation_API NamedEventImpl { protected: - NamedEventImpl(const std::string& name); + NamedEventImpl(const std::string& name); ~NamedEventImpl(); void setImpl(); void waitImpl(); - + private: std::string _name; std::wstring _uname; - HANDLE _event; + HANDLE _event; }; diff --git a/Foundation/include/Poco/NamedMutex.h b/Foundation/include/Poco/NamedMutex.h index 686ff5f06..197fe38fb 100644 --- a/Foundation/include/Poco/NamedMutex.h +++ b/Foundation/include/Poco/NamedMutex.h @@ -22,7 +22,7 @@ #include "Poco/ScopedLock.h" -#if defined(POCO_OS_FAMILY_WINDOWS) +#if defined(POCO_OS_FAMILY_WINDOWS) #include "Poco/NamedMutex_WIN32U.h" #elif POCO_OS == POCO_OS_ANDROID #include "Poco/NamedMutex_Android.h" diff --git a/Foundation/include/Poco/NamedMutex_UNIX.h b/Foundation/include/Poco/NamedMutex_UNIX.h index da77a32ee..151aa1ead 100644 --- a/Foundation/include/Poco/NamedMutex_UNIX.h +++ b/Foundation/include/Poco/NamedMutex_UNIX.h @@ -37,7 +37,7 @@ protected: void lockImpl(); bool tryLockImpl(); void unlockImpl(); - + private: std::string getFileName(); diff --git a/Foundation/include/Poco/NamedMutex_WIN32U.h b/Foundation/include/Poco/NamedMutex_WIN32U.h index 8ee315865..04305436f 100644 --- a/Foundation/include/Poco/NamedMutex_WIN32U.h +++ b/Foundation/include/Poco/NamedMutex_WIN32U.h @@ -33,7 +33,7 @@ protected: void lockImpl(); bool tryLockImpl(); void unlockImpl(); - + private: std::string _name; std::wstring _uname; diff --git a/Foundation/include/Poco/NamedTuple.h b/Foundation/include/Poco/NamedTuple.h index 6b0262b00..fa0b41efa 100644 --- a/Foundation/include/Poco/NamedTuple.h +++ b/Foundation/include/Poco/NamedTuple.h @@ -36,7 +36,7 @@ template TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -84,124 +84,124 @@ struct NamedTuple: public Tuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), - typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38), - typename TypeWrapper::CONSTTYPE& t39 = POCO_TYPEWRAPPER_DEFAULTVALUE(T39)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), + typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38), + typename TypeWrapper::CONSTTYPE& t39 = POCO_TYPEWRAPPER_DEFAULTVALUE(T39)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), - typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38), - typename TypeWrapper::CONSTTYPE& t39 = POCO_TYPEWRAPPER_DEFAULTVALUE(T39)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), + typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38), + typename TypeWrapper::CONSTTYPE& t39 = POCO_TYPEWRAPPER_DEFAULTVALUE(T39)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -225,23 +225,23 @@ struct NamedTuple: public Tuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -263,16 +263,16 @@ struct NamedTuple: public Tuple::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38), const std::string& n39 = "N1", - typename TypeWrapper::CONSTTYPE& t39 = POCO_TYPEWRAPPER_DEFAULTVALUE(T39)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t39 = POCO_TYPEWRAPPER_DEFAULTVALUE(T39)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36,n37,n38,n39); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -284,11 +284,11 @@ struct NamedTuple: public Tuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -304,11 +304,11 @@ struct NamedTuple: public Tuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -324,7 +324,7 @@ struct NamedTuple: public Tuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -354,7 +354,7 @@ struct NamedTuple: public Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -540,122 +540,122 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), - typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), + typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), - typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), + typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -679,23 +679,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -715,16 +715,16 @@ struct NamedTuple::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37), const std::string& n38 = "M1", - typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t38 = POCO_TYPEWRAPPER_DEFAULTVALUE(T38)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36,n37,n38); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -736,11 +736,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -756,11 +756,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -775,7 +775,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -805,7 +805,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -988,120 +988,120 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -1125,23 +1125,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -1159,16 +1159,16 @@ struct NamedTuple::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36), const std::string& n37 = "L1", - typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t37 = POCO_TYPEWRAPPER_DEFAULTVALUE(T37)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36,n37); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -1180,11 +1180,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -1200,11 +1200,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -1218,7 +1218,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -1248,7 +1248,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -1428,118 +1428,118 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -1563,23 +1563,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -1595,16 +1595,16 @@ struct NamedTuple::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35), const std::string& n36 = "K1", - typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t36 = POCO_TYPEWRAPPER_DEFAULTVALUE(T36)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35,n36); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -1616,11 +1616,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -1636,11 +1636,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -1653,7 +1653,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -1683,7 +1683,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -1860,116 +1860,116 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -1993,23 +1993,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -2023,16 +2023,16 @@ struct NamedTuple::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34), const std::string& n35 = "J1", - typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t35 = POCO_TYPEWRAPPER_DEFAULTVALUE(T35)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34,n35); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -2044,11 +2044,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -2064,11 +2064,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -2080,7 +2080,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -2110,7 +2110,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -2284,114 +2284,114 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -2415,23 +2415,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -2443,16 +2443,16 @@ struct NamedTuple::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33), const std::string& n34 = "I1", - typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t34 = POCO_TYPEWRAPPER_DEFAULTVALUE(T34)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33,n34); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -2464,11 +2464,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -2484,11 +2484,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -2499,7 +2499,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -2529,7 +2529,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -2700,112 +2700,112 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -2829,23 +2829,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -2855,16 +2855,16 @@ struct NamedTuple::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32), const std::string& n33 = "H1", - typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t33 = POCO_TYPEWRAPPER_DEFAULTVALUE(T33)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32,n33); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -2876,11 +2876,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -2896,11 +2896,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -2910,7 +2910,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -2940,7 +2940,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -3108,110 +3108,110 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -3235,23 +3235,23 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", @@ -3259,16 +3259,16 @@ struct NamedTuple::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31), const std::string& n32 = "G1", - typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t32 = POCO_TYPEWRAPPER_DEFAULTVALUE(T32)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31,n32); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -3280,11 +3280,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -3300,11 +3300,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -3313,7 +3313,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -3343,7 +3343,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -3508,108 +3508,108 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -3633,38 +3633,38 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30), const std::string& n31 = "F1", - typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t31 = POCO_TYPEWRAPPER_DEFAULTVALUE(T31)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30,n31); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -3676,11 +3676,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -3696,11 +3696,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); @@ -3708,7 +3708,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -3738,7 +3738,7 @@ struct NamedTuple @@ -3889,8 +3889,8 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -3900,106 +3900,106 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -4023,36 +4023,36 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29), const std::string& n30 = "E1", - typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t30 = POCO_TYPEWRAPPER_DEFAULTVALUE(T30)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29,n30); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -4064,11 +4064,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -4084,18 +4084,18 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); case 30: return TupleType::template get<30>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -4106,7 +4106,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -4125,7 +4125,7 @@ struct NamedTuple struct NamedTuple: @@ -4273,8 +4273,8 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -4284,104 +4284,104 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -4405,34 +4405,34 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28), const std::string& n29 = "D1", - typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t29 = POCO_TYPEWRAPPER_DEFAULTVALUE(T29)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28,n29); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -4444,11 +4444,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -4464,17 +4464,17 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); case 29: return TupleType::template get<29>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -4485,7 +4485,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -4504,7 +4504,7 @@ struct NamedTuple struct NamedTuple: public Tuple { typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -4660,102 +4660,102 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28), + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28)): + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -4779,32 +4779,32 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27), const std::string& n28 = "C1", - typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t28 = POCO_TYPEWRAPPER_DEFAULTVALUE(T28)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27,n28); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -4816,11 +4816,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -4836,16 +4836,16 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); case 28: return TupleType::template get<28>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -4856,7 +4856,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -4875,7 +4875,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -5028,100 +5028,100 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), - typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27), + typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), - typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27)): + typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -5145,30 +5145,30 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26), const std::string& n27 = "B1", - typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t27 = POCO_TYPEWRAPPER_DEFAULTVALUE(T27)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26,n27); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -5180,11 +5180,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -5200,15 +5200,15 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); - case 27: return TupleType::template get<27>(); + case 27: return TupleType::template get<27>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -5219,7 +5219,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -5238,7 +5238,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -5388,98 +5388,98 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26)): + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -5503,28 +5503,28 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25), const std::string& n26 = "A1", - typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t26 = POCO_TYPEWRAPPER_DEFAULTVALUE(T26)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25,n26); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -5536,11 +5536,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -5556,14 +5556,14 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); case 26: return TupleType::template get<26>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -5574,7 +5574,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -5593,7 +5593,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -5740,96 +5740,96 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25), + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25)): + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -5853,26 +5853,26 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24), const std::string& n25 = "Z", - typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t25 = POCO_TYPEWRAPPER_DEFAULTVALUE(T25)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24,n25); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -5884,11 +5884,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -5904,13 +5904,13 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); case 25: return TupleType::template get<25>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -5921,7 +5921,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -5940,7 +5940,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -6084,94 +6084,94 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24), + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24)): + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -6195,24 +6195,24 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23), const std::string& n24 = "Y", - typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t24 = POCO_TYPEWRAPPER_DEFAULTVALUE(T24)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23,n24); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -6224,11 +6224,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -6244,12 +6244,12 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); case 24: return TupleType::template get<24>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -6260,7 +6260,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -6279,7 +6279,7 @@ struct NamedTuple @@ -6409,8 +6409,8 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -6420,92 +6420,92 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), - typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23)): + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), - typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23)): + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -6529,22 +6529,22 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22), const std::string& n23 = "X", - typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t23 = POCO_TYPEWRAPPER_DEFAULTVALUE(T23)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22,n23); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -6556,11 +6556,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -6576,11 +6576,11 @@ struct NamedTuple(); case 21: return TupleType::template get<21>(); case 22: return TupleType::template get<22>(); - case 23: return TupleType::template get<23>(); + case 23: return TupleType::template get<23>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -6591,7 +6591,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -6610,7 +6610,7 @@ struct NamedTuple struct NamedTuple: @@ -6737,8 +6737,8 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -6748,90 +6748,90 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22)): + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -6855,20 +6855,20 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21), const std::string& n22 = "W", - typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t22 = POCO_TYPEWRAPPER_DEFAULTVALUE(T22)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21,n22); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -6880,11 +6880,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -6903,7 +6903,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -6933,7 +6933,7 @@ struct NamedTuple struct NamedTuple: public Tuple { typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -7068,88 +7068,88 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21), + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21)): + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -7173,18 +7173,18 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20), const std::string& n21 = "V", - typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t21 = POCO_TYPEWRAPPER_DEFAULTVALUE(T21)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20,n21); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -7196,11 +7196,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -7218,7 +7218,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -7248,7 +7248,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -7380,86 +7380,86 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -7483,16 +7483,16 @@ struct NamedTuple::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19), const std::string& n20 = "U", - typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t20 = POCO_TYPEWRAPPER_DEFAULTVALUE(T20)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19,n20); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -7504,11 +7504,11 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -7525,7 +7525,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -7555,7 +7555,7 @@ struct NamedTuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -7684,84 +7684,84 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -7783,16 +7783,16 @@ struct NamedTuple::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18), const std::string& n19 = "T", - typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t19 = POCO_TYPEWRAPPER_DEFAULTVALUE(T19)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18,n19); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -7800,15 +7800,15 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -7824,7 +7824,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -7854,7 +7854,7 @@ struct NamedTuplepush_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); - _pNames->push_back(n14); - _pNames->push_back(n15); - _pNames->push_back(n16); - _pNames->push_back(n17); - _pNames->push_back(n18); - _pNames->push_back(n19); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); + _pNames->push_back(n14); + _pNames->push_back(n15); + _pNames->push_back(n16); + _pNames->push_back(n17); + _pNames->push_back(n18); + _pNames->push_back(n19); } } @@ -7945,14 +7945,14 @@ private: }; -template TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -8075,16 +8075,16 @@ struct NamedTuple::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17), const std::string& n18 = "S", - typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t18 = POCO_TYPEWRAPPER_DEFAULTVALUE(T18)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17,n18); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -8092,15 +8092,15 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -8115,7 +8115,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -8145,7 +8145,7 @@ struct NamedTuplepush_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); - _pNames->push_back(n14); - _pNames->push_back(n15); - _pNames->push_back(n16); - _pNames->push_back(n17); - _pNames->push_back(n18); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); + _pNames->push_back(n14); + _pNames->push_back(n15); + _pNames->push_back(n16); + _pNames->push_back(n17); + _pNames->push_back(n18); } } @@ -8234,14 +8234,14 @@ private: }; -template TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { @@ -8268,80 +8268,80 @@ struct NamedTuplesize() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -8359,16 +8359,16 @@ struct NamedTuple::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16), const std::string& n17 = "R", - typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t17 = POCO_TYPEWRAPPER_DEFAULTVALUE(T17)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16,n17); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -8376,15 +8376,15 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -8398,7 +8398,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -8428,7 +8428,7 @@ struct NamedTuplepush_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); - _pNames->push_back(n14); - _pNames->push_back(n15); - _pNames->push_back(n16); - _pNames->push_back(n17); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); + _pNames->push_back(n14); + _pNames->push_back(n15); + _pNames->push_back(n16); + _pNames->push_back(n17); } } @@ -8515,14 +8515,14 @@ private: }; -template TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -8635,16 +8635,16 @@ struct NamedTuple::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15), const std::string& n16 = "Q", - typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t16 = POCO_TYPEWRAPPER_DEFAULTVALUE(T16)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15,n16); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -8652,15 +8652,15 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -8673,7 +8673,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -8703,7 +8703,7 @@ struct NamedTuplepush_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); - _pNames->push_back(n14); - _pNames->push_back(n15); - _pNames->push_back(n16); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); + _pNames->push_back(n14); + _pNames->push_back(n15); + _pNames->push_back(n16); } } @@ -8788,14 +8788,14 @@ private: }; -template TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -8904,16 +8904,16 @@ struct NamedTuple::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14), const std::string& n15 = "P", - typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t15 = POCO_TYPEWRAPPER_DEFAULTVALUE(T15)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14,n15); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -8921,15 +8921,15 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -8941,7 +8941,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -8971,7 +8971,7 @@ struct NamedTuplepush_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); - _pNames->push_back(n14); - _pNames->push_back(n15); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); + _pNames->push_back(n14); + _pNames->push_back(n15); } } @@ -9054,14 +9054,14 @@ private: }; -template TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -9165,16 +9165,16 @@ struct NamedTuple::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13), const std::string& n14 = "O", - typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t14 = POCO_TYPEWRAPPER_DEFAULTVALUE(T14)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13,n14); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -9182,15 +9182,15 @@ struct NamedTuple(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -9201,7 +9201,7 @@ struct NamedTuple - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -9231,7 +9231,7 @@ struct NamedTuplepush_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); - _pNames->push_back(n14); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); + _pNames->push_back(n14); } } @@ -9312,14 +9312,14 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -9418,16 +9418,16 @@ struct NamedTuple: const std::string& n12 = "M", typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12), const std::string& n13 = "N", - typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t13 = POCO_TYPEWRAPPER_DEFAULTVALUE(T13)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12,n13); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -9435,15 +9435,15 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -9453,7 +9453,7 @@ struct NamedTuple: default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -9464,7 +9464,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -9483,7 +9483,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -9507,7 +9507,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -9515,9 +9515,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -9528,7 +9528,7 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H", const std::string& n8 = "I", @@ -9537,24 +9537,24 @@ private: const std::string& n11 = "L", const std::string& n12 = "M", const std::string& n13 = "N") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); - _pNames->push_back(n13); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); + _pNames->push_back(n13); } } @@ -9562,14 +9562,14 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", @@ -9663,15 +9663,15 @@ struct NamedTuple: const std::string& n11 = "L", typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11), const std::string& n12 = "M", - typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12), _pNames(0) + typename TypeWrapper::CONSTTYPE& t12 = POCO_TYPEWRAPPER_DEFAULTVALUE(T12)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12), _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11,n12); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -9679,15 +9679,15 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -9696,7 +9696,7 @@ struct NamedTuple: default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -9707,7 +9707,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -9726,7 +9726,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -9750,7 +9750,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -9758,9 +9758,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -9771,7 +9771,7 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H", const std::string& n8 = "I", @@ -9779,23 +9779,23 @@ private: const std::string& n10 = "K", const std::string& n11 = "L", const std::string& n12 = "M") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); - _pNames->push_back(n12); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); + _pNames->push_back(n12); } } @@ -9803,14 +9803,14 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10), const std::string& n11 = "L", - typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t11 = POCO_TYPEWRAPPER_DEFAULTVALUE(T11)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10,n11); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -9916,15 +9916,15 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); @@ -9932,7 +9932,7 @@ struct NamedTuple: default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -9943,7 +9943,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -9962,7 +9962,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -9986,7 +9986,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -9994,9 +9994,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -10007,29 +10007,29 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H", const std::string& n8 = "I", const std::string& n9 = "J", const std::string& n10 = "K", const std::string& n11 = "L") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); - _pNames->push_back(n11); + _pNames->push_back(n9); + _pNames->push_back(n10); + _pNames->push_back(n11); } } @@ -10037,14 +10037,14 @@ private: }; -template @@ -10054,89 +10054,89 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9), const std::string& n10 = "K", - typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10), _pNames(0) + typename TypeWrapper::CONSTTYPE& t10 = POCO_TYPEWRAPPER_DEFAULTVALUE(T10)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10), _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9,n10); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -10144,22 +10144,22 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); case 10: return TupleType::template get<10>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -10170,7 +10170,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -10189,7 +10189,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -10213,7 +10213,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -10221,9 +10221,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -10234,27 +10234,27 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H", const std::string& n8 = "I", const std::string& n9 = "J", const std::string& n10 = "K") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); - _pNames->push_back(n10); + _pNames->push_back(n9); + _pNames->push_back(n10); } } @@ -10262,14 +10262,14 @@ private: }; -template struct NamedTuple: @@ -10278,86 +10278,86 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8), const std::string& n9 = "J", - typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t9 = POCO_TYPEWRAPPER_DEFAULTVALUE(T9)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8,n9); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -10365,21 +10365,21 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); case 9: return TupleType::template get<9>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -10390,7 +10390,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -10409,7 +10409,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -10433,7 +10433,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -10441,9 +10441,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -10454,25 +10454,25 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H", const std::string& n8 = "I", const std::string& n9 = "J") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); _pNames->push_back(n7); _pNames->push_back(n8); - _pNames->push_back(n9); + _pNames->push_back(n9); } } @@ -10480,14 +10480,14 @@ private: }; -template struct NamedTuple: public Tuple @@ -10495,82 +10495,82 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8), + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8)): + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7), const std::string& n8 = "I", - typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t8 = POCO_TYPEWRAPPER_DEFAULTVALUE(T8)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7,t8), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7,n8); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -10578,20 +10578,20 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); case 8: return TupleType::template get<8>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -10602,7 +10602,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -10621,7 +10621,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -10645,7 +10645,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -10653,9 +10653,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -10666,18 +10666,18 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H", const std::string& n8 = "I") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); @@ -10690,7 +10690,7 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), - typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7), + typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), - typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7)): + typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7)): TupleType(t0,t1,t2,t3,t4,t5,t6,t7) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6), const std::string& n7 = "H", - typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7)): - TupleType(t0,t1,t2,t3,t4,t5,t6,t7), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t7 = POCO_TYPEWRAPPER_DEFAULTVALUE(T7)): + TupleType(t0,t1,t2,t3,t4,t5,t6,t7), + _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6,n7); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -10783,19 +10783,19 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); - case 7: return TupleType::template get<7>(); + case 7: return TupleType::template get<7>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -10806,7 +10806,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -10825,7 +10825,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -10849,7 +10849,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -10857,9 +10857,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -10870,17 +10870,17 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G", const std::string& n7 = "H") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); @@ -10892,7 +10892,7 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6)): + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6)): TupleType(t0,t1,t2,t3,t4,t5,t6), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6)): + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6)): TupleType(t0,t1,t2,t3,t4,t5,t6) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5), const std::string& n6 = "G", - typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6)): - TupleType(t0,t1,t2,t3,t4,t5,t6), _pNames(0) + typename TypeWrapper::CONSTTYPE& t6 = POCO_TYPEWRAPPER_DEFAULTVALUE(T6)): + TupleType(t0,t1,t2,t3,t4,t5,t6), _pNames(0) { init(n0,n1,n2,n3,n4,n5,n6); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -10978,18 +10978,18 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); case 6: return TupleType::template get<6>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -11000,7 +11000,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -11019,7 +11019,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -11043,7 +11043,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -11051,9 +11051,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -11064,16 +11064,16 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E", - const std::string& n5 = "F", + const std::string& n5 = "F", const std::string& n6 = "G") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); _pNames->push_back(n6); @@ -11084,7 +11084,7 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5)): + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5)): TupleType(t0,t1,t2,t3,t4,t5), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5)): + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5)): TupleType(t0,t1,t2,t3,t4,t5) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4), const std::string& n5 = "F", - typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5)): - TupleType(t0,t1,t2,t3,t4,t5), _pNames(0) + typename TypeWrapper::CONSTTYPE& t5 = POCO_TYPEWRAPPER_DEFAULTVALUE(T5)): + TupleType(t0,t1,t2,t3,t4,t5), _pNames(0) { init(n0,n1,n2,n3,n4,n5); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -11165,17 +11165,17 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); case 5: return TupleType::template get<5>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -11186,7 +11186,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -11205,7 +11205,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -11229,7 +11229,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -11237,9 +11237,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -11251,14 +11251,14 @@ private: const std::string& n3 = "D", const std::string& n4 = "E", const std::string& n5 = "F") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); _pNames->push_back(n5); } @@ -11268,7 +11268,7 @@ private: }; -template: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4)): - TupleType(t0,t1,t2,t3,t4), + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4)): + TupleType(t0,t1,t2,t3,t4), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4)): + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4)): TupleType(t0,t1,t2,t3,t4) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), const std::string& n4 = "E", - typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4)): - TupleType(t0,t1,t2,t3,t4), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t4 = POCO_TYPEWRAPPER_DEFAULTVALUE(T4)): + TupleType(t0,t1,t2,t3,t4), + _pNames(0) { init(n0,n1,n2,n3,n4); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -11346,16 +11346,16 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); case 4: return TupleType::template get<4>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -11366,7 +11366,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -11385,7 +11385,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -11409,7 +11409,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -11417,9 +11417,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -11430,14 +11430,14 @@ private: const std::string& n2 = "C", const std::string& n3 = "D", const std::string& n4 = "E") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); _pNames->push_back(n4); } } @@ -11446,7 +11446,7 @@ private: }; -template @@ -11456,61 +11456,61 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), - typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): - TupleType(t0,t1,t2,t3), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): + TupleType(t0,t1,t2,t3), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), - typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): TupleType(t0,t1,t2,t3) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), const std::string& n3 = "D", - typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): - TupleType(t0,t1,t2,t3), _pNames(0) + typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): + TupleType(t0,t1,t2,t3), _pNames(0) { init(n0,n1,n2,n3); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -11518,15 +11518,15 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); - case 3: return TupleType::template get<3>(); + case 3: return TupleType::template get<3>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -11537,7 +11537,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -11556,7 +11556,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -11580,7 +11580,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -11588,9 +11588,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -11600,14 +11600,14 @@ private: const std::string& n1 = "B", const std::string& n2 = "C", const std::string& n3 = "D") - { + { if (!_pNames) { _pNames = new NameVec; _pNames->push_back(n0); _pNames->push_back(n1); _pNames->push_back(n2); - _pNames->push_back(n3); + _pNames->push_back(n3); } } @@ -11615,7 +11615,7 @@ private: }; -template struct NamedTuple: @@ -11624,58 +11624,58 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): - TupleType(t0,t1,t2), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): + TupleType(t0,t1,t2), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): TupleType(t0,t1,t2) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), const std::string& n2 = "C", - typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): - TupleType(t0,t1,t2), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): + TupleType(t0,t1,t2), + _pNames(0) { init(n0,n1,n2); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -11683,14 +11683,14 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); case 2: return TupleType::template get<2>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -11701,7 +11701,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -11720,7 +11720,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -11744,7 +11744,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -11752,9 +11752,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -11763,7 +11763,7 @@ private: void init(const std::string& n0 = "A", const std::string& n1 = "B", const std::string& n2 = "C") - { + { if (!_pNames) { _pNames = new NameVec; @@ -11777,7 +11777,7 @@ private: }; -template struct NamedTuple: public Tuple @@ -11785,54 +11785,54 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): - TupleType(t0,t1), + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): + TupleType(t0,t1), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, + NamedTuple(const NameVecPtr& rNames, typename TypeWrapper::CONSTTYPE& t0, - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): TupleType(t0,t1) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } NamedTuple(const std::string& n0, - typename TypeWrapper::CONSTTYPE& t0, + typename TypeWrapper::CONSTTYPE& t0, const std::string& n1 = "B", - typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): - TupleType(t0,t1), - _pNames(0) + typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): + TupleType(t0,t1), + _pNames(0) { init(n0,n1); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -11840,13 +11840,13 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); case 1: return TupleType::template get<1>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -11857,7 +11857,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -11876,7 +11876,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -11900,7 +11900,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -11908,9 +11908,9 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } @@ -11918,7 +11918,7 @@ struct NamedTuple: private: void init(const std::string& n0 = "A", const std::string& n1 = "B") - { + { if (!_pNames) { _pNames = new NameVec; @@ -11938,49 +11938,49 @@ struct NamedTuple: typedef Tuple TupleType; typedef typename Tuple::Type Type; - typedef std::vector NameVec; - typedef SharedPtr NameVecPtr; + typedef std::vector NameVec; + typedef SharedPtr NameVecPtr; NamedTuple(): _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames) + NamedTuple(const NameVecPtr& rNames) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } - NamedTuple(typename TypeWrapper::CONSTTYPE& t0): - TupleType(t0), + NamedTuple(typename TypeWrapper::CONSTTYPE& t0): + TupleType(t0), _pNames(0) { init(); } - NamedTuple(const NameVecPtr& rNames, - typename TypeWrapper::CONSTTYPE& t0): + NamedTuple(const NameVecPtr& rNames, + typename TypeWrapper::CONSTTYPE& t0): TupleType(t0) { if (rNames->size() != TupleType::length) - throw InvalidArgumentException("Wrong names vector length."); + throw InvalidArgumentException("Wrong names vector length."); _pNames = rNames; } - NamedTuple(const std::string& n0, typename TypeWrapper::CONSTTYPE& t0): - TupleType(t0), - _pNames(0) + NamedTuple(const std::string& n0, typename TypeWrapper::CONSTTYPE& t0): + TupleType(t0), + _pNames(0) { init(n0); } const DynamicAny get(const std::string& name) const { - NameVec::const_iterator it = _pNames->begin(); + NameVec::const_iterator it = _pNames->begin(); NameVec::const_iterator itEnd = _pNames->end(); for(std::size_t counter = 0; it != itEnd; ++it, ++counter) @@ -11988,12 +11988,12 @@ struct NamedTuple: if (name == *it) { switch (counter) - { + { case 0: return TupleType::template get<0>(); default: throw RangeException(); } } - } + } throw NotFoundException("Name not found: " + name); } @@ -12004,7 +12004,7 @@ struct NamedTuple: } template - typename TypeGetter::ConstHeadType& get() const + typename TypeGetter::ConstHeadType& get() const { return TupleType::template get(); } @@ -12023,7 +12023,7 @@ struct NamedTuple: const NameVecPtr& names() { - return _pNames; + return _pNames; } void setName(std::size_t index, const std::string& name) @@ -12047,7 +12047,7 @@ struct NamedTuple: return TupleType(*this) == TupleType(other) && _pNames == other._pNames; } - bool operator != (const NamedTuple& other) const + bool operator != (const NamedTuple& other) const { return !(*this == other); } @@ -12055,16 +12055,16 @@ struct NamedTuple: bool operator < (const NamedTuple& other) const { TupleType th(*this); - TupleType oth(other); + TupleType oth(other); - return (th < oth && _pNames == other._pNames) || + return (th < oth && _pNames == other._pNames) || (th == oth && _pNames < other._pNames) || (th < oth && _pNames < other._pNames); } private: void init(const std::string& n0 = "A") - { + { if (!_pNames) { _pNames = new NameVec; diff --git a/Foundation/include/Poco/NestedDiagnosticContext.h b/Foundation/include/Poco/NestedDiagnosticContext.h index ccb29a56a..80b0c223e 100644 --- a/Foundation/include/Poco/NestedDiagnosticContext.h +++ b/Foundation/include/Poco/NestedDiagnosticContext.h @@ -31,7 +31,7 @@ class NDCScope; class Foundation_API NestedDiagnosticContext /// This class implements a Nested Diagnostic Context (NDC), - /// as described in Neil Harrison's article "Patterns for Logging + /// as described in Neil Harrison's article "Patterns for Logging /// Diagnostic Messages" in "Pattern Languages of Program Design 3" /// (Addison-Wesley). /// @@ -61,29 +61,29 @@ public: ~NestedDiagnosticContext(); /// Destroys the NestedDiagnosticContext. - + NestedDiagnosticContext& operator = (const NestedDiagnosticContext& ctx); /// Assignment operator. - + void push(const std::string& info); /// Pushes a context (without line number and filename) onto the stack. - + void push(const std::string& info, int line, const char* filename); - /// Pushes a context (including line number and filename) + /// Pushes a context (including line number and filename) /// onto the stack. Filename must be a static string, such as the /// one produced by the __FILE__ preprocessor macro. void pop(); /// Pops the top-most context off the stack. - + int depth() const; /// Returns the depth (number of contexts) of the stack. - + std::string toString() const; /// Returns the stack as a string with entries /// delimited by colons. The string does not contain /// line numbers and filenames. - + void dump(std::ostream& ostr) const; /// Dumps the stack (including line number and filenames) /// to the given stream. The entries are delimited by @@ -92,10 +92,10 @@ public: void dump(std::ostream& ostr, const std::string& delimiter) const; /// Dumps the stack (including line number and filenames) /// to the given stream. - + void clear(); /// Clears the NDC stack. - + static NestedDiagnosticContext& current(); /// Returns the current thread's NDC. @@ -107,7 +107,7 @@ private: int line; }; typedef std::vector Stack; - + Stack _stack; }; @@ -123,7 +123,7 @@ class Foundation_API NDCScope public: NDCScope(const std::string& info); /// Pushes a context on the stack. - + NDCScope(const std::string& info, int line, const char* filename); /// Pushes a context on the stack. @@ -140,7 +140,7 @@ inline NDCScope::NDCScope(const std::string& info) NestedDiagnosticContext::current().push(info); } - + inline NDCScope::NDCScope(const std::string& info, int line, const char* filename) { NestedDiagnosticContext::current().push(info, line, filename); diff --git a/Foundation/include/Poco/Notification.h b/Foundation/include/Poco/Notification.h index 2246c6b12..4226ebf7d 100644 --- a/Foundation/include/Poco/Notification.h +++ b/Foundation/include/Poco/Notification.h @@ -36,7 +36,7 @@ class Foundation_API Notification: public RefCountedObject { public: using Ptr = AutoPtr; - + Notification(); /// Creates the notification. diff --git a/Foundation/include/Poco/NotificationCenter.h b/Foundation/include/Poco/NotificationCenter.h index 411bba894..dd77972b2 100644 --- a/Foundation/include/Poco/NotificationCenter.h +++ b/Foundation/include/Poco/NotificationCenter.h @@ -33,24 +33,24 @@ class AbstractObserver; class Foundation_API NotificationCenter - /// A NotificationCenter is essentially a notification dispatcher. + /// A NotificationCenter is essentially a notification dispatcher. /// It notifies all observers of notifications meeting specific criteria. /// This information is encapsulated in Notification objects. - /// Client objects register themselves with the notification center as observers of - /// specific notifications posted by other objects. When an event occurs, an object - /// posts an appropriate notification to the notification center. The notification - /// center invokes the registered method on each matching observer, passing the notification + /// Client objects register themselves with the notification center as observers of + /// specific notifications posted by other objects. When an event occurs, an object + /// posts an appropriate notification to the notification center. The notification + /// center invokes the registered method on each matching observer, passing the notification /// as argument. /// - /// The order in which observers receive notifications is undefined. + /// The order in which observers receive notifications is undefined. /// It is possible for the posting object and the observing object to be the same. - /// The NotificationCenter delivers notifications to observers synchronously. - /// In other words the postNotification() method does not return until all observers have - /// received and processed the notification. + /// The NotificationCenter delivers notifications to observers synchronously. + /// In other words the postNotification() method does not return until all observers have + /// received and processed the notification. /// If an observer throws an exception while handling a notification, the NotificationCenter /// stops dispatching the notification and postNotification() rethrows the exception. /// - /// In a multithreaded scenario, notifications are always delivered in the thread in which the + /// In a multithreaded scenario, notifications are always delivered in the thread in which the /// notification was posted, which may not be the same thread in which an observer registered itself. /// /// The NotificationCenter class is basically a C++ implementation of the NSNotificationCenter class @@ -116,10 +116,10 @@ public: /// /// Can be used to improve performance if an expensive notification /// shall only be created and posted if there are any observers. - + std::size_t countObservers() const; /// Returns the number of registered observers. - + static NotificationCenter& defaultCenter(); /// Returns a reference to the default /// NotificationCenter. diff --git a/Foundation/include/Poco/NotificationQueue.h b/Foundation/include/Poco/NotificationQueue.h index f299ed336..e34219c72 100644 --- a/Foundation/include/Poco/NotificationQueue.h +++ b/Foundation/include/Poco/NotificationQueue.h @@ -34,9 +34,9 @@ class NotificationCenter; class Foundation_API NotificationQueue /// A NotificationQueue object provides a way to implement asynchronous /// notifications. This is especially useful for sending notifications - /// from one thread to another, for example from a background thread to - /// the main (user interface) thread. - /// + /// from one thread to another, for example from a background thread to + /// the main (user interface) thread. + /// /// The NotificationQueue can also be used to distribute work from /// a controlling thread to one or more worker threads. Each worker thread /// repeatedly calls waitDequeueNotification() and processes the @@ -62,7 +62,7 @@ public: /// a call like /// notificationQueue.enqueueNotification(new MyNotification); /// does not result in a memory leak. - + void enqueueUrgentNotification(Notification::Ptr pNotification); /// Enqueues the given notification by adding it to /// the front of the queue (LIFO). The event therefore gets processed @@ -85,7 +85,7 @@ public: Notification* waitDequeueNotification(); /// Dequeues the next pending notification. /// If no notification is available, waits for a notification - /// to be enqueued. + /// to be enqueued. /// The caller gains ownership of the notification and /// is expected to release it when done with it. /// This method returns 0 (null) if wakeUpWaitingThreads() @@ -113,31 +113,31 @@ public: void wakeUpAll(); /// Wakes up all threads that wait for a notification. - + bool empty() const; /// Returns true iff the queue is empty. - + int size() const; /// Returns the number of notifications in the queue. void clear(); /// Removes all notifications from the queue. - + bool remove(Notification::Ptr pNotification); /// Removes a notification from the queue. /// Returns true if remove succeeded, false otherwise - bool hasIdleThreads() const; - /// Returns true if the queue has at least one thread waiting + bool hasIdleThreads() const; + /// Returns true if the queue has at least one thread waiting /// for a notification. - + static NotificationQueue& defaultQueue(); /// Returns a reference to the default /// NotificationQueue. protected: Notification::Ptr dequeueOne(); - + private: typedef std::deque NfQueue; struct WaitInfo diff --git a/Foundation/include/Poco/NotificationStrategy.h b/Foundation/include/Poco/NotificationStrategy.h index 856507678..63e820916 100644 --- a/Foundation/include/Poco/NotificationStrategy.h +++ b/Foundation/include/Poco/NotificationStrategy.h @@ -24,10 +24,10 @@ namespace Poco { -template +template class NotificationStrategy /// The interface that all notification strategies must implement. - /// + /// /// Note: Event is based on policy-driven design, so every strategy implementation /// must provide all the methods from this interface (otherwise: compile errors) /// but does not need to inherit from NotificationStrategy. @@ -65,10 +65,10 @@ public: }; -template +template class NotificationStrategy /// The interface that all notification strategies must implement. - /// + /// /// Note: Event is based on policy-driven design, so every strategy implementation /// must provide all the methods from this interface (otherwise: compile errors) /// but does not need to inherit from NotificationStrategy. diff --git a/Foundation/include/Poco/NullChannel.h b/Foundation/include/Poco/NullChannel.h index 426107e71..bd3ab3f57 100644 --- a/Foundation/include/Poco/NullChannel.h +++ b/Foundation/include/Poco/NullChannel.h @@ -29,7 +29,7 @@ class Foundation_API NullChannel: public Channel /// The NullChannel is the /dev/null of Channels. /// /// A NullChannel discards all information sent to it. - /// Furthermore, its setProperty() method ignores + /// Furthermore, its setProperty() method ignores /// all properties, so it the NullChannel has the /// nice feature that it can stand in for any /// other channel class in a logging configuration. diff --git a/Foundation/include/Poco/NullStream.h b/Foundation/include/Poco/NullStream.h index 52c292dff..07c689590 100644 --- a/Foundation/include/Poco/NullStream.h +++ b/Foundation/include/Poco/NullStream.h @@ -34,10 +34,10 @@ class Foundation_API NullStreamBuf: public UnbufferedStreamBuf public: NullStreamBuf(); /// Creates a NullStreamBuf. - + ~NullStreamBuf(); /// Destroys the NullStreamBuf. - + protected: int readFromDevice(); int writeToDevice(char c); @@ -78,7 +78,7 @@ class Foundation_API NullOutputStream: public NullIOS, public std::ostream public: NullOutputStream(); /// Creates the NullOutputStream. - + ~NullOutputStream(); /// Destroys the NullOutputStream. }; diff --git a/Foundation/include/Poco/Nullable.h b/Foundation/include/Poco/Nullable.h index f6cc5e2f8..5a22cc94d 100644 --- a/Foundation/include/Poco/Nullable.h +++ b/Foundation/include/Poco/Nullable.h @@ -177,7 +177,7 @@ public: return *this; } - void swap(Nullable& other) + void swap(Nullable& other) noexcept /// Swaps this Nullable with other. { std::swap(_value, other._value); @@ -310,7 +310,7 @@ private: template -inline void swap(Nullable& n1, Nullable& n2) +inline void swap(Nullable& n1, Nullable& n2) noexcept { n1.swap(n2); } diff --git a/Foundation/include/Poco/NumberFormatter.h b/Foundation/include/Poco/NumberFormatter.h index 6207f13d3..a197712f1 100644 --- a/Foundation/include/Poco/NumberFormatter.h +++ b/Foundation/include/Poco/NumberFormatter.h @@ -192,7 +192,7 @@ public: static std::string formatHex(unsigned long long value, bool prefix = false); /// Formats a 64-bit integer value in hexadecimal notation. - /// If prefix is true, "0x" prefix is prepended to the + /// If prefix is true, "0x" prefix is prepended to the /// resulting string. static std::string formatHex(unsigned long long value, int width, bool prefix = false); @@ -217,7 +217,7 @@ public: static std::string formatHex(Int64 value, bool prefix = false); /// Formats a 64-bit integer value in hexadecimal notation. - /// If prefix is true, "0x" prefix is prepended to the + /// If prefix is true, "0x" prefix is prepended to the /// resulting string. /// The value is treated as unsigned. @@ -849,6 +849,8 @@ inline std::string NumberFormatter::format(float value) inline std::string NumberFormatter::format(float value, int precision) { + if (precision < 0) + throw InvalidArgumentException("NumberFormatter::format() requires non-negative precision."); char buffer[POCO_MAX_FLT_STRING_LEN]; floatToFixedStr(buffer, POCO_MAX_FLT_STRING_LEN, value, precision); return std::string(buffer); @@ -857,6 +859,8 @@ inline std::string NumberFormatter::format(float value, int precision) inline std::string NumberFormatter::format(float value, int width, int precision) { + if (precision < 0) + throw InvalidArgumentException("NumberFormatter::format() requires non-negative precision."); std::string result; floatToFixedStr(result, value, precision, width); return result; @@ -873,6 +877,8 @@ inline std::string NumberFormatter::format(double value) inline std::string NumberFormatter::format(double value, int precision) { + if (precision < 0) + throw InvalidArgumentException("NumberFormatter::format() requires non-negative precision."); char buffer[POCO_MAX_FLT_STRING_LEN]; doubleToFixedStr(buffer, POCO_MAX_FLT_STRING_LEN, value, precision); return std::string(buffer); @@ -881,6 +887,8 @@ inline std::string NumberFormatter::format(double value, int precision) inline std::string NumberFormatter::format(double value, int width, int precision) { + if (precision < 0) + throw InvalidArgumentException("NumberFormatter::format() requires non-negative precision."); std::string result; doubleToFixedStr(result, value, precision, width); return result; diff --git a/Foundation/include/Poco/NumberParser.h b/Foundation/include/Poco/NumberParser.h index c58ed4f35..2383a02e5 100644 --- a/Foundation/include/Poco/NumberParser.h +++ b/Foundation/include/Poco/NumberParser.h @@ -44,19 +44,19 @@ public: static int parse(const std::string& s, char thousandSeparator = ','); /// Parses an integer value in decimal notation from the given string. /// Throws a SyntaxException if the string does not hold a number in decimal notation. - + static bool tryParse(const std::string& s, int& value, char thousandSeparator = ','); /// Parses an integer value in decimal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. - + static unsigned parseUnsigned(const std::string& s, char thousandSeparator = ','); /// Parses an unsigned integer value in decimal notation from the given string. /// Throws a SyntaxException if the string does not hold a number in decimal notation. static bool tryParseUnsigned(const std::string& s, unsigned& value, char thousandSeparator = ','); /// Parses an unsigned integer value in decimal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. static unsigned parseHex(const std::string& s); @@ -66,7 +66,7 @@ public: static bool tryParseHex(const std::string& s, unsigned& value); /// Parses an unsigned integer value in hexadecimal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. static unsigned parseOct(const std::string& s); @@ -76,7 +76,7 @@ public: static bool tryParseOct(const std::string& s, unsigned& value); /// Parses an unsigned integer value in octal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. #if defined(POCO_HAVE_INT64) @@ -87,7 +87,7 @@ public: static bool tryParse64(const std::string& s, Int64& value, char thousandSeparator = ','); /// Parses a 64-bit integer value in decimal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. static UInt64 parseUnsigned64(const std::string& s, char thousandSeparator = ','); @@ -96,7 +96,7 @@ public: static bool tryParseUnsigned64(const std::string& s, UInt64& value, char thousandSeparator = ','); /// Parses an unsigned 64-bit integer value in decimal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. static UInt64 parseHex64(const std::string& s); @@ -105,7 +105,7 @@ public: static bool tryParseHex64(const std::string& s, UInt64& value); /// Parses an unsigned 64-bit integer value in hexadecimal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. static UInt64 parseOct64(const std::string& s); @@ -114,7 +114,7 @@ public: static bool tryParseOct64(const std::string& s, UInt64& value); /// Parses an unsigned 64-bit integer value in octal notation from the given string. - /// Returns true if a valid integer has been found, false otherwise. + /// Returns true if a valid integer has been found, false otherwise. /// If parsing was not successful, value is undefined. #endif // defined(POCO_HAVE_INT64) @@ -122,9 +122,9 @@ public: static double parseFloat(const std::string& s, char decimalSeparator = '.', char thousandSeparator = ','); /// Parses a double value in decimal floating point notation /// from the given string. - /// Throws a SyntaxException if the string does not hold a floating-point + /// Throws a SyntaxException if the string does not hold a floating-point /// number in decimal notation. - + static bool tryParseFloat(const std::string& s, double& value, char decimalSeparator = '.', char thousandSeparator = ','); /// Parses a double value in decimal floating point notation /// from the given string. diff --git a/Foundation/include/Poco/NumericString.h b/Foundation/include/Poco/NumericString.h index 3890d0f9f..7fbb5b3f4 100644 --- a/Foundation/include/Poco/NumericString.h +++ b/Foundation/include/Poco/NumericString.h @@ -33,7 +33,6 @@ #if !defined(POCO_NO_LOCALE) #include #endif - #if defined(POCO_NOINTMAX) typedef Poco::UInt64 uintmax_t; typedef Poco::Int64 intmax_t; @@ -46,7 +45,6 @@ typedef Poco::Int64 intmax_t; #pragma warning(disable : 4146) #endif // POCO_COMPILER_MSVC - // binary numbers are supported, thus 64 (bits) + 1 (string terminating zero) #define POCO_MAX_INT_STRING_LEN 65 // value from strtod.cc (double_conversion::kMaxSignificantDecimalDigits) @@ -112,6 +110,46 @@ inline bool isIntOverflow(From val) } +template +bool safeMultiply(R& result, F f, S s) +{ + if ((f == 0) || (s==0)) + { + result = 0; + return true; + } + + if (f > 0) + { + if (s > 0) + { + if (f > (std::numeric_limits::max() / s)) + return false; + } + else + { + if (s < (std::numeric_limits::min() / f)) + return false; + } + } + else + { + if (s > 0) + { + if (f < (std::numeric_limits::min() / s)) + return false; + } + else + { + if (s < (std::numeric_limits::max() / f)) + return false; + } + } + result = f * s; + return true; +} + + template inline T& isSafeIntCast(F from) /// Returns true if it is safe to cast @@ -124,7 +162,7 @@ inline T& isSafeIntCast(F from) template inline T& safeIntCast(F from, T& to) - /// Returns csted value if it is safe + /// Returns cast value if it is safe /// to cast integer from F to T, /// otherwise throws BadCastException. { @@ -188,101 +226,54 @@ bool strToInt(const char* pStr, I& outResult, short base, char thSep = ',') } else if (*pStr == '+') ++pStr; - // all numbers are parsed as positive; the sign - // for negative numbers is adjusted after parsing + // numbers are parsed as unsigned, for negative numbers the sign is applied after parsing + // overflow is checked in every parse step uintmax_t limitCheck = std::numeric_limits::max(); - if (negative) - { - poco_assert_dbg(std::numeric_limits::is_signed); - // to cover the entire range, (-min > max) has to be - // taken into account; - // to avoid overflow for the largest int size, - // we resort to FPEnvironment::copySign() (ie. floating-point) - if (sizeof(I) == sizeof(intmax_t)) - limitCheck = static_cast(FPEnvironment::copySign(static_cast(std::numeric_limits::min()), 1)); - else - { - intmax_t i = std::numeric_limits::min(); - limitCheck = -i; - } - } - + if (negative) ++limitCheck; uintmax_t result = 0; + unsigned char add = 0; for (; *pStr != '\0'; ++pStr) { - if (result > (limitCheck / base)) return false; + if (*pStr == thSep) + { + if (base == 10) continue; + throw Poco::SyntaxException("strToInt: thousand separators only allowed for base 10"); + } + if (result > (limitCheck / base)) return false; + if (!safeMultiply(result, result, base)) return false; switch (*pStr) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': - { - char add = (*pStr - '0'); - if ((limitCheck - result) < add) return false; - result = result * base + add; - } + add = (*pStr - '0'); break; case '8': case '9': - if ((base == 10) || (base == 0x10)) - { - char add = (*pStr - '0'); - if ((limitCheck - result) < add) return false; - result = result * base + add; - } + if ((base == 10) || (base == 0x10)) add = (*pStr - '0'); else return false; - break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': - { - if (base != 0x10) return false; - char add = (*pStr - 'a'); - if ((limitCheck - result) < add) return false; - result = result * base + (10 + add); - } + if (base != 0x10) return false; + add = (*pStr - 'a') + 10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - { - if (base != 0x10) return false; - char add = (*pStr - 'A'); - if ((limitCheck - result) < add) return false; - result = result * base + (10 + add); - } + if (base != 0x10) return false; + add = (*pStr - 'A') + 10; break; - case '.': - if ((base == 10) && (thSep == '.')) break; - else return false; - - case ',': - if ((base == 10) && (thSep == ',')) break; - else return false; - - case ' ': - if ((base == 10) && (thSep == ' ')) break; - default: return false; } + if ((limitCheck - static_cast(result)) < add) return false; + result += add; } if (negative && (base == 10)) - { - poco_assert_dbg(std::numeric_limits::is_signed); - intmax_t i; - if (sizeof(I) == sizeof(intmax_t)) - i = static_cast(FPEnvironment::copySign(static_cast(result), -1)); - else - i = static_cast(-result); - if (isIntOverflow(i)) return false; - outResult = static_cast(i); - } + outResult = static_cast(-result); else - { - if (isIntOverflow(result)) return false; outResult = static_cast(result); - } return true; } diff --git a/Foundation/include/Poco/Observer.h b/Foundation/include/Poco/Observer.h old mode 100644 new mode 100755 index 9be67b2ee..e7bc67413 --- a/Foundation/include/Poco/Observer.h +++ b/Foundation/include/Poco/Observer.h @@ -30,7 +30,7 @@ template class Observer: public AbstractObserver /// This template class implements an adapter that sits between /// a NotificationCenter and an object receiving notifications - /// from it. It is quite similar in concept to the + /// from it. It is quite similar in concept to the /// RunnableAdapter, but provides some NotificationCenter /// specific additional methods. /// See the NotificationCenter class for information on how @@ -44,23 +44,23 @@ class Observer: public AbstractObserver public: typedef void (C::*Callback)(N*); - Observer(C& object, Callback method): - _pObject(&object), + Observer(C& object, Callback method): + _pObject(&object), _method(method) { } - + Observer(const Observer& observer): AbstractObserver(observer), - _pObject(observer._pObject), + _pObject(observer._pObject), _method(observer._method) { } - + ~Observer() { } - + Observer& operator = (const Observer& observer) { if (&observer != this) @@ -85,7 +85,7 @@ public: } } } - + bool equals(const AbstractObserver& abstractObserver) const { const Observer* pObs = dynamic_cast(&abstractObserver); @@ -96,19 +96,19 @@ public: { return dynamic_cast(pNf) && (!pName || pNf->name() == pName); } - + AbstractObserver* clone() const { return new Observer(*this); } - + void disable() { Poco::Mutex::ScopedLock lock(_mutex); - + _pObject = 0; } - + private: Observer(); diff --git a/Foundation/include/Poco/Optional.h b/Foundation/include/Poco/Optional.h index 15415a796..31c38fd5a 100644 --- a/Foundation/include/Poco/Optional.h +++ b/Foundation/include/Poco/Optional.h @@ -141,7 +141,7 @@ public: return *this; } - void swap(Optional& other) + void swap(Optional& other) noexcept { std::swap(_value, other._value); std::swap(_isSpecified, other._isSpecified); @@ -185,7 +185,7 @@ private: template -inline void swap(Optional& n1, Optional& n2) +inline void swap(Optional& n1, Optional& n2) noexcept { n1.swap(n2); } diff --git a/Foundation/include/Poco/PBKDF2Engine.h b/Foundation/include/Poco/PBKDF2Engine.h index ca660e5b0..4c6a34eb2 100644 --- a/Foundation/include/Poco/PBKDF2Engine.h +++ b/Foundation/include/Poco/PBKDF2Engine.h @@ -31,25 +31,25 @@ template class PBKDF2Engine: public DigestEngine /// This class implements the Password-Based Key Derivation Function 2, /// as specified in RFC 2898. The underlying DigestEngine (HMACEngine, etc.), - /// which must accept the passphrase as constructor argument (std::string), - /// must be given as template argument. + /// which must accept the passphrase as constructor argument (std::string), + /// must be given as template argument. /// - /// PBKDF2 (Password-Based Key Derivation Function 2) is a key derivation function - /// that is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, - /// specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's - /// RFC 2898. It replaces an earlier standard, PBKDF1, which could only produce + /// PBKDF2 (Password-Based Key Derivation Function 2) is a key derivation function + /// that is part of RSA Laboratories' Public-Key Cryptography Standards (PKCS) series, + /// specifically PKCS #5 v2.0, also published as Internet Engineering Task Force's + /// RFC 2898. It replaces an earlier standard, PBKDF1, which could only produce /// derived keys up to 160 bits long. /// - /// PBKDF2 applies a pseudorandom function, such as a cryptographic hash, cipher, or - /// HMAC to the input password or passphrase along with a salt value and repeats the - /// process many times to produce a derived key, which can then be used as a - /// cryptographic key in subsequent operations. The added computational work makes - /// password cracking much more difficult, and is known as key stretching. - /// When the standard was written in 2000, the recommended minimum number of - /// iterations was 1000, but the parameter is intended to be increased over time as - /// CPU speeds increase. Having a salt added to the password reduces the ability to - /// use precomputed hashes (rainbow tables) for attacks, and means that multiple - /// passwords have to be tested individually, not all at once. The standard + /// PBKDF2 applies a pseudorandom function, such as a cryptographic hash, cipher, or + /// HMAC to the input password or passphrase along with a salt value and repeats the + /// process many times to produce a derived key, which can then be used as a + /// cryptographic key in subsequent operations. The added computational work makes + /// password cracking much more difficult, and is known as key stretching. + /// When the standard was written in 2000, the recommended minimum number of + /// iterations was 1000, but the parameter is intended to be increased over time as + /// CPU speeds increase. Having a salt added to the password reduces the ability to + /// use precomputed hashes (rainbow tables) for attacks, and means that multiple + /// passwords have to be tested individually, not all at once. The standard /// recommends a salt length of at least 64 bits. [Wikipedia] /// /// The PBKDF2 algorithm is implemented as a DigestEngine. The passphrase is specified @@ -65,30 +65,30 @@ public: { PRF_DIGEST_SIZE = PRF::DIGEST_SIZE }; - + PBKDF2Engine(const std::string& salt, unsigned c = 4096, Poco::UInt32 dkLen = PRF_DIGEST_SIZE): _s(salt), _c(c), _dkLen(dkLen) - { + { _result.reserve(_dkLen + PRF_DIGEST_SIZE); } - + ~PBKDF2Engine() { } - + std::size_t digestLength() const { return _dkLen; } - + void reset() { _p.clear(); _result.clear(); } - + const DigestEngine::Digest& digest() { Poco::UInt32 i = 1; @@ -105,7 +105,7 @@ protected: { _p.append(reinterpret_cast(data), length); } - + void f(Poco::UInt32 i) { PRF prf(_p); diff --git a/Foundation/include/Poco/Path.h b/Foundation/include/Poco/Path.h index 033e2d31d..0f0a889d0 100644 --- a/Foundation/include/Poco/Path.h +++ b/Foundation/include/Poco/Path.h @@ -102,7 +102,7 @@ public: Path& operator = (const char* path); /// Assigns a string containing a path in native format. - void swap(Path& path); + void swap(Path& path) noexcept; /// Swaps the path with another one. Path& assign(const std::string& path); @@ -495,7 +495,7 @@ inline char Path::pathSeparator() } -inline void swap(Path& p1, Path& p2) +inline void swap(Path& p1, Path& p2) noexcept { p1.swap(p2); } diff --git a/Foundation/include/Poco/Path_WIN32U.h b/Foundation/include/Poco/Path_WIN32U.h index 94fca2b0a..fb9d451cc 100644 --- a/Foundation/include/Poco/Path_WIN32U.h +++ b/Foundation/include/Poco/Path_WIN32U.h @@ -40,7 +40,7 @@ public: static std::string systemImpl(); static std::string expandImpl(const std::string& path); static void listRootsImpl(std::vector& roots); - + enum { MAX_PATH_LEN = 32767 diff --git a/Foundation/include/Poco/Path_WINCE.h b/Foundation/include/Poco/Path_WINCE.h index a32e3316a..37e3fff58 100644 --- a/Foundation/include/Poco/Path_WINCE.h +++ b/Foundation/include/Poco/Path_WINCE.h @@ -40,7 +40,7 @@ public: static std::string systemImpl(); static std::string expandImpl(const std::string& path); static void listRootsImpl(std::vector& roots); - + enum { MAX_PATH_LEN = 32767 diff --git a/Foundation/include/Poco/PatternFormatter.h b/Foundation/include/Poco/PatternFormatter.h index 7a11fa1f6..9f259bd61 100644 --- a/Foundation/include/Poco/PatternFormatter.h +++ b/Foundation/include/Poco/PatternFormatter.h @@ -43,6 +43,7 @@ class Foundation_API PatternFormatter: public Formatter /// * %P - message process identifier /// * %T - message thread name /// * %I - message thread identifier (numeric) + /// * %J - message thread OS identifier (numeric) /// * %N - node or host name /// * %U - message source file path (empty string if not set) /// * %O - message source file filename (empty string if not set) @@ -94,13 +95,13 @@ public: void format(const Message& msg, std::string& text); /// Formats the message according to the specified - /// format pattern and places the result in text. - + /// format pattern and places the result in text. + void setProperty(const std::string& name, const std::string& value); /// Sets the property with the given name to the given value. /// /// The following properties are supported: - /// + /// /// * pattern: The format pattern. See the PatternFormatter class /// for details. /// * times: Specifies whether times are adjusted for local time @@ -123,11 +124,11 @@ public: protected: const std::string& getPriorityName(int); /// Returns a string for the given priority value. - + private: struct PatternAction { - PatternAction(): key(0), length(0) + PatternAction(): key(0), length(0) { } diff --git a/Foundation/include/Poco/Pipe.h b/Foundation/include/Poco/Pipe.h index 89704b12b..e27a0d25d 100644 --- a/Foundation/include/Poco/Pipe.h +++ b/Foundation/include/Poco/Pipe.h @@ -35,7 +35,7 @@ class Foundation_API Pipe /// that data only flows in one direction. /// Pipes have a read-end and a write-end. One process writes to /// the pipe and another process reads the data written by - /// its peer. + /// its peer. /// Read and write operations are always synchronous. A read will /// block until data is available and a write will block until /// the reader reads the data. @@ -49,20 +49,20 @@ class Foundation_API Pipe { public: typedef PipeImpl::Handle Handle; /// The read/write handle or file descriptor. - + enum CloseMode /// used by close() { CLOSE_READ = 0x01, /// Close reading end of pipe. CLOSE_WRITE = 0x02, /// Close writing end of pipe. CLOSE_BOTH = 0x03 /// Close both ends of pipe. }; - + Pipe(); /// Creates the Pipe. /// /// Throws a CreateFileException if the pipe cannot be /// created. - + Pipe(const Pipe& pipe); /// Creates the Pipe using the PipeImpl from another one. @@ -94,7 +94,7 @@ public: Handle readHandle() const; /// Returns the read handle or file descriptor /// for the Pipe. For internal use only. - + Handle writeHandle() const; /// Returns the write handle or file descriptor /// for the Pipe. For internal use only. @@ -103,7 +103,7 @@ public: /// Depending on the argument, closes either the /// reading end, the writing end, or both ends /// of the Pipe. - + private: PipeImpl* _pImpl; }; diff --git a/Foundation/include/Poco/PipeImpl_POSIX.h b/Foundation/include/Poco/PipeImpl_POSIX.h index 448e616ef..5b62fefc6 100644 --- a/Foundation/include/Poco/PipeImpl_POSIX.h +++ b/Foundation/include/Poco/PipeImpl_POSIX.h @@ -40,7 +40,7 @@ public: Handle writeHandle() const; void closeRead(); void closeWrite(); - + private: int _readfd; int _writefd; diff --git a/Foundation/include/Poco/PipeImpl_WIN32.h b/Foundation/include/Poco/PipeImpl_WIN32.h index 936817987..3e5bcd8e4 100644 --- a/Foundation/include/Poco/PipeImpl_WIN32.h +++ b/Foundation/include/Poco/PipeImpl_WIN32.h @@ -41,7 +41,7 @@ public: Handle writeHandle() const; void closeRead(); void closeWrite(); - + private: HANDLE _readHandle; HANDLE _writeHandle; diff --git a/Foundation/include/Poco/PipeStream.h b/Foundation/include/Poco/PipeStream.h index 96b602aea..5f107986c 100644 --- a/Foundation/include/Poco/PipeStream.h +++ b/Foundation/include/Poco/PipeStream.h @@ -33,22 +33,22 @@ class Foundation_API PipeStreamBuf: public BufferedStreamBuf { public: typedef BufferedStreamBuf::openmode openmode; - + PipeStreamBuf(const Pipe& pipe, openmode mode); /// Creates a PipeStreamBuf with the given Pipe. ~PipeStreamBuf(); /// Destroys the PipeStreamBuf. - + void close(); /// Closes the pipe. - + protected: int readFromDevice(char* buffer, std::streamsize length); int writeToDevice(const char* buffer, std::streamsize length); private: - enum + enum { STREAM_BUFFER_SIZE = 1024 }; @@ -67,15 +67,15 @@ class Foundation_API PipeIOS: public virtual std::ios public: PipeIOS(const Pipe& pipe, openmode mode); /// Creates the PipeIOS with the given Pipe. - + ~PipeIOS(); /// Destroys the PipeIOS. /// /// Flushes the buffer, but does not close the pipe. - + PipeStreamBuf* rdbuf(); /// Returns a pointer to the internal PipeStreamBuf. - + void close(); /// Flushes the stream and closes the pipe. diff --git a/Foundation/include/Poco/Platform.h b/Foundation/include/Poco/Platform.h index f5a9a7fe9..f5cc457a7 100644 --- a/Foundation/include/Poco/Platform.h +++ b/Foundation/include/Poco/Platform.h @@ -234,6 +234,9 @@ #define POCO_ARCH POCO_ARCH_RISCV32 #define POCO_ARCH_LITTLE_ENDIAN 1 #endif +#elif defined(__loongarch64) + #define POCO_ARCH POCO_ARCH_LOONGARCH64 + #define POCO_ARCH_LITTLE_ENDIAN 1 #endif @@ -243,6 +246,9 @@ #define POCO_COMPILER_MSVC #elif defined (__GNUC__) #define POCO_COMPILER_GCC + #if defined (__MINGW32__) || defined (__MINGW64__) + #define POCO_COMPILER_MINGW + #endif #elif defined (__MINGW32__) || defined (__MINGW64__) #define POCO_COMPILER_MINGW #elif defined (__INTEL_COMPILER) || defined(__ICC) || defined(__ECC) || defined(__ICL) diff --git a/Foundation/include/Poco/Platform_VX.h b/Foundation/include/Poco/Platform_VX.h index f21e822fd..fbe566f7d 100644 --- a/Foundation/include/Poco/Platform_VX.h +++ b/Foundation/include/Poco/Platform_VX.h @@ -19,9 +19,9 @@ #define Foundation_Platform_VX_INCLUDED -#define POCO_NO_SYS_SELECT_H +#define POCO_NO_SYS_SELECT_H #define POCO_NO_FPENVIRONMENT -#define POCO_NO_WSTRING +#define POCO_NO_WSTRING #define POCO_NO_SHAREDMEMORY #define POCO_NO_SYSLOGCHANNEL diff --git a/Foundation/include/Poco/Platform_WIN32.h b/Foundation/include/Poco/Platform_WIN32.h index 65cdf46f5..9e88b8678 100644 --- a/Foundation/include/Poco/Platform_WIN32.h +++ b/Foundation/include/Poco/Platform_WIN32.h @@ -23,19 +23,14 @@ -// Verify that we're built with the multithreaded +// Verify that we're built with the multithreaded // versions of the runtime libraries #if defined(_MSC_VER) && !defined(_MT) #error Must compile with /MD, /MDd, /MT or /MTd #endif -// Check debug/release settings consistency -#if defined(NDEBUG) && defined(_DEBUG) - #error Inconsistent build settings (check for /MD[d]) -#endif - - +// https://en.wikipedia.org/wiki/Microsoft_Visual_C++ #if (_MSC_VER >= 1300) && (_MSC_VER < 1400) // Visual Studio 2003, MSVC++ 7.1 #define POCO_MSVS_VERSION 2003 #define POCO_MSVC_VERSION 71 @@ -57,9 +52,15 @@ #elif (_MSC_VER >= 1900) && (_MSC_VER < 1910) // Visual Studio 2015, MSVC++ 14.0 #define POCO_MSVS_VERSION 2015 #define POCO_MSVC_VERSION 140 -#elif (_MSC_VER >= 1910) && (_MSC_VER < 2000) // Visual Studio 2017, MSVC++ 14.1 +#elif (_MSC_VER >= 1910) && (_MSC_VER < 1920) // Visual Studio 2017, MSVC++ 14.1 #define POCO_MSVS_VERSION 2017 #define POCO_MSVC_VERSION 141 +#elif (_MSC_VER >= 1920) && (_MSC_VER < 1930) // Visual Studio 2019, MSVC++ 14.2 + #define POCO_MSVS_VERSION 2019 + #define POCO_MSVC_VERSION 142 +#elif (_MSC_VER >= 1930) // Visual Studio 2022, MSVC++ 14.3 + #define POCO_MSVS_VERSION 2022 + #define POCO_MSVC_VERSION 143 #endif diff --git a/Foundation/include/Poco/PriorityDelegate.h b/Foundation/include/Poco/PriorityDelegate.h index 7c776b940..4cd664aab 100644 --- a/Foundation/include/Poco/PriorityDelegate.h +++ b/Foundation/include/Poco/PriorityDelegate.h @@ -28,7 +28,7 @@ namespace Poco { -template +template class PriorityDelegate: public AbstractPriorityDelegate { public: @@ -40,14 +40,14 @@ public: _receiverMethod(method) { } - + PriorityDelegate(const PriorityDelegate& delegate): AbstractPriorityDelegate(delegate), _receiverObject(delegate._receiverObject), _receiverMethod(delegate._receiverMethod) { } - + PriorityDelegate& operator = (const PriorityDelegate& delegate) { if (&delegate != this) @@ -70,7 +70,7 @@ public: if (_receiverObject) { (_receiverObject->*_receiverMethod)(sender, arguments); - return true; + return true; } else return false; } @@ -91,7 +91,7 @@ public: Mutex::ScopedLock lock(_mutex); _receiverObject = 0; } - + protected: TObj* _receiverObject; NotifyMethod _receiverMethod; @@ -102,7 +102,7 @@ private: }; -template +template class PriorityDelegate: public AbstractPriorityDelegate { public: @@ -114,14 +114,14 @@ public: _receiverMethod(method) { } - + PriorityDelegate(const PriorityDelegate& delegate): AbstractPriorityDelegate(delegate), _receiverObject(delegate._receiverObject), _receiverMethod(delegate._receiverMethod) { } - + PriorityDelegate& operator = (const PriorityDelegate& delegate) { if (&delegate != this) diff --git a/Foundation/include/Poco/PriorityEvent.h b/Foundation/include/Poco/PriorityEvent.h index 48b9f604f..1ccfb89c5 100644 --- a/Foundation/include/Poco/PriorityEvent.h +++ b/Foundation/include/Poco/PriorityEvent.h @@ -26,14 +26,14 @@ namespace Poco { -template -class PriorityEvent: public AbstractEvent < +template +class PriorityEvent: public AbstractEvent < TArgs, PriorityStrategy >, AbstractPriorityDelegate, TMutex > - /// A PriorityEvent uses internally a PriorityStrategy which + /// A PriorityEvent uses internally a PriorityStrategy which /// invokes delegates in order of priority (lower priorities first). /// PriorityEvent's can only be used together with PriorityDelegate's. /// PriorityDelegate's are sorted according to the priority value, when diff --git a/Foundation/include/Poco/PriorityExpire.h b/Foundation/include/Poco/PriorityExpire.h index 9491445f0..d9fc5a4fa 100644 --- a/Foundation/include/Poco/PriorityExpire.h +++ b/Foundation/include/Poco/PriorityExpire.h @@ -28,17 +28,17 @@ namespace Poco { template class PriorityExpire: public AbstractPriorityDelegate - /// Decorator for AbstractPriorityDelegate adding automatic + /// Decorator for AbstractPriorityDelegate adding automatic /// expiring of registrations to AbstractPriorityDelegate. { public: PriorityExpire(const AbstractPriorityDelegate& p, Timestamp::TimeDiff expireMilliSec): AbstractPriorityDelegate(p), - _pDelegate(static_cast*>(p.clone())), + _pDelegate(static_cast*>(p.clone())), _expire(expireMilliSec*1000) { } - + PriorityExpire(const PriorityExpire& expire): AbstractPriorityDelegate(expire), _pDelegate(static_cast*>(expire._pDelegate->clone())), @@ -51,7 +51,7 @@ public: { delete _pDelegate; } - + PriorityExpire& operator = (const PriorityExpire& expire) { if (&expire != this) @@ -62,7 +62,7 @@ public: this->_expire = expire._expire; this->_creationTime = expire._creationTime; } - return *this; + return *this; } bool notify(const void* sender, TArgs& arguments) diff --git a/Foundation/include/Poco/PriorityNotificationQueue.h b/Foundation/include/Poco/PriorityNotificationQueue.h index e5269ab85..d11317465 100644 --- a/Foundation/include/Poco/PriorityNotificationQueue.h +++ b/Foundation/include/Poco/PriorityNotificationQueue.h @@ -35,19 +35,19 @@ class NotificationCenter; class Foundation_API PriorityNotificationQueue /// A PriorityNotificationQueue object provides a way to implement asynchronous /// notifications. This is especially useful for sending notifications - /// from one thread to another, for example from a background thread to - /// the main (user interface) thread. + /// from one thread to another, for example from a background thread to + /// the main (user interface) thread. /// /// The PriorityNotificationQueue is quite similar to the NotificationQueue class. /// The only difference to NotificationQueue is that each Notification is tagged /// with a priority value. When inserting a Notification into the queue, the - /// Notification is inserted according to the given priority value, with + /// Notification is inserted according to the given priority value, with /// lower priority values being inserted before higher priority /// values. Therefore, the lower the numerical priority value, the higher - /// the actual notification priority. + /// the actual notification priority. /// /// Notifications are dequeued in order of their priority. - /// + /// /// The PriorityNotificationQueue can also be used to distribute work from /// a controlling thread to one or more worker threads. Each worker thread /// repeatedly calls waitDequeueNotification() and processes the @@ -74,7 +74,7 @@ public: /// a call like /// notificationQueue.enqueueNotification(new MyNotification, 1); /// does not result in a memory leak. - + Notification* dequeueNotification(); /// Dequeues the next pending notification. /// Returns 0 (null) if no notification is available. @@ -88,7 +88,7 @@ public: Notification* waitDequeueNotification(); /// Dequeues the next pending notification. /// If no notification is available, waits for a notification - /// to be enqueued. + /// to be enqueued. /// The caller gains ownership of the notification and /// is expected to release it when done with it. /// This method returns 0 (null) if wakeUpAll() @@ -116,27 +116,27 @@ public: void wakeUpAll(); /// Wakes up all threads that wait for a notification. - + bool empty() const; /// Returns true iff the queue is empty. - + int size() const; /// Returns the number of notifications in the queue. void clear(); /// Removes all notifications from the queue. - - bool hasIdleThreads() const; - /// Returns true if the queue has at least one thread waiting + + bool hasIdleThreads() const; + /// Returns true if the queue has at least one thread waiting /// for a notification. - + static PriorityNotificationQueue& defaultQueue(); /// Returns a reference to the default /// PriorityNotificationQueue. protected: Notification::Ptr dequeueOne(); - + private: typedef std::multimap NfQueue; struct WaitInfo diff --git a/Foundation/include/Poco/PriorityStrategy.h b/Foundation/include/Poco/PriorityStrategy.h index 418e5c04d..db031e4e3 100644 --- a/Foundation/include/Poco/PriorityStrategy.h +++ b/Foundation/include/Poco/PriorityStrategy.h @@ -26,7 +26,7 @@ namespace Poco { -template +template class PriorityStrategy: public NotificationStrategy /// NotificationStrategy for PriorityEvent. /// diff --git a/Foundation/include/Poco/PurgeStrategy.h b/Foundation/include/Poco/PurgeStrategy.h index c7ef96b48..216f47b0b 100644 --- a/Foundation/include/Poco/PurgeStrategy.h +++ b/Foundation/include/Poco/PurgeStrategy.h @@ -39,7 +39,7 @@ public: /// Purges archived log files. The path to the /// current "hot" log file is given. /// To find archived log files, look for files - /// with a name consisting of the given path + /// with a name consisting of the given path /// plus any suffix (e.g., .1, .20050929081500, .1.gz). /// A list of archived files can be obtained by calling /// the list() method. @@ -67,9 +67,9 @@ class Foundation_API PurgeByAgeStrategy: public PurgeStrategy public: PurgeByAgeStrategy(const Timespan& age); ~PurgeByAgeStrategy(); - + void purge(const std::string& path); - + private: Timespan _age; }; @@ -83,9 +83,9 @@ class Foundation_API PurgeByCountStrategy: public PurgeStrategy public: PurgeByCountStrategy(int count); ~PurgeByCountStrategy(); - + void purge(const std::string& path); - + private: int _count; }; diff --git a/Foundation/include/Poco/RWLock.h b/Foundation/include/Poco/RWLock.h index b8cbe9937..60ce8bf9c 100644 --- a/Foundation/include/Poco/RWLock.h +++ b/Foundation/include/Poco/RWLock.h @@ -56,10 +56,10 @@ public: RWLock(); /// Creates the Reader/Writer lock. - + ~RWLock(); /// Destroys the Reader/Writer lock. - + void readLock(); /// Acquires a read lock. If another thread currently holds a write lock, /// waits until the write lock is released. @@ -69,13 +69,13 @@ public: /// false if another thread currently holds a write lock. void writeLock(); - /// Acquires a write lock. If one or more other threads currently hold + /// Acquires a write lock. If one or more other threads currently hold /// locks, waits until all locks are released. The results are undefined /// if the same thread already holds a read or write lock bool tryWriteLock(); /// Tries to acquire a write lock. Immediately returns true if successful, - /// or false if one or more other threads currently hold + /// or false if one or more other threads currently hold /// locks. The result is undefined if the same thread already /// holds a read or write lock. diff --git a/Foundation/include/Poco/RWLock_Android.h b/Foundation/include/Poco/RWLock_Android.h index c6dfc4e5b..b95aa8422 100644 --- a/Foundation/include/Poco/RWLock_Android.h +++ b/Foundation/include/Poco/RWLock_Android.h @@ -37,7 +37,7 @@ protected: void writeLockImpl(); bool tryWriteLockImpl(); void unlockImpl(); - + private: pthread_mutex_t _mutex; }; @@ -48,7 +48,7 @@ private: // inline void RWLockImpl::readLockImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot lock reader/writer lock"); } @@ -67,7 +67,7 @@ inline bool RWLockImpl::tryReadLockImpl() inline void RWLockImpl::writeLockImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot lock reader/writer lock"); } diff --git a/Foundation/include/Poco/RWLock_POSIX.h b/Foundation/include/Poco/RWLock_POSIX.h index be4d11beb..0b50fd30f 100644 --- a/Foundation/include/Poco/RWLock_POSIX.h +++ b/Foundation/include/Poco/RWLock_POSIX.h @@ -37,7 +37,7 @@ protected: void writeLockImpl(); bool tryWriteLockImpl(); void unlockImpl(); - + private: pthread_rwlock_t _rwl; }; @@ -48,7 +48,7 @@ private: // inline void RWLockImpl::readLockImpl() { - if (pthread_rwlock_rdlock(&_rwl)) + if (pthread_rwlock_rdlock(&_rwl)) throw SystemException("cannot lock reader/writer lock"); } @@ -68,7 +68,7 @@ inline bool RWLockImpl::tryReadLockImpl() inline void RWLockImpl::writeLockImpl() { - if (pthread_rwlock_wrlock(&_rwl)) + if (pthread_rwlock_wrlock(&_rwl)) throw SystemException("cannot lock reader/writer lock"); } diff --git a/Foundation/include/Poco/RWLock_VX.h b/Foundation/include/Poco/RWLock_VX.h index bdc4af2fe..e5a18e052 100644 --- a/Foundation/include/Poco/RWLock_VX.h +++ b/Foundation/include/Poco/RWLock_VX.h @@ -37,7 +37,7 @@ protected: void writeLockImpl(); bool tryWriteLockImpl(); void unlockImpl(); - + private: pthread_mutex_t _mutex; }; @@ -48,7 +48,7 @@ private: // inline void RWLockImpl::readLockImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot lock mutex"); } diff --git a/Foundation/include/Poco/RWLock_WIN32.h b/Foundation/include/Poco/RWLock_WIN32.h index e50856e1b..0b7cb2b95 100644 --- a/Foundation/include/Poco/RWLock_WIN32.h +++ b/Foundation/include/Poco/RWLock_WIN32.h @@ -36,7 +36,7 @@ protected: void writeLockImpl(); bool tryWriteLockImpl(); void unlockImpl(); - + private: void addWriter(); void removeWriter(); diff --git a/Foundation/include/Poco/RWLock_WINCE.h b/Foundation/include/Poco/RWLock_WINCE.h index d6c8314b2..13d080654 100644 --- a/Foundation/include/Poco/RWLock_WINCE.h +++ b/Foundation/include/Poco/RWLock_WINCE.h @@ -42,7 +42,7 @@ protected: void writeLockImpl(); bool tryWriteLockImpl(DWORD timeout = 1); void unlockImpl(); - + private: DWORD _readerCount; DWORD _readerWaiting; diff --git a/Foundation/include/Poco/RefCountedObject.h b/Foundation/include/Poco/RefCountedObject.h index 55ea76a16..66d4ac6f2 100644 --- a/Foundation/include/Poco/RefCountedObject.h +++ b/Foundation/include/Poco/RefCountedObject.h @@ -39,12 +39,12 @@ public: void duplicate() const; /// Increments the object's reference count. - + void release() const noexcept; /// Decrements the object's reference count /// and deletes the object if the count /// reaches zero. - + int referenceCount() const; /// Returns the reference count. diff --git a/Foundation/include/Poco/RegularExpression.h b/Foundation/include/Poco/RegularExpression.h index 5291aab6c..6597a249f 100644 --- a/Foundation/include/Poco/RegularExpression.h +++ b/Foundation/include/Poco/RegularExpression.h @@ -23,6 +23,7 @@ #include "Poco/Foundation.h" #include +#include namespace Poco { @@ -30,16 +31,16 @@ namespace Poco { class Foundation_API RegularExpression /// A class for working with regular expressions. - /// Implemented using PCRE, the Perl Compatible + /// Implemented using PCRE2, the Perl Compatible /// Regular Expressions library by Philip Hazel /// (see http://www.pcre.org). { public: - enum Options // These must match the corresponding options in pcre.h! + enum Options /// Some of the following options can only be passed to the constructor; /// some can be passed only to matching functions, and some can be used /// everywhere. - /// + /// /// * Options marked [ctor] can be passed to the constructor. /// * Options marked [match] can be passed to match, extract, split and subst. /// * Options marked [subst] can be passed to subst. @@ -61,10 +62,10 @@ public: RE_NO_AUTO_CAPTURE = 0x00001000, /// disable numbered capturing parentheses [ctor, match] RE_NO_UTF8_CHECK = 0x00002000, /// do not check validity of UTF-8 code sequences [match] RE_FIRSTLINE = 0x00040000, /// an unanchored pattern is required to match - /// before or at the first newline in the subject string, + /// before or at the first newline in the subject string, /// though the matched text may continue over the newline [ctor] - RE_DUPNAMES = 0x00080000, /// names used to identify capturing subpatterns need not be unique [ctor] - RE_NEWLINE_CR = 0x00100000, /// assume newline is CR ('\r'), the default [ctor] + RE_DUPNAMES = 0x00080000, /// names used to identify capturing subpatterns need not be unique [ctor] + RE_NEWLINE_CR = 0x00100000, /// assume newline is CR ('\r'), the default [ctor] RE_NEWLINE_LF = 0x00200000, /// assume newline is LF ('\n') [ctor] RE_NEWLINE_CRLF = 0x00300000, /// assume newline is CRLF ("\r\n") [ctor] RE_NEWLINE_ANY = 0x00400000, /// assume newline is any valid Unicode newline character [ctor] @@ -72,21 +73,23 @@ public: RE_GLOBAL = 0x10000000, /// replace all occurences (/g) [subst] RE_NO_VARS = 0x20000000 /// treat dollar in replacement string as ordinary character [subst] }; - + struct Match { std::string::size_type offset; /// zero based offset (std::string::npos if subexpr does not match) std::string::size_type length; /// length of substring + std::string name; /// name of group }; using MatchVec = std::vector; - + using GroupMap = std::map; + RegularExpression(const std::string& pattern, int options = 0, bool study = true); /// Creates a regular expression and parses the given pattern. - /// If study is true, the pattern is analyzed and optimized. This - /// is mainly useful if the pattern is used more than once. + /// Note: the study argument is only provided for backwards compatibility + /// and is ignored since POCO release 1.12, which uses PCRE2. /// For a description of the options, please see the PCRE documentation. /// Throws a RegularExpressionException if the patter cannot be compiled. - + ~RegularExpression(); /// Destroys the regular expression. @@ -99,7 +102,7 @@ public: /// Returns the number of matches. int match(const std::string& subject, std::string::size_type offset, Match& mtch, int options = 0) const; - /// Matches the given subject string, starting at offset, against the pattern. + /// Matches the given subject string, starting at offset, against the pattern. /// Returns the position of the captured substring in mtch. /// If no part of the subject matches the pattern, mtch.offset is std::string::npos and /// mtch.length is 0. @@ -107,7 +110,7 @@ public: /// Returns the number of matches. int match(const std::string& subject, std::string::size_type offset, MatchVec& matches, int options = 0) const; - /// Matches the given subject string against the pattern. + /// Matches the given subject string against the pattern. /// The first entry in matches contains the position of the captured substring. /// The following entries identify matching subpatterns. See the PCRE documentation /// for a more detailed explanation. @@ -140,19 +143,19 @@ public: /// the pattern is treated as if it starts with a ^. int extract(const std::string& subject, std::string& str, int options = 0) const; - /// Matches the given subject string against the pattern. + /// Matches the given subject string against the pattern. /// Returns the captured string. /// Throws a RegularExpressionException in case of an error. /// Returns the number of matches. int extract(const std::string& subject, std::string::size_type offset, std::string& str, int options = 0) const; - /// Matches the given subject string, starting at offset, against the pattern. + /// Matches the given subject string, starting at offset, against the pattern. /// Returns the captured string. /// Throws a RegularExpressionException in case of an error. /// Returns the number of matches. int split(const std::string& subject, std::vector& strings, int options = 0) const; - /// Matches the given subject string against the pattern. + /// Matches the given subject string against the pattern. /// The first entry in captured is the captured substring. /// The following entries contain substrings matching subpatterns. See the PCRE documentation /// for a more detailed explanation. @@ -161,14 +164,14 @@ public: /// Returns the number of matches. int split(const std::string& subject, std::string::size_type offset, std::vector& strings, int options = 0) const; - /// Matches the given subject string against the pattern. + /// Matches the given subject string against the pattern. /// The first entry in captured is the captured substring. /// The following entries contain substrings matching subpatterns. See the PCRE documentation /// for a more detailed explanation. /// If no part of the subject matches the pattern, captured is empty. /// Throws a RegularExpressionException in case of an error. /// Returns the number of matches. - + int subst(std::string& subject, const std::string& replacement, int options = 0) const; /// Substitute in subject all matches of the pattern with replacement. /// If RE_GLOBAL is specified as option, all matches are replaced. Otherwise, @@ -183,7 +186,7 @@ public: /// If RE_GLOBAL is specified as option, all matches are replaced. Otherwise, /// only the first match is replaced. /// Unless RE_NO_VARS is specified, occurrences of $ (for example, $0, $1, $2, ... $9) - /// in replacement are replaced with the corresponding captured string. + /// in replacement are replaced with the corresponding captured string. /// $0 is the captured substring. $1 ... $n are the substrings matching the subpatterns. /// Returns the number of replaced occurrences. @@ -193,15 +196,16 @@ public: protected: std::string::size_type substOne(std::string& subject, std::string::size_type offset, const std::string& replacement, int options) const; + static int compileOptions(int options); + static int matchOptions(int options); private: - // Note: to avoid a dependency on the pcre.h header the following are + // Note: to avoid a dependency on the pcre2.h header the following are // declared as void* and casted to the correct type in the implementation file. - void* _pcre; // Actual type is pcre* - void* _extra; // Actual type is struct pcre_extra* - - static const int OVEC_SIZE; - + void* _pcre; // Actual type is pcre2_code_8* + + GroupMap _groups; + RegularExpression(); RegularExpression(const RegularExpression&); RegularExpression& operator = (const RegularExpression&); diff --git a/Foundation/include/Poco/RotateStrategy.h b/Foundation/include/Poco/RotateStrategy.h index 82c331f1f..1776fd0ee 100644 --- a/Foundation/include/Poco/RotateStrategy.h +++ b/Foundation/include/Poco/RotateStrategy.h @@ -42,7 +42,7 @@ public: virtual bool mustRotate(LogFile* pFile) = 0; /// Returns true if the given log file must /// be rotated, false otherwise. - + private: RotateStrategy(const RotateStrategy&); RotateStrategy& operator = (const RotateStrategy&); @@ -55,14 +55,14 @@ class RotateAtTimeStrategy: public RotateStrategy { public: RotateAtTimeStrategy(const std::string& rtime): - _day(-1), - _hour(-1), + _day(-1), + _hour(-1), _minute(0) { - if (rtime.empty()) + if (rtime.empty()) throw InvalidArgumentException("Rotation time must be specified."); - if ((rtime.find(',') != rtime.npos) && (rtime.find(':') == rtime.npos)) + if ((rtime.find(',') != rtime.npos) && (rtime.find(':') == rtime.npos)) throw InvalidArgumentException("Invalid rotation time specified."); StringTokenizer timestr(rtime, ",:", StringTokenizer::TOK_TRIM | StringTokenizer::TOK_IGNORE_EMPTY); @@ -87,11 +87,11 @@ public: } getNextRollover(); } - + ~RotateAtTimeStrategy() { } - + bool mustRotate(LogFile* /*pFile*/) { if (DT() >= _threshold) @@ -111,7 +111,7 @@ private: _threshold += tsp; } while (!(_threshold.minute() == _minute && - (-1 == _hour || _threshold.hour() == _hour) && + (-1 == _hour || _threshold.hour() == _hour) && (-1 == _day || _threshold.dayOfWeek() == _day))); // round to :00.0 seconds _threshold.assign(_threshold.year(), _threshold.month(), _threshold.day(), _threshold.hour(), _threshold.minute()); @@ -125,7 +125,7 @@ private: class Foundation_API RotateByIntervalStrategy: public RotateStrategy - /// The file is rotated when the log file + /// The file is rotated when the log file /// exceeds a given age. /// /// For this to work reliably across all platforms and file systems diff --git a/Foundation/include/Poco/Runnable.h b/Foundation/include/Poco/Runnable.h index c87a62817..8a08012f2 100644 --- a/Foundation/include/Poco/Runnable.h +++ b/Foundation/include/Poco/Runnable.h @@ -29,10 +29,10 @@ class Foundation_API Runnable /// must be implemented by classes that provide /// an entry point for a thread. { -public: +public: Runnable(); virtual ~Runnable(); - + virtual void run() = 0; /// Do whatever the thread needs to do. Must /// be overridden by subclasses. diff --git a/Foundation/include/Poco/RunnableAdapter.h b/Foundation/include/Poco/RunnableAdapter.h index 571871be9..0fa16ef8b 100644 --- a/Foundation/include/Poco/RunnableAdapter.h +++ b/Foundation/include/Poco/RunnableAdapter.h @@ -39,11 +39,11 @@ class RunnableAdapter: public Runnable { public: typedef void (C::*Callback)(); - + RunnableAdapter(C& object, Callback method): _pObject(&object), _method(method) { } - + RunnableAdapter(const RunnableAdapter& ra): _pObject(ra._pObject), _method(ra._method) { } @@ -63,7 +63,7 @@ public: { (_pObject->*_method)(); } - + private: RunnableAdapter(); diff --git a/Foundation/include/Poco/SHA1Engine.h b/Foundation/include/Poco/SHA1Engine.h index 9aa2b45e3..6d9c07644 100644 --- a/Foundation/include/Poco/SHA1Engine.h +++ b/Foundation/include/Poco/SHA1Engine.h @@ -44,7 +44,7 @@ public: SHA1Engine(); ~SHA1Engine(); - + std::size_t digestLength() const; void reset(); const DigestEngine::Digest& digest(); diff --git a/Foundation/include/Poco/SHA2Engine.h b/Foundation/include/Poco/SHA2Engine.h index 803cdff70..c1de5cd50 100644 --- a/Foundation/include/Poco/SHA2Engine.h +++ b/Foundation/include/Poco/SHA2Engine.h @@ -38,14 +38,16 @@ class Foundation_API SHA2Engine: public DigestEngine public: enum ALGORITHM { - SHA_224 = 224, - SHA_256 = 256, - SHA_384 = 384, - SHA_512 = 512 + SHA_224 = 1, + SHA_256, + SHA_384, + SHA_512, + SHA_512_224, + SHA_512_256 }; SHA2Engine(ALGORITHM algorithm = SHA_256); - ~SHA2Engine(); + virtual ~SHA2Engine(); std::size_t digestLength() const; void reset(); @@ -66,6 +68,82 @@ private: }; +class Foundation_API SHA2Engine224 : public SHA2Engine +{ +public: + enum + { + BLOCK_SIZE = 64, + DIGEST_SIZE = 28 + }; + + SHA2Engine224(): Poco::SHA2Engine(Poco::SHA2Engine::ALGORITHM::SHA_224) + { + } + + virtual ~SHA2Engine224() + { + } +}; + + +class Foundation_API SHA2Engine256 : public SHA2Engine +{ +public: + enum + { + BLOCK_SIZE = 64, + DIGEST_SIZE = 32 + }; + + SHA2Engine256(): Poco::SHA2Engine(Poco::SHA2Engine::ALGORITHM::SHA_256) + { + } + + virtual ~SHA2Engine256() + { + } +}; + + +class Foundation_API SHA2Engine384 : public SHA2Engine +{ +public: + enum + { + BLOCK_SIZE = 128, + DIGEST_SIZE = 48 + }; + + SHA2Engine384(): Poco::SHA2Engine(Poco::SHA2Engine::ALGORITHM::SHA_384) + { + } + + virtual ~SHA2Engine384() + { + } +}; + + +class Foundation_API SHA2Engine512 : public SHA2Engine +{ +public: + enum + { + BLOCK_SIZE = 128, + DIGEST_SIZE = 64 + }; + + SHA2Engine512(): Poco::SHA2Engine(Poco::SHA2Engine::ALGORITHM::SHA_512) + { + } + + virtual ~SHA2Engine512() + { + } +}; + + } // namespace Poco diff --git a/Foundation/include/Poco/ScopedLock.h b/Foundation/include/Poco/ScopedLock.h index 8415c3808..4b1f5ce71 100644 --- a/Foundation/include/Poco/ScopedLock.h +++ b/Foundation/include/Poco/ScopedLock.h @@ -37,12 +37,12 @@ public: { _mutex.lock(); } - + ScopedLock(M& mutex, long milliseconds): _mutex(mutex) { _mutex.lock(milliseconds); } - + ~ScopedLock() { try @@ -79,12 +79,12 @@ public: { _pMutex->lock(); } - + ScopedLockWithUnlock(M& mutex, long milliseconds): _pMutex(&mutex) { _pMutex->lock(milliseconds); } - + ~ScopedLockWithUnlock() { try @@ -96,7 +96,7 @@ public: poco_unexpected(); } } - + void unlock() { if (_pMutex) diff --git a/Foundation/include/Poco/Semaphore.h b/Foundation/include/Poco/Semaphore.h index 7c10c4afe..67b7dddc0 100644 --- a/Foundation/include/Poco/Semaphore.h +++ b/Foundation/include/Poco/Semaphore.h @@ -35,16 +35,16 @@ namespace Poco { class Foundation_API Semaphore: private SemaphoreImpl - /// A Semaphore is a synchronization object with the following + /// A Semaphore is a synchronization object with the following /// characteristics: /// A semaphore has a value that is constrained to be a non-negative - /// integer and two atomic operations. The allowable operations are V - /// (here called set()) and P (here called wait()). A V (set()) operation - /// increases the value of the semaphore by one. - /// A P (wait()) operation decreases the value of the semaphore by one, - /// provided that can be done without violating the constraint that the - /// value be non-negative. A P (wait()) operation that is initiated when - /// the value of the semaphore is 0 suspends the calling thread. + /// integer and two atomic operations. The allowable operations are V + /// (here called set()) and P (here called wait()). A V (set()) operation + /// increases the value of the semaphore by one. + /// A P (wait()) operation decreases the value of the semaphore by one, + /// provided that can be done without violating the constraint that the + /// value be non-negative. A P (wait()) operation that is initiated when + /// the value of the semaphore is 0 suspends the calling thread. /// The calling thread may continue when the value becomes positive again. { public: @@ -60,7 +60,7 @@ public: /// greater than zero, n must be greater than /// or equal to zero and less than or equal /// to max. - + ~Semaphore(); /// Destroys the semaphore. @@ -73,7 +73,7 @@ public: void wait(); /// Waits for the semaphore to become signalled. /// To become signalled, a semaphore's value must - /// be greater than zero. + /// be greater than zero. /// Decrements the semaphore's value by one. void wait(long milliseconds); @@ -95,7 +95,7 @@ public: /// time interval, false otherwise. /// Decrements the semaphore's value by one /// if successful. - + private: Semaphore(); Semaphore(const Semaphore&); diff --git a/Foundation/include/Poco/Semaphore_POSIX.h b/Foundation/include/Poco/Semaphore_POSIX.h index 3fc0897fa..841f0a702 100644 --- a/Foundation/include/Poco/Semaphore_POSIX.h +++ b/Foundation/include/Poco/Semaphore_POSIX.h @@ -30,12 +30,12 @@ namespace Poco { class Foundation_API SemaphoreImpl { protected: - SemaphoreImpl(int n, int max); + SemaphoreImpl(int n, int max); ~SemaphoreImpl(); void setImpl(); void waitImpl(); bool waitImpl(long milliseconds); - + private: volatile int _n; int _max; @@ -49,7 +49,7 @@ private: // inline void SemaphoreImpl::setImpl() { - if (pthread_mutex_lock(&_mutex)) + if (pthread_mutex_lock(&_mutex)) throw SystemException("cannot signal semaphore (lock)"); if (_n < _max) { @@ -59,7 +59,7 @@ inline void SemaphoreImpl::setImpl() { pthread_mutex_unlock(&_mutex); throw SystemException("cannot signal semaphore: count would exceed maximum"); - } + } if (pthread_cond_signal(&_cond)) { pthread_mutex_unlock(&_mutex); diff --git a/Foundation/include/Poco/Semaphore_VX.h b/Foundation/include/Poco/Semaphore_VX.h index 181afe2f5..2ec1dda65 100644 --- a/Foundation/include/Poco/Semaphore_VX.h +++ b/Foundation/include/Poco/Semaphore_VX.h @@ -29,12 +29,12 @@ namespace Poco { class Foundation_API SemaphoreImpl { protected: - SemaphoreImpl(int n, int max); + SemaphoreImpl(int n, int max); ~SemaphoreImpl(); void setImpl(); void waitImpl(); bool waitImpl(long milliseconds); - + private: SEM_ID _sem; }; diff --git a/Foundation/include/Poco/Semaphore_WIN32.h b/Foundation/include/Poco/Semaphore_WIN32.h index ac9c31356..97515c5b8 100644 --- a/Foundation/include/Poco/Semaphore_WIN32.h +++ b/Foundation/include/Poco/Semaphore_WIN32.h @@ -29,12 +29,12 @@ namespace Poco { class Foundation_API SemaphoreImpl { protected: - SemaphoreImpl(int n, int max); + SemaphoreImpl(int n, int max); ~SemaphoreImpl(); void setImpl(); void waitImpl(); bool waitImpl(long milliseconds); - + private: HANDLE _sema; }; diff --git a/Foundation/include/Poco/SharedLibrary.h b/Foundation/include/Poco/SharedLibrary.h index b7e6acc7c..008da32fd 100644 --- a/Foundation/include/Poco/SharedLibrary.h +++ b/Foundation/include/Poco/SharedLibrary.h @@ -27,7 +27,7 @@ #include "Poco/SharedLibrary_VX.h" #elif defined(POCO_OS_FAMILY_UNIX) #include "Poco/SharedLibrary_UNIX.h" -#elif defined(POCO_OS_FAMILY_WINDOWS) +#elif defined(POCO_OS_FAMILY_WINDOWS) #include "Poco/SharedLibrary_WIN32U.h" #endif diff --git a/Foundation/include/Poco/SharedMemory.h b/Foundation/include/Poco/SharedMemory.h index 233856787..e0bc1614b 100644 --- a/Foundation/include/Poco/SharedMemory.h +++ b/Foundation/include/Poco/SharedMemory.h @@ -46,7 +46,7 @@ public: }; SharedMemory(); - /// Default constructor creates an unmapped SharedMemory object. + /// Default constructor creates an unmapped SharedMemory object. /// No clients can connect to an unmapped SharedMemory object. SharedMemory(const std::string& name, std::size_t size, AccessMode mode, const void* addrHint = 0, bool server = true); @@ -81,7 +81,7 @@ public: SharedMemory& operator = (const SharedMemory& other); /// Assigns another SharedMemory object. - void swap(SharedMemory& other); + void swap(SharedMemory& other) noexcept; /// Swaps the SharedMemory object with another one. char* begin() const; @@ -89,7 +89,7 @@ public: /// Will be NULL for illegal segments. char* end() const; - /// Returns the one-past-end end address of the shared memory segment. + /// Returns the one-past-end end address of the shared memory segment. /// Will be NULL for illegal segments. private: @@ -100,7 +100,7 @@ private: // // inlines // -inline void SharedMemory::swap(SharedMemory& other) +inline void SharedMemory::swap(SharedMemory& other) noexcept { using std::swap; swap(_pImpl, other._pImpl); diff --git a/Foundation/include/Poco/SharedMemory_DUMMY.h b/Foundation/include/Poco/SharedMemory_DUMMY.h index 5a487a0f7..6b740f709 100644 --- a/Foundation/include/Poco/SharedMemory_DUMMY.h +++ b/Foundation/include/Poco/SharedMemory_DUMMY.h @@ -54,7 +54,7 @@ public: /// Returns the start address of the shared memory segment. char* end() const; - /// Returns the one-past-end end address of the shared memory segment. + /// Returns the one-past-end end address of the shared memory segment. protected: ~SharedMemoryImpl(); diff --git a/Foundation/include/Poco/SharedMemory_POSIX.h b/Foundation/include/Poco/SharedMemory_POSIX.h index 4ba6ab5e8..8b7f34e65 100644 --- a/Foundation/include/Poco/SharedMemory_POSIX.h +++ b/Foundation/include/Poco/SharedMemory_POSIX.h @@ -56,7 +56,7 @@ public: /// Returns the start address of the shared memory segment. char* end() const; - /// Returns the one-past-end end address of the shared memory segment. + /// Returns the one-past-end end address of the shared memory segment. protected: void map(const void* addrHint); diff --git a/Foundation/include/Poco/SharedPtr.h b/Foundation/include/Poco/SharedPtr.h index 30553f7b6..9a4fd69e6 100644 --- a/Foundation/include/Poco/SharedPtr.h +++ b/Foundation/include/Poco/SharedPtr.h @@ -239,7 +239,7 @@ public: return assign(ptr); } - void swap(SharedPtr& ptr) + void swap(SharedPtr& ptr) noexcept { std::swap(_ptr, ptr._ptr); std::swap(_pCounter, ptr._pCounter); diff --git a/Foundation/include/Poco/SignalHandler.h b/Foundation/include/Poco/SignalHandler.h index 22b5f1673..471d7a7f0 100644 --- a/Foundation/include/Poco/SignalHandler.h +++ b/Foundation/include/Poco/SignalHandler.h @@ -36,7 +36,7 @@ class Foundation_API SignalHandler /// /// The class provides a signal handler (installed with /// installHandlers()) that translates certain POSIX - /// signals (SIGILL, SIGBUS, SIGSEGV, SIGSYS) into + /// signals (SIGILL, SIGBUS, SIGSEGV, SIGSYS) into /// C++ exceptions. /// /// Internally, a stack of sigjmp_buf structs is maintained for @@ -81,9 +81,9 @@ public: /// Returns the top-most sigjmp_buf for the current thread. static void throwSignalException(int sig); - /// Throws a SignalException with a textual description - /// of the given signal as argument. - + /// Throws a SignalException with a textual description + /// of the given signal as argument. + static void install(); /// Installs signal handlers for SIGILL, SIGBUS, SIGSEGV /// and SIGSYS. @@ -105,7 +105,7 @@ protected: private: static JumpBufferVec _jumpBufferVec; - + friend class ThreadImpl; }; diff --git a/Foundation/include/Poco/SimpleFileChannel.h b/Foundation/include/Poco/SimpleFileChannel.h index 844cacc51..0e03178d8 100644 --- a/Foundation/include/Poco/SimpleFileChannel.h +++ b/Foundation/include/Poco/SimpleFileChannel.h @@ -40,15 +40,15 @@ class Foundation_API SimpleFileChannel: public Channel /// by a newline. /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is in the text. + /// appropriate Formatter to control what is in the text. /// /// Log file rotation based on log file size is supported. /// - /// If rotation is enabled, the SimpleFileChannel will + /// If rotation is enabled, the SimpleFileChannel will /// alternate between two log files. If the size of /// the primary log file exceeds a specified limit, /// the secondary log file will be used, and vice - /// versa. + /// versa. /// /// Log rotation is configured with the "rotation" /// property, which supports the following values: @@ -88,20 +88,20 @@ public: void open(); /// Opens the FileChannel and creates the log file if necessary. - + void close(); /// Closes the FileChannel. void log(const Message& msg); /// Logs the given message to the file. - + void setProperty(const std::string& name, const std::string& value); - /// Sets the property with the given name. - /// + /// Sets the property with the given name. + /// /// The following properties are supported: /// * path: The primary log file's path. /// * secondaryPath: The secondary log file's path. - /// * rotation: The log file's rotation mode. See the + /// * rotation: The log file's rotation mode. See the /// SimpleFileChannel class for details. /// * flush: Specifies whether messages are immediately /// flushed to the log file. See the SimpleFileChannel @@ -114,7 +114,7 @@ public: Timestamp creationDate() const; /// Returns the log file's creation date. - + UInt64 size() const; /// Returns the log file's current size in bytes. diff --git a/Foundation/include/Poco/SimpleHashTable.h b/Foundation/include/Poco/SimpleHashTable.h index cc2e92fb3..ef8b7d634 100644 --- a/Foundation/include/Poco/SimpleHashTable.h +++ b/Foundation/include/Poco/SimpleHashTable.h @@ -68,7 +68,7 @@ public: _entries.reserve(ht._capacity); for (auto p: ht._entries.end()) { - if (p) + if (p) _entries.push_back(new HashEntry(p)); else _entries.push_back(0); @@ -90,8 +90,8 @@ public: } return *this; } - - void swap(SimpleHashTable& ht) + + void swap(SimpleHashTable& ht) noexcept { using std::swap; swap(_entries, ht._entries); @@ -216,12 +216,12 @@ public: UInt32 hsh = hash(key); return const_cast(getRaw(key, hsh)); } - + const Value& operator [] (const Key& key) const { return get(key); } - + Value& operator [] (const Key& key) { UInt32 hsh = hash(key); @@ -326,7 +326,7 @@ public: { return _size; } - + UInt32 capacity() const { return _capacity; diff --git a/Foundation/include/Poco/SingletonHolder.h b/Foundation/include/Poco/SingletonHolder.h index 8735f114b..3f0b997b5 100644 --- a/Foundation/include/Poco/SingletonHolder.h +++ b/Foundation/include/Poco/SingletonHolder.h @@ -39,14 +39,14 @@ public: /// Creates the SingletonHolder. { } - + ~SingletonHolder() /// Destroys the SingletonHolder and the singleton /// object that it holds. { delete _pS; } - + S* get() /// Returns a pointer to the singleton object /// hold by the SingletonHolder. The first call @@ -56,7 +56,7 @@ public: if (!_pS) _pS = new S; return _pS; } - + void reset() /// Deletes the singleton object. { @@ -64,7 +64,7 @@ public: delete _pS; _pS = 0; } - + private: S* _pS; FastMutex _m; diff --git a/Foundation/include/Poco/SplitterChannel.h b/Foundation/include/Poco/SplitterChannel.h index 6f48eab3e..cdac8f578 100644 --- a/Foundation/include/Poco/SplitterChannel.h +++ b/Foundation/include/Poco/SplitterChannel.h @@ -40,13 +40,13 @@ public: void addChannel(Channel::Ptr pChannel); /// Attaches a channel, which may not be null. - + void removeChannel(Channel::Ptr pChannel); /// Removes a channel. void log(const Message& msg); /// Sends the given Message to all - /// attaches channels. + /// attaches channels. void setProperty(const std::string& name, const std::string& value); /// Sets or changes a configuration property. @@ -59,7 +59,7 @@ public: void close(); /// Removes all channels. - + int count() const; /// Returns the number of channels in the SplitterChannel. @@ -68,7 +68,7 @@ protected: private: typedef std::vector ChannelVec; - + ChannelVec _channels; mutable FastMutex _mutex; }; diff --git a/Foundation/include/Poco/Stopwatch.h b/Foundation/include/Poco/Stopwatch.h index 6bc27fc92..add8e4c8b 100644 --- a/Foundation/include/Poco/Stopwatch.h +++ b/Foundation/include/Poco/Stopwatch.h @@ -35,20 +35,20 @@ public: void start(); /// Starts (or restarts) the stopwatch. - + void stop(); /// Stops or pauses the stopwatch. - + void reset(); /// Resets the stopwatch. - + void restart(); /// Resets and starts the stopwatch. - + Clock::ClockDiff elapsed() const; /// Returns the elapsed time in microseconds /// since the stopwatch started. - + int elapsedSeconds() const; /// Returns the number of seconds elapsed /// since the stopwatch started. diff --git a/Foundation/include/Poco/StrategyCollection.h b/Foundation/include/Poco/StrategyCollection.h index 7994f5417..b67370ddc 100644 --- a/Foundation/include/Poco/StrategyCollection.h +++ b/Foundation/include/Poco/StrategyCollection.h @@ -28,7 +28,7 @@ namespace Poco { -template +template class StrategyCollection: public AbstractStrategy /// An StrategyCollection is a decorator masking n collections as a single one. { diff --git a/Foundation/include/Poco/StreamChannel.h b/Foundation/include/Poco/StreamChannel.h index 27ed0c7db..ab8ae57f0 100644 --- a/Foundation/include/Poco/StreamChannel.h +++ b/Foundation/include/Poco/StreamChannel.h @@ -34,7 +34,7 @@ class Foundation_API StreamChannel: public Channel /// by a newline. /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is contained + /// appropriate Formatter to control what is contained /// in the text. { public: @@ -45,7 +45,7 @@ public: void log(const Message& msg); /// Logs the given message to the channel's stream. - + protected: virtual ~StreamChannel(); diff --git a/Foundation/include/Poco/StreamConverter.h b/Foundation/include/Poco/StreamConverter.h index c880e2632..99701aadb 100644 --- a/Foundation/include/Poco/StreamConverter.h +++ b/Foundation/include/Poco/StreamConverter.h @@ -91,7 +91,7 @@ class Foundation_API InputStreamConverter: public StreamConverterIOS, public std /// underlying istream from one character encoding into another. /// If a character cannot be represented in outEncoding, defaultChar /// is used instead. - /// If a byte sequence read from the underlying stream is not valid in inEncoding, + /// If a byte sequence read from the underlying stream is not valid in inEncoding, /// defaultChar is used instead and the encoding error count is incremented. { public: @@ -109,7 +109,7 @@ class Foundation_API OutputStreamConverter: public StreamConverterIOS, public st /// underlying ostream from one character encoding into another. /// If a character cannot be represented in outEncoding, defaultChar /// is used instead. - /// If a byte sequence written to the stream is not valid in inEncoding, + /// If a byte sequence written to the stream is not valid in inEncoding, /// defaultChar is used instead and the encoding error count is incremented. { public: diff --git a/Foundation/include/Poco/StreamTokenizer.h b/Foundation/include/Poco/StreamTokenizer.h index 3c5b69641..2b5ad5c13 100644 --- a/Foundation/include/Poco/StreamTokenizer.h +++ b/Foundation/include/Poco/StreamTokenizer.h @@ -54,7 +54,7 @@ public: /// and whitespace tokens will be marked as /// ignorable, which means that next() will not /// return them. - + void addToken(Token* pToken, bool ignore); /// Adds a token class to the tokenizer. The /// tokenizer takes ownership of the token and @@ -62,11 +62,11 @@ public: /// If ignore is true, the token will be marked /// as ignorable, which means that next() will /// not return it. - + const Token* next(); /// Extracts the next token from the input stream. /// Returns a pointer to an EOFToken if there are - /// no more characters to read. + /// no more characters to read. /// Returns a pointer to an InvalidToken if an /// invalid character is encountered. /// If a token is marked as ignorable, it will not @@ -81,9 +81,9 @@ private: Token* pToken; bool ignore; }; - + typedef std::vector TokenVec; - + TokenVec _tokens; std::istream* _pIstr; InvalidToken _invalidToken; diff --git a/Foundation/include/Poco/StringTokenizer.h b/Foundation/include/Poco/StringTokenizer.h index 0690fb720..a3c625889 100644 --- a/Foundation/include/Poco/StringTokenizer.h +++ b/Foundation/include/Poco/StringTokenizer.h @@ -38,10 +38,10 @@ public: TOK_IGNORE_EMPTY = 1, /// ignore empty tokens TOK_TRIM = 2 /// remove leading and trailing whitespace from tokens }; - + typedef std::vector TokenVec; typedef TokenVec::const_iterator Iterator; - + StringTokenizer(const std::string& str, const std::string& separators, int options = 0); /// Splits the given string into tokens. The tokens are expected to be /// separated by one of the separator characters given in separators. @@ -51,10 +51,10 @@ public: ~StringTokenizer(); /// Destroys the tokenizer. - + Iterator begin() const; Iterator end() const; - + const std::string& operator [] (std::size_t index) const; /// Returns const reference the index'th token. /// Throws a RangeException if the index is out of range. @@ -72,10 +72,10 @@ public: /// Throws a NotFoundException if the token is not found. std::size_t replace(const std::string& oldToken, const std::string& newToken, std::string::size_type pos = 0); - /// Starting at position pos, replaces all subsequent tokens having value + /// Starting at position pos, replaces all subsequent tokens having value /// equal to oldToken with newToken. /// Returns the number of modified tokens. - + std::size_t count() const; /// Returns the total number of tokens. diff --git a/Foundation/include/Poco/SynchronizedObject.h b/Foundation/include/Poco/SynchronizedObject.h index a2cfd96fb..a201f7c86 100644 --- a/Foundation/include/Poco/SynchronizedObject.h +++ b/Foundation/include/Poco/SynchronizedObject.h @@ -34,10 +34,10 @@ class Foundation_API SynchronizedObject { public: using ScopedLock = Poco::ScopedLock; - + SynchronizedObject(); /// Creates the object. - + virtual ~SynchronizedObject(); /// Destroys the object. @@ -49,14 +49,14 @@ public: /// Tries to lock the object. Returns false immediately /// if the object is already locked by another thread /// Returns true if the object was successfully locked. - + void unlock() const; /// Unlocks the object so that it can be locked by /// other threads. - + void notify() const; - /// Signals the object. - /// Exactly only one thread waiting for the object + /// Signals the object. + /// Exactly only one thread waiting for the object /// can resume execution. void wait() const; diff --git a/Foundation/include/Poco/SyslogChannel.h b/Foundation/include/Poco/SyslogChannel.h index 843d4ce98..2b3e398b7 100644 --- a/Foundation/include/Poco/SyslogChannel.h +++ b/Foundation/include/Poco/SyslogChannel.h @@ -38,7 +38,7 @@ public: SYSLOG_NDELAY = 0x08, /// don't delay open SYSLOG_PERROR = 0x20 /// log to stderr as well (not supported on all platforms) }; - + enum Facility { SYSLOG_KERN = ( 0<<3), /// kernel messages @@ -62,22 +62,22 @@ public: SYSLOG_LOCAL6 = (22<<3), /// reserved for local use SYSLOG_LOCAL7 = (23<<3) /// reserved for local use }; - + SyslogChannel(); /// Creates a SyslogChannel. - + SyslogChannel(const std::string& name, int options = SYSLOG_CONS, int facility = SYSLOG_USER); /// Creates a SyslogChannel with the given name, options and facility. - + void open(); /// Opens the SyslogChannel. - + void close(); /// Closes the SyslogChannel. - + void log(const Message& msg); /// Sens the message's text to the syslog service. - + void setProperty(const std::string& name, const std::string& value); /// Sets the property with the given value. /// @@ -85,7 +85,7 @@ public: /// * name: The name used to identify the source of log messages. /// * facility: The facility added to each log message. See the Facility enumeration for a list of supported values. /// * options: The logging options. See the Option enumeration for a list of supported values. - + std::string getProperty(const std::string& name) const; /// Returns the value of the property with the given name. diff --git a/Foundation/include/Poco/Task.h b/Foundation/include/Poco/Task.h index 6ae11d283..123c74ab3 100644 --- a/Foundation/include/Poco/Task.h +++ b/Foundation/include/Poco/Task.h @@ -34,7 +34,7 @@ class NotificationCenter; class Foundation_API Task: public Runnable, public RefCountedObject - /// A Task is a subclass of Runnable that has a name + /// A Task is a subclass of Runnable that has a name /// and supports progress reporting and cancellation. /// /// A TaskManager object can be used to take care of the @@ -49,13 +49,13 @@ public: TASK_CANCELLING, TASK_FINISHED }; - + Task(const std::string& name); /// Creates the Task. const std::string& name() const; - /// Returns the task's name. - + /// Returns the task's name. + float progress() const; /// Returns the task's progress. /// The value will be between 0.0 (just started) @@ -72,7 +72,7 @@ public: bool isCancelled() const; /// Returns true if cancellation of the task has been - /// requested. + /// requested. /// /// A Task's runTask() method should periodically /// call this method and stop whatever it is doing in an @@ -84,11 +84,11 @@ public: void reset(); /// Sets the task's progress to zero and clears the /// cancel flag. - + virtual void runTask() = 0; /// Do whatever the task needs to do. Must /// be overridden by subclasses. - + void run(); /// Calls the task's runTask() method and notifies the owner /// of the task's start and completion. @@ -130,7 +130,7 @@ protected: void setOwner(TaskManager* pOwner); /// Sets the (optional) owner of the task. - + TaskManager* getOwner() const; /// Returns the owner of the task, which may be NULL. @@ -139,19 +139,19 @@ protected: virtual ~Task(); /// Destroys the Task. - + private: Task(); Task(const Task&); Task& operator = (const Task&); - + std::string _name; TaskManager* _pOwner; float _progress; - TaskState _state; + std::atomic _state; Event _cancelEvent; mutable FastMutex _mutex; - + friend class TaskManager; }; diff --git a/Foundation/include/Poco/TaskManager.h b/Foundation/include/Poco/TaskManager.h index 0a4ff86f2..6b7cd2090 100644 --- a/Foundation/include/Poco/TaskManager.h +++ b/Foundation/include/Poco/TaskManager.h @@ -70,7 +70,7 @@ public: void cancelAll(); /// Requests cancellation of all tasks. - + void joinAll(); /// Waits for the completion of all the threads /// in the TaskManager's thread pool. @@ -100,7 +100,7 @@ public: protected: void postNotification(const Notification::Ptr& pNf); - /// Posts a notification to the task manager's + /// Posts a notification to the task manager's /// notification center. void taskStarted(Task* pTask); diff --git a/Foundation/include/Poco/TaskNotification.h b/Foundation/include/Poco/TaskNotification.h index 88dab508d..120643fff 100644 --- a/Foundation/include/Poco/TaskNotification.h +++ b/Foundation/include/Poco/TaskNotification.h @@ -51,7 +51,7 @@ class Foundation_API TaskStartedNotification: public TaskNotification { public: TaskStartedNotification(Task* pTask); - + protected: ~TaskStartedNotification(); }; @@ -92,7 +92,7 @@ public: protected: ~TaskFailedNotification(); - + private: Exception* _pException; }; @@ -109,7 +109,7 @@ public: protected: ~TaskProgressNotification(); - + private: float _progress; }; @@ -137,7 +137,7 @@ public: protected: ~TaskCustomNotification(){}; - + private: C _custom; }; diff --git a/Foundation/include/Poco/TeeStream.h b/Foundation/include/Poco/TeeStream.h index 07744d834..ad6f2940c 100644 --- a/Foundation/include/Poco/TeeStream.h +++ b/Foundation/include/Poco/TeeStream.h @@ -36,7 +36,7 @@ public: TeeStreamBuf(); /// Creates an unconnected CountingStreamBuf. /// Use addStream() to attach output streams. - + TeeStreamBuf(std::istream& istr); /// Creates the CountingStreamBuf and connects it /// to the given input stream. @@ -57,7 +57,7 @@ protected: private: typedef std::vector StreamVec; - + std::istream* _pIstr; StreamVec _streams; }; @@ -116,7 +116,7 @@ class Foundation_API TeeOutputStream: public TeeIOS, public std::ostream public: TeeOutputStream(); /// Creates an unconnected TeeOutputStream. - + TeeOutputStream(std::ostream& ostr); /// Creates the TeeOutputStream and connects it /// to the given input stream. diff --git a/Foundation/include/Poco/TextBufferIterator.h b/Foundation/include/Poco/TextBufferIterator.h index d8eda8417..1d3956283 100644 --- a/Foundation/include/Poco/TextBufferIterator.h +++ b/Foundation/include/Poco/TextBufferIterator.h @@ -53,7 +53,7 @@ class Foundation_API TextBufferIterator public: TextBufferIterator(); /// Creates an uninitialized TextBufferIterator. - + TextBufferIterator(const char* begin, const TextEncoding& encoding); /// Creates a TextBufferIterator for the given buffer, which must be 0-terminated. /// The encoding object must not be deleted as long as the iterator @@ -74,37 +74,37 @@ public: ~TextBufferIterator(); /// Destroys the TextBufferIterator. - + TextBufferIterator(const TextBufferIterator& it); /// Copy constructor. - + TextBufferIterator& operator = (const TextBufferIterator& it); /// Assignment operator. - - void swap(TextBufferIterator& it); + + void swap(TextBufferIterator& it) noexcept; /// Swaps the iterator with another one. - + int operator * () const; /// Returns the Unicode value of the current character. /// If there is no valid character at the current position, /// -1 is returned. - - TextBufferIterator& operator ++ (); + + TextBufferIterator& operator ++ (); /// Prefix increment operator. - TextBufferIterator operator ++ (int); + TextBufferIterator operator ++ (int); /// Postfix increment operator. bool operator == (const TextBufferIterator& it) const; /// Compares two iterators for equality. - + bool operator != (const TextBufferIterator& it) const; /// Compares two iterators for inequality. TextBufferIterator end() const; /// Returns the end iterator for the range handled /// by the iterator. - + private: const TextEncoding* _pEncoding; const char* _it; @@ -127,7 +127,7 @@ inline bool TextBufferIterator::operator != (const TextBufferIterator& it) const } -inline void swap(TextBufferIterator& it1, TextBufferIterator& it2) +inline void swap(TextBufferIterator& it1, TextBufferIterator& it2) noexcept { it1.swap(it2); } diff --git a/Foundation/include/Poco/TextConverter.h b/Foundation/include/Poco/TextConverter.h index ebf978fa6..88e2d3191 100644 --- a/Foundation/include/Poco/TextConverter.h +++ b/Foundation/include/Poco/TextConverter.h @@ -34,14 +34,14 @@ class Foundation_API TextConverter public: typedef int (*Transform)(int); /// Transform function for convert. - + TextConverter(const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar = '?'); /// Creates the TextConverter. The encoding objects must not be deleted while the /// TextConverter is in use. ~TextConverter(); /// Destroys the TextConverter. - + int convert(const std::string& source, std::string& destination, Transform trans); /// Converts the source string from inEncoding to outEncoding /// and appends the result to destination. Every character is diff --git a/Foundation/include/Poco/TextIterator.h b/Foundation/include/Poco/TextIterator.h index 17f48a4ab..f78fb868b 100644 --- a/Foundation/include/Poco/TextIterator.h +++ b/Foundation/include/Poco/TextIterator.h @@ -51,7 +51,7 @@ class Foundation_API TextIterator public: TextIterator(); /// Creates an uninitialized TextIterator. - + TextIterator(const std::string& str, const TextEncoding& encoding); /// Creates a TextIterator for the given string. /// The encoding object must not be deleted as long as the iterator @@ -70,37 +70,37 @@ public: ~TextIterator(); /// Destroys the TextIterator. - + TextIterator(const TextIterator& it); /// Copy constructor. - + TextIterator& operator = (const TextIterator& it); /// Assignment operator. - - void swap(TextIterator& it); + + void swap(TextIterator& it) noexcept; /// Swaps the iterator with another one. - + int operator * () const; /// Returns the Unicode value of the current character. /// If there is no valid character at the current position, /// -1 is returned. - - TextIterator& operator ++ (); + + TextIterator& operator ++ (); /// Prefix increment operator. - TextIterator operator ++ (int); + TextIterator operator ++ (int); /// Postfix increment operator. bool operator == (const TextIterator& it) const; /// Compares two iterators for equality. - + bool operator != (const TextIterator& it) const; /// Compares two iterators for inequality. - + TextIterator end() const; /// Returns the end iterator for the range handled /// by the iterator. - + private: const TextEncoding* _pEncoding; std::string::const_iterator _it; @@ -123,7 +123,7 @@ inline bool TextIterator::operator != (const TextIterator& it) const } -inline void swap(TextIterator& it1, TextIterator& it2) +inline void swap(TextIterator& it1, TextIterator& it2) noexcept { it1.swap(it2); } diff --git a/Foundation/include/Poco/Thread.h b/Foundation/include/Poco/Thread.h index 777255318..f29d7b46f 100644 --- a/Foundation/include/Poco/Thread.h +++ b/Foundation/include/Poco/Thread.h @@ -224,8 +224,11 @@ public: /// Returns the Thread object for the currently active thread. /// If the current thread is the main thread, 0 is returned. - static TID currentTid(); - /// Returns the native thread ID for the current thread. + static TID currentTid(); + /// Returns the native thread ID for the current thread. + + static long currentOsTid(); + /// Returns the operating system specific thread ID for the current thread. protected: ThreadLocalStorage& tls(); @@ -378,6 +381,10 @@ inline Thread::TID Thread::currentTid() return currentTidImpl(); } +inline long Thread::currentOsTid() +{ + return currentOsTidImpl(); +} } // namespace Poco diff --git a/Foundation/include/Poco/ThreadLocal.h b/Foundation/include/Poco/ThreadLocal.h index cea17d5c1..9cdd01521 100644 --- a/Foundation/include/Poco/ThreadLocal.h +++ b/Foundation/include/Poco/ThreadLocal.h @@ -47,16 +47,16 @@ public: _value() { } - + ~TLSSlot() { } - + C& value() { return _value; } - + private: TLSSlot(const TLSSlot&); TLSSlot& operator = (const TLSSlot&); @@ -73,24 +73,24 @@ class Foundation_API ThreadLocalStorage public: ThreadLocalStorage(); /// Creates the TLS. - + ~ThreadLocalStorage(); /// Deletes the TLS. TLSAbstractSlot*& get(const void* key); /// Returns the slot for the given key. - + static ThreadLocalStorage& current(); /// Returns the TLS object for the current thread /// (which may also be the main thread). - + static void clear(); /// Clears the current thread's TLS object. /// Does nothing in the main thread. - + private: typedef std::map TLSMap; - + TLSMap _map; friend class Thread; @@ -118,16 +118,16 @@ public: ThreadLocal() { } - + ~ThreadLocal() { } - + C* operator -> () { return &get(); } - + C& operator * () /// "Dereferences" the smart pointer and returns a reference /// to the underlying data object. The reference can be used @@ -144,7 +144,7 @@ public: if (!p) p = new Slot; return static_cast(p)->value(); } - + private: ThreadLocal(const ThreadLocal&); ThreadLocal& operator = (const ThreadLocal&); diff --git a/Foundation/include/Poco/ThreadTarget.h b/Foundation/include/Poco/ThreadTarget.h index 88452694c..5cf9c4e60 100644 --- a/Foundation/include/Poco/ThreadTarget.h +++ b/Foundation/include/Poco/ThreadTarget.h @@ -26,7 +26,7 @@ namespace Poco { class Foundation_API ThreadTarget: public Runnable - /// This adapter simplifies using static member functions as well as + /// This adapter simplifies using static member functions as well as /// standalone functions as targets for threads. /// Note that it is possible to pass those entities directly to Thread::start(). /// This adapter is provided as a convenience for higher abstraction level @@ -34,7 +34,7 @@ class Foundation_API ThreadTarget: public Runnable /// /// For using a non-static member function as a thread target, please /// see the RunnableAdapter class. - /// + /// /// Usage: /// class MyObject /// { @@ -45,18 +45,18 @@ class Foundation_API ThreadTarget: public Runnable /// thr.start(ra); /// /// or: - /// + /// /// void doSomething() {} - /// + /// /// ThreadTarget ra(doSomething); /// Thread thr; /// thr.start(ra); { public: typedef void (*Callback)(); - + ThreadTarget(Callback method); - + ThreadTarget(const ThreadTarget& te); ~ThreadTarget(); @@ -64,7 +64,7 @@ public: ThreadTarget& operator = (const ThreadTarget& te); void run(); - + private: ThreadTarget(); diff --git a/Foundation/include/Poco/Thread_POSIX.h b/Foundation/include/Poco/Thread_POSIX.h index 6b70907ed..b46351009 100644 --- a/Foundation/include/Poco/Thread_POSIX.h +++ b/Foundation/include/Poco/Thread_POSIX.h @@ -59,7 +59,7 @@ public: { POLICY_DEFAULT_IMPL = SCHED_OTHER }; - + ThreadImpl(); ~ThreadImpl(); @@ -80,6 +80,7 @@ public: static void yieldImpl(); static ThreadImpl* currentImpl(); static TIDImpl currentTidImpl(); + static long currentOsTidImpl(); protected: static void* runnableEntry(void* pThread); @@ -140,12 +141,12 @@ private: std::size_t stackSize; bool started; bool joined; + mutable FastMutex mutex; }; AutoPtr _pData; - static CurrentThreadHolder _currentThreadHolder; - + #if defined(POCO_OS_FAMILY_UNIX) && !defined(POCO_VXWORKS) SignalHandler::JumpBufferVec _jumpBufferVec; friend class SignalHandler; @@ -170,6 +171,7 @@ inline int ThreadImpl::getOSPriorityImpl() const inline bool ThreadImpl::isRunningImpl() const { + FastMutex::ScopedLock l(_pData->mutex); return !_pData->pRunnableTarget.isNull(); } diff --git a/Foundation/include/Poco/Thread_VX.h b/Foundation/include/Poco/Thread_VX.h index a6dad9d1f..506c5ab67 100644 --- a/Foundation/include/Poco/Thread_VX.h +++ b/Foundation/include/Poco/Thread_VX.h @@ -33,7 +33,7 @@ namespace Poco { class Foundation_API ThreadImpl { -public: +public: typedef int TIDImpl; typedef void (*Callable)(void*); @@ -63,7 +63,7 @@ public: } Callable callback; - void* pData; + void* pData; }; ThreadImpl(); @@ -88,6 +88,7 @@ public: static void yieldImpl(); static ThreadImpl* currentImpl(); static TIDImpl currentTidImpl(); + static long currentOsTidImpl(); protected: static void runnableEntry(void* pThread, int, int, int, int, int, int, int, int, int); diff --git a/Foundation/include/Poco/Thread_WIN32.h b/Foundation/include/Poco/Thread_WIN32.h index 194b0a3b7..2d44a20bc 100644 --- a/Foundation/include/Poco/Thread_WIN32.h +++ b/Foundation/include/Poco/Thread_WIN32.h @@ -29,7 +29,7 @@ namespace Poco { class Foundation_API ThreadImpl { -public: +public: typedef DWORD TIDImpl; typedef void (*Callable)(void*); @@ -53,7 +53,7 @@ public: POLICY_DEFAULT_IMPL = 0 }; - ThreadImpl(); + ThreadImpl(); ~ThreadImpl(); TIDImpl tidImpl() const; @@ -73,7 +73,8 @@ public: static void yieldImpl(); static ThreadImpl* currentImpl(); static TIDImpl currentTidImpl(); - + static long currentOsTidImpl(); + protected: #if defined(_DLL) static DWORD WINAPI runnableEntry(LPVOID pThread); @@ -105,7 +106,7 @@ private: { TlsSetValue(_slot, pThread); } - + private: DWORD _slot; }; diff --git a/Foundation/include/Poco/Thread_WINCE.h b/Foundation/include/Poco/Thread_WINCE.h index 29f08aa34..47e9f18e8 100644 --- a/Foundation/include/Poco/Thread_WINCE.h +++ b/Foundation/include/Poco/Thread_WINCE.h @@ -34,7 +34,7 @@ namespace Poco { class Foundation_API ThreadImpl { -public: +public: typedef DWORD TIDImpl; typedef void (*Callable)(void*); typedef DWORD (WINAPI *Entry)(LPVOID); @@ -53,7 +53,7 @@ public: POLICY_DEFAULT_IMPL = 0 }; - ThreadImpl(); + ThreadImpl(); ~ThreadImpl(); TIDImpl tidImpl() const; @@ -73,6 +73,7 @@ public: static void yieldImpl(); static ThreadImpl* currentImpl(); static TIDImpl currentTidImpl(); + static long currentOsTidImpl(); protected: static DWORD WINAPI runnableEntry(LPVOID pThread); @@ -101,7 +102,7 @@ private: { TlsSetValue(_slot, pThread); } - + private: DWORD _slot; }; diff --git a/Foundation/include/Poco/TimedNotificationQueue.h b/Foundation/include/Poco/TimedNotificationQueue.h index 841ace6b0..d08e54bcf 100644 --- a/Foundation/include/Poco/TimedNotificationQueue.h +++ b/Foundation/include/Poco/TimedNotificationQueue.h @@ -33,13 +33,13 @@ namespace Poco { class Foundation_API TimedNotificationQueue /// A TimedNotificationQueue object provides a way to implement timed, asynchronous /// notifications. This is especially useful for sending notifications - /// from one thread to another, for example from a background thread to - /// the main (user interface) thread. + /// from one thread to another, for example from a background thread to + /// the main (user interface) thread. /// /// The TimedNotificationQueue is quite similar to the NotificationQueue class. /// The only difference to NotificationQueue is that each Notification is tagged /// with a Timestamp. When inserting a Notification into the queue, the - /// Notification is inserted according to the given Timestamp, with + /// Notification is inserted according to the given Timestamp, with /// lower Timestamp values being inserted before higher ones. /// /// Notifications are dequeued in order of their timestamps. @@ -88,11 +88,11 @@ public: /// It is highly recommended that the result is immediately /// assigned to a Notification::Ptr, to avoid potential /// memory management issues. - + Notification* waitDequeueNotification(); /// Dequeues the next pending notification. /// If no notification is available, waits for a notification - /// to be enqueued. + /// to be enqueued. /// The caller gains ownership of the notification and /// is expected to release it when done with it. /// @@ -114,7 +114,7 @@ public: bool empty() const; /// Returns true iff the queue is empty. - + int size() const; /// Returns the number of notifications in the queue. @@ -129,7 +129,7 @@ protected: typedef std::multimap NfQueue; Notification::Ptr dequeueOne(NfQueue::iterator& it); bool wait(Clock::ClockDiff interval); - + private: NfQueue _nfQueue; Event _nfAvailable; diff --git a/Foundation/include/Poco/Timer.h b/Foundation/include/Poco/Timer.h index 56dbd2b5b..ce77ae2d1 100644 --- a/Foundation/include/Poco/Timer.h +++ b/Foundation/include/Poco/Timer.h @@ -39,14 +39,14 @@ class Foundation_API Timer: protected Runnable /// Once that interval expires, the timer callback is called repeatedly /// in the given periodic interval. If the interval is 0, the timer is only /// called once. - /// The timer callback method can stop the timer by setting the + /// The timer callback method can stop the timer by setting the /// timer's periodic interval to 0. /// /// The timer callback runs in its own thread, so multithreading - /// issues (proper synchronization) have to be considered when writing + /// issues (proper synchronization) have to be considered when writing /// the callback method. /// - /// The exact interval at which the callback is called depends on many + /// The exact interval at which the callback is called depends on many /// factors like operating system, CPU performance and system load and /// may differ from the specified interval. /// @@ -66,7 +66,7 @@ class Foundation_API Timer: protected Runnable public: Timer(long startInterval = 0, long periodicInterval = 0); /// Creates a new timer object. StartInterval and periodicInterval - /// are given in milliseconds. If a periodicInterval of zero is + /// are given in milliseconds. If a periodicInterval of zero is /// specified, the callback will only be called once, after the /// startInterval expires. /// To start the timer, call the Start() method. @@ -101,7 +101,7 @@ public: /// Create the TimerCallback as follows: /// TimerCallback callback(*this, &MyClass::onTimer); /// timer.start(callback); - + void stop(); /// Stops the timer. If the callback method is currently running /// it will be allowed to finish first. @@ -121,7 +121,7 @@ public: /// Returns the start interval. void setStartInterval(long milliseconds); - /// Sets the start interval. Will only be + /// Sets the start interval. Will only be /// effective before start() is called. long getPeriodicInterval() const; @@ -131,7 +131,7 @@ public: /// Sets the periodic interval. If the timer is already running /// the new interval will be effective when the current interval /// expires. - + long skipped() const; /// Returns the number of skipped invocations since the last invocation. /// Skipped invocations happen if the timer callback function takes @@ -149,7 +149,7 @@ private: AbstractTimerCallback* _pCallback; Clock _nextInvocation; mutable FastMutex _mutex; - + Timer(const Timer&); Timer& operator = (const Timer&); }; @@ -163,7 +163,7 @@ public: AbstractTimerCallback(); AbstractTimerCallback(const AbstractTimerCallback& callback); virtual ~AbstractTimerCallback(); - + AbstractTimerCallback& operator = (const AbstractTimerCallback& callback); virtual void invoke(Timer& timer) const = 0; @@ -171,11 +171,11 @@ public: }; -template +template class TimerCallback: public AbstractTimerCallback /// This template class implements an adapter that sits between /// a Timer and an object's method invoked by the timer. - /// It is quite similar in concept to the RunnableAdapter, but provides + /// It is quite similar in concept to the RunnableAdapter, but provides /// some Timer specific additional methods. /// See the Timer class for information on how /// to use this template class. diff --git a/Foundation/include/Poco/Timespan.h b/Foundation/include/Poco/Timespan.h index 09f17428e..d00f9c23f 100644 --- a/Foundation/include/Poco/Timespan.h +++ b/Foundation/include/Poco/Timespan.h @@ -20,6 +20,7 @@ #include "Poco/Foundation.h" #include "Poco/Timestamp.h" +#include namespace Poco { @@ -33,20 +34,25 @@ public: Timespan(); /// Creates a zero Timespan. - + Timespan(TimeDiff microseconds); /// Creates a Timespan. - + Timespan(long seconds, long microseconds); /// Creates a Timespan. Useful for creating /// a Timespan from a struct timeval. - + Timespan(int days, int hours, int minutes, int seconds, int microSeconds); /// Creates a Timespan. Timespan(const Timespan& timespan); /// Creates a Timespan from another one. + template + Timespan(const std::chrono::duration& dtime) : + _span(std::chrono::duration_cast(dtime).count()) {} + /// Creates a Timespan from std::chrono::duration + ~Timespan(); /// Destroys the Timespan. @@ -55,15 +61,23 @@ public: Timespan& operator = (TimeDiff microseconds); /// Assignment operator. - + Timespan& assign(int days, int hours, int minutes, int seconds, int microSeconds); /// Assigns a new span. - + Timespan& assign(long seconds, long microseconds); /// Assigns a new span. Useful for assigning /// from a struct timeval. - void swap(Timespan& timespan); + template + Timespan& assign(const std::chrono::duration& dtime) + /// Assigns a new span from std::chrono::duration. + { + _span = std::chrono::duration_cast(dtime).count(); + return *this; + } + + void swap(Timespan& timespan) noexcept; /// Swaps the Timespan with another one. bool operator == (const Timespan& ts) const; @@ -79,7 +93,7 @@ public: bool operator >= (TimeDiff microSeconds) const; bool operator < (TimeDiff microSeconds) const; bool operator <= (TimeDiff microSeconds) const; - + Timespan operator + (const Timespan& d) const; Timespan operator - (const Timespan& d) const; Timespan& operator += (const Timespan& d); @@ -92,39 +106,39 @@ public: int days() const; /// Returns the number of days. - + int hours() const; /// Returns the number of hours (0 to 23). - + int totalHours() const; /// Returns the total number of hours. - + int minutes() const; /// Returns the number of minutes (0 to 59). - + int totalMinutes() const; /// Returns the total number of minutes. - + int seconds() const; /// Returns the number of seconds (0 to 59). - + int totalSeconds() const; /// Returns the total number of seconds. - + int milliseconds() const; /// Returns the number of milliseconds (0 to 999). - + TimeDiff totalMilliseconds() const; /// Returns the total number of milliseconds. - + int microseconds() const; /// Returns the fractions of a millisecond /// in microseconds (0 to 999). - + int useconds() const; /// Returns the fractions of a second /// in microseconds (0 to 999999). - + TimeDiff totalMicroseconds() const; /// Returns the total number of microseconds. @@ -153,49 +167,49 @@ inline int Timespan::hours() const return int((_span/HOURS) % 24); } - + inline int Timespan::totalHours() const { return int(_span/HOURS); } - + inline int Timespan::minutes() const { return int((_span/MINUTES) % 60); } - + inline int Timespan::totalMinutes() const { return int(_span/MINUTES); } - + inline int Timespan::seconds() const { return int((_span/SECONDS) % 60); } - + inline int Timespan::totalSeconds() const { return int(_span/SECONDS); } - + inline int Timespan::milliseconds() const { return int((_span/MILLISECONDS) % 1000); } - + inline Timespan::TimeDiff Timespan::totalMilliseconds() const { return _span/MILLISECONDS; } - + inline int Timespan::microseconds() const { return int(_span % 1000); @@ -207,7 +221,7 @@ inline int Timespan::useconds() const return int(_span % 1000000); } - + inline Timespan::TimeDiff Timespan::totalMicroseconds() const { return _span; @@ -286,7 +300,7 @@ inline bool Timespan::operator <= (TimeDiff microSeconds) const } -inline void swap(Timespan& s1, Timespan& s2) +inline void swap(Timespan& s1, Timespan& s2) noexcept { s1.swap(s2); } diff --git a/Foundation/include/Poco/Timestamp.h b/Foundation/include/Poco/Timestamp.h index 0f869e1bd..089ae05b4 100644 --- a/Foundation/include/Poco/Timestamp.h +++ b/Foundation/include/Poco/Timestamp.h @@ -43,18 +43,18 @@ class Foundation_API Timestamp /// based and thus independent of the timezone /// in effect on the system. /// - /// The internal reference time is the Unix epoch, + /// The internal reference time is the Unix epoch, /// midnight, January 1, 1970. { public: - using TimeVal = Int64; + using TimeVal = Int64; /// Monotonic UTC time value in microsecond resolution, /// with base time midnight, January 1, 1970. - - using UtcTimeVal = Int64; + + using UtcTimeVal = Int64; /// Monotonic UTC time value in 100 nanosecond resolution, /// with base time midnight, October 15, 1582. - + using TimeDiff = Int64; /// Difference between two TimeVal values in microseconds. @@ -63,23 +63,23 @@ public: Timestamp(); /// Creates a timestamp with the current time. - + Timestamp(TimeVal tv); /// Creates a timestamp from the given time value /// (microseconds since midnight, January 1, 1970). - + Timestamp(const Timestamp& other); /// Copy constructor. - + ~Timestamp(); /// Destroys the timestamp - + Timestamp& operator = (const Timestamp& other); Timestamp& operator = (TimeVal tv); - - void swap(Timestamp& timestamp); + + void swap(Timestamp& timestamp) noexcept; /// Swaps the Timestamp with another one. - + void update(); /// Updates the Timestamp with the current time. @@ -89,7 +89,7 @@ public: bool operator >= (const Timestamp& ts) const; bool operator < (const Timestamp& ts) const; bool operator <= (const Timestamp& ts) const; - + Timestamp operator + (TimeDiff d) const; Timestamp operator + (const Timespan& span) const; Timestamp operator - (TimeDiff d) const; @@ -99,25 +99,25 @@ public: Timestamp& operator += (const Timespan& span); Timestamp& operator -= (TimeDiff d); Timestamp& operator -= (const Timespan& span); - + std::time_t epochTime() const; /// Returns the timestamp expressed in time_t. /// time_t base time is midnight, January 1, 1970. /// Resolution is one second. - + UtcTimeVal utcTime() const; /// Returns the timestamp expressed in UTC-based /// time. UTC base time is midnight, October 15, 1582. /// Resolution is 100 nanoseconds. - + TimeVal epochMicroseconds() const; /// Returns the timestamp expressed in microseconds /// since the Unix epoch, midnight, January 1, 1970. - + TimeDiff elapsed() const; /// Returns the time elapsed since the time denoted by /// the timestamp. Equivalent to Timestamp() - *this. - + bool isElapsed(TimeDiff interval) const; /// Returns true iff the given interval has passed /// since the time denoted by the timestamp. @@ -126,15 +126,15 @@ public: /// Returns the raw time value. /// /// Same as epochMicroseconds(). - + static Timestamp fromEpochTime(std::time_t t); /// Creates a timestamp from a std::time_t. - + static Timestamp fromUtcTime(UtcTimeVal val); /// Creates a timestamp from a UTC time value /// (100 nanosecond intervals since midnight, /// October 15, 1582). - + static TimeDiff resolution(); /// Returns the resolution in units per second. /// Since the timestamp has microsecond resolution, @@ -260,7 +260,7 @@ inline Timestamp::TimeDiff Timestamp::resolution() } -inline void swap(Timestamp& s1, Timestamp& s2) +inline void swap(Timestamp& s1, Timestamp& s2) noexcept { s1.swap(s2); } diff --git a/Foundation/include/Poco/Token.h b/Foundation/include/Poco/Token.h index 13540af91..be1eea239 100644 --- a/Foundation/include/Poco/Token.h +++ b/Foundation/include/Poco/Token.h @@ -50,13 +50,13 @@ public: INVALID_TOKEN, USER_TOKEN }; - + Token(); /// Creates the Token. virtual ~Token(); /// Destroys the Token. - + virtual bool start(char c, std::istream& istr); /// Checks if the given character (and, optionally, /// the next character in the input stream) start @@ -71,18 +71,18 @@ public: /// be set as the token's value. virtual void finish(std::istream& istr); - /// Builds the token by reading and appending + /// Builds the token by reading and appending /// the remaining characters from istr. - + virtual Class tokenClass() const; /// Returns the kind of the token. - + const std::string& tokenString() const; /// Returns the token's raw string. - + virtual std::string asString() const; /// Returns a string representation of the token. - + #if defined(POCO_HAVE_INT64) virtual Int64 asInteger64() const; /// Returns a 64-bit integer representation of the token. @@ -108,7 +108,7 @@ public: protected: std::string _value; - + private: Token(const Token&); Token& operator = (const Token&); diff --git a/Foundation/include/Poco/Tuple.h b/Foundation/include/Poco/Tuple.h index 000749695..ee1e7aee7 100644 --- a/Foundation/include/Poco/Tuple.h +++ b/Foundation/include/Poco/Tuple.h @@ -3088,7 +3088,7 @@ struct Tuple::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3198,7 +3198,7 @@ struct Tuple::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3305,7 +3305,7 @@ struct Tuple::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3409,7 +3409,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3510,7 +3510,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3608,7 +3608,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3703,7 +3703,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3795,7 +3795,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3884,7 +3884,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -3970,7 +3970,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -4053,7 +4053,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -4133,7 +4133,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -4210,7 +4210,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -4284,7 +4284,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -4355,7 +4355,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3), @@ -4423,7 +4423,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2), typename TypeWrapper::CONSTTYPE& t3 = POCO_TYPEWRAPPER_DEFAULTVALUE(T3)): @@ -4488,7 +4488,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1), typename TypeWrapper::CONSTTYPE& t2 = POCO_TYPEWRAPPER_DEFAULTVALUE(T2)): _data(t0, typename TypeListType::HeadType @@ -4550,7 +4550,7 @@ struct Tuple { } - Tuple(typename TypeWrapper::CONSTTYPE& t0, + Tuple(typename TypeWrapper::CONSTTYPE& t0, typename TypeWrapper::CONSTTYPE& t1 = POCO_TYPEWRAPPER_DEFAULTVALUE(T1)): _data(t0, typename TypeListType::HeadType(t1, NullTypeList())) { @@ -4598,7 +4598,7 @@ template struct Tuple { typedef TypeList Type; - + enum TupleLengthType { length = Type::length diff --git a/Foundation/include/Poco/TypeList.h b/Foundation/include/Poco/TypeList.h index 4a53737af..a4022c5a7 100644 --- a/Foundation/include/Poco/TypeList.h +++ b/Foundation/include/Poco/TypeList.h @@ -29,7 +29,7 @@ namespace Poco { -template +template struct TypeList; @@ -57,7 +57,7 @@ struct NullTypeList }; -template +template struct TypeList /// Compile Time List of Types { @@ -110,7 +110,7 @@ struct TypeList return tail < tl.tail; return false; } - + HeadType head; TailType tail; }; @@ -183,7 +183,7 @@ struct TypeListType<> }; -template +template struct Getter { template @@ -200,7 +200,7 @@ struct Getter }; -template <> +template <> struct Getter<0> { template @@ -217,11 +217,11 @@ struct Getter<0> }; -template +template struct TypeGetter; -template +template struct TypeGetter> { typedef typename TypeGetter::HeadType HeadType; @@ -229,7 +229,7 @@ struct TypeGetter> }; -template +template struct TypeGetter<0, TypeList> { typedef typename TypeList::HeadType HeadType; @@ -248,7 +248,7 @@ struct TypeLocator; /// /// if (2 == TypeLoc.value) ... /// - + template struct TypeLocator @@ -274,7 +274,7 @@ public: }; -template +template struct TypeAppender; /// TypeAppender appends T (type or a TypeList) to Head. /// @@ -318,7 +318,7 @@ struct TypeAppender, T> }; -template +template struct TypeOneEraser; /// TypeOneEraser erases the first occurrence of the type T in Head. /// Usage: @@ -350,7 +350,7 @@ struct TypeOneEraser, T> }; -template +template struct TypeAllEraser; /// TypeAllEraser erases all the occurrences of the type T in Head. /// Usage: @@ -382,7 +382,7 @@ struct TypeAllEraser, T> }; -template +template struct TypeDuplicateEraser; /// TypeDuplicateEraser erases all but the first occurrence of the type T in Head. /// Usage: @@ -393,7 +393,7 @@ struct TypeDuplicateEraser; /// -template <> +template <> struct TypeDuplicateEraser { typedef NullTypeList HeadType; diff --git a/Foundation/include/Poco/URI.h b/Foundation/include/Poco/URI.h index 258b0af9f..b36b935b4 100644 --- a/Foundation/include/Poco/URI.h +++ b/Foundation/include/Poco/URI.h @@ -40,15 +40,18 @@ class Foundation_API URI /// The class automatically performs a few normalizations on /// all URIs and URI parts passed to it: /// * scheme identifiers are converted to lower case - /// * percent-encoded characters are decoded (except for the query string) + /// * percent-encoded characters are decoded (except for the query string and fragment string) /// * optionally, dot segments are removed from paths (see normalize()) /// - /// Note that dealing with query strings requires some precautions, as, internally, - /// query strings are stored in percent-encoded form, while all other parts of the URI - /// are stored in decoded form. While parsing query strings from properly encoded URLs - /// generally works, explicitly setting query strings with setQuery() or extracting - /// query strings with getQuery() may lead to ambiguities. See the descriptions of - /// setQuery(), setRawQuery(), getQuery() and getRawQuery() for more information. + /// Note that dealing with query strings and fragment strings requires some precautions, + /// as, internally, query strings and fragment strings are stored in percent-encoded + /// form, while all other parts of the URI are stored in decoded form. While parsing + /// query strings and fragment strings from properly encoded URLs generally works, + /// explicitly setting query strings (fragment strings) with setQuery() (setFragment()) + /// or extracting query strings (fragment strings) with getQuery() (getFragment()) may + /// lead to ambiguities. See the descriptions of setQuery(), setRawQuery(), getQuery(), + /// getRawQuery(), setFragment(), setRawFragment(), getFragment() and getRawFragment() + /// for more information. { public: using QueryParameters = std::vector>; @@ -109,7 +112,7 @@ public: /// Parses and assigns an URI from the given string. Throws a /// SyntaxException if the uri is not valid. - void swap(URI& uri); + void swap(URI& uri) noexcept; /// Swaps the URI with another one. void clear(); @@ -220,7 +223,7 @@ public: /// /// The given query string must be properly percent-encoded. - QueryParameters getQueryParameters() const; + QueryParameters getQueryParameters(bool plusIsSpace = true) const; /// Returns the decoded query string parameters as a vector /// of name-value pairs. @@ -230,12 +233,20 @@ public: /// /// Calls addQueryParameter() for each parameter name and value. - const std::string& getFragment() const; + std::string getFragment() const; /// Returns the fragment part of the URI. void setFragment(const std::string& fragment); /// Sets the fragment part of the URI. + std::string getRawFragment() const; + /// Returns the fragment part of the URI in raw form. + + void setRawFragment(const std::string& fragment); + /// Sets the fragment part of the URI. + /// + /// The given fragment string must be properly percent-encoded + void setPathEtc(const std::string& pathEtc); /// Sets the path, query and fragment parts of the URI. @@ -400,7 +411,7 @@ inline const std::string& URI::getRawQuery() const } -inline const std::string& URI::getFragment() const +inline std::string URI::getRawFragment() const { return _fragment; } @@ -412,7 +423,7 @@ inline unsigned short URI::getSpecifiedPort() const } -inline void swap(URI& u1, URI& u2) +inline void swap(URI& u1, URI& u2) noexcept { u1.swap(u2); } diff --git a/Foundation/include/Poco/URIStreamFactory.h b/Foundation/include/Poco/URIStreamFactory.h index c5efa22bd..207bc3a93 100644 --- a/Foundation/include/Poco/URIStreamFactory.h +++ b/Foundation/include/Poco/URIStreamFactory.h @@ -55,7 +55,7 @@ protected: private: URIStreamFactory(const URIStreamFactory&); URIStreamFactory& operator = (const URIStreamFactory&); - + friend class URIStreamOpener; }; @@ -68,16 +68,16 @@ class Foundation_API URIRedirection public: URIRedirection(const std::string& uri); URIRedirection(const URIRedirection& redir); - + URIRedirection& operator = (const URIRedirection& redir); - void swap(URIRedirection& redir); - + void swap(URIRedirection& redir) noexcept; + const std::string& uri() const; /// Returns the new URI. - + private: URIRedirection(); - + std::string _uri; }; diff --git a/Foundation/include/Poco/URIStreamOpener.h b/Foundation/include/Poco/URIStreamOpener.h index 85de22b1a..009923882 100644 --- a/Foundation/include/Poco/URIStreamOpener.h +++ b/Foundation/include/Poco/URIStreamOpener.h @@ -44,7 +44,7 @@ public: { MAX_REDIRECTS = 10 }; - + URIStreamOpener(); /// Creates the URIStreamOpener and registers a FileStreamFactory /// for file URIs. @@ -93,7 +93,7 @@ public: /// /// Whoever calls the method is responsible for deleting /// the returned stream. - + void registerStreamFactory(const std::string& scheme, URIStreamFactory* pFactory); /// Registers a URIStreamFactory for the given scheme. If another factory /// has already been registered for the scheme, an ExistsException is thrown. @@ -106,7 +106,7 @@ public: /// /// Throws a NotFoundException if no URIStreamFactory has been registered /// for the given scheme. - + bool supportsScheme(const std::string& scheme); /// Returns true iff a URIStreamFactory for the given scheme /// has been registered. @@ -123,7 +123,7 @@ private: URIStreamOpener& operator = (const URIStreamOpener&); typedef std::map FactoryMap; - + FactoryMap _map; mutable FastMutex _mutex; }; diff --git a/Foundation/include/Poco/UTF16Encoding.h b/Foundation/include/Poco/UTF16Encoding.h index 0d38a71dd..5e95d0aa2 100644 --- a/Foundation/include/Poco/UTF16Encoding.h +++ b/Foundation/include/Poco/UTF16Encoding.h @@ -30,7 +30,7 @@ class Foundation_API UTF16Encoding: public TextEncoding /// /// When converting from UTF-16 to Unicode, surrogates are /// reported as they are - in other words, surrogate pairs - /// are not combined into one Unicode character. + /// are not combined into one Unicode character. /// When converting from Unicode to UTF-16, however, characters /// outside the 16-bit range are converted into a low and /// high surrogate. @@ -42,28 +42,28 @@ public: LITTLE_ENDIAN_BYTE_ORDER, NATIVE_BYTE_ORDER }; - + UTF16Encoding(ByteOrderType byteOrder = NATIVE_BYTE_ORDER); /// Creates and initializes the encoding for the given byte order. - + UTF16Encoding(int byteOrderMark); /// Creates and initializes the encoding for the byte-order /// indicated by the given byte-order mark, which is the Unicode /// character 0xFEFF. - + ~UTF16Encoding(); - + ByteOrderType getByteOrder() const; /// Returns the byte-order currently in use. - + void setByteOrder(ByteOrderType byteOrder); /// Sets the byte order. - + void setByteOrder(int byteOrderMark); /// Sets the byte order according to the given /// byte order mark, which is the Unicode /// character 0xFEFF. - + const char* canonicalName() const; bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; @@ -71,7 +71,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: bool _flipBytes; static const char* _names[]; diff --git a/Foundation/include/Poco/UTF32Encoding.h b/Foundation/include/Poco/UTF32Encoding.h index 6f8af525a..fc466b0d2 100644 --- a/Foundation/include/Poco/UTF32Encoding.h +++ b/Foundation/include/Poco/UTF32Encoding.h @@ -30,7 +30,7 @@ class Foundation_API UTF32Encoding: public TextEncoding /// /// When converting from UTF-32 to Unicode, surrogates are /// reported as they are - in other words, surrogate pairs - /// are not combined into one Unicode character. + /// are not combined into one Unicode character. { public: enum ByteOrderType @@ -39,28 +39,28 @@ public: LITTLE_ENDIAN_BYTE_ORDER, NATIVE_BYTE_ORDER }; - + UTF32Encoding(ByteOrderType byteOrder = NATIVE_BYTE_ORDER); /// Creates and initializes the encoding for the given byte order. - + UTF32Encoding(int byteOrderMark); /// Creates and initializes the encoding for the byte-order /// indicated by the given byte-order mark, which is the Unicode /// character 0xFEFF. - + ~UTF32Encoding(); - + ByteOrderType getByteOrder() const; /// Returns the byte-order currently in use. - + void setByteOrder(ByteOrderType byteOrder); /// Sets the byte order. - + void setByteOrder(int byteOrderMark); /// Sets the byte order according to the given /// byte order mark, which is the Unicode /// character 0xFEFF. - + const char* canonicalName() const; bool isA(const std::string& encodingName) const; const CharacterMap& characterMap() const; @@ -68,7 +68,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: bool _flipBytes; static const char* _names[]; diff --git a/Foundation/include/Poco/UTF8Encoding.h b/Foundation/include/Poco/UTF8Encoding.h index 66e29d2d0..984c163f4 100644 --- a/Foundation/include/Poco/UTF8Encoding.h +++ b/Foundation/include/Poco/UTF8Encoding.h @@ -42,10 +42,10 @@ public: static bool isLegal(const unsigned char *bytes, int length); /// Utility routine to tell whether a sequence of bytes is legal UTF-8. /// This must be called with the length pre-determined by the first byte. - /// The sequence is illegal right away if there aren't enough bytes + /// The sequence is illegal right away if there aren't enough bytes /// available. If presented with a length > 4, this function returns false. /// The Unicode definition of UTF-8 goes up to 4-byte sequences. - /// + /// /// Adapted from ftp://ftp.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c /// Copyright 2001-2004 Unicode, Inc. diff --git a/Foundation/include/Poco/UTF8String.h b/Foundation/include/Poco/UTF8String.h index 73898c65c..9b0ddb911 100644 --- a/Foundation/include/Poco/UTF8String.h +++ b/Foundation/include/Poco/UTF8String.h @@ -52,7 +52,7 @@ struct Foundation_API UTF8 static std::string& toUpperInPlace(std::string& str); static std::string toLower(const std::string& str); static std::string& toLowerInPlace(std::string& str); - + static void removeBOM(std::string& str); /// Remove the UTF-8 Byte Order Mark sequence (0xEF, 0xBB, 0xBF) /// from the beginning of the string, if it's there. diff --git a/Foundation/include/Poco/UTFString.h b/Foundation/include/Poco/UTFString.h index 7364583e7..09bc7d83c 100644 --- a/Foundation/include/Poco/UTFString.h +++ b/Foundation/include/Poco/UTFString.h @@ -39,12 +39,12 @@ struct UTF16CharTraits { c1 = c2; } - + static bool eq(char_type c1, char_type c2) { return c1 == c2; } - + static bool lt(char_type c1, char_type c2) { return c1 < c2; @@ -120,22 +120,22 @@ struct UTF16CharTraits { return eq_int_type(c, eof()) ? ~eof() : c; } - + static char_type to_char_type(int_type c) { return char_type(c); } - + static int_type to_int_type(char_type c) { return int_type(c); } - + static bool eq_int_type(int_type c1, int_type c2) { return c1 == c2; } - + static int_type eof() { return int_type(0xDFFF); @@ -156,12 +156,12 @@ struct UTF32CharTraits { c1 = c2; } - + static bool eq(char_type c1, char_type c2) { return c1 == c2; } - + static bool lt(char_type c1, char_type c2) { return c1 < c2; @@ -237,22 +237,22 @@ struct UTF32CharTraits { return eq_int_type(c, eof()) ? ~eof() : c; } - + static char_type to_char_type(int_type c) { return char_type(c); } - + static int_type to_int_type(char_type c) { return int_type(c); } - + static bool eq_int_type(int_type c1, int_type c2) { return c1 == c2; } - + static int_type eof() { return int_type(0xDFFF); diff --git a/Foundation/include/Poco/UUID.h b/Foundation/include/Poco/UUID.h index 2708a0003..0e72f31c2 100644 --- a/Foundation/include/Poco/UUID.h +++ b/Foundation/include/Poco/UUID.h @@ -37,7 +37,7 @@ class Foundation_API UUID /// as specified in Appendix A of the DCE 1.1 Remote Procedure /// Call Specification (http://www.opengroup.org/onlinepubs/9629399/), /// RFC 2518 (WebDAV), section 6.4.1 and the UUIDs and GUIDs internet - /// draft by Leach/Salz from February, 1998 + /// draft by Leach/Salz from February, 1998 /// (http://www.ics.uci.edu/~ejw/authoring/uuid-guid/draft-leach-uuids-guids-01.txt) /// and also http://tools.ietf.org/html/draft-mealling-uuid-urn-05 { @@ -49,18 +49,18 @@ public: UUID_NAME_BASED = 0x03, UUID_RANDOM = 0x04, UUID_NAME_BASED_SHA1 = 0x05 - + }; UUID(); /// Creates a nil (all zero) UUID. - + UUID(const UUID& uuid); /// Copy constructor. explicit UUID(const std::string& uuid); /// Parses the UUID from a string. - + explicit UUID(const char* uuid); /// Parses the UUID from a string. @@ -69,17 +69,17 @@ public: UUID& operator = (const UUID& uuid); /// Assignment operator. - - void swap(UUID& uuid); - /// Swaps the UUID with another one. - + + void swap(UUID& uuid) noexcept; + /// Swaps the UUID with another one. + void parse(const std::string& uuid); /// Parses the UUID from its string representation. bool tryParse(const std::string& uuid); /// Tries to interpret the given string as an UUID. /// If the UUID is syntactically valid, assigns the - /// members and returns true. Otherwise leaves the + /// members and returns true. Otherwise leaves the /// object unchanged and returns false. std::string toString() const; @@ -100,7 +100,7 @@ public: Version version() const; /// Returns the version of the UUID. - + int variant() const; /// Returns the variant number of the UUID: /// - 0 reserved for NCS backward compatibility @@ -114,7 +114,7 @@ public: bool operator <= (const UUID& uuid) const; bool operator > (const UUID& uuid) const; bool operator >= (const UUID& uuid) const; - + bool isNull() const; /// Returns true iff the UUID is nil (in other words, /// consists of all zeros). @@ -124,7 +124,7 @@ public: static const UUID& dns(); /// Returns the namespace identifier for the DNS namespace. - + static const UUID& uri(); /// Returns the namespace identifier for the URI (former URL) namespace. @@ -151,7 +151,7 @@ private: UInt16 _timeHiAndVersion; UInt16 _clockSeq; UInt8 _node[6]; - + friend class UUIDGenerator; }; @@ -207,7 +207,7 @@ inline bool UUID::isNull() const } -inline void swap(UUID& u1, UUID& u2) +inline void swap(UUID& u1, UUID& u2) noexcept { u1.swap(u2); } diff --git a/Foundation/include/Poco/UnbufferedStreamBuf.h b/Foundation/include/Poco/UnbufferedStreamBuf.h index 32bb38ab4..314a138f5 100644 --- a/Foundation/include/Poco/UnbufferedStreamBuf.h +++ b/Foundation/include/Poco/UnbufferedStreamBuf.h @@ -28,7 +28,7 @@ namespace Poco { -template +template class BasicUnbufferedStreamBuf: public std::basic_streambuf /// This is an implementation of an unbuffered streambuf /// that greatly simplifies the implementation of @@ -61,7 +61,7 @@ public: virtual int_type overflow(int_type c) { - if (c != char_traits::eof()) + if (c != char_traits::eof()) return writeToDevice(char_traits::to_char_type(c)); else return c; @@ -116,9 +116,9 @@ public: return c; } } - + virtual std::streamsize xsgetn(char_type* p, std::streamsize count) - /// Some platforms (for example, Compaq C++) have buggy implementations of + /// Some platforms (for example, Compaq C++) have buggy implementations of /// xsgetn that handle null buffers incorrectly. /// Anyway, it does not hurt to provide an optimized implementation /// of xsgetn for this streambuf implementation. @@ -146,7 +146,7 @@ private: { return char_traits::eof(); } - + virtual int_type writeToDevice(char_type) { return char_traits::eof(); @@ -154,7 +154,7 @@ private: int_type _pb; bool _ispb; - + BasicUnbufferedStreamBuf(const BasicUnbufferedStreamBuf&); BasicUnbufferedStreamBuf& operator = (const BasicUnbufferedStreamBuf&); }; diff --git a/Foundation/include/Poco/Unicode.h b/Foundation/include/Poco/Unicode.h index b6d027685..c6a534592 100644 --- a/Foundation/include/Poco/Unicode.h +++ b/Foundation/include/Poco/Unicode.h @@ -36,7 +36,7 @@ class Foundation_API Unicode { public: // Implementation note: the following definitions must be kept - // in sync with those from ucp.h (PCRE). + // in sync with those from pcre2_ucp.h (PCRE). enum CharacterCategory /// Unicode character categories. { @@ -83,7 +83,7 @@ public: UCP_PARAGRAPH_SEPARATOR, UCP_SPACE_SEPARATOR }; - + enum Script /// Unicode 7.0 script identifiers. { @@ -219,12 +219,12 @@ public: UCP_TIRHUTA, UCP_WARANG_CITI }; - + enum { UCP_MAX_CODEPOINT = 0x10FFFF }; - + struct CharacterProperties /// This structure holds the character properties /// of an Unicode character. @@ -237,27 +237,27 @@ public: static void properties(int ch, CharacterProperties& props); /// Return the Unicode character properties for the /// character with the given Unicode value. - + static bool isSpace(int ch); /// Returns true iff the given character is a separator. - + static bool isDigit(int ch); /// Returns true iff the given character is a numeric character. - + static bool isPunct(int ch); /// Returns true iff the given character is a punctuation character. - + static bool isAlpha(int ch); - /// Returns true iff the given character is a letter. - + /// Returns true iff the given character is a letter. + static bool isLower(int ch); /// Returns true iff the given character is a lowercase /// character. - + static bool isUpper(int ch); /// Returns true iff the given character is an uppercase /// character. - + static int toLower(int ch); /// If the given character is an uppercase character, /// return its lowercase counterpart, otherwise return @@ -312,7 +312,7 @@ inline bool Unicode::isLower(int ch) return props.category == UCP_LETTER && props.type == UCP_LOWER_CASE_LETTER; } - + inline bool Unicode::isUpper(int ch) { CharacterProperties props; diff --git a/Foundation/include/Poco/UnicodeConverter.h b/Foundation/include/Poco/UnicodeConverter.h index 0733b67b7..54cda407d 100644 --- a/Foundation/include/Poco/UnicodeConverter.h +++ b/Foundation/include/Poco/UnicodeConverter.h @@ -46,10 +46,10 @@ public: static void convert(const std::string& utf8String, UTF16String& utf16String); /// Converts the given UTF-8 encoded string into an UTF-16 encoded wide string. - static void convert(const char* utf8String, std::size_t length, UTF16String& utf16String); + static void convert(const char* utf8String, std::size_t length, UTF16String& utf16String); /// Converts the given UTF-8 encoded character sequence into an UTF-16 encoded wide string. - static void convert(const char* utf8String, UTF16String& utf16String); + static void convert(const char* utf8String, UTF16String& utf16String); /// Converts the given zero-terminated UTF-8 encoded character sequence into an UTF-16 encoded wide string. static void convert(const UTF16String& utf16String, std::string& utf8String); diff --git a/Foundation/include/Poco/UniqueAccessExpireCache.h b/Foundation/include/Poco/UniqueAccessExpireCache.h index a2d58f643..17db35072 100644 --- a/Foundation/include/Poco/UniqueAccessExpireCache.h +++ b/Foundation/include/Poco/UniqueAccessExpireCache.h @@ -26,19 +26,19 @@ namespace Poco { template < - class TKey, + class TKey, class TValue, - class TMutex = FastMutex, + class TMutex = FastMutex, class TEventMutex = FastMutex -> +> class UniqueAccessExpireCache: public AbstractCache, TMutex, TEventMutex> /// An UniqueAccessExpireCache caches entries for a given time span. In contrast - /// to ExpireCache which only allows to set a per cache expiration value, it allows to define + /// to ExpireCache which only allows to set a per cache expiration value, it allows to define /// expiration per CacheEntry. /// Each TValue object must thus offer the following method: - /// + /// /// const Poco::Timespan& getTimeout() const; - /// + /// /// which returns the relative timespan for how long the entry should be valid without being accessed! /// The absolute expire timepoint is calculated as now() + getTimeout(). /// Accessing an object will update this absolute expire timepoint. @@ -48,7 +48,7 @@ class UniqueAccessExpireCache: public AbstractCache class UniqueAccessExpireLRUCache: public AbstractCache, TMutex, TEventMutex> @@ -38,9 +38,9 @@ class UniqueAccessExpireLRUCache: public AbstractCache, TMutex, TEventMutex>(StrategyCollection()) { this->_strategy.pushBack(new LRUStrategy(cacheSize)); diff --git a/Foundation/include/Poco/UniqueAccessExpireStrategy.h b/Foundation/include/Poco/UniqueAccessExpireStrategy.h index d20f2185e..811a350e5 100644 --- a/Foundation/include/Poco/UniqueAccessExpireStrategy.h +++ b/Foundation/include/Poco/UniqueAccessExpireStrategy.h @@ -33,18 +33,18 @@ namespace Poco { -template < +template < class TKey, class TValue > class UniqueAccessExpireStrategy: public AbstractStrategy /// An UniqueExpireStrategy implements time based expiration of cache entries. In contrast - /// to ExpireStrategy which only allows to set a per cache expiration value, it allows to define + /// to ExpireStrategy which only allows to set a per cache expiration value, it allows to define /// expiration per CacheEntry. /// Each TValue object must thus offer the following method: - /// + /// /// const Poco::Timestamp& getTimeout() const; - /// + /// /// which returns the timespan for how long an object will be valid without being accessed. { public: @@ -71,7 +71,7 @@ public: // value will expire, even insert negative values! Timestamp expire; expire += args.value().getTimeout().totalMicroseconds(); - + IndexIterator it = _keyIndex.insert(std::make_pair(expire, std::make_pair(args.key(), args.value().getTimeout()))); std::pair stat = _keys.insert(std::make_pair(args.key(), it)); if (!stat.second) diff --git a/Foundation/include/Poco/UniqueExpireCache.h b/Foundation/include/Poco/UniqueExpireCache.h index 613f9e215..9c1b67fb9 100644 --- a/Foundation/include/Poco/UniqueExpireCache.h +++ b/Foundation/include/Poco/UniqueExpireCache.h @@ -26,19 +26,19 @@ namespace Poco { template < - class TKey, + class TKey, class TValue, - class TMutex = FastMutex, + class TMutex = FastMutex, class TEventMutex = FastMutex -> +> class UniqueExpireCache: public AbstractCache, TMutex, TEventMutex> /// An UniqueExpireCache caches entries for a given time amount. In contrast - /// to ExpireCache which only allows to set a per cache expiration value, it allows to define + /// to ExpireCache which only allows to set a per cache expiration value, it allows to define /// expiration per CacheEntry. /// Each TValue object must thus offer the following method: - /// + /// /// const Poco::Timestamp& getExpiration() const; - /// + /// /// which returns the absolute timepoint when the entry will be invalidated. /// Accessing an object will NOT update this absolute expire timepoint. /// You can use the Poco::ExpirationDecorator to add the getExpiration @@ -47,7 +47,7 @@ class UniqueExpireCache: public AbstractCache class UniqueExpireLRUCache: public AbstractCache, TMutex, TEventMutex> @@ -38,9 +38,9 @@ class UniqueExpireLRUCache: public AbstractCache class UniqueExpireStrategy: public AbstractStrategy /// An UniqueExpireStrategy implements time based expiration of cache entries. In contrast - /// to ExpireStrategy which only allows to set a per cache expiration value, it allows to define + /// to ExpireStrategy which only allows to set a per cache expiration value, it allows to define /// expiration per CacheEntry. /// Each TValue object must thus offer the following method: - /// + /// /// const Poco::Timestamp& getExpiration() const; - /// + /// /// which returns the absolute timepoint when the entry will be invalidated. { public: diff --git a/Foundation/include/Poco/ValidArgs.h b/Foundation/include/Poco/ValidArgs.h index 7928a0fe8..04afd775a 100644 --- a/Foundation/include/Poco/ValidArgs.h +++ b/Foundation/include/Poco/ValidArgs.h @@ -29,13 +29,13 @@ class ValidArgs { public: ValidArgs(const TKey& key): - _key(key), + _key(key), _isValid(true) { } - ValidArgs(const ValidArgs& args): - _key(args._key), + ValidArgs(const ValidArgs& args): + _key(args._key), _isValid(args._isValid) { } @@ -43,7 +43,7 @@ public: ~ValidArgs() { } - + const TKey& key() const { return _key; diff --git a/Foundation/include/Poco/Version.h b/Foundation/include/Poco/Version.h index 9ef9c629b..cb014e985 100644 --- a/Foundation/include/Poco/Version.h +++ b/Foundation/include/Poco/Version.h @@ -35,7 +35,7 @@ // Ax: alpha releases // Bx: beta releases // -#define POCO_VERSION 0x010B0300 +#define POCO_VERSION 0x010C0000 #endif // Foundation_Version_INCLUDED diff --git a/Foundation/include/Poco/Void.h b/Foundation/include/Poco/Void.h index fa0cd31af..fa3911a71 100644 --- a/Foundation/include/Poco/Void.h +++ b/Foundation/include/Poco/Void.h @@ -25,7 +25,7 @@ namespace Poco { class Foundation_API Void - /// A dummy class with value-type semantics, + /// A dummy class with value-type semantics, /// mostly useful as a template argument. /// /// This class is typically used together with ActiveMethod, @@ -38,9 +38,9 @@ public: Void(const Void& v); /// Creates the Void from another Void. /// - /// The philosophical aspects of this operation + /// The philosophical aspects of this operation /// remain undiscussed for now. - + ~Void(); /// Destroys the Void. diff --git a/Foundation/include/Poco/Windows1250Encoding.h b/Foundation/include/Poco/Windows1250Encoding.h index c40a42884..35a470740 100644 --- a/Foundation/include/Poco/Windows1250Encoding.h +++ b/Foundation/include/Poco/Windows1250Encoding.h @@ -39,7 +39,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/Windows1251Encoding.h b/Foundation/include/Poco/Windows1251Encoding.h index 87510a9d9..d44ba8d2b 100644 --- a/Foundation/include/Poco/Windows1251Encoding.h +++ b/Foundation/include/Poco/Windows1251Encoding.h @@ -39,7 +39,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/Windows1252Encoding.h b/Foundation/include/Poco/Windows1252Encoding.h index a5e290141..cd35a29d7 100644 --- a/Foundation/include/Poco/Windows1252Encoding.h +++ b/Foundation/include/Poco/Windows1252Encoding.h @@ -38,7 +38,7 @@ public: int convert(int ch, unsigned char* bytes, int length) const; int queryConvert(const unsigned char* bytes, int length) const; int sequenceLength(const unsigned char* bytes, int length) const; - + private: static const char* _names[]; static const CharacterMap _charMap; diff --git a/Foundation/include/Poco/WindowsConsoleChannel.h b/Foundation/include/Poco/WindowsConsoleChannel.h index 4c7aef662..41c2f88fe 100644 --- a/Foundation/include/Poco/WindowsConsoleChannel.h +++ b/Foundation/include/Poco/WindowsConsoleChannel.h @@ -39,7 +39,7 @@ class Foundation_API WindowsConsoleChannel: public Channel /// class, which cannot handle UTF-8 encoded messages on Windows. /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is contained + /// appropriate Formatter to control what is contained /// in the text. /// /// Only available on Windows platforms. @@ -52,7 +52,7 @@ public: void log(const Message& msg); /// Logs the given message to the channel's stream. - + protected: ~WindowsConsoleChannel(); @@ -79,7 +79,7 @@ class Foundation_API WindowsColorConsoleChannel: public Channel /// property to true (default). Furthermore, colors can be /// configured by setting the following properties /// (default values are given in parenthesis): - /// + /// /// * traceColor (gray) /// * debugColor (gray) /// * informationColor (default) @@ -90,7 +90,7 @@ class Foundation_API WindowsColorConsoleChannel: public Channel /// * fatalColor (lightRed) /// /// The following color values are supported: - /// + /// /// * default /// * black /// * red @@ -110,7 +110,7 @@ class Foundation_API WindowsColorConsoleChannel: public Channel /// * white /// /// Chain this channel to a FormattingChannel with an - /// appropriate Formatter to control what is contained + /// appropriate Formatter to control what is contained /// in the text. /// /// Only available on Windows platforms. @@ -125,8 +125,8 @@ public: /// Logs the given message to the channel's stream. void setProperty(const std::string& name, const std::string& value); - /// Sets the property with the given name. - /// + /// Sets the property with the given name. + /// /// The following properties are supported: /// * enableColors: Enable or disable colors. /// * traceColor: Specify color for trace messages. @@ -144,7 +144,7 @@ public: /// Returns the value of the property with the given name. /// See setProperty() for a description of the supported /// properties. - + protected: enum Color { diff --git a/Foundation/include/Poco/ordered_hash.h b/Foundation/include/Poco/ordered_hash.h index e728c6156..560de7991 100644 --- a/Foundation/include/Poco/ordered_hash.h +++ b/Foundation/include/Poco/ordered_hash.h @@ -1,18 +1,18 @@ /** * MIT License - * + * * Copyright (c) 2017 Tessil - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -59,7 +59,7 @@ /* - * Only activate tsl_assert if TSL_DEBUG is defined. + * Only activate tsl_assert if TSL_DEBUG is defined. * This way we avoid the performance hit when NDEBUG is not defined with assert as tsl_assert is used a lot * (people usually compile with "-O3" and not "-O3 -DNDEBUG"). */ @@ -75,7 +75,7 @@ namespace tsl { namespace detail_ordered_hash { - + template struct make_void { using type = void; @@ -102,9 +102,9 @@ struct is_vector::max() - NB_RESERVED_INDEXES; } - + private: static const index_type EMPTY_MARKER_INDEX = std::numeric_limits::max(); static const std::size_t NB_RESERVED_INDEXES = 1; - + index_type m_index; truncated_hash_type m_hash; }; @@ -177,27 +177,27 @@ private: /** * Internal common class used by ordered_map and ordered_set. - * + * * ValueType is what will be stored by ordered_hash (usually std::pair for map and Key for set). - * + * * KeySelect should be a FunctionObject which takes a ValueType in parameter and return a reference to the key. - * - * ValueSelect should be a FunctionObject which takes a ValueType in parameter and return a reference to the value. + * + * ValueSelect should be a FunctionObject which takes a ValueType in parameter and return a reference to the value. * ValueSelect should be void if there is no value (in set for example). - * - * ValueTypeContainer is the container which will be used to store ValueType values. + * + * ValueTypeContainer is the container which will be used to store ValueType values. * Usually a std::deque or std::vector. - * - * - * + * + * + * * The orderd_hash structure is a hash table which preserves the order of insertion of the elements. * To do so, it stores the values in the ValueTypeContainer (m_values) using emplace_back at each - * insertion of a new element. Another structure (m_buckets of type std::vector) will - * serve as buckets array for the hash table part. Each bucket stores an index which corresponds to + * insertion of a new element. Another structure (m_buckets of type std::vector) will + * serve as buckets array for the hash table part. Each bucket stores an index which corresponds to * the index in m_values where the bucket's value is and the (truncated) hash of this value. An index * is used instead of a pointer to the value to reduce the size of each bucket entry. - * - * To resolve collisions in the buckets array, the structures use robin hood linear probing with + * + * To resolve collisions in the buckets array, the structures use robin hood linear probing with * backward shift deletion. */ template using has_mapped_type = typename std::integral_constant::value>; - - static_assert(std::is_same::value, + + static_assert(std::is_same::value, "ValueTypeContainer::value_type != ValueType."); - static_assert(std::is_same::value, + static_assert(std::is_same::value, "ValueTypeContainer::allocator_type != Allocator."); - - + + public: template class ordered_iterator; - + using key_type = typename KeySelect::key_type; using value_type = ValueType; using size_type = std::size_t; @@ -237,34 +237,34 @@ public: using const_iterator = ordered_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - + using values_container_type = ValueTypeContainer; - + public: template class ordered_iterator { friend class ordered_hash; - + private: - using iterator = typename std::conditional::type; - - + + ordered_iterator(iterator it) noexcept: m_iterator(it) { } - + public: using iterator_category = std::random_access_iterator_tag; using value_type = const typename ordered_hash::value_type; using difference_type = typename iterator::difference_type; using reference = value_type&; using pointer = value_type*; - - + + ordered_iterator() noexcept { } - + ordered_iterator(const ordered_iterator& other) noexcept: m_iterator(other.m_iterator) { } @@ -281,77 +281,77 @@ public: typename U::value_type& value() { return U()(*m_iterator); } - + reference operator*() const { return *m_iterator; } pointer operator->() const { return m_iterator.operator->(); } - + ordered_iterator& operator++() { ++m_iterator; return *this; } ordered_iterator& operator--() { --m_iterator; return *this; } - + ordered_iterator operator++(int) { ordered_iterator tmp(*this); ++(*this); return tmp; } ordered_iterator operator--(int) { ordered_iterator tmp(*this); --(*this); return tmp; } - + reference operator[](difference_type n) const { return m_iterator[n]; } - + ordered_iterator& operator+=(difference_type n) { m_iterator += n; return *this; } ordered_iterator& operator-=(difference_type n) { m_iterator -= n; return *this; } - + ordered_iterator operator+(difference_type n) { ordered_iterator tmp(*this); tmp += n; return tmp; } ordered_iterator operator-(difference_type n) { ordered_iterator tmp(*this); tmp -= n; return tmp; } - - friend bool operator==(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator == rhs.m_iterator; - } - - friend bool operator!=(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator != rhs.m_iterator; - } - - friend bool operator<(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator < rhs.m_iterator; - } - - friend bool operator>(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator > rhs.m_iterator; - } - - friend bool operator<=(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator <= rhs.m_iterator; - } - - friend bool operator>=(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator >= rhs.m_iterator; + + friend bool operator==(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator == rhs.m_iterator; } - friend ordered_iterator operator+(difference_type n, const ordered_iterator& it) { + friend bool operator!=(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator != rhs.m_iterator; + } + + friend bool operator<(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator < rhs.m_iterator; + } + + friend bool operator>(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator > rhs.m_iterator; + } + + friend bool operator<=(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator <= rhs.m_iterator; + } + + friend bool operator>=(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator >= rhs.m_iterator; + } + + friend ordered_iterator operator+(difference_type n, const ordered_iterator& it) { return n + it.m_iterator; } - friend difference_type operator-(const ordered_iterator& lhs, const ordered_iterator& rhs) { - return lhs.m_iterator - rhs.m_iterator; + friend difference_type operator-(const ordered_iterator& lhs, const ordered_iterator& rhs) { + return lhs.m_iterator - rhs.m_iterator; } private: iterator m_iterator; }; - - + + private: - using buckets_container_allocator = typename - std::allocator_traits::template rebind_alloc; - + using buckets_container_allocator = typename + std::allocator_traits::template rebind_alloc; + using buckets_container_type = std::vector; - - + + using truncated_hash_type = typename bucket_entry::truncated_hash_type; using index_type = typename bucket_entry::index_type; - + public: - ordered_hash(size_type bucket_count, + ordered_hash(size_type bucket_count, const Hash& hash, const KeyEqual& equal, const Allocator& alloc, - float max_load_factor): Hash(hash), KeyEqual(equal), m_buckets(alloc), + float max_load_factor): Hash(hash), KeyEqual(equal), m_buckets(alloc), m_values(alloc), m_grow_on_next_insert(false) { bucket_count = round_up_to_power_of_two(bucket_count); @@ -359,86 +359,86 @@ public: throw std::length_error("The map exceeds its maxmimum size."); } tsl_assert(bucket_count > 0); - + m_buckets.resize(bucket_count); - m_mask = bucket_count - 1; - + m_mask = bucket_count - 1; + this->max_load_factor(max_load_factor); } - + allocator_type get_allocator() const { return m_values.get_allocator(); } - - + + /* * Iterators */ iterator begin() noexcept { return iterator(m_values.begin()); } - + const_iterator begin() const noexcept { return cbegin(); } - + const_iterator cbegin() const noexcept { return const_iterator(m_values.cbegin()); } - + iterator end() noexcept { return iterator(m_values.end()); } - + const_iterator end() const noexcept { return cend(); } - + const_iterator cend() const noexcept { return const_iterator(m_values.cend()); - } - - + } + + reverse_iterator rbegin() noexcept { return reverse_iterator(m_values.end()); } - + const_reverse_iterator rbegin() const noexcept { return rcbegin(); } - + const_reverse_iterator rcbegin() const noexcept { return const_reverse_iterator(m_values.cend()); } - + reverse_iterator rend() noexcept { return reverse_iterator(m_values.begin()); } - + const_reverse_iterator rend() const noexcept { return rcend(); } - + const_reverse_iterator rcend() const noexcept { return const_reverse_iterator(m_values.cbegin()); - } - - + } + + /* * Capacity */ bool empty() const noexcept { return m_values.empty(); } - + size_type size() const noexcept { return m_values.size(); } - + size_type max_size() const noexcept { return std::min(bucket_entry::max_size(), m_values.max_size()); } - + /* * Modifiers @@ -447,100 +447,100 @@ public: for(auto& bucket: m_buckets) { bucket.clear(); } - + m_values.clear(); m_grow_on_next_insert = false; } - + template std::pair insert(P&& value) { return insert_impl(KeySelect()(value), std::forward

(value)); } - + template - iterator insert(const_iterator hint, P&& value) { - if(hint != cend() && compare_keys(KeySelect()(*hint), KeySelect()(value))) { - return mutable_iterator(hint); + iterator insert(const_iterator hint, P&& value) { + if(hint != cend() && compare_keys(KeySelect()(*hint), KeySelect()(value))) { + return mutable_iterator(hint); } - - return insert(std::forward

(value)).first; + + return insert(std::forward

(value)).first; } - + template void insert(InputIt first, InputIt last) { - if(std::is_base_of::iterator_category>::value) + if(std::is_base_of::iterator_category>::value) { const auto nb_elements_insert = std::distance(first, last); const size_type nb_free_buckets = m_load_threshold - size(); tsl_assert(m_load_threshold >= size()); - + if(nb_elements_insert > 0 && nb_free_buckets < size_type(nb_elements_insert)) { reserve(size() + size_type(nb_elements_insert)); } } - + for(; first != last; ++first) { insert(*first); } } - - - + + + template std::pair insert_or_assign(K&& key, M&& value) { auto it = try_emplace(std::forward(key), std::forward(value)); if(!it.second) { it.first.value() = std::forward(value); } - + return it; } - + template iterator insert_or_assign(const_iterator hint, K&& key, M&& obj) { - if(hint != cend() && compare_keys(KeySelect()(*hint), key)) { - auto it = mutable_iterator(hint); + if(hint != cend() && compare_keys(KeySelect()(*hint), key)) { + auto it = mutable_iterator(hint); it.value() = std::forward(obj); - + return it; } - + return insert_or_assign(std::forward(key), std::forward(obj)).first; } - - - + + + template std::pair emplace(Args&&... args) { return insert(value_type(std::forward(args)...)); } - + template - iterator emplace_hint(const_iterator hint, Args&&... args) { + iterator emplace_hint(const_iterator hint, Args&&... args) { return insert(hint, value_type(std::forward(args)...)); } - - - + + + template std::pair try_emplace(K&& key, Args&&... value_args) { - return insert_impl(key, std::piecewise_construct, - std::forward_as_tuple(std::forward(key)), - std::forward_as_tuple(std::forward(value_args)...)); + return insert_impl(key, std::piecewise_construct, + std::forward_as_tuple(std::forward(key)), + std::forward_as_tuple(std::forward(value_args)...)); } - + template iterator try_emplace(const_iterator hint, K&& key, Args&&... args) { - if(hint != cend() && compare_keys(KeySelect()(*hint), key)) { - return mutable_iterator(hint); + if(hint != cend() && compare_keys(KeySelect()(*hint), key)) { + return mutable_iterator(hint); } - + return try_emplace(std::forward(key), std::forward(args)...).first; } - - - + + + /** * Here to avoid `template size_type erase(const K& key)` being used when * we use a iterator instead of a const_iterator. @@ -548,19 +548,19 @@ public: iterator erase(iterator pos) { return erase(const_iterator(pos)); } - + iterator erase(const_iterator pos) { tsl_assert(pos != cend()); - + const std::size_t index_erase = iterator_to_index(pos); - + auto it_bucket = find_key(pos.key(), hash_key(pos.key())); tsl_assert(it_bucket != m_buckets.end()); - + erase_value_from_bucket(it_bucket); - + /* - * One element was removed from m_values, due to the left shift the next element + * One element was removed from m_values, due to the left shift the next element * is now at the position of the previous element (or end if none). */ return begin() + index_erase; @@ -570,22 +570,22 @@ public: if(first == last) { return mutable_iterator(first); } - + tsl_assert(std::distance(first, last) > 0); const std::size_t start_index = iterator_to_index(first); const std::size_t nb_values = std::size_t(std::distance(first, last)); const std::size_t end_index = start_index + nb_values; - + // Delete all values -#ifdef TSL_NO_CONTAINER_ERASE_CONST_ITERATOR - auto next_it = m_values.erase(mutable_iterator(first).m_iterator, mutable_iterator(last).m_iterator); +#ifdef TSL_NO_CONTAINER_ERASE_CONST_ITERATOR + auto next_it = m_values.erase(mutable_iterator(first).m_iterator, mutable_iterator(last).m_iterator); #else auto next_it = m_values.erase(first.m_iterator, last.m_iterator); #endif - + /* * Mark the buckets corresponding to the values as empty and do a backward shift. - * + * * Also, the erase operation on m_values has shifted all the values on the right of last.m_iterator. * Adapt the indexes for these values. */ @@ -607,24 +607,24 @@ public: ibucket++; } } - + return iterator(next_it); } - + template size_type erase(const K& key) { return erase(key, hash_key(key)); } - + template size_type erase(const K& key, std::size_t hash) { return erase_impl(key, hash); } - - void swap(ordered_hash& other) { + + void swap(ordered_hash& other) noexcept { using std::swap; - + swap(static_cast(*this), static_cast(other)); swap(static_cast(*this), static_cast(other)); swap(m_buckets, other.m_buckets); @@ -634,28 +634,28 @@ public: swap(m_max_load_factor, other.m_max_load_factor); swap(m_load_threshold, other.m_load_threshold); } - - - + + + /* * Lookup - */ + */ template::value>::type* = nullptr> typename U::value_type& at(const K& key) { return at(key, hash_key(key)); } - + template::value>::type* = nullptr> typename U::value_type& at(const K& key, std::size_t hash) { return const_cast(static_cast(this)->at(key, hash)); } - + template::value>::type* = nullptr> const typename U::value_type& at(const K& key) const { return at(key, hash_key(key)); } - + template::value>::type* = nullptr> const typename U::value_type& at(const K& key, std::size_t hash) const { auto it = find(key, hash); @@ -666,19 +666,19 @@ public: throw std::out_of_range("Couldn't find the key."); } } - - + + template::value>::type* = nullptr> typename U::value_type& operator[](K&& key) { return try_emplace(std::forward(key)).first.value(); } - - + + template size_type count(const K& key) const { return count(key, hash_key(key)); } - + template size_type count(const K& key, std::size_t hash) const { if(find(key, hash) == cend()) { @@ -688,282 +688,282 @@ public: return 1; } } - + template iterator find(const K& key) { return find(key, hash_key(key)); } - + template iterator find(const K& key, std::size_t hash) { auto it_bucket = find_key(key, hash); return (it_bucket != m_buckets.end())?iterator(m_values.begin() + it_bucket->index()):end(); } - + template const_iterator find(const K& key) const { return find(key, hash_key(key)); } - + template const_iterator find(const K& key, std::size_t hash) const { auto it_bucket = find_key(key, hash); return (it_bucket != m_buckets.cend())?const_iterator(m_values.begin() + it_bucket->index()):end(); } - - + + template std::pair equal_range(const K& key) { return equal_range(key, hash_key(key)); } - + template std::pair equal_range(const K& key, std::size_t hash) { iterator it = find(key, hash); return std::make_pair(it, (it == end())?it:std::next(it)); } - + template std::pair equal_range(const K& key) const { return equal_range(key, hash_key(key)); } - + template std::pair equal_range(const K& key, std::size_t hash) const { const_iterator it = find(key, hash); return std::make_pair(it, (it == cend())?it:std::next(it)); - } - - + } + + /* - * Bucket interface + * Bucket interface */ size_type bucket_count() const { - return m_buckets.size(); + return m_buckets.size(); } - + size_type max_bucket_count() const { return m_buckets.max_size(); - } - + } + /* - * Hash policy + * Hash policy */ float load_factor() const { return float(size())/float(bucket_count()); } - + float max_load_factor() const { return m_max_load_factor; } - + void max_load_factor(float ml) { m_max_load_factor = std::max(0.1f, std::min(ml, 0.95f)); m_load_threshold = size_type(float(bucket_count())*m_max_load_factor); } - + void rehash(size_type count) { count = std::max(count, size_type(std::ceil(float(size())/max_load_factor()))); rehash_impl(count); } - + void reserve(size_type count) { reserve_space_for_values(count); - + count = size_type(std::ceil(float(count)/max_load_factor())); rehash(count); } - - + + /* * Observers */ hasher hash_function() const { return static_cast(*this); } - + key_equal key_eq() const { return static_cast(*this); } - + /* * Other */ iterator mutable_iterator(const_iterator pos) { return iterator(m_values.begin() + iterator_to_index(pos)); } - + iterator nth(size_type index) { return iterator(m_values.begin() + index); } - + const_iterator nth(size_type index) const { return const_iterator(m_values.cbegin() + index); } - + const_reference front() const { return m_values.front(); } - + const_reference back() const { return m_values.back(); } - + const values_container_type& values_container() const noexcept { return m_values; } - - template::value>::type* = nullptr> + + template::value>::type* = nullptr> const typename values_container_type::value_type* data() const noexcept { return m_values.data(); } - - template::value>::type* = nullptr> + + template::value>::type* = nullptr> size_type capacity() const noexcept { return m_values.capacity(); } - + void shrink_to_fit() { m_values.shrink_to_fit(); } - - + + template std::pair insert_at_position(const_iterator pos, P&& value) { return insert_at_position_impl(pos.m_iterator, KeySelect()(value), std::forward

(value)); } - + template std::pair emplace_at_position(const_iterator pos, Args&&... args) { return insert_at_position(pos, value_type(std::forward(args)...)); } - + template std::pair try_emplace_at_position(const_iterator pos, K&& key, Args&&... value_args) { - return insert_at_position_impl(pos.m_iterator, key, - std::piecewise_construct, - std::forward_as_tuple(std::forward(key)), + return insert_at_position_impl(pos.m_iterator, key, + std::piecewise_construct, + std::forward_as_tuple(std::forward(key)), std::forward_as_tuple(std::forward(value_args)...)); } - + void pop_back() { tsl_assert(!empty()); erase(std::prev(end())); } - - + + /** * Here to avoid `template size_type unordered_erase(const K& key)` being used when * we use a iterator instead of a const_iterator. - */ + */ iterator unordered_erase(iterator pos) { return unordered_erase(const_iterator(pos)); } - + iterator unordered_erase(const_iterator pos) { const std::size_t index_erase = iterator_to_index(pos); unordered_erase(pos.key()); - + /* * One element was deleted, index_erase now points to the next element as the elements after * the deleted value were shifted to the left in m_values (will be end() if we deleted the last element). */ return begin() + index_erase; } - + template size_type unordered_erase(const K& key) { return unordered_erase(key, hash_key(key)); } - + template size_type unordered_erase(const K& key, std::size_t hash) { auto it_bucket_key = find_key(key, hash); if(it_bucket_key == m_buckets.end()) { return 0; } - + /** - * If we are not erasing the last element in m_values, we swap - * the element we are erasing with the last element. We then would + * If we are not erasing the last element in m_values, we swap + * the element we are erasing with the last element. We then would * just have to do a pop_back() in m_values. */ if(!compare_keys(key, KeySelect()(back()))) { auto it_bucket_last_elem = find_key(KeySelect()(back()), hash_key(KeySelect()(back()))); tsl_assert(it_bucket_last_elem != m_buckets.end()); tsl_assert(it_bucket_last_elem->index() == m_values.size() - 1); - + using std::swap; swap(m_values[it_bucket_key->index()], m_values[it_bucket_last_elem->index()]); swap(it_bucket_key->index_ref(), it_bucket_last_elem->index_ref()); } - + erase_value_from_bucket(it_bucket_key); - + return 1; } - + friend bool operator==(const ordered_hash& lhs, const ordered_hash& rhs) { return lhs.m_values == rhs.m_values; } - + friend bool operator!=(const ordered_hash& lhs, const ordered_hash& rhs) { return lhs.m_values != rhs.m_values; } - + friend bool operator<(const ordered_hash& lhs, const ordered_hash& rhs) { return lhs.m_values < rhs.m_values; } - + friend bool operator<=(const ordered_hash& lhs, const ordered_hash& rhs) { return lhs.m_values <= rhs.m_values; } - + friend bool operator>(const ordered_hash& lhs, const ordered_hash& rhs) { return lhs.m_values > rhs.m_values; } - + friend bool operator>=(const ordered_hash& lhs, const ordered_hash& rhs) { return lhs.m_values >= rhs.m_values; } - - + + private: template std::size_t hash_key(const K& key) const { return Hash::operator()(key); } - + template bool compare_keys(const K1& key1, const K2& key2) const { return KeyEqual::operator()(key1, key2); } - + template typename buckets_container_type::iterator find_key(const K& key, std::size_t hash) { auto it = static_cast(this)->find_key(key, hash); return m_buckets.begin() + std::distance(m_buckets.cbegin(), it); } - + /** * Return bucket which has the key 'key' or m_buckets.end() if none. - * + * * From the bucket_for_hash, search for the value until we either find an empty bucket * or a bucket which has a value with a distance from its ideal bucket longer * than the probe length for the value we are looking for. */ template typename buckets_container_type::const_iterator find_key(const K& key, std::size_t hash) const { - for(std::size_t ibucket = bucket_for_hash(hash), dist_from_ideal_bucket = 0; ; - ibucket = next_bucket(ibucket), dist_from_ideal_bucket++) + for(std::size_t ibucket = bucket_for_hash(hash), dist_from_ideal_bucket = 0; ; + ibucket = next_bucket(ibucket), dist_from_ideal_bucket++) { if(m_buckets[ibucket].empty()) { return m_buckets.end(); } - else if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) && - compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()]))) + else if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) && + compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()]))) { return m_buckets.begin() + ibucket; } @@ -972,47 +972,47 @@ private: } } } - + void rehash_impl(size_type bucket_count) { bucket_count = round_up_to_power_of_two(bucket_count); tsl_assert(bucket_count > 0); - + if(bucket_count == this->bucket_count()) { return; } - + if(bucket_count > max_bucket_count()) { throw std::length_error("The map exceeds its maxmimum size."); } - - + + buckets_container_type old_buckets(bucket_count); m_buckets.swap(old_buckets); // Everything should be noexcept from here. - + m_mask = bucket_count - 1; this->max_load_factor(m_max_load_factor); m_grow_on_next_insert = false; - - - + + + for(const bucket_entry& old_bucket: old_buckets) { if(old_bucket.empty()) { continue; } - + truncated_hash_type insert_hash = old_bucket.truncated_hash(); index_type insert_index = old_bucket.index(); - - for(std::size_t ibucket = bucket_for_hash(insert_hash), dist_from_ideal_bucket = 0; ; - ibucket = next_bucket(ibucket), dist_from_ideal_bucket++) + + for(std::size_t ibucket = bucket_for_hash(insert_hash), dist_from_ideal_bucket = 0; ; + ibucket = next_bucket(ibucket), dist_from_ideal_bucket++) { if(m_buckets[ibucket].empty()) { m_buckets[ibucket].set_index(insert_index); m_buckets[ibucket].set_hash(insert_hash); break; } - + const std::size_t distance = distance_from_ideal_bucket(ibucket); if(dist_from_ideal_bucket > distance) { std::swap(insert_index, m_buckets[ibucket].index_ref()); @@ -1022,145 +1022,145 @@ private: } } } - + template::value>::type* = nullptr> void reserve_space_for_values(size_type count) { m_values.reserve(count); } - + template::value>::type* = nullptr> void reserve_space_for_values(size_type /*count*/) { } - + /** * Swap the empty bucket with the values on its right until we cross another empty bucket * or if the other bucket has a distance_from_ideal_bucket == 0. */ void backward_shift(std::size_t empty_ibucket) noexcept { tsl_assert(m_buckets[empty_ibucket].empty()); - + std::size_t previous_ibucket = empty_ibucket; - for(std::size_t current_ibucket = next_bucket(previous_ibucket); + for(std::size_t current_ibucket = next_bucket(previous_ibucket); !m_buckets[current_ibucket].empty() && distance_from_ideal_bucket(current_ibucket) > 0; - previous_ibucket = current_ibucket, current_ibucket = next_bucket(current_ibucket)) + previous_ibucket = current_ibucket, current_ibucket = next_bucket(current_ibucket)) { std::swap(m_buckets[current_ibucket], m_buckets[previous_ibucket]); } } - + void erase_value_from_bucket(typename buckets_container_type::iterator it_bucket) { tsl_assert(it_bucket != m_buckets.end() && !it_bucket->empty()); - + m_values.erase(m_values.begin() + it_bucket->index()); - + /* - * m_values.erase shifted all the values on the right of the erased value, + * m_values.erase shifted all the values on the right of the erased value, * shift the indexes by 1 in the buckets array for these values. */ if(it_bucket->index() != m_values.size()) { shift_indexes_in_buckets(it_bucket->index(), short(1)); - } - + } + // Mark the bucket as empty and do a backward shift of the values on the right it_bucket->clear(); backward_shift(std::size_t(std::distance(m_buckets.begin(), it_bucket))); } - + /** * Go through each value from [from_ivalue, m_values.size()) in m_values and for each * bucket corresponding to the value, shift the indexes to the left by delta. */ void shift_indexes_in_buckets(index_type from_ivalue, short delta) noexcept { - static_assert(std::is_unsigned::value && sizeof(index_type) >= sizeof(short), + static_assert(std::is_unsigned::value && sizeof(index_type) >= sizeof(short), "index_type should be unsigned and sizeof(index_type) >= sizeof(short)"); - + for(std::size_t ivalue = from_ivalue; ivalue < m_values.size(); ivalue++) { std::size_t ibucket = bucket_for_hash(hash_key(KeySelect()(m_values[ivalue]))); - + // Modulo arithmetic, we should be alright for index_type(ivalue + delta). TODO further checks while(m_buckets[ibucket].index() != index_type(ivalue + delta)) { ibucket = next_bucket(ibucket); } - + m_buckets[ibucket].set_index(index_type(m_buckets[ibucket].index() - delta)); } } - + template size_type erase_impl(const K& key, std::size_t hash) { auto it_bucket = find_key(key, hash); if(it_bucket != m_buckets.end()) { erase_value_from_bucket(it_bucket); - + return 1; } else { return 0; } } - + template std::pair insert_impl(const K& key, Args&&... value_type_args) { return insert_at_position_impl(m_values.cend(), key, std::forward(value_type_args)...); } - + /** * Insert the element before insert_position. */ template std::pair insert_at_position_impl(typename values_container_type::const_iterator insert_position, - const K& key, Args&&... value_type_args) + const K& key, Args&&... value_type_args) { const std::size_t hash = hash_key(key); - - std::size_t ibucket = bucket_for_hash(hash); + + std::size_t ibucket = bucket_for_hash(hash); std::size_t dist_from_ideal_bucket = 0; - + while(!m_buckets[ibucket].empty() && dist_from_ideal_bucket <= distance_from_ideal_bucket(ibucket)) { - if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) && - compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()]))) + if(m_buckets[ibucket].truncated_hash() == bucket_entry::truncate_hash(hash) && + compare_keys(key, KeySelect()(m_values[m_buckets[ibucket].index()]))) { return std::make_pair(begin() + m_buckets[ibucket].index(), false); } - + ibucket = next_bucket(ibucket); dist_from_ideal_bucket++; } - + if(size() >= max_size()) { throw std::length_error("We reached the maximum size for the hash table."); } - - + + if(grow_on_high_load()) { ibucket = bucket_for_hash(hash); dist_from_ideal_bucket = 0; } - - + + const index_type index_insert_position = index_type(std::distance(m_values.cbegin(), insert_position)); - + #ifdef TSL_NO_CONTAINER_EMPLACE_CONST_ITERATOR m_values.emplace(m_values.begin() + std::distance(m_values.cbegin(), insert_position), std::forward(value_type_args)...); -#else +#else m_values.emplace(insert_position, std::forward(value_type_args)...); -#endif +#endif - insert_index(ibucket, dist_from_ideal_bucket, + insert_index(ibucket, dist_from_ideal_bucket, index_insert_position, bucket_entry::truncate_hash(hash)); - + /* - * The insertion didn't happend at the end of the m_values container, + * The insertion didn't happend at the end of the m_values container, * we need to shift the indexes in m_buckets. */ if(index_insert_position != m_values.size() - 1) { shift_indexes_in_buckets(index_insert_position + 1, short(-1)); } - + return std::make_pair(iterator(m_values.begin() + index_insert_position), true); } - - void insert_index(std::size_t ibucket, std::size_t dist_from_ideal_bucket, + + void insert_index(std::size_t ibucket, std::size_t dist_from_ideal_bucket, index_type index_insert, truncated_hash_type hash_insert) noexcept { while(!m_buckets[ibucket].empty()) { @@ -1168,15 +1168,15 @@ private: if(dist_from_ideal_bucket > distance) { std::swap(index_insert, m_buckets[ibucket].index_ref()); std::swap(hash_insert, m_buckets[ibucket].truncated_hash_ref()); - + dist_from_ideal_bucket = distance; } - + ibucket = next_bucket(ibucket); dist_from_ideal_bucket++; - - + + if(dist_from_ideal_bucket > REHASH_ON_HIGH_NB_PROBES__NPROBES && !m_grow_on_next_insert && load_factor() >= REHASH_ON_HIGH_NB_PROBES__MIN_LOAD_FACTOR) { @@ -1185,43 +1185,43 @@ private: m_grow_on_next_insert = true; } } - - + + m_buckets[ibucket].set_index(index_insert); - m_buckets[ibucket].set_hash(hash_insert); + m_buckets[ibucket].set_hash(hash_insert); } - + std::size_t distance_from_ideal_bucket(std::size_t ibucket) const noexcept { const std::size_t ideal_bucket = bucket_for_hash(m_buckets[ibucket].truncated_hash()); - + if(ibucket >= ideal_bucket) { return ibucket - ideal_bucket; } - // If the bucket is smaller than the ideal bucket for the value, there was a wrapping at the end of the + // If the bucket is smaller than the ideal bucket for the value, there was a wrapping at the end of the // bucket array due to the modulo. else { return (bucket_count() + ibucket) - ideal_bucket; } } - + std::size_t next_bucket(std::size_t index) const noexcept { tsl_assert(index < m_buckets.size()); - + index++; return (index < m_buckets.size())?index:0; } - + std::size_t bucket_for_hash(std::size_t hash) const noexcept { return hash & m_mask; - } - + } + std::size_t iterator_to_index(const_iterator it) const noexcept { const auto dist = std::distance(cbegin(), it); tsl_assert(dist >= 0); - + return std::size_t(dist); } - + /** * Return true if the map has been rehashed. */ @@ -1229,50 +1229,50 @@ private: if(m_grow_on_next_insert || size() >= m_load_threshold) { rehash_impl(bucket_count() * 2); m_grow_on_next_insert = false; - + return true; } else { return false; } } - + static std::size_t round_up_to_power_of_two(std::size_t value) { if(is_power_of_two(value)) { return value; } - + if(value == 0) { return 1; } - + --value; for(std::size_t i = 1; i < sizeof(std::size_t) * CHAR_BIT; i *= 2) { value |= value >> i; } - + return value + 1; } - + static constexpr bool is_power_of_two(std::size_t value) { return value != 0 && (value & (value - 1)) == 0; } - + public: static const size_type DEFAULT_INIT_BUCKETS_SIZE = 16; static constexpr float DEFAULT_MAX_LOAD_FACTOR = 0.75f; -private: +private: static const size_type REHASH_ON_HIGH_NB_PROBES__NPROBES = 128; static constexpr float REHASH_ON_HIGH_NB_PROBES__MIN_LOAD_FACTOR = 0.15f; - + private: buckets_container_type m_buckets; size_type m_mask; - + values_container_type m_values; - + bool m_grow_on_next_insert; float m_max_load_factor; size_type m_load_threshold; diff --git a/Foundation/include/Poco/ordered_map.h b/Foundation/include/Poco/ordered_map.h index 0b0c28e8a..870a13975 100644 --- a/Foundation/include/Poco/ordered_map.h +++ b/Foundation/include/Poco/ordered_map.h @@ -1,18 +1,18 @@ /** * MIT License - * + * * Copyright (c) 2017 Tessil - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,29 +41,29 @@ namespace tsl { /** * Implementation of an hash map using open adressing with robin hood with backshift delete to resolve collisions. - * + * * The particularity of this hash map is that it remembers the order in which the elements were added and - * provide a way to access the structure which stores these values through the 'values_container()' method. + * provide a way to access the structure which stores these values through the 'values_container()' method. * The used container is defined by ValueTypeContainer, by default a std::deque is used (grows faster) but - * a std::vector may be used. In this case the map provides a 'data()' method which give a direct access + * a std::vector may be used. In this case the map provides a 'data()' method which give a direct access * to the memory used to store the values (which can be usefull to communicate with C API's). - * + * * The Key and T must be copy constructible and/or move constructible. To use `unordered_erase` they both * must be swappable. - * + * * The behaviour of the hash map is undefinded if the destructor of Key or T throws an exception. - * + * * Iterators invalidation: * - clear, operator=, reserve, rehash: always invalidate the iterators (also invalidate end()). - * - insert, emplace, emplace_hint, operator[]: when a std::vector is used as ValueTypeContainer - * and if size() < capacity(), only end(). + * - insert, emplace, emplace_hint, operator[]: when a std::vector is used as ValueTypeContainer + * and if size() < capacity(), only end(). * Otherwise all the iterators are invalidated if an insert occurs. - * - erase, unordered_erase: when a std::vector is used as ValueTypeContainer invalidate the iterator of - * the erased element and all the ones after the erased element (including end()). + * - erase, unordered_erase: when a std::vector is used as ValueTypeContainer invalidate the iterator of + * the erased element and all the ones after the erased element (including end()). * Otherwise all the iterators are invalidated if an erase occurs. */ -template, class KeyEqual = std::equal_to, class Allocator = std::allocator>, @@ -72,36 +72,36 @@ class ordered_map { private: template using has_is_transparent = tsl::detail_ordered_hash::has_is_transparent; - + class KeySelect { public: using key_type = Key; - + const key_type& operator()(const std::pair& key_value) const noexcept { return key_value.first; } - + key_type& operator()(std::pair& key_value) noexcept { return key_value.first; } - }; - + }; + class ValueSelect { public: using value_type = T; - + const value_type& operator()(const std::pair& key_value) const noexcept { return key_value.second; } - + value_type& operator()(std::pair& key_value) noexcept { return key_value.second; } }; - + using ht = detail_ordered_hash::ordered_hash, KeySelect, ValueSelect, Hash, KeyEqual, Allocator, ValueTypeContainer>; - + public: using key_type = typename ht::key_type; using mapped_type = T; @@ -119,38 +119,38 @@ public: using const_iterator = typename ht::const_iterator; using reverse_iterator = typename ht::reverse_iterator; using const_reverse_iterator = typename ht::const_reverse_iterator; - + using values_container_type = typename ht::values_container_type; - - + + /* * Constructors */ ordered_map(): ordered_map(ht::DEFAULT_INIT_BUCKETS_SIZE) { } - - explicit ordered_map(size_type bucket_count, + + explicit ordered_map(size_type bucket_count, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual(), - const Allocator& alloc = Allocator()): + const Allocator& alloc = Allocator()): m_ht(bucket_count, hash, equal, alloc, ht::DEFAULT_MAX_LOAD_FACTOR) { } - + ordered_map(size_type bucket_count, const Allocator& alloc): ordered_map(bucket_count, Hash(), KeyEqual(), alloc) { } - + ordered_map(size_type bucket_count, const Hash& hash, const Allocator& alloc): ordered_map(bucket_count, hash, KeyEqual(), alloc) { } - + explicit ordered_map(const Allocator& alloc): ordered_map(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) { } - + template ordered_map(InputIt first, InputIt last, size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, @@ -160,14 +160,14 @@ public: { insert(first, last); } - + template ordered_map(InputIt first, InputIt last, size_type bucket_count, const Allocator& alloc): ordered_map(first, last, bucket_count, Hash(), KeyEqual(), alloc) { } - + template ordered_map(InputIt first, InputIt last, size_type bucket_count, @@ -180,14 +180,14 @@ public: size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual(), - const Allocator& alloc = Allocator()): + const Allocator& alloc = Allocator()): ordered_map(init.begin(), init.end(), bucket_count, hash, equal, alloc) { } ordered_map(std::initializer_list init, size_type bucket_count, - const Allocator& alloc): + const Allocator& alloc): ordered_map(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(), alloc) { } @@ -195,587 +195,586 @@ public: ordered_map(std::initializer_list init, size_type bucket_count, const Hash& hash, - const Allocator& alloc): + const Allocator& alloc): ordered_map(init.begin(), init.end(), bucket_count, hash, KeyEqual(), alloc) { } - + ordered_map& operator=(std::initializer_list ilist) { m_ht.clear(); - + m_ht.reserve(ilist.size()); m_ht.insert(ilist.begin(), ilist.end()); - + return *this; } - - allocator_type get_allocator() const { return m_ht.get_allocator(); } - - + allocator_type get_allocator() const { return m_ht.get_allocator(); } + + + /* * Iterators */ iterator begin() noexcept { return m_ht.begin(); } const_iterator begin() const noexcept { return m_ht.begin(); } const_iterator cbegin() const noexcept { return m_ht.cbegin(); } - + iterator end() noexcept { return m_ht.end(); } const_iterator end() const noexcept { return m_ht.end(); } const_iterator cend() const noexcept { return m_ht.cend(); } - + reverse_iterator rbegin() noexcept { return m_ht.rbegin(); } const_reverse_iterator rbegin() const noexcept { return m_ht.rbegin(); } const_reverse_iterator rcbegin() const noexcept { return m_ht.rcbegin(); } - + reverse_iterator rend() noexcept { return m_ht.rend(); } const_reverse_iterator rend() const noexcept { return m_ht.rend(); } const_reverse_iterator rcend() const noexcept { return m_ht.rcend(); } - - + + /* * Capacity */ bool empty() const noexcept { return m_ht.empty(); } size_type size() const noexcept { return m_ht.size(); } size_type max_size() const noexcept { return m_ht.max_size(); } - + /* * Modifiers */ void clear() noexcept { m_ht.clear(); } - - - + + + std::pair insert(const value_type& value) { return m_ht.insert(value); } - + template::value>::type* = nullptr> std::pair insert(P&& value) { return m_ht.emplace(std::forward

(value)); } - + std::pair insert(value_type&& value) { return m_ht.insert(std::move(value)); } - - + + iterator insert(const_iterator hint, const value_type& value) { return m_ht.insert(hint, value); } - + template::value>::type* = nullptr> iterator insert(const_iterator hint, P&& value) { return m_ht.emplace_hint(hint, std::forward

(value)); } - - iterator insert(const_iterator hint, value_type&& value) { + + iterator insert(const_iterator hint, value_type&& value) { return m_ht.insert(hint, std::move(value)); } - - + + template void insert(InputIt first, InputIt last) { m_ht.insert(first, last); } void insert(std::initializer_list ilist) { m_ht.insert(ilist.begin(), ilist.end()); } - - - + + + template - std::pair insert_or_assign(const key_type& k, M&& obj) { - return m_ht.insert_or_assign(k, std::forward(obj)); + std::pair insert_or_assign(const key_type& k, M&& obj) { + return m_ht.insert_or_assign(k, std::forward(obj)); } template - std::pair insert_or_assign(key_type&& k, M&& obj) { - return m_ht.insert_or_assign(std::move(k), std::forward(obj)); + std::pair insert_or_assign(key_type&& k, M&& obj) { + return m_ht.insert_or_assign(std::move(k), std::forward(obj)); } - - + + template iterator insert_or_assign(const_iterator hint, const key_type& k, M&& obj) { return m_ht.insert_or_assign(hint, k, std::forward(obj)); } - + template iterator insert_or_assign(const_iterator hint, key_type&& k, M&& obj) { return m_ht.insert_or_assign(hint, std::move(k), std::forward(obj)); } - + /** * Due to the way elements are stored, emplace will need to move or copy the key-value once. * The method is equivalent to insert(value_type(std::forward(args)...)); - * + * * Mainly here for compatibility with the std::unordered_map interface. */ template std::pair emplace(Args&&... args) { return m_ht.emplace(std::forward(args)...); } - + /** * Due to the way elements are stored, emplace_hint will need to move or copy the key-value once. * The method is equivalent to insert(hint, value_type(std::forward(args)...)); - * + * * Mainly here for compatibility with the std::unordered_map interface. */ template iterator emplace_hint(const_iterator hint, Args&&... args) { return m_ht.emplace_hint(hint, std::forward(args)...); } - - - - + + + + template - std::pair try_emplace(const key_type& k, Args&&... args) { + std::pair try_emplace(const key_type& k, Args&&... args) { return m_ht.try_emplace(k, std::forward(args)...); } - + template std::pair try_emplace(key_type&& k, Args&&... args) { return m_ht.try_emplace(std::move(k), std::forward(args)...); } - + template iterator try_emplace(const_iterator hint, const key_type& k, Args&&... args) { return m_ht.try_emplace(hint, k, std::forward(args)...); } - + template iterator try_emplace(const_iterator hint, key_type&& k, Args&&... args) { return m_ht.try_emplace(hint, std::move(k), std::forward(args)...); } - - - + + + /** * When erasing an element, the insert order will be preserved and no holes will be present in the container - * returned by 'values_container()'. - * + * returned by 'values_container()'. + * * The method is in O(n), if the order is not important 'unordered_erase(...)' method is faster with an O(1) * average complexity. */ iterator erase(iterator pos) { return m_ht.erase(pos); } - + /** * @copydoc erase(iterator pos) */ iterator erase(const_iterator pos) { return m_ht.erase(pos); } - + /** * @copydoc erase(iterator pos) - */ + */ iterator erase(const_iterator first, const_iterator last) { return m_ht.erase(first, last); } - + /** * @copydoc erase(iterator pos) - */ + */ size_type erase(const key_type& key) { return m_ht.erase(key); } - + /** * @copydoc erase(iterator pos) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash. - */ - size_type erase(const key_type& key, std::size_t precalculated_hash) { - return m_ht.erase(key, precalculated_hash); + */ + size_type erase(const key_type& key, std::size_t precalculated_hash) { + return m_ht.erase(key, precalculated_hash); } - + /** * @copydoc erase(iterator pos) - * - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> size_type erase(const K& key) { return m_ht.erase(key); } - + /** * @copydoc erase(const key_type& key, std::size_t precalculated_hash) - * - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> - size_type erase(const K& key, std::size_t precalculated_hash) { - return m_ht.erase(key, precalculated_hash); + template::value>::type* = nullptr> + size_type erase(const K& key, std::size_t precalculated_hash) { + return m_ht.erase(key, precalculated_hash); } - - - - void swap(ordered_map& other) { other.m_ht.swap(m_ht); } - + + + void swap(ordered_map& other) noexcept { other.m_ht.swap(m_ht); } + /* * Lookup */ T& at(const Key& key) { return m_ht.at(key); } - + /** * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ T& at(const Key& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); } - - + + const T& at(const Key& key) const { return m_ht.at(key); } - + /** * @copydoc at(const Key& key, std::size_t precalculated_hash) */ const T& at(const Key& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); } - - + + /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> T& at(const K& key) { return m_ht.at(key); } - + /** * @copydoc at(const K& key) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - template::value>::type* = nullptr> + */ + template::value>::type* = nullptr> T& at(const K& key, std::size_t precalculated_hash) { return m_ht.at(key, precalculated_hash); } - + /** * @copydoc at(const K& key) */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> const T& at(const K& key) const { return m_ht.at(key); } - + /** * @copydoc at(const K& key, std::size_t precalculated_hash) - */ - template::value>::type* = nullptr> + */ + template::value>::type* = nullptr> const T& at(const K& key, std::size_t precalculated_hash) const { return m_ht.at(key, precalculated_hash); } - - - - T& operator[](const Key& key) { return m_ht[key]; } + + + + T& operator[](const Key& key) { return m_ht[key]; } T& operator[](Key&& key) { return m_ht[std::move(key)]; } - - - + + + size_type count(const Key& key) const { return m_ht.count(key); } - + /** * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - size_type count(const Key& key, std::size_t precalculated_hash) const { - return m_ht.count(key, precalculated_hash); - } - - /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. - * If so, K must be hashable and comparable to Key. - */ - template::value>::type* = nullptr> - size_type count(const K& key) const { return m_ht.count(key); } - - /** - * @copydoc count(const K& key) const - * - * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same - * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - template::value>::type* = nullptr> - size_type count(const K& key, std::size_t precalculated_hash) const { + size_type count(const Key& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } - - - + + /** + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * If so, K must be hashable and comparable to Key. + */ + template::value>::type* = nullptr> + size_type count(const K& key) const { return m_ht.count(key); } + + /** + * @copydoc count(const K& key) const + * + * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same + * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. + */ + template::value>::type* = nullptr> + size_type count(const K& key, std::size_t precalculated_hash) const { + return m_ht.count(key, precalculated_hash); + } + + + iterator find(const Key& key) { return m_ht.find(key); } - + /** * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ iterator find(const Key& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } - + const_iterator find(const Key& key) const { return m_ht.find(key); } - + /** * @copydoc find(const Key& key, std::size_t precalculated_hash) */ - const_iterator find(const Key& key, std::size_t precalculated_hash) const { + const_iterator find(const Key& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } - - /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. - * If so, K must be hashable and comparable to Key. - */ - template::value>::type* = nullptr> - iterator find(const K& key) { return m_ht.find(key); } - - /** - * @copydoc find(const K& key) - * - * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same - * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - template::value>::type* = nullptr> - iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } - - /** - * @copydoc find(const K& key) - */ - template::value>::type* = nullptr> - const_iterator find(const K& key) const { return m_ht.find(key); } - - /** - * @copydoc find(const K& key) - * - * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same - * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - template::value>::type* = nullptr> - const_iterator find(const K& key, std::size_t precalculated_hash) const { - return m_ht.find(key, precalculated_hash); - } - - - - std::pair equal_range(const Key& key) { return m_ht.equal_range(key); } - - /** - * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same - * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - std::pair equal_range(const Key& key, std::size_t precalculated_hash) { - return m_ht.equal_range(key, precalculated_hash); - } - - std::pair equal_range(const Key& key) const { return m_ht.equal_range(key); } - - /** - * @copydoc equal_range(const Key& key, std::size_t precalculated_hash) - */ - std::pair equal_range(const Key& key, std::size_t precalculated_hash) const { - return m_ht.equal_range(key, precalculated_hash); - } /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> - std::pair equal_range(const K& key) { return m_ht.equal_range(key); } - + template::value>::type* = nullptr> + iterator find(const K& key) { return m_ht.find(key); } + /** - * @copydoc equal_range(const K& key) - * + * @copydoc find(const K& key) + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - template::value>::type* = nullptr> - std::pair equal_range(const K& key, std::size_t precalculated_hash) { - return m_ht.equal_range(key, precalculated_hash); + template::value>::type* = nullptr> + iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } + + /** + * @copydoc find(const K& key) + */ + template::value>::type* = nullptr> + const_iterator find(const K& key) const { return m_ht.find(key); } + + /** + * @copydoc find(const K& key) + * + * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same + * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. + */ + template::value>::type* = nullptr> + const_iterator find(const K& key, std::size_t precalculated_hash) const { + return m_ht.find(key, precalculated_hash); } - + + + + std::pair equal_range(const Key& key) { return m_ht.equal_range(key); } + + /** + * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same + * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. + */ + std::pair equal_range(const Key& key, std::size_t precalculated_hash) { + return m_ht.equal_range(key, precalculated_hash); + } + + std::pair equal_range(const Key& key) const { return m_ht.equal_range(key); } + + /** + * @copydoc equal_range(const Key& key, std::size_t precalculated_hash) + */ + std::pair equal_range(const Key& key, std::size_t precalculated_hash) const { + return m_ht.equal_range(key, precalculated_hash); + } + + /** + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * If so, K must be hashable and comparable to Key. + */ + template::value>::type* = nullptr> + std::pair equal_range(const K& key) { return m_ht.equal_range(key); } + + /** + * @copydoc equal_range(const K& key) + * + * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same + * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. + */ + template::value>::type* = nullptr> + std::pair equal_range(const K& key, std::size_t precalculated_hash) { + return m_ht.equal_range(key, precalculated_hash); + } + /** * @copydoc equal_range(const K& key) */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> std::pair equal_range(const K& key) const { return m_ht.equal_range(key); } - + /** * @copydoc equal_range(const K& key, std::size_t precalculated_hash) - */ - template::value>::type* = nullptr> - std::pair equal_range(const K& key, std::size_t precalculated_hash) const { - return m_ht.equal_range(key, precalculated_hash); + */ + template::value>::type* = nullptr> + std::pair equal_range(const K& key, std::size_t precalculated_hash) const { + return m_ht.equal_range(key, precalculated_hash); } - - - + + + /* - * Bucket interface + * Bucket interface */ size_type bucket_count() const { return m_ht.bucket_count(); } size_type max_bucket_count() const { return m_ht.max_bucket_count(); } - - + + /* - * Hash policy + * Hash policy */ float load_factor() const { return m_ht.load_factor(); } float max_load_factor() const { return m_ht.max_load_factor(); } void max_load_factor(float ml) { m_ht.max_load_factor(ml); } - + void rehash(size_type count) { m_ht.rehash(count); } void reserve(size_type count) { m_ht.reserve(count); } - - + + /* * Observers */ hasher hash_function() const { return m_ht.hash_function(); } key_equal key_eq() const { return m_ht.key_eq(); } - - - + + + /* * Other */ - + /** * Convert a const_iterator to an iterator. */ iterator mutable_iterator(const_iterator pos) { return m_ht.mutable_iterator(pos); } - + /** * Requires index <= size(). - * + * * Return an iterator to the element at index. Return end() if index == size(). */ iterator nth(size_type index) { return m_ht.nth(index); } - + /** * @copydoc nth(size_type index) */ const_iterator nth(size_type index) const { return m_ht.nth(index); } - - + + /** * Return const_reference to the first element. Requires the container to not be empty. */ const_reference front() const { return m_ht.front(); } - + /** * Return const_reference to the last element. Requires the container to not be empty. */ const_reference back() const { return m_ht.back(); } - - + + /** * Only available if ValueTypeContainer is a std::vector. Same as calling 'values_container().data()'. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> const typename values_container_type::value_type* data() const noexcept { return m_ht.data(); } - + /** * Return the container in which the values are stored. The values are in the same order as the insertion order * and are contiguous in the structure, no holes (size() == values_container().size()). */ const values_container_type& values_container() const noexcept { return m_ht.values_container(); } - template::value>::type* = nullptr> + template::value>::type* = nullptr> size_type capacity() const noexcept { return m_ht.capacity(); } - + void shrink_to_fit() { m_ht.shrink_to_fit(); } - - - + + + /** - * Insert the value before pos shifting all the elements on the right of pos (including pos) one position + * Insert the value before pos shifting all the elements on the right of pos (including pos) one position * to the right. - * + * * Amortized linear time-complexity in the distance between pos and end(). */ - std::pair insert_at_position(const_iterator pos, const value_type& value) { - return m_ht.insert_at_position(pos, value); + std::pair insert_at_position(const_iterator pos, const value_type& value) { + return m_ht.insert_at_position(pos, value); } - + /** * @copydoc insert_at_position(const_iterator pos, const value_type& value) */ - std::pair insert_at_position(const_iterator pos, value_type&& value) { - return m_ht.insert_at_position(pos, std::move(value)); + std::pair insert_at_position(const_iterator pos, value_type&& value) { + return m_ht.insert_at_position(pos, std::move(value)); } - + /** * @copydoc insert_at_position(const_iterator pos, const value_type& value) - * + * * Same as insert_at_position(pos, value_type(std::forward(args)...), mainly * here for coherence. */ template std::pair emplace_at_position(const_iterator pos, Args&&... args) { - return m_ht.emplace_at_position(pos, std::forward(args)...); + return m_ht.emplace_at_position(pos, std::forward(args)...); } - + /** * @copydoc insert_at_position(const_iterator pos, const value_type& value) - */ + */ template - std::pair try_emplace_at_position(const_iterator pos, const key_type& k, Args&&... args) { + std::pair try_emplace_at_position(const_iterator pos, const key_type& k, Args&&... args) { return m_ht.try_emplace_at_position(pos, k, std::forward(args)...); } - + /** * @copydoc insert_at_position(const_iterator pos, const value_type& value) - */ + */ template std::pair try_emplace_at_position(const_iterator pos, key_type&& k, Args&&... args) { return m_ht.try_emplace_at_position(pos, std::move(k), std::forward(args)...); } - - - + + + void pop_back() { m_ht.pop_back(); } - + /** * Faster erase operation with an O(1) average complexity but it doesn't preserve the insertion order. - * + * * If an erasure occurs, the last element of the map will take the place of the erased element. */ iterator unordered_erase(iterator pos) { return m_ht.unordered_erase(pos); } - + /** * @copydoc unordered_erase(iterator pos) */ iterator unordered_erase(const_iterator pos) { return m_ht.unordered_erase(pos); } - + /** * @copydoc unordered_erase(iterator pos) - */ + */ size_type unordered_erase(const key_type& key) { return m_ht.unordered_erase(key); } - + /** * @copydoc unordered_erase(iterator pos) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - size_type unordered_erase(const key_type& key, std::size_t precalculated_hash) { - return m_ht.unordered_erase(key, precalculated_hash); + */ + size_type unordered_erase(const key_type& key, std::size_t precalculated_hash) { + return m_ht.unordered_erase(key, precalculated_hash); } - + /** * @copydoc unordered_erase(iterator pos) - * - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> size_type unordered_erase(const K& key) { return m_ht.unordered_erase(key); } - + /** * @copydoc unordered_erase(const K& key) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - template::value>::type* = nullptr> - size_type unordered_erase(const K& key, std::size_t precalculated_hash) { - return m_ht.unordered_erase(key, precalculated_hash); + template::value>::type* = nullptr> + size_type unordered_erase(const K& key, std::size_t precalculated_hash) { + return m_ht.unordered_erase(key, precalculated_hash); } - - - + + + friend bool operator==(const ordered_map& lhs, const ordered_map& rhs) { return lhs.m_ht == rhs.m_ht; } friend bool operator!=(const ordered_map& lhs, const ordered_map& rhs) { return lhs.m_ht != rhs.m_ht; } friend bool operator<(const ordered_map& lhs, const ordered_map& rhs) { return lhs.m_ht < rhs.m_ht; } friend bool operator<=(const ordered_map& lhs, const ordered_map& rhs) { return lhs.m_ht <= rhs.m_ht; } friend bool operator>(const ordered_map& lhs, const ordered_map& rhs) { return lhs.m_ht > rhs.m_ht; } friend bool operator>=(const ordered_map& lhs, const ordered_map& rhs) { return lhs.m_ht >= rhs.m_ht; } - + friend void swap(ordered_map& lhs, ordered_map& rhs) { lhs.swap(rhs); } private: diff --git a/Foundation/include/Poco/ordered_set.h b/Foundation/include/Poco/ordered_set.h index eeebbaf0e..db7075299 100644 --- a/Foundation/include/Poco/ordered_set.h +++ b/Foundation/include/Poco/ordered_set.h @@ -1,18 +1,18 @@ /** * MIT License - * + * * Copyright (c) 2017 Tessil - * + * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -41,27 +41,27 @@ namespace tsl { /** * Implementation of an hash set using open adressing with robin hood with backshift delete to resolve collisions. - * + * * The particularity of this hash set is that it remembers the order in which the elements were added and - * provide a way to access the structure which stores these values through the 'values_container()' method. + * provide a way to access the structure which stores these values through the 'values_container()' method. * The used container is defined by ValueTypeContainer, by default a std::deque is used (grows faster) but - * a std::vector may be used. In this case the set provides a 'data()' method which give a direct access + * a std::vector may be used. In this case the set provides a 'data()' method which give a direct access * to the memory used to store the values (which can be usefull to communicate with C API's). - * + * * The Key must be copy constructible and/or move constructible. To use `unordered_erase` it also must be swappable. - * + * * The behaviour of the hash set is undefinded if the destructor of Key throws an exception. - * + * * Iterators invalidation: * - clear, operator=, reserve, rehash: always invalidate the iterators (also invalidate end()). - * - insert, emplace, emplace_hint, operator[]: when a std::vector is used as ValueTypeContainer - * and if size() < capacity(), only end(). + * - insert, emplace, emplace_hint, operator[]: when a std::vector is used as ValueTypeContainer + * and if size() < capacity(), only end(). * Otherwise all the iterators are invalidated if an insert occurs. - * - erase, unordered_erase: when a std::vector is used as ValueTypeContainer invalidate the iterator of - * the erased element and all the ones after the erased element (including end()). + * - erase, unordered_erase: when a std::vector is used as ValueTypeContainer invalidate the iterator of + * the erased element and all the ones after the erased element (including end()). * Otherwise all the iterators are invalidated if an erase occurs. */ -template, class KeyEqual = std::equal_to, class Allocator = std::allocator, @@ -70,23 +70,23 @@ class ordered_set { private: template using has_is_transparent = tsl::detail_ordered_hash::has_is_transparent; - + class KeySelect { public: using key_type = Key; - + const key_type& operator()(const Key& key) const noexcept { return key; } - + key_type& operator()(Key& key) noexcept { return key; } }; - + using ht = detail_ordered_hash::ordered_hash; - + public: using key_type = typename ht::key_type; using value_type = typename ht::value_type; @@ -103,38 +103,38 @@ public: using const_iterator = typename ht::const_iterator; using reverse_iterator = typename ht::reverse_iterator; using const_reverse_iterator = typename ht::const_reverse_iterator; - + using values_container_type = typename ht::values_container_type; - + /* * Constructors */ ordered_set(): ordered_set(ht::DEFAULT_INIT_BUCKETS_SIZE) { } - - explicit ordered_set(size_type bucket_count, + + explicit ordered_set(size_type bucket_count, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual(), - const Allocator& alloc = Allocator()): + const Allocator& alloc = Allocator()): m_ht(bucket_count, hash, equal, alloc, ht::DEFAULT_MAX_LOAD_FACTOR) { } - + ordered_set(size_type bucket_count, const Allocator& alloc): ordered_set(bucket_count, Hash(), KeyEqual(), alloc) { } - + ordered_set(size_type bucket_count, const Hash& hash, const Allocator& alloc): ordered_set(bucket_count, hash, KeyEqual(), alloc) { } - + explicit ordered_set(const Allocator& alloc): ordered_set(ht::DEFAULT_INIT_BUCKETS_SIZE, alloc) { } - + template ordered_set(InputIt first, InputIt last, size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, @@ -144,14 +144,14 @@ public: { insert(first, last); } - + template ordered_set(InputIt first, InputIt last, size_type bucket_count, const Allocator& alloc): ordered_set(first, last, bucket_count, Hash(), KeyEqual(), alloc) { } - + template ordered_set(InputIt first, InputIt last, size_type bucket_count, @@ -164,14 +164,14 @@ public: size_type bucket_count = ht::DEFAULT_INIT_BUCKETS_SIZE, const Hash& hash = Hash(), const KeyEqual& equal = KeyEqual(), - const Allocator& alloc = Allocator()): + const Allocator& alloc = Allocator()): ordered_set(init.begin(), init.end(), bucket_count, hash, equal, alloc) { } ordered_set(std::initializer_list init, size_type bucket_count, - const Allocator& alloc): + const Allocator& alloc): ordered_set(init.begin(), init.end(), bucket_count, Hash(), KeyEqual(), alloc) { } @@ -179,462 +179,462 @@ public: ordered_set(std::initializer_list init, size_type bucket_count, const Hash& hash, - const Allocator& alloc): + const Allocator& alloc): ordered_set(init.begin(), init.end(), bucket_count, hash, KeyEqual(), alloc) { } - + ordered_set& operator=(std::initializer_list ilist) { m_ht.clear(); - + m_ht.reserve(ilist.size()); m_ht.insert(ilist.begin(), ilist.end()); - + return *this; } - + allocator_type get_allocator() const { return m_ht.get_allocator(); } - - + + /* * Iterators */ iterator begin() noexcept { return m_ht.begin(); } const_iterator begin() const noexcept { return m_ht.begin(); } const_iterator cbegin() const noexcept { return m_ht.cbegin(); } - + iterator end() noexcept { return m_ht.end(); } const_iterator end() const noexcept { return m_ht.end(); } const_iterator cend() const noexcept { return m_ht.cend(); } - + reverse_iterator rbegin() noexcept { return m_ht.rbegin(); } const_reverse_iterator rbegin() const noexcept { return m_ht.rbegin(); } const_reverse_iterator rcbegin() const noexcept { return m_ht.rcbegin(); } - + reverse_iterator rend() noexcept { return m_ht.rend(); } const_reverse_iterator rend() const noexcept { return m_ht.rend(); } const_reverse_iterator rcend() const noexcept { return m_ht.rcend(); } - - + + /* * Capacity */ bool empty() const noexcept { return m_ht.empty(); } size_type size() const noexcept { return m_ht.size(); } size_type max_size() const noexcept { return m_ht.max_size(); } - + /* * Modifiers */ void clear() noexcept { m_ht.clear(); } - - - + + + std::pair insert(const value_type& value) { return m_ht.insert(value); } std::pair insert(value_type&& value) { return m_ht.insert(std::move(value)); } - + iterator insert(const_iterator hint, const value_type& value) { - return m_ht.insert(hint, value); + return m_ht.insert(hint, value); } - - iterator insert(const_iterator hint, value_type&& value) { - return m_ht.insert(hint, std::move(value)); + + iterator insert(const_iterator hint, value_type&& value) { + return m_ht.insert(hint, std::move(value)); } - + template void insert(InputIt first, InputIt last) { m_ht.insert(first, last); } void insert(std::initializer_list ilist) { m_ht.insert(ilist.begin(), ilist.end()); } - - + + /** * Due to the way elements are stored, emplace will need to move or copy the key-value once. * The method is equivalent to insert(value_type(std::forward(args)...)); - * + * * Mainly here for compatibility with the std::unordered_map interface. */ template std::pair emplace(Args&&... args) { return m_ht.emplace(std::forward(args)...); } - + /** * Due to the way elements are stored, emplace_hint will need to move or copy the key-value once. * The method is equivalent to insert(hint, value_type(std::forward(args)...)); - * + * * Mainly here for compatibility with the std::unordered_map interface. */ template iterator emplace_hint(const_iterator hint, Args&&... args) { - return m_ht.emplace_hint(hint, std::forward(args)...); + return m_ht.emplace_hint(hint, std::forward(args)...); } /** * When erasing an element, the insert order will be preserved and no holes will be present in the container - * returned by 'values_container()'. - * + * returned by 'values_container()'. + * * The method is in O(n), if the order is not important 'unordered_erase(...)' method is faster with an O(1) * average complexity. - */ + */ iterator erase(iterator pos) { return m_ht.erase(pos); } - + /** * @copydoc erase(iterator pos) - */ + */ iterator erase(const_iterator pos) { return m_ht.erase(pos); } - + /** * @copydoc erase(iterator pos) - */ + */ iterator erase(const_iterator first, const_iterator last) { return m_ht.erase(first, last); } - + /** * @copydoc erase(iterator pos) - */ + */ size_type erase(const key_type& key) { return m_ht.erase(key); } - + /** * @copydoc erase(iterator pos) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup to the value if you already have the hash. - */ - size_type erase(const key_type& key, std::size_t precalculated_hash) { - return m_ht.erase(key, precalculated_hash); + */ + size_type erase(const key_type& key, std::size_t precalculated_hash) { + return m_ht.erase(key, precalculated_hash); } - + /** * @copydoc erase(iterator pos) - * - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> size_type erase(const K& key) { return m_ht.erase(key); } - + /** * @copydoc erase(const key_type& key, std::size_t precalculated_hash) - * - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> - size_type erase(const K& key, std::size_t precalculated_hash) { - return m_ht.erase(key, precalculated_hash); + template::value>::type* = nullptr> + size_type erase(const K& key, std::size_t precalculated_hash) { + return m_ht.erase(key, precalculated_hash); } - - - - void swap(ordered_set& other) { other.m_ht.swap(m_ht); } - + + + + void swap(ordered_set& other) noexcept { other.m_ht.swap(m_ht); } + /* * Lookup */ size_type count(const Key& key) const { return m_ht.count(key); } - + /** * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - size_type count(const Key& key, std::size_t precalculated_hash) const { - return m_ht.count(key, precalculated_hash); + size_type count(const Key& key, std::size_t precalculated_hash) const { + return m_ht.count(key, precalculated_hash); } - + /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ template::value>::type* = nullptr> size_type count(const K& key) const { return m_ht.count(key); } - + /** * @copydoc count(const K& key) const - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - template::value>::type* = nullptr> - size_type count(const K& key, std::size_t precalculated_hash) const { + */ + template::value>::type* = nullptr> + size_type count(const K& key, std::size_t precalculated_hash) const { return m_ht.count(key, precalculated_hash); } - - - - + + + + iterator find(const Key& key) { return m_ht.find(key); } - + /** * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ iterator find(const Key& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } - + const_iterator find(const Key& key) const { return m_ht.find(key); } - + /** * @copydoc find(const Key& key, std::size_t precalculated_hash) */ - const_iterator find(const Key& key, std::size_t precalculated_hash) const { + const_iterator find(const Key& key, std::size_t precalculated_hash) const { return m_ht.find(key, precalculated_hash); } - + /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ template::value>::type* = nullptr> iterator find(const K& key) { return m_ht.find(key); } - + /** * @copydoc find(const K& key) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> iterator find(const K& key, std::size_t precalculated_hash) { return m_ht.find(key, precalculated_hash); } - + /** * @copydoc find(const K& key) */ template::value>::type* = nullptr> const_iterator find(const K& key) const { return m_ht.find(key); } - + /** * @copydoc find(const K& key) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - template::value>::type* = nullptr> - const_iterator find(const K& key, std::size_t precalculated_hash) const { - return m_ht.find(key, precalculated_hash); + template::value>::type* = nullptr> + const_iterator find(const K& key, std::size_t precalculated_hash) const { + return m_ht.find(key, precalculated_hash); } - - - + + + std::pair equal_range(const Key& key) { return m_ht.equal_range(key); } - + /** * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - std::pair equal_range(const Key& key, std::size_t precalculated_hash) { - return m_ht.equal_range(key, precalculated_hash); + std::pair equal_range(const Key& key, std::size_t precalculated_hash) { + return m_ht.equal_range(key, precalculated_hash); } - + std::pair equal_range(const Key& key) const { return m_ht.equal_range(key); } - + /** * @copydoc equal_range(const Key& key, std::size_t precalculated_hash) */ - std::pair equal_range(const Key& key, std::size_t precalculated_hash) const { - return m_ht.equal_range(key, precalculated_hash); + std::pair equal_range(const Key& key, std::size_t precalculated_hash) const { + return m_ht.equal_range(key, precalculated_hash); } - + /** - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> std::pair equal_range(const K& key) { return m_ht.equal_range(key); } - + /** * @copydoc equal_range(const K& key) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - template::value>::type* = nullptr> - std::pair equal_range(const K& key, std::size_t precalculated_hash) { - return m_ht.equal_range(key, precalculated_hash); + template::value>::type* = nullptr> + std::pair equal_range(const K& key, std::size_t precalculated_hash) { + return m_ht.equal_range(key, precalculated_hash); } - + /** * @copydoc equal_range(const K& key) */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> std::pair equal_range(const K& key) const { return m_ht.equal_range(key); } - + /** * @copydoc equal_range(const K& key, std::size_t precalculated_hash) - */ - template::value>::type* = nullptr> - std::pair equal_range(const K& key, std::size_t precalculated_hash) const { - return m_ht.equal_range(key, precalculated_hash); + */ + template::value>::type* = nullptr> + std::pair equal_range(const K& key, std::size_t precalculated_hash) const { + return m_ht.equal_range(key, precalculated_hash); } - + /* - * Bucket interface + * Bucket interface */ size_type bucket_count() const { return m_ht.bucket_count(); } size_type max_bucket_count() const { return m_ht.max_bucket_count(); } - - + + /* - * Hash policy + * Hash policy */ float load_factor() const { return m_ht.load_factor(); } float max_load_factor() const { return m_ht.max_load_factor(); } void max_load_factor(float ml) { m_ht.max_load_factor(ml); } - + void rehash(size_type count) { m_ht.rehash(count); } void reserve(size_type count) { m_ht.reserve(count); } - - + + /* * Observers */ hasher hash_function() const { return m_ht.hash_function(); } key_equal key_eq() const { return m_ht.key_eq(); } - - + + /* * Other */ - + /** * Convert a const_iterator to an iterator. */ iterator mutable_iterator(const_iterator pos) { return m_ht.mutable_iterator(pos); } - + /** * Requires index <= size(). - * + * * Return an iterator to the element at index. Return end() if index == size(). */ iterator nth(size_type index) { return m_ht.nth(index); } - + /** * @copydoc nth(size_type index) */ const_iterator nth(size_type index) const { return m_ht.nth(index); } - - + + /** * Return const_reference to the first element. Requires the container to not be empty. */ const_reference front() const { return m_ht.front(); } - + /** * Return const_reference to the last element. Requires the container to not be empty. */ const_reference back() const { return m_ht.back(); } - - + + /** * Only available if ValueTypeContainer is a std::vector. Same as calling 'values_container().data()'. - */ - template::value>::type* = nullptr> + */ + template::value>::type* = nullptr> const typename values_container_type::value_type* data() const noexcept { return m_ht.data(); } - + /** * Return the container in which the values are stored. The values are in the same order as the insertion order * and are contiguous in the structure, no holes (size() == values_container().size()). - */ + */ const values_container_type& values_container() const noexcept { return m_ht.values_container(); } - template::value>::type* = nullptr> + template::value>::type* = nullptr> size_type capacity() const noexcept { return m_ht.capacity(); } - + void shrink_to_fit() { m_ht.shrink_to_fit(); } - - - + + + /** - * Insert the value before pos shifting all the elements on the right of pos (including pos) one position + * Insert the value before pos shifting all the elements on the right of pos (including pos) one position * to the right. - * + * * Amortized linear time-complexity in the distance between pos and end(). */ - std::pair insert_at_position(const_iterator pos, const value_type& value) { - return m_ht.insert_at_position(pos, value); + std::pair insert_at_position(const_iterator pos, const value_type& value) { + return m_ht.insert_at_position(pos, value); } - + /** * @copydoc insert_at_position(const_iterator pos, const value_type& value) */ - std::pair insert_at_position(const_iterator pos, value_type&& value) { - return m_ht.insert_at_position(pos, std::move(value)); + std::pair insert_at_position(const_iterator pos, value_type&& value) { + return m_ht.insert_at_position(pos, std::move(value)); } - + /** * @copydoc insert_at_position(const_iterator pos, const value_type& value) - * + * * Same as insert_at_position(pos, value_type(std::forward(args)...), mainly * here for coherence. */ template std::pair emplace_at_position(const_iterator pos, Args&&... args) { - return m_ht.emplace_at_position(pos, std::forward(args)...); + return m_ht.emplace_at_position(pos, std::forward(args)...); } - - - + + + void pop_back() { m_ht.pop_back(); } - + /** * Faster erase operation with an O(1) average complexity but it doesn't preserve the insertion order. - * + * * If an erasure occurs, the last element of the map will take the place of the erased element. - */ + */ iterator unordered_erase(iterator pos) { return m_ht.unordered_erase(pos); } - + /** * @copydoc unordered_erase(iterator pos) - */ + */ iterator unordered_erase(const_iterator pos) { return m_ht.unordered_erase(pos); } - + /** * @copydoc unordered_erase(iterator pos) - */ + */ size_type unordered_erase(const key_type& key) { return m_ht.unordered_erase(key); } - + /** * @copydoc unordered_erase(iterator pos) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. - */ - size_type unordered_erase(const key_type& key, std::size_t precalculated_hash) { - return m_ht.unordered_erase(key, precalculated_hash); + */ + size_type unordered_erase(const key_type& key, std::size_t precalculated_hash) { + return m_ht.unordered_erase(key, precalculated_hash); } - + /** * @copydoc unordered_erase(iterator pos) - * - * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. + * + * This overload only participates in the overload resolution if the typedef KeyEqual::is_transparent exists. * If so, K must be hashable and comparable to Key. */ - template::value>::type* = nullptr> + template::value>::type* = nullptr> size_type unordered_erase(const K& key) { return m_ht.unordered_erase(key); } - + /** * @copydoc unordered_erase(const K& key) - * + * * Use the hash value 'precalculated_hash' instead of hashing the key. The hash value should be the same * as hash_function()(key). Usefull to speed-up the lookup if you already have the hash. */ - template::value>::type* = nullptr> - size_type unordered_erase(const K& key, std::size_t precalculated_hash) { - return m_ht.unordered_erase(key, precalculated_hash); + template::value>::type* = nullptr> + size_type unordered_erase(const K& key, std::size_t precalculated_hash) { + return m_ht.unordered_erase(key, precalculated_hash); } - - - + + + friend bool operator==(const ordered_set& lhs, const ordered_set& rhs) { return lhs.m_ht == rhs.m_ht; } friend bool operator!=(const ordered_set& lhs, const ordered_set& rhs) { return lhs.m_ht != rhs.m_ht; } friend bool operator<(const ordered_set& lhs, const ordered_set& rhs) { return lhs.m_ht < rhs.m_ht; } friend bool operator<=(const ordered_set& lhs, const ordered_set& rhs) { return lhs.m_ht <= rhs.m_ht; } friend bool operator>(const ordered_set& lhs, const ordered_set& rhs) { return lhs.m_ht > rhs.m_ht; } friend bool operator>=(const ordered_set& lhs, const ordered_set& rhs) { return lhs.m_ht >= rhs.m_ht; } - + friend void swap(ordered_set& lhs, ordered_set& rhs) { lhs.swap(rhs); } - + private: - ht m_ht; + ht m_ht; }; } // end namespace tsl diff --git a/Foundation/include/Poco/zconf.h b/Foundation/include/Poco/zconf.h index 4754e9a63..8ace27f34 100644 --- a/Foundation/include/Poco/zconf.h +++ b/Foundation/include/Poco/zconf.h @@ -1,5 +1,5 @@ /* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2013 Jean-loup Gailly. + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ diff --git a/Foundation/include/Poco/zlib.h b/Foundation/include/Poco/zlib.h index f09cdaf1e..4b7d19543 100644 --- a/Foundation/include/Poco/zlib.h +++ b/Foundation/include/Poco/zlib.h @@ -1,7 +1,7 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.11, January 15th, 2017 + version 1.2.12, March 11th, 2022 - Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -37,11 +37,11 @@ extern "C" { #endif -#define ZLIB_VERSION "1.2.11" -#define ZLIB_VERNUM 0x12b0 +#define ZLIB_VERSION "1.2.12" +#define ZLIB_VERNUM 0x12c0 #define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 11 +#define ZLIB_VER_REVISION 12 #define ZLIB_VER_SUBREVISION 0 /* @@ -543,8 +543,7 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int strategy)); This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. + fields zalloc, zfree and opaque must be initialized before by the caller. The method parameter is the compression method. It must be Z_DEFLATED in this version of the library. @@ -712,11 +711,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, used to switch between compression and straight copy of the input data, or to switch to a different kind of input data requiring a different strategy. If the compression approach (which is a function of the level) or the - strategy is changed, and if any input has been consumed in a previous - deflate() call, then the input available so far is compressed with the old - level and strategy using deflate(strm, Z_BLOCK). There are three approaches - for the compression levels 0, 1..3, and 4..9 respectively. The new level - and strategy will take effect at the next call of deflate(). + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does not have enough output space to complete, then the parameter change will not @@ -865,9 +865,11 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, detection, or add 16 to decode only the gzip format (the zlib format will return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see - below), inflate() will not automatically decode concatenated gzip streams. - inflate() will return Z_STREAM_END at the end of the gzip stream. The state - would need to be reset to continue decoding a subsequent gzip stream. + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough memory, Z_VERSION_ERROR if the zlib library version is incompatible with the @@ -1302,14 +1304,14 @@ typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ /* ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) 'T' will - request transparent writing or appending with no compression and not using - the gzip format. + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. "a" can be used instead of "w" to request that the gzip stream that will be written be appended to the file. "+" will result in an error, since @@ -1339,9 +1341,9 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); /* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. The next call of gzclose on the returned gzFile will also close the file descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor @@ -1362,13 +1364,13 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); /* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Three times that size in buffer space is allocated. A larger buffer - size of, for example, 64K or 128K bytes will noticeably increase the speed - of decompression (reading). + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). The new buffer size also affects the maximum length for gzprintf(). @@ -1378,9 +1380,9 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); /* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. Previously provided - data is flushed before the parameter change. + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not opened for writing, Z_ERRNO if there is an error writing the flushed data, @@ -1389,7 +1391,7 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); /* - Reads the given number of uncompressed bytes from the compressed file. If + Read and decompress up to len uncompressed bytes from file into buf. If the input file is not in gzip format, gzread copies the given number of bytes into the buffer directly from the file. @@ -1420,11 +1422,11 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, gzFile file)); /* - Read up to nitems items of size size from file to buf, otherwise operating - as gzread() does. This duplicates the interface of stdio's fread(), with - size_t request and return types. If the library defines size_t, then - z_size_t is identical to size_t. If not, then z_size_t is an unsigned - integer type that can contain a pointer. + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. gzfread() returns the number of full items read of size size, or zero if the end of the file was reached and a full item could not be read, or if @@ -1443,18 +1445,16 @@ ZEXTERN z_size_t ZEXPORT gzfread OF((voidp buf, z_size_t size, z_size_t nitems, file, reseting and retrying on end-of-file, when size is not 1. */ -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, voidpc buf, unsigned len)); /* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. */ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, z_size_t nitems, gzFile file)); /* - gzfwrite() writes nitems items of size size from buf to file, duplicating + Compress and write nitems items of size size from buf to file, duplicating the interface of stdio's fwrite(), with size_t request and return types. If the library defines size_t, then z_size_t is identical to size_t. If not, then z_size_t is an unsigned integer type that can contain a pointer. @@ -1467,22 +1467,22 @@ ZEXTERN z_size_t ZEXPORT gzfwrite OF((voidpc buf, z_size_t size, ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); /* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or a negative zlib error code in case of error. The number of uncompressed bytes written is limited to 8191, or one less than the buffer size given to gzbuffer(). The caller should assure that this limit is not exceeded. If it is exceeded, then gzprintf() will return an error (0) with nothing written. In this case, there may also be a buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() + zlib was compiled with the insecure functions sprintf() or vsprintf(), because the secure snprintf() or vsnprintf() functions were not available. This can be determined using zlibCompileFlags(). */ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); /* - Writes the given null-terminated string to the compressed file, excluding + Compress and write the given null-terminated string s to file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. @@ -1490,11 +1490,12 @@ ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); /* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. gzgets returns buf which is a null-terminated string, or it returns NULL for end-of-file or in case of error. If there was an error, the contents at @@ -1503,13 +1504,13 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); /* - Writes c, converted to an unsigned char, into the compressed file. gzputc + Compress and write c, converted to an unsigned char, into file. gzputc returns the value that was written, or -1 in case of error. */ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); /* - Reads one byte from the compressed file. gzgetc returns this byte or -1 + Read and decompress one byte from file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. As such, it does not do all of the checking the other functions do. I.e. it does not check to see if file is NULL, nor whether the structure file @@ -1518,8 +1519,8 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); /* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will fail if c is -1, and may fail if a character has been pushed but not read yet. If gzungetc is used immediately after gzopen or gzdopen, at least the @@ -1530,9 +1531,9 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); /* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. If the flush parameter is Z_FINISH, the remaining data is written and the gzip stream is completed in the output. If gzwrite() is called again, a new @@ -1547,8 +1548,8 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the uncompressed data stream. The whence parameter is defined as in lseek(2); the value SEEK_END is not supported. @@ -1565,18 +1566,18 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); /* - Rewinds the given file. This function is supported only for reading. + Rewind file. This function is supported only for reading. - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). */ /* ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ @@ -1584,22 +1585,22 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); /* ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. */ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); /* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. If gzeof() returns true, then the read functions will return no more data, unless the end-of-file indicator is reset by gzclearerr() and the input file @@ -1608,7 +1609,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); /* - Returns true (1) if file is being copied directly while reading, or false + Return true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. If the input file is empty, gzdirect() will return true, since the input @@ -1629,8 +1630,8 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); ZEXTERN int ZEXPORT gzclose OF((gzFile file)); /* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. gzclose must not be called more than once on the same file, just as free must not be called more than once on the same allocation. @@ -1654,10 +1655,10 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); /* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. The application must not modify the returned string. Future calls to this function may invalidate the previously returned string. If file is @@ -1670,7 +1671,7 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); /* - Clears the error and end-of-file flags for file. This is analogous to the + Clear the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. */ @@ -1688,8 +1689,9 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed much faster. @@ -1722,12 +1724,13 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, negative, the result has no meaning or utility. */ -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); /* Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. Usage example: @@ -1739,7 +1742,7 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ -ZEXTERN uLong ZEXPORT crc32_z OF((uLong adler, const Bytef *buf, +ZEXTERN uLong ZEXPORT crc32_z OF((uLong crc, const Bytef *buf, z_size_t len)); /* Same as crc32(), but with a size_t length. @@ -1755,6 +1758,20 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); len2. */ +/* +ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t len2)); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +ZEXTERN uLong ZEXPORT crc32_combine_op OF((uLong crc1, uLong crc2, uLong op)); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + /* various hacks, don't look :) */ @@ -1842,6 +1859,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off64_t)); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) @@ -1852,6 +1870,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define z_gzoffset z_gzoffset64 # define z_adler32_combine z_adler32_combine64 # define z_crc32_combine z_crc32_combine64 +# define z_crc32_combine_gen z_crc32_combine_gen64 # else # define gzopen gzopen64 # define gzseek gzseek64 @@ -1859,6 +1878,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ # define gzoffset gzoffset64 # define adler32_combine adler32_combine64 # define crc32_combine crc32_combine64 +# define crc32_combine_gen crc32_combine_gen64 # endif # ifndef Z_LARGE64 ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); @@ -1867,6 +1887,7 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine_gen64 OF((z_off_t)); # endif #else ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); @@ -1875,12 +1896,14 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); #endif #else /* Z_SOLO */ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine_gen OF((z_off_t)); #endif /* !Z_SOLO */ diff --git a/Foundation/samples/ActiveMethod/src/ActiveMethod.cpp b/Foundation/samples/ActiveMethod/src/ActiveMethod.cpp index 1d2be4d42..d47f9940f 100644 --- a/Foundation/samples/ActiveMethod/src/ActiveMethod.cpp +++ b/Foundation/samples/ActiveMethod/src/ActiveMethod.cpp @@ -27,14 +27,14 @@ public: int a; int b; }; - + ActiveMethodExample(): activeAdd(this, &ActiveMethodExample::activeAddImp) { } - + ActiveMethod activeAdd; - + private: int activeAddImp(const AddArgs& args) { @@ -46,11 +46,11 @@ private: int main(int argc, char** argv) { ActiveMethodExample example; - + ActiveMethodExample::AddArgs args = {1, 2}; ActiveResult result = example.activeAdd(args); result.wait(); std::cout << result.data() << std::endl; - + return 0; } diff --git a/Foundation/samples/Activity/src/Activity.cpp b/Foundation/samples/Activity/src/Activity.cpp index 7d13bc39d..0dac9e849 100644 --- a/Foundation/samples/Activity/src/Activity.cpp +++ b/Foundation/samples/Activity/src/Activity.cpp @@ -26,12 +26,12 @@ public: _activity(this, &ActivityExample::runActivity) { } - + void start() { _activity.start(); } - + void stop() { _activity.stop(); @@ -48,7 +48,7 @@ protected: } std::cout << "Activity stopped." << std::endl; } - + private: Activity _activity; }; diff --git a/Foundation/samples/BinaryReaderWriter/BinaryReaderWriter.progen b/Foundation/samples/BinaryReaderWriter/BinaryReaderWriter.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/BinaryReaderWriter/BinaryReaderWriter.progen +++ b/Foundation/samples/BinaryReaderWriter/BinaryReaderWriter.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/BinaryReaderWriter/src/BinaryReaderWriter.cpp b/Foundation/samples/BinaryReaderWriter/src/BinaryReaderWriter.cpp index d7205e7b6..c32dc507a 100644 --- a/Foundation/samples/BinaryReaderWriter/src/BinaryReaderWriter.cpp +++ b/Foundation/samples/BinaryReaderWriter/src/BinaryReaderWriter.cpp @@ -23,32 +23,32 @@ using Poco::BinaryReader; int main(int argc, char** argv) { std::stringstream str; - + BinaryWriter writer(str); writer << true << 'x' << 42 << 3.14159265 << "foo bar"; - + bool b; char c; int i; double d; std::string s; - + BinaryReader reader(str); reader >> b >> c >> i >> d >> s; - + std::cout << b << std::endl << c << std::endl << i << std::endl << d << std::endl << s << std::endl; - + return 0; } diff --git a/Foundation/samples/DateTime/DateTime.progen b/Foundation/samples/DateTime/DateTime.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/DateTime/DateTime.progen +++ b/Foundation/samples/DateTime/DateTime.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/DateTime/src/DateTime.cpp b/Foundation/samples/DateTime/src/DateTime.cpp index 9cf571890..ac55721b8 100644 --- a/Foundation/samples/DateTime/src/DateTime.cpp +++ b/Foundation/samples/DateTime/src/DateTime.cpp @@ -28,7 +28,7 @@ using Poco::DateTimeParser; int main(int argc, char** argv) { LocalDateTime now; - + std::string str = DateTimeFormatter::format(now, DateTimeFormat::ISO8601_FORMAT); DateTime dt; int tzd; diff --git a/Foundation/samples/LineEndingConverter/LineEndingConverter.progen b/Foundation/samples/LineEndingConverter/LineEndingConverter.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/LineEndingConverter/LineEndingConverter.progen +++ b/Foundation/samples/LineEndingConverter/LineEndingConverter.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/LogRotation/LogRotation.progen b/Foundation/samples/LogRotation/LogRotation.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/LogRotation/LogRotation.progen +++ b/Foundation/samples/LogRotation/LogRotation.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/Logger/Logger.progen b/Foundation/samples/Logger/Logger.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/Logger/Logger.progen +++ b/Foundation/samples/Logger/Logger.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/Logger/src/Logger.cpp b/Foundation/samples/Logger/src/Logger.cpp index 9b0af0450..5ed2d9126 100644 --- a/Foundation/samples/Logger/src/Logger.cpp +++ b/Foundation/samples/Logger/src/Logger.cpp @@ -31,10 +31,10 @@ int main(int argc, char** argv) { // set up two channel chains - one to the // console and the other one to a log file. - FormattingChannel* pFCConsole = new FormattingChannel(new PatternFormatter("%s: %p: %t")); + FormattingChannel* pFCConsole = new FormattingChannel(new PatternFormatter("[%O] %s: %p: %t")); pFCConsole->setChannel(new ConsoleChannel); pFCConsole->open(); - + FormattingChannel* pFCFile = new FormattingChannel(new PatternFormatter("%Y-%m-%d %H:%M:%S.%c %N[%P]:%s:%q:%t")); pFCFile->setChannel(new FileChannel("sample.log")); pFCFile->open(); @@ -43,21 +43,21 @@ int main(int argc, char** argv) // each channel chain. Logger& consoleLogger = Logger::create("ConsoleLogger", pFCConsole, Message::PRIO_INFORMATION); Logger& fileLogger = Logger::create("FileLogger", pFCFile, Message::PRIO_WARNING); - + // log some messages consoleLogger.error("An error message"); fileLogger.error("An error message"); - + consoleLogger.warning("A warning message"); fileLogger.error("A warning message"); - + consoleLogger.information("An information message"); fileLogger.information("An information message"); - + poco_information(consoleLogger, "Another informational message"); poco_warning_f2(consoleLogger, "A warning message with arguments: %d, %d", 1, 2); - + Logger::get("ConsoleLogger").error("Another error message"); - + return 0; } diff --git a/Foundation/samples/NotificationQueue/NotificationQueue.progen b/Foundation/samples/NotificationQueue/NotificationQueue.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/NotificationQueue/NotificationQueue.progen +++ b/Foundation/samples/NotificationQueue/NotificationQueue.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/NotificationQueue/src/NotificationQueue.cpp b/Foundation/samples/NotificationQueue/src/NotificationQueue.cpp index 2885d8423..c14a1bd07 100644 --- a/Foundation/samples/NotificationQueue/src/NotificationQueue.cpp +++ b/Foundation/samples/NotificationQueue/src/NotificationQueue.cpp @@ -36,12 +36,12 @@ class WorkNotification: public Notification { public: typedef AutoPtr Ptr; - + WorkNotification(int data): _data(data) { } - + int data() const { return _data; @@ -62,7 +62,7 @@ public: _queue(queue) { } - + void run() { Poco::Random rnd; @@ -84,7 +84,7 @@ public: else break; } } - + private: std::string _name; NotificationQueue& _queue; @@ -98,7 +98,7 @@ FastMutex Worker::_mutex; int main(int argc, char** argv) { NotificationQueue queue; - + // create some worker threads Worker worker1("Worker 1", queue); Worker worker2("Worker 2", queue); @@ -114,15 +114,15 @@ int main(int argc, char** argv) { queue.enqueueNotification(new WorkNotification(i)); } - - // wait until queue is empty and all threads are + + // wait until queue is empty and all threads are // waiting for new work. while (!queue.empty()) Thread::sleep(200); Thread::sleep(500); - + // stop all worker threads queue.wakeUpAll(); ThreadPool::defaultPool().joinAll(); - + return 0; } diff --git a/Foundation/samples/StringTokenizer/StringTokenizer.progen b/Foundation/samples/StringTokenizer/StringTokenizer.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/StringTokenizer/StringTokenizer.progen +++ b/Foundation/samples/StringTokenizer/StringTokenizer.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/Timer/Timer.progen b/Foundation/samples/Timer/Timer.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/Timer/Timer.progen +++ b/Foundation/samples/Timer/Timer.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/Timer/src/Timer.cpp b/Foundation/samples/Timer/src/Timer.cpp index 72193a092..5685f20bf 100644 --- a/Foundation/samples/Timer/src/Timer.cpp +++ b/Foundation/samples/Timer/src/Timer.cpp @@ -29,27 +29,27 @@ public: { _sw.start(); } - + void onTimer(Timer& timer) { std::cout << "Callback called after " << _sw.elapsed()/1000 << " milliseconds." << std::endl; } - + private: Stopwatch _sw; }; int main(int argc, char** argv) -{ +{ TimerExample example; Timer timer(250, 500); timer.start(TimerCallback(example, &TimerExample::onTimer)); - + Thread::sleep(5000); - + timer.stop(); - + return 0; } diff --git a/Foundation/samples/URI/URI.progen b/Foundation/samples/URI/URI.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/URI/URI.progen +++ b/Foundation/samples/URI/URI.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/URI/src/URI.cpp b/Foundation/samples/URI/src/URI.cpp index c386843c3..8fecd047a 100644 --- a/Foundation/samples/URI/src/URI.cpp +++ b/Foundation/samples/URI/src/URI.cpp @@ -20,19 +20,19 @@ using Poco::URI; int main(int argc, char** argv) { URI uri1("http://www.appinf.com:81/sample?example-query#somewhere"); - + std::cout << "Scheme: " << uri1.getScheme() << std::endl << "Authority: " << uri1.getAuthority() << std::endl << "Path: " << uri1.getPath() << std::endl << "Query: " << uri1.getQuery() << std::endl << "Fragment: " << uri1.getFragment() << std::endl; - + URI uri2; uri2.setScheme("https"); uri2.setAuthority("www.appinf.com"); uri2.setPath("/another sample"); - + std::cout << uri2.toString() << std::endl; - + return 0; } diff --git a/Foundation/samples/base64decode/base64decode.progen b/Foundation/samples/base64decode/base64decode.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/base64decode/base64decode.progen +++ b/Foundation/samples/base64decode/base64decode.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/base64decode/src/base64decode.cpp b/Foundation/samples/base64decode/src/base64decode.cpp index adda31ac5..1cc15bf4e 100644 --- a/Foundation/samples/base64decode/src/base64decode.cpp +++ b/Foundation/samples/base64decode/src/base64decode.cpp @@ -28,29 +28,29 @@ int main(int argc, char** argv) << " read base64-encoded , decode it and write the result to " << std::endl; return 1; } - + std::ifstream istr(argv[1]); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } - + std::ofstream ostr(argv[2], std::ios::binary); if (!ostr) { std::cerr << "cannot open output file: " << argv[2] << std::endl; return 3; } - + Base64Decoder decoder(istr); StreamCopier::copyStream(decoder, ostr); - + if (!ostr) { std::cerr << "error writing output file: " << argv[2] << std::endl; return 4; } - + return 0; } diff --git a/Foundation/samples/base64encode/base64encode.progen b/Foundation/samples/base64encode/base64encode.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/base64encode/base64encode.progen +++ b/Foundation/samples/base64encode/base64encode.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/base64encode/src/base64encode.cpp b/Foundation/samples/base64encode/src/base64encode.cpp index c525330af..d20c9601e 100644 --- a/Foundation/samples/base64encode/src/base64encode.cpp +++ b/Foundation/samples/base64encode/src/base64encode.cpp @@ -28,29 +28,29 @@ int main(int argc, char** argv) << " read , base64-encode it and write the result to " << std::endl; return 1; } - + std::ifstream istr(argv[1], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } - + std::ofstream ostr(argv[2]); if (!ostr) { std::cerr << "cannot open output file: " << argv[2] << std::endl; return 3; } - + Base64Encoder encoder(ostr); StreamCopier::copyStream(istr, encoder); - + if (!ostr) { std::cerr << "error writing output file: " << argv[2] << std::endl; return 4; } - + return 0; } diff --git a/Foundation/samples/deflate/deflate.progen b/Foundation/samples/deflate/deflate.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/deflate/deflate.progen +++ b/Foundation/samples/deflate/deflate.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/deflate/src/deflate.cpp b/Foundation/samples/deflate/src/deflate.cpp index f13c4863b..46b28b4e5 100644 --- a/Foundation/samples/deflate/src/deflate.cpp +++ b/Foundation/samples/deflate/src/deflate.cpp @@ -28,29 +28,29 @@ int main(int argc, char** argv) << " read , deflate (compress) it and write the result to " << std::endl; return 1; } - + std::ifstream istr(argv[1], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } - + std::ofstream ostr(argv[2], std::ios::binary); if (!ostr) { std::cerr << "cannot open output file: " << argv[2] << std::endl; return 3; } - + DeflatingOutputStream deflater(ostr); StreamCopier::copyStream(istr, deflater); - + if (!ostr) { std::cerr << "error writing output file: " << argv[2] << std::endl; return 4; } - + return 0; } diff --git a/Foundation/samples/dir/dir.progen b/Foundation/samples/dir/dir.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/dir/dir.progen +++ b/Foundation/samples/dir/dir.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/dir/src/dir.cpp b/Foundation/samples/dir/src/dir.cpp index fe771fb65..923219a80 100644 --- a/Foundation/samples/dir/src/dir.cpp +++ b/Foundation/samples/dir/src/dir.cpp @@ -33,7 +33,7 @@ int main(int argc, char** argv) dir = argv[1]; else dir = Path::current(); - + try { DirectoryIterator it(dir); @@ -57,6 +57,6 @@ int main(int argc, char** argv) std::cerr << exc.displayText() << std::endl; return 1; } - + return 0; } diff --git a/Foundation/samples/grep/grep.progen b/Foundation/samples/grep/grep.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/grep/grep.progen +++ b/Foundation/samples/grep/grep.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/grep/src/grep.cpp b/Foundation/samples/grep/src/grep.cpp index 5be5c1693..c0e34bb94 100644 --- a/Foundation/samples/grep/src/grep.cpp +++ b/Foundation/samples/grep/src/grep.cpp @@ -24,7 +24,7 @@ int main(int argc, char** argv) std::cout << "usage: " << argv[0] << ": [-i] [-x] pattern" << std::endl; return 1; } - + std::string pattern; int options = 0; for (int i = 1; i < argc; ++i) @@ -37,9 +37,9 @@ int main(int argc, char** argv) else pattern = arg; } - + RegularExpression re(pattern, options); - + int c = std::cin.get(); while (c != -1) { @@ -56,6 +56,6 @@ int main(int argc, char** argv) if (c != -1) c = std::cin.get(); } - + return 0; } diff --git a/Foundation/samples/hmacmd5/hmacmd5.progen b/Foundation/samples/hmacmd5/hmacmd5.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/hmacmd5/hmacmd5.progen +++ b/Foundation/samples/hmacmd5/hmacmd5.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/hmacmd5/src/hmacmd5.cpp b/Foundation/samples/hmacmd5/src/hmacmd5.cpp index 785c7df2a..4606a9ce4 100644 --- a/Foundation/samples/hmacmd5/src/hmacmd5.cpp +++ b/Foundation/samples/hmacmd5/src/hmacmd5.cpp @@ -33,23 +33,23 @@ int main(int argc, char** argv) << " create the HMAC-MD5 for , using " << std::endl; return 1; } - + std::string passphrase(argv[1]); - + std::ifstream istr(argv[2], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[2] << std::endl; return 2; } - + HMACEngine hmac(passphrase); DigestOutputStream dos(hmac); - + StreamCopier::copyStream(istr, dos); dos.close(); - + std::cout << DigestEngine::digestToHex(hmac.digest()) << std::endl; - + return 0; } diff --git a/Foundation/samples/inflate/inflate.progen b/Foundation/samples/inflate/inflate.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/inflate/inflate.progen +++ b/Foundation/samples/inflate/inflate.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/inflate/src/inflate.cpp b/Foundation/samples/inflate/src/inflate.cpp index 0762ab9a0..fbd48ec17 100644 --- a/Foundation/samples/inflate/src/inflate.cpp +++ b/Foundation/samples/inflate/src/inflate.cpp @@ -28,29 +28,29 @@ int main(int argc, char** argv) << " read deflated (compressed) , inflate it and write the result to " << std::endl; return 1; } - + std::ifstream istr(argv[1], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } - + std::ofstream ostr(argv[2], std::ios::binary); if (!ostr) { std::cerr << "cannot open output file: " << argv[2] << std::endl; return 3; } - + InflatingInputStream inflater(istr); StreamCopier::copyStream(inflater, ostr); - + if (!ostr) { std::cerr << "error writing output file: " << argv[2] << std::endl; return 4; } - + return 0; } diff --git a/Foundation/samples/md5/md5.progen b/Foundation/samples/md5/md5.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/md5/md5.progen +++ b/Foundation/samples/md5/md5.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/samples/md5/src/md5.cpp b/Foundation/samples/md5/src/md5.cpp index 0e3a24dfb..84a50cf13 100644 --- a/Foundation/samples/md5/src/md5.cpp +++ b/Foundation/samples/md5/src/md5.cpp @@ -32,21 +32,21 @@ int main(int argc, char** argv) << " create the MD5 digest for " << std::endl; return 1; } - + std::ifstream istr(argv[1], std::ios::binary); if (!istr) { std::cerr << "cannot open input file: " << argv[1] << std::endl; return 2; } - + MD5Engine md5; DigestOutputStream dos(md5); - + StreamCopier::copyStream(istr, dos); dos.close(); std::cout << DigestEngine::digestToHex(md5.digest()) << std::endl; - + return 0; } diff --git a/Foundation/samples/uuidgen/src/uuidgen.cpp b/Foundation/samples/uuidgen/src/uuidgen.cpp index e8df47344..33554b0d0 100644 --- a/Foundation/samples/uuidgen/src/uuidgen.cpp +++ b/Foundation/samples/uuidgen/src/uuidgen.cpp @@ -24,11 +24,11 @@ using Poco::Exception; int main(int argc, char** argv) { UUID uuid; - + std::string arg; if (argc > 1) arg = argv[1]; - + try { if (arg == "-random") @@ -37,7 +37,7 @@ int main(int argc, char** argv) uuid = UUIDGenerator::defaultGenerator().create(); else uuid = UUIDGenerator::defaultGenerator().createFromName(UUID::uri(), arg); - + std::cout << uuid.toString() << std::endl; } catch (Exception& exc) @@ -45,6 +45,6 @@ int main(int argc, char** argv) std::cerr << exc.displayText() << std::endl; return 1; } - + return 0; } diff --git a/Foundation/samples/uuidgen/uuidgen.progen b/Foundation/samples/uuidgen/uuidgen.progen index 7c2c98bb5..518a9d34a 100644 --- a/Foundation/samples/uuidgen/uuidgen.progen +++ b/Foundation/samples/uuidgen/uuidgen.progen @@ -7,4 +7,5 @@ vc.project.platforms = Win32 vc.project.configurations = debug_shared, release_shared, debug_static_mt, release_static_mt, debug_static_md, release_static_md vc.project.prototype = ${vc.project.name}_vs90.vcproj vc.project.compiler.include = ..\\..\\..\\Foundation\\include +vc.project.compiler.additionalOptions = /Zc:__cplusplus vc.project.linker.dependencies.Win32 = ws2_32.lib iphlpapi.lib diff --git a/Foundation/src/ASCIIEncoding.cpp b/Foundation/src/ASCIIEncoding.cpp index 66a1b3da9..862a0f5e7 100644 --- a/Foundation/src/ASCIIEncoding.cpp +++ b/Foundation/src/ASCIIEncoding.cpp @@ -27,24 +27,24 @@ const char* ASCIIEncoding::_names[] = }; -const TextEncoding::CharacterMap ASCIIEncoding::_charMap = +const TextEncoding::CharacterMap ASCIIEncoding::_charMap = { - /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - /* 10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - /* 20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - /* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - /* 60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - /* 70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - /* 80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* 90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* a0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* b0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* c0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* d0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* e0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* f0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + /* 10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + /* 20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + /* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + /* 60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + /* 70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + /* 80 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* 90 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* a0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* b0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* c0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* d0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* e0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* f0 */ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, }; diff --git a/Foundation/src/AbstractObserver.cpp b/Foundation/src/AbstractObserver.cpp index a0fd89657..715048981 100644 --- a/Foundation/src/AbstractObserver.cpp +++ b/Foundation/src/AbstractObserver.cpp @@ -32,7 +32,7 @@ AbstractObserver::~AbstractObserver() { } - + AbstractObserver& AbstractObserver::operator = (const AbstractObserver& /*observer*/) { return *this; diff --git a/Foundation/src/ActiveDispatcher.cpp b/Foundation/src/ActiveDispatcher.cpp index dbb031ee2..a39e5f7cf 100644 --- a/Foundation/src/ActiveDispatcher.cpp +++ b/Foundation/src/ActiveDispatcher.cpp @@ -29,16 +29,16 @@ namespace _pRunnable(pRunnable) { } - + ActiveRunnableBase::Ptr runnable() const { return _pRunnable; } - + private: ActiveRunnableBase::Ptr _pRunnable; }; - + class StopNotification: public Notification { }; diff --git a/Foundation/src/ArchiveStrategy.cpp b/Foundation/src/ArchiveStrategy.cpp index 08cacacbb..e45cddea8 100644 --- a/Foundation/src/ArchiveStrategy.cpp +++ b/Foundation/src/ArchiveStrategy.cpp @@ -40,11 +40,11 @@ public: compress(this, &ArchiveCompressor::compressImpl) { } - + ~ArchiveCompressor() { } - + ActiveMethod> compress; protected: @@ -83,7 +83,7 @@ protected: // -ArchiveStrategy::ArchiveStrategy(): +ArchiveStrategy::ArchiveStrategy(): _compress(false), _pCompressor(0) { @@ -174,7 +174,7 @@ LogFile* ArchiveByNumberStrategy::archive(LogFile* pFile) NumberFormatter::append(path, ++n); } while (exists(path)); - + while (n >= 0) { std::string oldPath = basePath; diff --git a/Foundation/src/Ascii.cpp b/Foundation/src/Ascii.cpp index 676b2db8e..5d5fab792 100644 --- a/Foundation/src/Ascii.cpp +++ b/Foundation/src/Ascii.cpp @@ -18,7 +18,7 @@ namespace Poco { -const int Ascii::CHARACTER_PROPERTIES[128] = +const int Ascii::CHARACTER_PROPERTIES[128] = { /* 00 . */ ACP_CONTROL, /* 01 . */ ACP_CONTROL, diff --git a/Foundation/src/AsyncChannel.cpp b/Foundation/src/AsyncChannel.cpp index 317eea6e4..37cdec477 100644 --- a/Foundation/src/AsyncChannel.cpp +++ b/Foundation/src/AsyncChannel.cpp @@ -51,7 +51,8 @@ private: AsyncChannel::AsyncChannel(Channel::Ptr pChannel, Thread::Priority prio): _pChannel(pChannel), - _thread("AsyncChannel") + _thread("AsyncChannel"), + _closed(false) { _thread.setPriority(prio); } @@ -94,21 +95,25 @@ void AsyncChannel::open() void AsyncChannel::close() { - if (_thread.isRunning()) + if (!_closed.exchange(true)) { - while (!_queue.empty()) Thread::sleep(100); - - do + if (_thread.isRunning()) { - _queue.wakeUpAll(); + while (!_queue.empty()) Thread::sleep(100); + + do + { + _queue.wakeUpAll(); + } + while (!_thread.tryJoin(100)); } - while (!_thread.tryJoin(100)); } } void AsyncChannel::log(const Message& msg) { + if (_closed) return; if (_queueSize != 0 && _queue.size() >= _queueSize) { ++_dropCount; diff --git a/Foundation/src/AtomicCounter.cpp b/Foundation/src/AtomicCounter.cpp index b1172976a..32a4ef6a0 100644 --- a/Foundation/src/AtomicCounter.cpp +++ b/Foundation/src/AtomicCounter.cpp @@ -23,7 +23,7 @@ AtomicCounter::AtomicCounter(): { } - + AtomicCounter::AtomicCounter(AtomicCounter::ValueType initialValue): _counter(initialValue) { @@ -47,7 +47,7 @@ AtomicCounter& AtomicCounter::operator = (const AtomicCounter& counter) return *this; } - + AtomicCounter& AtomicCounter::operator = (AtomicCounter::ValueType value) { _counter.store(value); diff --git a/Foundation/src/Base32Decoder.cpp b/Foundation/src/Base32Decoder.cpp index 8e5cf0e04..0e04871c9 100644 --- a/Foundation/src/Base32Decoder.cpp +++ b/Foundation/src/Base32Decoder.cpp @@ -32,7 +32,7 @@ namespace } -Base32DecoderBuf::Base32DecoderBuf(std::istream& istr): +Base32DecoderBuf::Base32DecoderBuf(std::istream& istr): _groupLength(0), _groupIndex(0), _buf(*istr.rdbuf()) @@ -61,7 +61,7 @@ Base32DecoderBuf::~Base32DecoderBuf() int Base32DecoderBuf::readFromDevice() { - if (_groupIndex < _groupLength) + if (_groupIndex < _groupLength) { return _group[_groupIndex++]; } @@ -109,11 +109,11 @@ int Base32DecoderBuf::readFromDevice() if (buffer[2] == '=') _groupLength = 1; - else if (buffer[4] == '=') + else if (buffer[4] == '=') _groupLength = 2; - else if (buffer[5] == '=') + else if (buffer[5] == '=') _groupLength = 3; - else if (buffer[7] == '=') + else if (buffer[7] == '=') _groupLength = 4; else _groupLength = 5; diff --git a/Foundation/src/Base32Encoder.cpp b/Foundation/src/Base32Encoder.cpp index dbac2c977..881d44299 100644 --- a/Foundation/src/Base32Encoder.cpp +++ b/Foundation/src/Base32Encoder.cpp @@ -27,7 +27,7 @@ const unsigned char Base32EncoderBuf::OUT_ENCODING[32] = }; -Base32EncoderBuf::Base32EncoderBuf(std::ostream& ostr, bool padding): +Base32EncoderBuf::Base32EncoderBuf(std::ostream& ostr, bool padding): _groupLength(0), _buf(*ostr.rdbuf()), _doPadding(padding) diff --git a/Foundation/src/Bugcheck.cpp b/Foundation/src/Bugcheck.cpp index 14f5170c8..36a250dc5 100644 --- a/Foundation/src/Bugcheck.cpp +++ b/Foundation/src/Bugcheck.cpp @@ -90,7 +90,7 @@ void Bugcheck::unexpected(const char* file, int line) catch (...) { } -#endif +#endif } diff --git a/Foundation/src/Clock.cpp b/Foundation/src/Clock.cpp index e52cd5db4..87336d1c9 100644 --- a/Foundation/src/Clock.cpp +++ b/Foundation/src/Clock.cpp @@ -85,7 +85,7 @@ Clock& Clock::operator = (ClockVal tv) } -void Clock::swap(Clock& timestamp) +void Clock::swap(Clock& timestamp) noexcept { std::swap(_clock, timestamp._clock); } @@ -112,7 +112,7 @@ void Clock::update() host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cs); clock_get_time(cs, &ts); mach_port_deallocate(mach_task_self(), cs); - + _clock = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000; #elif defined(POCO_VXWORKS) @@ -138,7 +138,7 @@ void Clock::update() Poco::Timestamp now; _clock = now.epochMicroseconds(); - + #endif } @@ -164,7 +164,7 @@ Clock::ClockDiff Clock::accuracy() host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cs); clock_get_attributes(cs, CLOCK_GET_TIME_RES, (clock_attr_t)&nanosecs, &n); mach_port_deallocate(mach_task_self(), cs); - + ClockVal acc = nanosecs/1000; return acc > 0 ? acc : 1; @@ -186,18 +186,18 @@ Clock::ClockDiff Clock::accuracy() struct timespec ts; if (clock_getres(CLOCK_MONOTONIC, &ts)) throw SystemException("cannot get system clock"); - + ClockVal acc = ClockVal(ts.tv_sec)*resolution() + ts.tv_nsec/1000; return acc > 0 ? acc : 1; #else return 1000; - + #endif } - + bool Clock::monotonic() { #if defined(POCO_OS_FAMILY_WINDOWS) @@ -223,7 +223,7 @@ bool Clock::monotonic() #else return false; - + #endif } diff --git a/Foundation/src/Condition.cpp b/Foundation/src/Condition.cpp index 0d237d69b..64bd88f24 100644 --- a/Foundation/src/Condition.cpp +++ b/Foundation/src/Condition.cpp @@ -30,7 +30,7 @@ Condition::~Condition() void Condition::signal() { FastMutex::ScopedLock lock(_mutex); - + if (!_waitQueue.empty()) { _waitQueue.front()->set(); @@ -42,7 +42,7 @@ void Condition::signal() void Condition::broadcast() { FastMutex::ScopedLock lock(_mutex); - + for (auto p: _waitQueue) { p->set(); diff --git a/Foundation/src/ConsoleChannel.cpp b/Foundation/src/ConsoleChannel.cpp index 9eafc3c43..9fecaa6c0 100644 --- a/Foundation/src/ConsoleChannel.cpp +++ b/Foundation/src/ConsoleChannel.cpp @@ -43,7 +43,7 @@ ConsoleChannel::~ConsoleChannel() void ConsoleChannel::log(const Message& msg) { FastMutex::ScopedLock lock(_mutex); - + _str << msg.getText() << std::endl; } @@ -52,7 +52,7 @@ FastMutex ColorConsoleChannel::_mutex; const std::string ColorConsoleChannel::CSI("\033["); -ColorConsoleChannel::ColorConsoleChannel(): +ColorConsoleChannel::ColorConsoleChannel(): _str(std::clog), _enableColors(true) { @@ -60,7 +60,7 @@ ColorConsoleChannel::ColorConsoleChannel(): } -ColorConsoleChannel::ColorConsoleChannel(std::ostream& str): +ColorConsoleChannel::ColorConsoleChannel(std::ostream& str): _str(str), _enableColors(true) { @@ -76,7 +76,7 @@ ColorConsoleChannel::~ColorConsoleChannel() void ColorConsoleChannel::log(const Message& msg) { FastMutex::ScopedLock lock(_mutex); - + if (_enableColors) { int color = _colors[msg.getPriority()]; @@ -87,14 +87,14 @@ void ColorConsoleChannel::log(const Message& msg) color &= 0xff; _str << CSI << color << "m"; } - + _str << msg.getText(); - + if (_enableColors) { _str << CSI << "0m"; } - + _str << std::endl; } diff --git a/Foundation/src/CountingStream.cpp b/Foundation/src/CountingStream.cpp index a2ecf907d..7b4b7ccf5 100644 --- a/Foundation/src/CountingStream.cpp +++ b/Foundation/src/CountingStream.cpp @@ -18,31 +18,31 @@ namespace Poco { -CountingStreamBuf::CountingStreamBuf(): - _pIstr(0), - _pOstr(0), - _chars(0), - _lines(0), +CountingStreamBuf::CountingStreamBuf(): + _pIstr(0), + _pOstr(0), + _chars(0), + _lines(0), _pos(0) { } -CountingStreamBuf::CountingStreamBuf(std::istream& istr): - _pIstr(&istr), - _pOstr(0), - _chars(0), - _lines(0), +CountingStreamBuf::CountingStreamBuf(std::istream& istr): + _pIstr(&istr), + _pOstr(0), + _chars(0), + _lines(0), _pos(0) { } -CountingStreamBuf::CountingStreamBuf(std::ostream& ostr): - _pIstr(0), - _pOstr(&ostr), - _chars(0), - _lines(0), +CountingStreamBuf::CountingStreamBuf(std::ostream& ostr): + _pIstr(0), + _pOstr(&ostr), + _chars(0), + _lines(0), _pos(0) { } @@ -99,13 +99,13 @@ void CountingStreamBuf::addChars(std::streamsize charsToAdd) _chars += charsToAdd; } - + void CountingStreamBuf::addLines(std::streamsize linesToAdd) { _lines += linesToAdd; } - + void CountingStreamBuf::addPos(std::streamsize posToAdd) { _pos += posToAdd; @@ -152,13 +152,13 @@ void CountingIOS::addChars(std::streamsize charsToAdd) _buf.addChars(charsToAdd); } - + void CountingIOS::addLines(std::streamsize linesToAdd) { _buf.addLines(linesToAdd); } - + void CountingIOS::addPos(std::streamsize posToAdd) { _buf.addPos(posToAdd); diff --git a/Foundation/src/DateTime.cpp b/Foundation/src/DateTime.cpp index 185aa0844..512a3df87 100644 --- a/Foundation/src/DateTime.cpp +++ b/Foundation/src/DateTime.cpp @@ -78,7 +78,7 @@ DateTime::DateTime(int year, int month, int day, int hour, int minute, int secon poco_assert (second >= 0 && second <= 60); // allow leap seconds poco_assert (millisecond >= 0 && millisecond <= 999); poco_assert (microsecond >= 0 && microsecond <= 999); - + _utcTime = toUtcTime(toJulianDay(year, month, day)) + 10*(hour*Timespan::HOURS + minute*Timespan::MINUTES + second*Timespan::SECONDS + millisecond*Timespan::MILLISECONDS + microsecond); } @@ -134,7 +134,7 @@ DateTime& DateTime::operator = (const DateTime& dateTime) return *this; } - + DateTime& DateTime::operator = (const Timestamp& timestamp) { _utcTime = timestamp.utcTime(); @@ -172,12 +172,12 @@ DateTime& DateTime::assign(int year, int month, int day, int hour, int minute, i _second = second; _millisecond = millisecond; _microsecond = microsecond; - + return *this; } -void DateTime::swap(DateTime& dateTime) +void DateTime::swap(DateTime& dateTime) noexcept { std::swap(_utcTime, dateTime._utcTime); std::swap(_year, dateTime._year); @@ -212,7 +212,7 @@ int DateTime::daysOfMonth(int year, int month) poco_assert (month >= 1 && month <= 12); static int daysOfMonthTable[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - + if (month == 2 && isLeapYear(year)) return 29; else @@ -243,7 +243,7 @@ int DateTime::week(int firstDayOfWeek) const while (DateTime(_year, 1, baseDay).dayOfWeek() != firstDayOfWeek) ++baseDay; int doy = dayOfYear(); - int offs = baseDay <= 4 ? 0 : 1; + int offs = baseDay <= 4 ? 0 : 1; if (doy < baseDay) return offs; else @@ -320,7 +320,7 @@ void DateTime::makeUTC(int tzd) operator -= (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS)); } - + void DateTime::makeLocal(int tzd) { operator += (Timespan(((Timestamp::TimeDiff) tzd)*Timespan::SECONDS)); @@ -331,7 +331,7 @@ double DateTime::toJulianDay(int year, int month, int day, int hour, int minute, { // lookup table for (153*month - 457)/5 - note that 3 <= month <= 14. static int lookup[] = {-91, -60, -30, 0, 31, 61, 92, 122, 153, 184, 214, 245, 275, 306, 337}; - + // day to double double dday = double(day) + ((double((hour*60 + minute)*60 + second)*1000 + millisecond)*1000 + microsecond)/86400000000.0; if (month < 3) diff --git a/Foundation/src/DateTimeFormatter.cpp b/Foundation/src/DateTimeFormatter.cpp index 25ce6b01f..7eb2969a6 100644 --- a/Foundation/src/DateTimeFormatter.cpp +++ b/Foundation/src/DateTimeFormatter.cpp @@ -57,9 +57,9 @@ void DateTimeFormatter::append(std::string& str, const DateTime& dateTime, const case 'A': str.append(dateTime.isAM() ? "AM" : "PM"); break; case 'M': NumberFormatter::append0(str, dateTime.minute(), 2); break; case 'S': NumberFormatter::append0(str, dateTime.second(), 2); break; - case 's': NumberFormatter::append0(str, dateTime.second(), 2); - str += '.'; - NumberFormatter::append0(str, dateTime.millisecond()*1000 + dateTime.microsecond(), 6); + case 's': NumberFormatter::append0(str, dateTime.second(), 2); + str += '.'; + NumberFormatter::append0(str, dateTime.millisecond()*1000 + dateTime.microsecond(), 6); break; case 'i': NumberFormatter::append0(str, dateTime.millisecond(), 3); break; case 'c': NumberFormatter::append(str, dateTime.millisecond()/100); break; @@ -146,7 +146,7 @@ void DateTimeFormatter::tzdRFC(std::string& str, int timeZoneDifferential) str += '-'; NumberFormatter::append0(str, -timeZoneDifferential/3600, 2); NumberFormatter::append0(str, (-timeZoneDifferential%3600)/60, 2); - } + } } else str += "GMT"; } diff --git a/Foundation/src/DateTimeParser.cpp b/Foundation/src/DateTimeParser.cpp index b58482c7b..c9eba1e7e 100644 --- a/Foundation/src/DateTimeParser.cpp +++ b/Foundation/src/DateTimeParser.cpp @@ -90,11 +90,11 @@ void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateT case 'o': SKIP_JUNK(); PARSE_NUMBER_N(month, 2); - break; + break; case 'y': SKIP_JUNK(); PARSE_NUMBER_N(year, 2); - if (year >= 69) + if (year >= 69) year += 1900; else year += 2000; @@ -108,7 +108,7 @@ void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateT PARSE_NUMBER(year); if (year < 1000) { - if (year >= 69) + if (year >= 69) year += 1900; else year += 2000; @@ -171,7 +171,7 @@ void DateTimeParser::parse(const std::string& fmt, const std::string& str, DateT if (day == 0) day = 1; if (DateTime::isValid(year, month, day, hour, minute, second, millis, micros)) dateTime.assign(year, month, day, hour, minute, second, millis, micros); - else + else throw SyntaxException("date/time component out of range"); timeZoneDifferential = tzd; } @@ -184,7 +184,7 @@ DateTime DateTimeParser::parse(const std::string& fmt, const std::string& str, i return result; } - + bool DateTimeParser::tryParse(const std::string& fmt, const std::string& str, DateTime& dateTime, int& timeZoneDifferential) { try @@ -205,7 +205,7 @@ void DateTimeParser::parse(const std::string& str, DateTime& dateTime, int& time throw SyntaxException("Unsupported or invalid date/time format"); } - + DateTime DateTimeParser::parse(const std::string& str, int& timeZoneDifferential) { DateTime result; @@ -215,11 +215,11 @@ DateTime DateTimeParser::parse(const std::string& str, int& timeZoneDifferential throw SyntaxException("Unsupported or invalid date/time format"); } - + bool DateTimeParser::tryParse(const std::string& str, DateTime& dateTime, int& timeZoneDifferential) { if (str.length() < 4) return false; - + if (str[3] == ',') return tryParse("%w, %e %b %r %H:%M:%S %Z", str, dateTime, timeZoneDifferential); else if (str[3] == ' ') @@ -326,14 +326,14 @@ int DateTimeParser::parseMonth(std::string::const_iterator& it, const std::strin std::string month; while (it != end && (Ascii::isSpace(*it) || Ascii::isPunct(*it))) ++it; bool isFirst = true; - while (it != end && Ascii::isAlpha(*it)) + while (it != end && Ascii::isAlpha(*it)) { char ch = (*it++); if (isFirst) { month += Ascii::toUpper(ch); isFirst = false; } else month += Ascii::toLower(ch); } if (month.length() < 3) throw SyntaxException("Month name must be at least three characters long", month); - for (int i = 0; i < 12; ++i) + for (int i = 0; i < 12; ++i) { if (DateTimeFormat::MONTH_NAMES[i].find(month) == 0) return i + 1; @@ -347,14 +347,14 @@ int DateTimeParser::parseDayOfWeek(std::string::const_iterator& it, const std::s std::string dow; while (it != end && (Ascii::isSpace(*it) || Ascii::isPunct(*it))) ++it; bool isFirst = true; - while (it != end && Ascii::isAlpha(*it)) + while (it != end && Ascii::isAlpha(*it)) { char ch = (*it++); if (isFirst) { dow += Ascii::toUpper(ch); isFirst = false; } else dow += Ascii::toLower(ch); } if (dow.length() < 3) throw SyntaxException("Weekday name must be at least three characters long", dow); - for (int i = 0; i < 7; ++i) + for (int i = 0; i < 7; ++i) { if (DateTimeFormat::WEEKDAY_NAMES[i].find(dow) == 0) return i; @@ -367,7 +367,7 @@ int DateTimeParser::parseAMPM(std::string::const_iterator& it, const std::string { std::string ampm; while (it != end && (Ascii::isSpace(*it) || Ascii::isPunct(*it))) ++it; - while (it != end && Ascii::isAlpha(*it)) + while (it != end && Ascii::isAlpha(*it)) { char ch = (*it++); ampm += Ascii::toUpper(ch); diff --git a/Foundation/src/DigestEngine.cpp b/Foundation/src/DigestEngine.cpp index bbdc34142..39c8512ca 100644 --- a/Foundation/src/DigestEngine.cpp +++ b/Foundation/src/DigestEngine.cpp @@ -13,6 +13,7 @@ #include "Poco/DigestEngine.h" +#include "Poco/Format.h" #include "Poco/Exception.h" @@ -29,15 +30,22 @@ DigestEngine::~DigestEngine() } -std::string DigestEngine::digestToHex(const Digest& bytes) +std::string DigestEngine::digestToHex(const Digest& bytes, std::size_t length) { static const char digits[] = "0123456789abcdef"; + const std::size_t fullLen = bytes.size()*2; + std::size_t len = length ? length*2 : fullLen; + if (len > fullLen) + throw Poco::InvalidArgumentException( + Poco::format("DigestEngine::digestToHex(): invalid length : %z," + "max alllowed is %z", length, fullLen)); std::string result; - result.reserve(bytes.size() * 2); + result.reserve(len); for (auto b: bytes) { result += digits[(b >> 4) & 0xF]; result += digits[b & 0xF]; + if (result.size() >= len) break; } return result; } diff --git a/Foundation/src/DigestStream.cpp b/Foundation/src/DigestStream.cpp index c5ec7b23b..27394d1cc 100644 --- a/Foundation/src/DigestStream.cpp +++ b/Foundation/src/DigestStream.cpp @@ -21,28 +21,28 @@ namespace Poco { const int DigestBuf::BUFFER_SIZE = 256; -DigestBuf::DigestBuf(DigestEngine& eng): - BufferedStreamBuf(BUFFER_SIZE, std::ios::out), - _eng(eng), +DigestBuf::DigestBuf(DigestEngine& eng): + BufferedStreamBuf(BUFFER_SIZE, std::ios::out), + _eng(eng), _pIstr(0), - _pOstr(0) -{ -} - - -DigestBuf::DigestBuf(DigestEngine& eng, std::istream& istr): - BufferedStreamBuf(BUFFER_SIZE, std::ios::in), - _eng(eng), - _pIstr(&istr), _pOstr(0) { } -DigestBuf::DigestBuf(DigestEngine& eng, std::ostream& ostr): - BufferedStreamBuf(BUFFER_SIZE, std::ios::out), - _eng(eng), - _pIstr(0), +DigestBuf::DigestBuf(DigestEngine& eng, std::istream& istr): + BufferedStreamBuf(BUFFER_SIZE, std::ios::in), + _eng(eng), + _pIstr(&istr), + _pOstr(0) +{ +} + + +DigestBuf::DigestBuf(DigestEngine& eng, std::ostream& ostr): + BufferedStreamBuf(BUFFER_SIZE, std::ios::out), + _eng(eng), + _pIstr(0), _pOstr(&ostr) { } @@ -110,8 +110,8 @@ DigestBuf* DigestIOS::rdbuf() } -DigestInputStream::DigestInputStream(DigestEngine& eng, std::istream& istr): - DigestIOS(eng, istr), +DigestInputStream::DigestInputStream(DigestEngine& eng, std::istream& istr): + DigestIOS(eng, istr), std::istream(&_buf) { } @@ -122,15 +122,15 @@ DigestInputStream::~DigestInputStream() } -DigestOutputStream::DigestOutputStream(DigestEngine& eng): - DigestIOS(eng), +DigestOutputStream::DigestOutputStream(DigestEngine& eng): + DigestIOS(eng), std::ostream(&_buf) { } -DigestOutputStream::DigestOutputStream(DigestEngine& eng, std::ostream& ostr): - DigestIOS(eng, ostr), +DigestOutputStream::DigestOutputStream(DigestEngine& eng, std::ostream& ostr): + DigestIOS(eng, ostr), std::ostream(&_buf) { } diff --git a/Foundation/src/DirectoryIterator_WIN32U.cpp b/Foundation/src/DirectoryIterator_WIN32U.cpp index 8f17bc314..7289016ee 100644 --- a/Foundation/src/DirectoryIterator_WIN32U.cpp +++ b/Foundation/src/DirectoryIterator_WIN32U.cpp @@ -44,7 +44,7 @@ DirectoryIteratorImpl::DirectoryIteratorImpl(const std::string& path): _fh(INVAL else { UnicodeConverter::toUTF8(_fd.cFileName, _current); - if (_current == "." || _current == "..") + if (_current == "." || _current == "..") next(); } } diff --git a/Foundation/src/DirectoryWatcher.cpp b/Foundation/src/DirectoryWatcher.cpp index 2f05977fb..6e72d2f4d 100644 --- a/Foundation/src/DirectoryWatcher.cpp +++ b/Foundation/src/DirectoryWatcher.cpp @@ -371,8 +371,8 @@ public: } private: - int _fd; - bool _stopped; + std::atomic _fd; + std::atomic _stopped; }; diff --git a/Foundation/src/Environment_WINCE.cpp b/Foundation/src/Environment_WINCE.cpp index afa59b68d..62f19bce3 100644 --- a/Foundation/src/Environment_WINCE.cpp +++ b/Foundation/src/Environment_WINCE.cpp @@ -121,7 +121,7 @@ std::string EnvironmentImpl::nodeNameImpl() { HKEY hKey; DWORD dwDisposition; - if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"\\Ident", 0, 0, 0, 0, 0, &hKey, &dwDisposition) != ERROR_SUCCESS) + if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"\\Ident", 0, 0, 0, 0, 0, &hKey, &dwDisposition) != ERROR_SUCCESS) throw SystemException("Cannot get node name", "registry key not found"); std::string value; @@ -130,7 +130,7 @@ std::string EnvironmentImpl::nodeNameImpl() DWORD dwData = sizeof(bData); if (RegQueryValueExW(hKey, L"Name", 0, &dwType, bData, &dwData) == ERROR_SUCCESS) { - switch (dwType) + switch (dwType) { case REG_SZ: UnicodeConverter::toUTF8(reinterpret_cast(bData), value); @@ -160,7 +160,7 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id) // Make an initial call to GetAdaptersInfo to get // the necessary size into len DWORD rc = GetAdaptersInfo(pAdapterInfo, &len); - if (rc == ERROR_BUFFER_OVERFLOW) + if (rc == ERROR_BUFFER_OVERFLOW) { delete [] reinterpret_cast(pAdapterInfo); pAdapterInfo = reinterpret_cast(new char[len]); @@ -172,10 +172,10 @@ void EnvironmentImpl::nodeIdImpl(NodeId& id) try { bool found = false; - if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR) + if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR) { pAdapter = pAdapterInfo; - while (pAdapter && !found) + while (pAdapter && !found) { if (pAdapter->Type == MIB_IF_TYPE_ETHERNET && pAdapter->AddressLength == sizeof(id)) { diff --git a/Foundation/src/Error.cpp b/Foundation/src/Error.cpp index 721b96ff3..f7aaae6c6 100644 --- a/Foundation/src/Error.cpp +++ b/Foundation/src/Error.cpp @@ -68,31 +68,31 @@ namespace Poco { setMessage(strerror_r(err, _buffer, sizeof(_buffer))); #else setMessage(strerror(err)); -#endif +#endif } - + ~StrErrorHelper() { } - + const std::string& message() const { return _message; } - + protected: void setMessage(int rc) /// Handles POSIX variant { _message = _buffer; } - + void setMessage(const char* msg) /// Handles GLIBC variant { _message = msg; } - + private: char _buffer[256]; std::string _message; diff --git a/Foundation/src/ErrorHandler.cpp b/Foundation/src/ErrorHandler.cpp index d0af8ea8a..6e60161f3 100644 --- a/Foundation/src/ErrorHandler.cpp +++ b/Foundation/src/ErrorHandler.cpp @@ -38,7 +38,7 @@ void ErrorHandler::exception(const Exception& exc) poco_debugger_msg(exc.what()); } - + void ErrorHandler::exception(const std::exception& exc) { poco_debugger_msg(exc.what()); @@ -63,7 +63,7 @@ void ErrorHandler::handle(const Exception& exc) } } - + void ErrorHandler::handle(const std::exception& exc) { FastMutex::ScopedLock lock(_mutex); diff --git a/Foundation/src/EventLogChannel.cpp b/Foundation/src/EventLogChannel.cpp index 1f51296bb..f9a9fb150 100644 --- a/Foundation/src/EventLogChannel.cpp +++ b/Foundation/src/EventLogChannel.cpp @@ -28,7 +28,7 @@ const std::string EventLogChannel::PROP_LOGHOST = "loghost"; const std::string EventLogChannel::PROP_LOGFILE = "logfile"; -EventLogChannel::EventLogChannel(): +EventLogChannel::EventLogChannel(): _logFile("Application"), _h(0) { @@ -46,16 +46,16 @@ EventLogChannel::EventLogChannel(): } -EventLogChannel::EventLogChannel(const std::string& name): - _name(name), +EventLogChannel::EventLogChannel(const std::string& name): + _name(name), _logFile("Application"), _h(0) { } -EventLogChannel::EventLogChannel(const std::string& name, const std::string& host): - _name(name), +EventLogChannel::EventLogChannel(const std::string& name, const std::string& host): + _name(name), _host(host), _logFile("Application"), _h(0) @@ -101,7 +101,7 @@ void EventLogChannel::log(const Message& msg) std::wstring utext; UnicodeConverter::toUTF16(msg.getText(), utext); const wchar_t* pMsg = utext.c_str(); - ReportEventW(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL); + ReportEventW(_h, getType(msg), getCategory(msg), POCO_MSG_LOG, NULL, 1, 0, &pMsg, NULL); } @@ -190,7 +190,7 @@ void EventLogChannel::setUpRegistry() const UnicodeConverter::toUTF16(key, ukey); DWORD rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, ukey.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &disp); if (rc != ERROR_SUCCESS) return; - + if (disp == REG_CREATED_NEW_KEY) { std::wstring path; @@ -209,10 +209,10 @@ void EventLogChannel::setUpRegistry() const #endif #endif #endif - + if (path.empty()) path = findLibrary(L"PocoMsg.dll"); - + if (!path.empty()) { DWORD count = 8; diff --git a/Foundation/src/Event_POSIX.cpp b/Foundation/src/Event_POSIX.cpp index 50fb6f78a..833dddff5 100644 --- a/Foundation/src/Event_POSIX.cpp +++ b/Foundation/src/Event_POSIX.cpp @@ -92,7 +92,10 @@ EventImpl::EventImpl(bool autoReset): _auto(autoReset), _state(false) EventImpl::~EventImpl() { - pthread_cond_destroy(&_cond); + if (0 == pthread_mutex_lock(&_mutex)) + pthread_cond_destroy(&_cond); + else poco_unexpected(); + pthread_mutex_unlock(&_mutex); pthread_mutex_destroy(&_mutex); } diff --git a/Foundation/src/Event_WIN32.cpp b/Foundation/src/Event_WIN32.cpp index 256951870..e2ff1efb3 100644 --- a/Foundation/src/Event_WIN32.cpp +++ b/Foundation/src/Event_WIN32.cpp @@ -53,7 +53,7 @@ bool EventImpl::waitImpl(long milliseconds) case WAIT_OBJECT_0: return true; default: - throw SystemException("wait for event failed"); + throw SystemException("wait for event failed"); } } diff --git a/Foundation/src/Exception.cpp b/Foundation/src/Exception.cpp index b8e5bacde..a0bfd5849 100644 --- a/Foundation/src/Exception.cpp +++ b/Foundation/src/Exception.cpp @@ -52,7 +52,7 @@ Exception::Exception(const Exception& exc): _pNested = exc._pNested ? exc._pNested->clone() : 0; } - + Exception::~Exception() noexcept { delete _pNested; @@ -84,13 +84,13 @@ const char* Exception::className() const noexcept return typeid(*this).name(); } - + const char* Exception::what() const noexcept { return name(); } - + std::string Exception::displayText() const { std::string txt = name(); diff --git a/Foundation/src/File.cpp b/Foundation/src/File.cpp index 0765fd489..7f96d5df7 100644 --- a/Foundation/src/File.cpp +++ b/Foundation/src/File.cpp @@ -93,7 +93,7 @@ File& File::operator = (const Path& path) } -void File::swap(File& file) +void File::swap(File& file) noexcept { swapImpl(file); } diff --git a/Foundation/src/FileChannel.cpp b/Foundation/src/FileChannel.cpp index 6ec311a18..ceb53a38b 100644 --- a/Foundation/src/FileChannel.cpp +++ b/Foundation/src/FileChannel.cpp @@ -39,7 +39,7 @@ const std::string FileChannel::PROP_PURGECOUNT = "purgeCount"; const std::string FileChannel::PROP_FLUSH = "flush"; const std::string FileChannel::PROP_ROTATEONOPEN = "rotateOnOpen"; -FileChannel::FileChannel(): +FileChannel::FileChannel(): _times("utc"), _compress(false), _flush(true), @@ -85,7 +85,7 @@ FileChannel::~FileChannel() void FileChannel::open() { FastMutex::ScopedLock lock(_mutex); - + if (!_pFile) { _pFile = new LogFile(_path); @@ -139,7 +139,7 @@ void FileChannel::log(const Message& msg) _pFile->write(msg.getText(), _flush); } - + void FileChannel::setProperty(const std::string& name, const std::string& value) { FastMutex::ScopedLock lock(_mutex); @@ -208,7 +208,7 @@ Timestamp FileChannel::creationDate() const return 0; } - + UInt64 FileChannel::size() const { if (_pFile) @@ -234,7 +234,7 @@ void FileChannel::setRotation(const std::string& rotation) while (it != end && Ascii::isSpace(*it)) ++it; std::string unit; while (it != end && Ascii::isAlpha(*it)) unit += *it++; - + RotateStrategy* pStrategy = 0; if ((rotation.find(',') != std::string::npos) || (rotation.find(':') != std::string::npos)) { @@ -379,13 +379,13 @@ int FileChannel::extractDigit(const std::string& value, std::string::const_itera while (it != end && Ascii::isSpace(*it)) ++it; while (it != end && Ascii::isDigit(*it)) - { + { digit *= 10; digit += *it++ - '0'; } if (digit == 0) - throw InvalidArgumentException("Zero is not valid purge age."); + throw InvalidArgumentException("Zero is not valid purge age."); if (nextToDigit) *nextToDigit = it; return digit; @@ -405,7 +405,7 @@ Timespan::TimeDiff FileChannel::extractFactor(const std::string& value, std::str std::string unit; while (start != value.end() && Ascii::isAlpha(*start)) unit += *start++; - + if (unit == "seconds") return Timespan::SECONDS; if (unit == "minutes") diff --git a/Foundation/src/FileStreamFactory.cpp b/Foundation/src/FileStreamFactory.cpp index 472559c95..ba22dafff 100644 --- a/Foundation/src/FileStreamFactory.cpp +++ b/Foundation/src/FileStreamFactory.cpp @@ -50,13 +50,13 @@ std::istream* FileStreamFactory::open(const Path& path) { File file(path); if (!file.exists()) throw FileNotFoundException(path.toString()); - + FileInputStream* istr = new FileInputStream(path.toString(), std::ios::binary); if (!istr->good()) { delete istr; throw OpenFileException(path.toString()); - } + } return istr; } diff --git a/Foundation/src/FileStream_POSIX.cpp b/Foundation/src/FileStream_POSIX.cpp index 848d7c367..faf0109c7 100644 --- a/Foundation/src/FileStream_POSIX.cpp +++ b/Foundation/src/FileStream_POSIX.cpp @@ -60,11 +60,11 @@ void FileStreamBuf::open(const std::string& path, std::ios::openmode mode) flags |= O_RDONLY; else flags |= O_WRONLY; - + _fd = ::open(path.c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (_fd == -1) File::handleLastError(_path); - + if ((mode & std::ios::app) || (mode & std::ios::ate)) seekoff(0, std::ios::end, mode); } @@ -73,10 +73,10 @@ void FileStreamBuf::open(const std::string& path, std::ios::openmode mode) int FileStreamBuf::readFromDevice(char* buffer, std::streamsize length) { if (_fd == -1) return -1; - + if (getMode() & std::ios::out) sync(); - + int n = read(_fd, buffer, length); if (n == -1) File::handleLastError(_path); @@ -123,7 +123,7 @@ bool FileStreamBuf::close() std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, std::ios::openmode mode) { - if (_fd == -1 || !(getMode() & mode)) + if (_fd == -1 || !(getMode() & mode)) return -1; if (getMode() & std::ios::out) @@ -154,7 +154,7 @@ std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mode) { - if (_fd == -1 || !(getMode() & mode)) + if (_fd == -1 || !(getMode() & mode)) return -1; if (getMode() & std::ios::out) diff --git a/Foundation/src/FileStream_WIN32.cpp b/Foundation/src/FileStream_WIN32.cpp index fb934e2a4..7e9ca7e4f 100644 --- a/Foundation/src/FileStream_WIN32.cpp +++ b/Foundation/src/FileStream_WIN32.cpp @@ -53,7 +53,7 @@ void FileStreamBuf::open(const std::string& path, std::ios::openmode mode) DWORD shareMode = FILE_SHARE_READ; if (!(mode & std::ios::out)) shareMode |= FILE_SHARE_WRITE; - + DWORD creationDisp = OPEN_EXISTING; if (mode & std::ios::trunc) creationDisp = CREATE_ALWAYS; @@ -61,14 +61,14 @@ void FileStreamBuf::open(const std::string& path, std::ios::openmode mode) creationDisp = OPEN_ALWAYS; DWORD flags = FILE_ATTRIBUTE_NORMAL; - + std::wstring utf16Path; FileImpl::convertPath(path, utf16Path); _handle = CreateFileW(utf16Path.c_str(), access, shareMode, NULL, creationDisp, flags, NULL); if (_handle == INVALID_HANDLE_VALUE) File::handleLastError(_path); - + if ((mode & std::ios::ate) || (mode & std::ios::app)) seekoff(0, std::ios::end, mode); } @@ -81,7 +81,7 @@ int FileStreamBuf::readFromDevice(char* buffer, std::streamsize length) if (getMode() & std::ios::out) sync(); - + DWORD bytesRead(0); BOOL rc = ReadFile(_handle, buffer, static_cast(length), &bytesRead, NULL); if (rc == 0) @@ -112,7 +112,7 @@ int FileStreamBuf::writeToDevice(const char* buffer, std::streamsize length) BOOL rc = WriteFile(_handle, buffer, static_cast(length), &bytesWritten, NULL); if (rc == 0) File::handleLastError(_path); - + _pos += bytesWritten; return static_cast(bytesWritten); @@ -144,7 +144,7 @@ std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, { if (INVALID_HANDLE_VALUE == _handle || !(getMode() & mode)) return -1; - + if (getMode() & std::ios::out) sync(); @@ -166,7 +166,7 @@ std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, { offset = FILE_END; } - + LARGE_INTEGER li; li.QuadPart = off; li.LowPart = SetFilePointer(_handle, li.LowPart, &li.HighPart, offset); diff --git a/Foundation/src/File_VX.cpp b/Foundation/src/File_VX.cpp index 97f2461e6..ad6b2e63b 100644 --- a/Foundation/src/File_VX.cpp +++ b/Foundation/src/File_VX.cpp @@ -289,7 +289,7 @@ void FileImpl::renameToImpl(const std::string& path, int options) struct stat st; if (stat(path.c_str(), &st) == 0 && (options &OPT_FAIL_ON_OVERWRITE_IMPL)) - throw FileExistsException(path, EEXIST); + throw FileExistsException(path, EEXIST); if (rename(_path.c_str(), path.c_str()) != 0) handleLastErrorImpl(_path); diff --git a/Foundation/src/File_WINCE.cpp b/Foundation/src/File_WINCE.cpp index 9ce78a41f..c894d3196 100644 --- a/Foundation/src/File_WINCE.cpp +++ b/Foundation/src/File_WINCE.cpp @@ -301,7 +301,7 @@ void FileImpl::renameToImpl(const std::string& path, int options) if (MoveFileW(_upath.c_str(), upath.c_str(), MOVEFILE_REPLACE_EXISTING) == 0) handleLastErrorImpl(_path); } - + } diff --git a/Foundation/src/Format.cpp b/Foundation/src/Format.cpp index 46d20f0b4..df1f37bfe 100644 --- a/Foundation/src/Format.cpp +++ b/Foundation/src/Format.cpp @@ -62,8 +62,8 @@ namespace } if (width > 0) str.width(width); } - - + + void parsePrec(std::ostream& str, std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt, std::vector::const_iterator& itVal) { if (itFmt != endFmt && *itFmt == '.') @@ -86,7 +86,7 @@ namespace if (prec >= 0) str.precision(prec); } } - + char parseMod(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt) { char mod = 0; @@ -96,13 +96,13 @@ namespace { case 'l': case 'h': - case 'L': + case 'L': case '?': mod = *itFmt++; break; } } return mod; } - + std::size_t parseIndex(std::string::const_iterator& itFmt, const std::string::const_iterator& endFmt) { int index = 0; @@ -129,8 +129,8 @@ namespace case 'f': str << std::fixed; break; } } - - + + void writeAnyInt(std::ostream& str, const Any& any) { if (any.type() == typeid(char)) @@ -223,7 +223,7 @@ namespace str << RefAnyCast(*itVal++); break; case 'z': - str << AnyCast(*itVal++); + str << AnyCast(*itVal++); break; case 'I': case 'D': @@ -241,7 +241,7 @@ namespace } -std::string format(const std::string& fmt, const Any& value) +std::string format(const std::string& fmt, const Any& value) { std::string result; format(result, fmt, value); @@ -260,7 +260,7 @@ void format(std::string& result, const std::string& fmt, const std::vector& std::string::const_iterator itFmt = fmt.begin(); std::string::const_iterator endFmt = fmt.end(); std::vector::const_iterator itVal = values.begin(); - std::vector::const_iterator endVal = values.end(); + std::vector::const_iterator endVal = values.end(); while (itFmt != endFmt) { switch (*itFmt) diff --git a/Foundation/src/FormattingChannel.cpp b/Foundation/src/FormattingChannel.cpp index bdaef07b9..a884fd936 100644 --- a/Foundation/src/FormattingChannel.cpp +++ b/Foundation/src/FormattingChannel.cpp @@ -20,22 +20,22 @@ namespace Poco { -FormattingChannel::FormattingChannel(): - _pFormatter(0), +FormattingChannel::FormattingChannel(): + _pFormatter(0), _pChannel(0) { } FormattingChannel::FormattingChannel(Formatter::Ptr pFormatter): - _pFormatter(pFormatter), + _pFormatter(pFormatter), _pChannel(0) { } -FormattingChannel::FormattingChannel(Formatter::Ptr pFormatter, Channel::Ptr pChannel): - _pFormatter(pFormatter), +FormattingChannel::FormattingChannel(Formatter::Ptr pFormatter, Channel::Ptr pChannel): + _pFormatter(pFormatter), _pChannel(pChannel) { } @@ -105,7 +105,7 @@ void FormattingChannel::open() _pChannel->open(); } - + void FormattingChannel::close() { if (_pChannel) diff --git a/Foundation/src/Glob.cpp b/Foundation/src/Glob.cpp index 4ca64debc..0f9fb4fc2 100644 --- a/Foundation/src/Glob.cpp +++ b/Foundation/src/Glob.cpp @@ -42,7 +42,7 @@ bool Glob::match(const std::string& subject) TextIterator endp(_pattern); TextIterator its(subject, utf8); TextIterator ends(subject); - + if ((_options & GLOB_DOT_SPECIAL) && its != ends && *its == '.' && (*itp == '?' || *itp == '*')) return false; else @@ -118,7 +118,7 @@ bool Glob::match(TextIterator& itp, const TextIterator& endp, TextIterator& its, } return true; case '[': - if (++itp != endp) + if (++itp != endp) { bool invert = *itp == '!'; if (invert) ++itp; @@ -165,7 +165,7 @@ bool Glob::matchSet(TextIterator& itp, const TextIterator& endp, int c) switch (*itp) { case ']': - ++itp; + ++itp; return false; case '\\': if (++itp == endp) throw SyntaxException("backslash must be followed by character in glob pattern"); diff --git a/Foundation/src/HashStatistic.cpp b/Foundation/src/HashStatistic.cpp index 52f618d7a..0203636c7 100644 --- a/Foundation/src/HashStatistic.cpp +++ b/Foundation/src/HashStatistic.cpp @@ -19,10 +19,10 @@ namespace Poco { HashStatistic::HashStatistic( - UInt32 tableSize, - UInt32 numEntries, - UInt32 numZeroEntries, - UInt32 maxEntry, + UInt32 tableSize, + UInt32 numEntries, + UInt32 numZeroEntries, + UInt32 maxEntry, std::vector details): _sizeOfTable(tableSize), _numberOfEntries(numEntries), diff --git a/Foundation/src/HexBinaryDecoder.cpp b/Foundation/src/HexBinaryDecoder.cpp index 7c80ac833..dc14ad5dc 100644 --- a/Foundation/src/HexBinaryDecoder.cpp +++ b/Foundation/src/HexBinaryDecoder.cpp @@ -19,7 +19,7 @@ namespace Poco { -HexBinaryDecoderBuf::HexBinaryDecoderBuf(std::istream& istr): +HexBinaryDecoderBuf::HexBinaryDecoderBuf(std::istream& istr): _buf(*istr.rdbuf()) { } diff --git a/Foundation/src/HexBinaryEncoder.cpp b/Foundation/src/HexBinaryEncoder.cpp index 728a2bfdf..5e1b2f274 100644 --- a/Foundation/src/HexBinaryEncoder.cpp +++ b/Foundation/src/HexBinaryEncoder.cpp @@ -18,7 +18,7 @@ namespace Poco { -HexBinaryEncoderBuf::HexBinaryEncoderBuf(std::ostream& ostr): +HexBinaryEncoderBuf::HexBinaryEncoderBuf(std::ostream& ostr): _pos(0), _lineLength(72), _uppercase(0), @@ -61,11 +61,11 @@ int HexBinaryEncoderBuf::writeToDevice(char c) { static const int eof = std::char_traits::eof(); static const char digits[] = "0123456789abcdef0123456789ABCDEF"; - + if (_buf.sputc(digits[_uppercase + ((c >> 4) & 0xF)]) == eof) return eof; ++_pos; if (_buf.sputc(digits[_uppercase + (c & 0xF)]) == eof) return eof; - if (++_pos >= _lineLength && _lineLength > 0) + if (++_pos >= _lineLength && _lineLength > 0) { if (_buf.sputc('\n') == eof) return eof; _pos = 0; diff --git a/Foundation/src/JSONString.cpp b/Foundation/src/JSONString.cpp index 2e901a1e3..e843867ff 100644 --- a/Foundation/src/JSONString.cpp +++ b/Foundation/src/JSONString.cpp @@ -49,11 +49,12 @@ void writeString(const std::string &value, T& obj, typename WriteFunc::Typ { for(std::string::const_iterator it = value.begin(), end = value.end(); it != end; ++it) { - if((*it >= 0 && *it <= 31) || (*it == '"') || (*it == '\\')) + if ((*it >= 0 && *it <= 31) || (*it == '"') || (*it == '\\')) { std::string str = Poco::UTF8::escape(it, it + 1, true); (obj.*write)(str.c_str(), str.size()); - }else (obj.*write)(&(*it), 1); + } + else (obj.*write)(&(*it), 1); } } if(wrap) (obj.*write)("\"", 1); diff --git a/Foundation/src/Latin1Encoding.cpp b/Foundation/src/Latin1Encoding.cpp index c5aa00d74..abab7a536 100644 --- a/Foundation/src/Latin1Encoding.cpp +++ b/Foundation/src/Latin1Encoding.cpp @@ -28,25 +28,25 @@ const char* Latin1Encoding::_names[] = }; -const TextEncoding::CharacterMap Latin1Encoding::_charMap = +const TextEncoding::CharacterMap Latin1Encoding::_charMap = { /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */ - /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - /* 10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - /* 20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - /* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - /* 60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - /* 70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, - /* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - /* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - /* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - /* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - /* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - /* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - /* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - /* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, + /* 00 */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + /* 10 */ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + /* 20 */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + /* 30 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + /* 40 */ 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + /* 50 */ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + /* 60 */ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + /* 70 */ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + /* 80 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + /* 90 */ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + /* a0 */ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + /* b0 */ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + /* c0 */ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + /* d0 */ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + /* e0 */ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + /* f0 */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, }; diff --git a/Foundation/src/Latin2Encoding.cpp b/Foundation/src/Latin2Encoding.cpp index a0c771500..2d8e8ba01 100644 --- a/Foundation/src/Latin2Encoding.cpp +++ b/Foundation/src/Latin2Encoding.cpp @@ -28,19 +28,19 @@ const char* Latin2Encoding::_names[] = }; -const TextEncoding::CharacterMap Latin2Encoding::_charMap = +const TextEncoding::CharacterMap Latin2Encoding::_charMap = { /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */ - /* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - /* 10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - /* 20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - /* 30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - /* 40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - /* 50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - /* 60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - /* 70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - /* 80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, - /* 90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + /* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + /* 20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + /* 30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + /* 40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + /* 50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + /* 60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + /* 70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + /* 80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + /* 90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, /* a0 */ 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, /* b0 */ 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, /* c0 */ 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, diff --git a/Foundation/src/Latin9Encoding.cpp b/Foundation/src/Latin9Encoding.cpp index eadc71f30..3f403540a 100644 --- a/Foundation/src/Latin9Encoding.cpp +++ b/Foundation/src/Latin9Encoding.cpp @@ -28,25 +28,25 @@ const char* Latin9Encoding::_names[] = }; -const TextEncoding::CharacterMap Latin9Encoding::_charMap = +const TextEncoding::CharacterMap Latin9Encoding::_charMap = { /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f */ - /* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, - /* 10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, - /* 20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, - /* 30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, - /* 40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, - /* 50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, - /* 60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, - /* 70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, - /* 80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, - /* 90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, - /* a0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, - /* b0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, - /* c0 */ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, - /* d0 */ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, - /* e0 */ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, - /* f0 */ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, + /* 00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, + /* 20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + /* 30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, + /* 40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + /* 50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + /* 60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + /* 70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f, + /* 80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f, + /* 90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f, + /* a0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* b0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, + /* c0 */ 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* d0 */ 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + /* e0 */ 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* f0 */ 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, }; diff --git a/Foundation/src/LineEndingConverter.cpp b/Foundation/src/LineEndingConverter.cpp index 49b4b7122..2f802fab9 100644 --- a/Foundation/src/LineEndingConverter.cpp +++ b/Foundation/src/LineEndingConverter.cpp @@ -24,9 +24,9 @@ const std::string LineEnding::NEWLINE_CRLF("\r\n"); const std::string LineEnding::NEWLINE_LF("\n"); -LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::istream& istr): - _pIstr(&istr), - _pOstr(0), +LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::istream& istr): + _pIstr(&istr), + _pOstr(0), _newLine(LineEnding::NEWLINE_DEFAULT), _lastChar(0) { @@ -34,9 +34,9 @@ LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::istream& istr): } -LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::ostream& ostr): - _pIstr(0), - _pOstr(&ostr), +LineEndingConverterStreamBuf::LineEndingConverterStreamBuf(std::ostream& ostr): + _pIstr(0), + _pOstr(&ostr), _newLine(LineEnding::NEWLINE_DEFAULT), _lastChar(0) { @@ -132,15 +132,15 @@ LineEndingConverterStreamBuf* LineEndingConverterIOS::rdbuf() } -InputLineEndingConverter::InputLineEndingConverter(std::istream& istr): - LineEndingConverterIOS(istr), +InputLineEndingConverter::InputLineEndingConverter(std::istream& istr): + LineEndingConverterIOS(istr), std::istream(&_buf) { } -InputLineEndingConverter::InputLineEndingConverter(std::istream& istr, const std::string& newLineCharacters): - LineEndingConverterIOS(istr), +InputLineEndingConverter::InputLineEndingConverter(std::istream& istr, const std::string& newLineCharacters): + LineEndingConverterIOS(istr), std::istream(&_buf) { setNewLine(newLineCharacters); @@ -152,15 +152,15 @@ InputLineEndingConverter::~InputLineEndingConverter() } -OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr): - LineEndingConverterIOS(ostr), +OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr): + LineEndingConverterIOS(ostr), std::ostream(&_buf) { } -OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr, const std::string& newLineCharacters): - LineEndingConverterIOS(ostr), +OutputLineEndingConverter::OutputLineEndingConverter(std::ostream& ostr, const std::string& newLineCharacters): + LineEndingConverterIOS(ostr), std::ostream(&_buf) { setNewLine(newLineCharacters); diff --git a/Foundation/src/LogFile_STD.cpp b/Foundation/src/LogFile_STD.cpp index 66dc45bf2..bfe1c292a 100644 --- a/Foundation/src/LogFile_STD.cpp +++ b/Foundation/src/LogFile_STD.cpp @@ -20,11 +20,12 @@ namespace Poco { -LogFileImpl::LogFileImpl(const std::string& path): +LogFileImpl::LogFileImpl(const std::string& path): _path(path), - _str(_path, std::ios::app) + _str(_path, std::ios::app), + _size(static_cast(_str.tellp())) { - if (sizeImpl() == 0) + if (_size == 0) _creationDate = File(path).getLastModified(); else _creationDate = File(path).created(); @@ -38,18 +39,25 @@ LogFileImpl::~LogFileImpl() void LogFileImpl::writeImpl(const std::string& text, bool flush) { + std::streampos pos = _str.tellp(); _str << text; if (flush) _str << std::endl; else _str << "\n"; - if (!_str.good()) throw WriteFileException(_path); + if (!_str.good()) + { + _str.clear(); + _str.seekp(pos); + throw WriteFileException(_path); + } + _size = static_cast(_str.tellp()); } UInt64 LogFileImpl::sizeImpl() const { - return (UInt64) _str.tellp(); + return _size; } diff --git a/Foundation/src/LogFile_WIN32U.cpp b/Foundation/src/LogFile_WIN32U.cpp index f42b98a7c..055e9c585 100644 --- a/Foundation/src/LogFile_WIN32U.cpp +++ b/Foundation/src/LogFile_WIN32U.cpp @@ -98,7 +98,7 @@ void LogFileImpl::createFile() { std::wstring upath; FileImpl::convertPath(_path, upath); - + _hFile = CreateFileW(upath.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (_hFile == INVALID_HANDLE_VALUE) throw OpenFileException(_path); SetFilePointer(_hFile, 0, 0, FILE_END); diff --git a/Foundation/src/Logger.cpp b/Foundation/src/Logger.cpp index 1b3446444..e8005a69c 100644 --- a/Foundation/src/Logger.cpp +++ b/Foundation/src/Logger.cpp @@ -69,7 +69,7 @@ void Logger::setProperty(const std::string& name, const std::string& value) setChannel(LoggingRegistry::defaultRegistry().channelForName(value)); else if (name == "level") setLevel(value); - else + else Channel::setProperty(name, value); } diff --git a/Foundation/src/LoggingRegistry.cpp b/Foundation/src/LoggingRegistry.cpp index da8feda24..7bf6e53d0 100644 --- a/Foundation/src/LoggingRegistry.cpp +++ b/Foundation/src/LoggingRegistry.cpp @@ -32,7 +32,7 @@ LoggingRegistry::~LoggingRegistry() Channel::Ptr LoggingRegistry::channelForName(const std::string& name) const { FastMutex::ScopedLock lock(_mutex); - + ChannelMap::const_iterator it = _channelMap.find(name); if (it != _channelMap.end()) return it->second; @@ -60,7 +60,7 @@ void LoggingRegistry::registerChannel(const std::string& name, Channel::Ptr pCha _channelMap[name] = ChannelPtr(pChannel, true); } - + void LoggingRegistry::registerFormatter(const std::string& name, Formatter::Ptr pFormatter) { FastMutex::ScopedLock lock(_mutex); diff --git a/Foundation/src/MD4Engine.cpp b/Foundation/src/MD4Engine.cpp index cab906231..02d37a03c 100644 --- a/Foundation/src/MD4Engine.cpp +++ b/Foundation/src/MD4Engine.cpp @@ -54,7 +54,7 @@ MD4Engine::~MD4Engine() reset(); } - + void MD4Engine::updateImpl(const void* input_, std::size_t inputLen) { const unsigned char* input = (const unsigned char*) input_; @@ -71,7 +71,7 @@ void MD4Engine::updateImpl(const void* input_, std::size_t inputLen) partLen = 64 - index; /* Transform as many times as possible. */ - if (inputLen >= partLen) + if (inputLen >= partLen) { std::memcpy(&_context.buffer[index], input, partLen); transform(_context.state, _context.buffer); @@ -107,7 +107,7 @@ void MD4Engine::reset() const DigestEngine::Digest& MD4Engine::digest() { - static const unsigned char PADDING[64] = + static const unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, diff --git a/Foundation/src/MD5Engine.cpp b/Foundation/src/MD5Engine.cpp index 7ac89f0bd..8ba995842 100644 --- a/Foundation/src/MD5Engine.cpp +++ b/Foundation/src/MD5Engine.cpp @@ -14,7 +14,7 @@ // MD5 (RFC 1321) algorithm: // Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All // rights reserved. -// +// // License to copy and use this software is granted provided that it // is identified as the "RSA Data Security, Inc. MD5 Message-Digest // Algorithm" in all material mentioning or referencing this software @@ -54,7 +54,7 @@ MD5Engine::~MD5Engine() reset(); } - + void MD5Engine::updateImpl(const void* input_, std::size_t inputLen) { const unsigned char* input = (const unsigned char*) input_; @@ -71,7 +71,7 @@ void MD5Engine::updateImpl(const void* input_, std::size_t inputLen) partLen = 64 - index; /* Transform as many times as possible. */ - if (inputLen >= partLen) + if (inputLen >= partLen) { std::memcpy(&_context.buffer[index], input, partLen); transform(_context.state, _context.buffer); @@ -107,7 +107,7 @@ void MD5Engine::reset() const DigestEngine::Digest& MD5Engine::digest() { - static const unsigned char PADDING[64] = + static const unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -286,7 +286,7 @@ void MD5Engine::encode(unsigned char* output, const UInt32* input, std::size_t l { unsigned int i, j; - for (i = 0, j = 0; j < len; i++, j += 4) + for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (unsigned char)(input[i] & 0xff); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); diff --git a/Foundation/src/MemoryPool.cpp b/Foundation/src/MemoryPool.cpp index 5b6e79cfa..4ee008b7d 100644 --- a/Foundation/src/MemoryPool.cpp +++ b/Foundation/src/MemoryPool.cpp @@ -33,7 +33,7 @@ MemoryPool::MemoryPool(std::size_t blockSize, int preAlloc, int maxAlloc): if (maxAlloc > 0 && maxAlloc < r) r = maxAlloc; _blocks.reserve(r); - + try { for (int i = 0; i < preAlloc; ++i) @@ -48,7 +48,7 @@ MemoryPool::MemoryPool(std::size_t blockSize, int preAlloc, int maxAlloc): } } - + MemoryPool::~MemoryPool() { clear(); @@ -68,7 +68,7 @@ void MemoryPool::clear() void* MemoryPool::get() { FastMutex::ScopedLock lock(_mutex); - + if (_blocks.empty()) { if (_maxAlloc == 0 || _allocated < _maxAlloc) @@ -86,11 +86,11 @@ void* MemoryPool::get() } } - + void MemoryPool::release(void* ptr) { FastMutex::ScopedLock lock(_mutex); - + try { _blocks.push_back(reinterpret_cast(ptr)); diff --git a/Foundation/src/MemoryStream.cpp b/Foundation/src/MemoryStream.cpp index cf3f4c325..699fc6849 100644 --- a/Foundation/src/MemoryStream.cpp +++ b/Foundation/src/MemoryStream.cpp @@ -30,8 +30,8 @@ MemoryIOS::~MemoryIOS() } -MemoryInputStream::MemoryInputStream(const char* pBuffer, std::streamsize bufferSize): - MemoryIOS(const_cast(pBuffer), bufferSize), +MemoryInputStream::MemoryInputStream(const char* pBuffer, std::streamsize bufferSize): + MemoryIOS(const_cast(pBuffer), bufferSize), std::istream(&_buf) { } @@ -42,8 +42,8 @@ MemoryInputStream::~MemoryInputStream() } -MemoryOutputStream::MemoryOutputStream(char* pBuffer, std::streamsize bufferSize): - MemoryIOS(pBuffer, bufferSize), +MemoryOutputStream::MemoryOutputStream(char* pBuffer, std::streamsize bufferSize): + MemoryIOS(pBuffer, bufferSize), std::ostream(&_buf) { } diff --git a/Foundation/src/Message.cpp b/Foundation/src/Message.cpp index 94a3b53b3..7de6dc354 100644 --- a/Foundation/src/Message.cpp +++ b/Foundation/src/Message.cpp @@ -27,6 +27,7 @@ namespace Poco { Message::Message(): _prio(PRIO_FATAL), _tid(0), + _ostid(0), _pid(0), _file(0), _line(0), @@ -41,6 +42,7 @@ Message::Message(const std::string& source, const std::string& text, Priority pr _text(text), _prio(prio), _tid(0), + _ostid(0), _pid(0), _file(0), _line(0), @@ -55,6 +57,7 @@ Message::Message(const std::string& source, const std::string& text, Priority pr _text(text), _prio(prio), _tid(0), + _ostid(0), _pid(0), _file(file), _line(line), @@ -70,6 +73,7 @@ Message::Message(const Message& msg): _prio(msg._prio), _time(msg._time), _tid(msg._tid), + _ostid(msg._ostid), _thread(msg._thread), _pid(msg._pid), _file(msg._file), @@ -88,6 +92,7 @@ Message::Message(Message&& msg) noexcept: _prio(std::move(msg._prio)), _time(std::move(msg._time)), _tid(std::move(msg._tid)), + _ostid(std::move(msg._ostid)), _thread(std::move(msg._thread)), _pid(std::move(msg._pid)), _file(std::move(msg._file)), @@ -104,6 +109,7 @@ Message::Message(const Message& msg, const std::string& text): _prio(msg._prio), _time(msg._time), _tid(msg._tid), + _ostid(msg._ostid), _thread(msg._thread), _pid(msg._pid), _file(msg._file), @@ -127,6 +133,7 @@ void Message::init() #if !defined(POCO_VXWORKS) _pid = Process::id(); #endif + _ostid = (IntPtr)Thread::currentOsTid(); Thread* pThread = Thread::current(); if (pThread) { @@ -154,6 +161,7 @@ Message& Message::operator = (Message&& msg) noexcept _prio = std::move(msg._prio); _time = std::move(msg._time); _tid = std::move(msg._tid); + _ostid = std::move(msg._ostid); _thread = std::move(msg._thread); _pid = std::move(msg._pid); _file = std::move(msg._file); @@ -173,6 +181,7 @@ void Message::swap(Message& msg) swap(_prio, msg._prio); swap(_time, msg._time); swap(_tid, msg._tid); + swap(_ostid, msg._ostid); swap(_thread, msg._thread); swap(_pid, msg._pid); swap(_file, msg._file); @@ -266,6 +275,15 @@ const std::string& Message::get(const std::string& param, const std::string& def return defaultValue; } +const Message::StringMap& Message::getAll() const +{ + static StringMap empty; + + if (_pMap) + return *_pMap; + + return empty; +} void Message::set(const std::string& param, const std::string& value) { diff --git a/Foundation/src/Mutex_WINCE.cpp b/Foundation/src/Mutex_WINCE.cpp index 90ea6956d..927d98d99 100644 --- a/Foundation/src/Mutex_WINCE.cpp +++ b/Foundation/src/Mutex_WINCE.cpp @@ -52,7 +52,7 @@ bool MutexImpl::tryLockImpl() case WAIT_OBJECT_0: return true; default: - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex"); } } @@ -66,7 +66,7 @@ bool MutexImpl::tryLockImpl(long milliseconds) case WAIT_OBJECT_0: return true; default: - throw SystemException("cannot lock mutex"); + throw SystemException("cannot lock mutex"); } } diff --git a/Foundation/src/NamedEvent_WIN32U.cpp b/Foundation/src/NamedEvent_WIN32U.cpp index 8a7ad1c18..a4fec5b7a 100644 --- a/Foundation/src/NamedEvent_WIN32U.cpp +++ b/Foundation/src/NamedEvent_WIN32U.cpp @@ -29,7 +29,7 @@ NamedEventImpl::NamedEventImpl(const std::string& name): _event = CreateEventW(NULL, FALSE, FALSE, _uname.c_str()); if (!_event) { - DWORD dwRetVal = GetLastError(); + DWORD dwRetVal = GetLastError(); throw SystemException(format("cannot create named event %s [Error %d: %s]", _name, (int)dwRetVal, Error::getMessage(dwRetVal))); } } diff --git a/Foundation/src/NamedMutex_WIN32U.cpp b/Foundation/src/NamedMutex_WIN32U.cpp index 1358658b9..40d99ed39 100644 --- a/Foundation/src/NamedMutex_WIN32U.cpp +++ b/Foundation/src/NamedMutex_WIN32U.cpp @@ -25,7 +25,7 @@ NamedMutexImpl::NamedMutexImpl(const std::string& name): { UnicodeConverter::toUTF16(_name, _uname); _mutex = CreateMutexW(NULL, FALSE, _uname.c_str()); - if (!_mutex) + if (!_mutex) throw SystemException("cannot create named mutex", _name); } diff --git a/Foundation/src/NestedDiagnosticContext.cpp b/Foundation/src/NestedDiagnosticContext.cpp index fda6e921d..3be966ace 100644 --- a/Foundation/src/NestedDiagnosticContext.cpp +++ b/Foundation/src/NestedDiagnosticContext.cpp @@ -43,7 +43,7 @@ NestedDiagnosticContext& NestedDiagnosticContext::operator = (const NestedDiagno return *this; } - + void NestedDiagnosticContext::push(const std::string& info) { Context ctx; @@ -53,7 +53,7 @@ void NestedDiagnosticContext::push(const std::string& info) _stack.push_back(ctx); } - + void NestedDiagnosticContext::push(const std::string& info, int line, const char* filename) { Context ctx; @@ -70,7 +70,7 @@ void NestedDiagnosticContext::pop() _stack.pop_back(); } - + int NestedDiagnosticContext::depth() const { return int(_stack.size()); @@ -89,7 +89,7 @@ std::string NestedDiagnosticContext::toString() const return result; } - + void NestedDiagnosticContext::dump(std::ostream& ostr) const { dump(ostr, "\n"); diff --git a/Foundation/src/NotificationQueue.cpp b/Foundation/src/NotificationQueue.cpp index 7b5969c9a..88a182a38 100644 --- a/Foundation/src/NotificationQueue.cpp +++ b/Foundation/src/NotificationQueue.cpp @@ -53,7 +53,7 @@ void NotificationQueue::enqueueNotification(Notification::Ptr pNotification) _waitQueue.pop_front(); pWI->pNf = pNotification; pWI->nfAvailable.set(); - } + } } @@ -71,7 +71,7 @@ void NotificationQueue::enqueueUrgentNotification(Notification::Ptr pNotificatio _waitQueue.pop_front(); pWI->pNf = pNotification; pWI->nfAvailable.set(); - } + } } @@ -162,7 +162,7 @@ bool NotificationQueue::empty() const return _nfQueue.empty(); } - + int NotificationQueue::size() const { FastMutex::ScopedLock lock(_mutex); @@ -173,7 +173,7 @@ int NotificationQueue::size() const void NotificationQueue::clear() { FastMutex::ScopedLock lock(_mutex); - _nfQueue.clear(); + _nfQueue.clear(); } diff --git a/Foundation/src/NullStream.cpp b/Foundation/src/NullStream.cpp index e27042587..70062a5ca 100644 --- a/Foundation/src/NullStream.cpp +++ b/Foundation/src/NullStream.cpp @@ -27,7 +27,7 @@ NullStreamBuf::~NullStreamBuf() { } - + int NullStreamBuf::readFromDevice() { return -1; diff --git a/Foundation/src/NumberParser.cpp b/Foundation/src/NumberParser.cpp index 56eeb1675..ab3ec14f8 100644 --- a/Foundation/src/NumberParser.cpp +++ b/Foundation/src/NumberParser.cpp @@ -28,7 +28,7 @@ #define I64_FMT "l" #elif defined(_MSC_VER) || defined(__MINGW32__) #define I64_FMT "I64" -#elif defined(__APPLE__) +#elif defined(__APPLE__) #define I64_FMT "q" #else #define I64_FMT "ll" @@ -201,7 +201,7 @@ bool NumberParser::parseBool(const std::string& s) throw SyntaxException("Not a valid bool number", s); } - + bool NumberParser::tryParseBool(const std::string& s, bool& value) { int n; @@ -226,7 +226,7 @@ bool NumberParser::tryParseBool(const std::string& s, bool& value) value = true; return true; } - + if (icompare(s, "false") == 0) { value = false; @@ -242,7 +242,7 @@ bool NumberParser::tryParseBool(const std::string& s, bool& value) value = false; return true; } - + return false; } diff --git a/Foundation/src/NumericString.cpp b/Foundation/src/NumericString.cpp index 2d932e0da..3815c95b4 100644 --- a/Foundation/src/NumericString.cpp +++ b/Foundation/src/NumericString.cpp @@ -13,23 +13,23 @@ #include "Poco/Bugcheck.h" - +#include "Poco/NumericString.h" // +++ double conversion +++ // don't collide with standalone double_conversion library #define double_conversion poco_double_conversion #define UNIMPLEMENTED poco_bugcheck -#include "diy-fp.cc" +#include "double-conversion.h" #include "cached-powers.cc" #include "bignum-dtoa.cc" #include "bignum.cc" #include "fast-dtoa.cc" #include "fixed-dtoa.cc" #include "strtod.cc" -#include "double-conversion.cc" +#include "double-to-string.cc" +#include "string-to-double.cc" // --- double conversion --- -#include "Poco/NumericString.h" poco_static_assert(POCO_MAX_FLT_STRING_LEN == double_conversion::kMaxSignificantDecimalDigits); #include "Poco/String.h" #include diff --git a/Foundation/src/Path.cpp b/Foundation/src/Path.cpp index 33be9b26c..7b85a65c6 100644 --- a/Foundation/src/Path.cpp +++ b/Foundation/src/Path.cpp @@ -169,7 +169,7 @@ Path& Path::operator = (const char* path) } -void Path::swap(Path& path) +void Path::swap(Path& path) noexcept { std::swap(_node, path._node); std::swap(_device, path._device); diff --git a/Foundation/src/Path_WINCE.cpp b/Foundation/src/Path_WINCE.cpp index 750f18dda..05d9c868c 100644 --- a/Foundation/src/Path_WINCE.cpp +++ b/Foundation/src/Path_WINCE.cpp @@ -134,7 +134,7 @@ void PathImpl::listRootsImpl(std::vector& roots) roots.push_back(root); } } - } + } while (FindNextFileW(hFind, &fd)); FindClose(hFind); } diff --git a/Foundation/src/PatternFormatter.cpp b/Foundation/src/PatternFormatter.cpp index e7e96b302..c014eef0c 100644 --- a/Foundation/src/PatternFormatter.cpp +++ b/Foundation/src/PatternFormatter.cpp @@ -80,6 +80,7 @@ void PatternFormatter::format(const Message& msg, std::string& text) case 'P': NumberFormatter::append(text, msg.getPid()); break; case 'T': text.append(msg.getThread()); break; case 'I': NumberFormatter::append(text, msg.getTid()); break; + case 'J': NumberFormatter::append(text, msg.getOsTid()); break; case 'N': text.append(Environment::nodeName()); break; case 'U': text.append(msg.getSourceFile() ? msg.getSourceFile() : ""); break; case 'O': text.append(msg.getSourceFile() ? Path(msg.getSourceFile()).getFileName() : ""); break; @@ -197,7 +198,7 @@ void PatternFormatter::parsePattern() } } - + void PatternFormatter::setProperty(const std::string& name, const std::string& value) { if (name == PROP_PATTERN) @@ -214,7 +215,7 @@ void PatternFormatter::setProperty(const std::string& name, const std::string& v _priorityNames = value; parsePriorityNames(); } - else + else { Formatter::setProperty(name, value); } @@ -250,7 +251,7 @@ void PatternFormatter::parsePriorityNames() const std::string& PatternFormatter::getPriorityName(int prio) { - poco_assert (1 <= prio && prio <= 8); + poco_assert (1 <= prio && prio <= 8); return _priorities[prio]; } diff --git a/Foundation/src/Pipe.cpp b/Foundation/src/Pipe.cpp index 8cd9eb244..ccf4cf79f 100644 --- a/Foundation/src/Pipe.cpp +++ b/Foundation/src/Pipe.cpp @@ -23,7 +23,7 @@ Pipe::Pipe(): { } - + Pipe::Pipe(const Pipe& pipe): _pImpl(pipe._pImpl) { diff --git a/Foundation/src/PipeImpl_WIN32.cpp b/Foundation/src/PipeImpl_WIN32.cpp index 87dbbbf3e..ac3372116 100644 --- a/Foundation/src/PipeImpl_WIN32.cpp +++ b/Foundation/src/PipeImpl_WIN32.cpp @@ -25,7 +25,7 @@ PipeImpl::PipeImpl() attr.nLength = sizeof(attr); attr.lpSecurityDescriptor = NULL; attr.bInheritHandle = FALSE; - + if (!CreatePipe(&_readHandle, &_writeHandle, &attr, 0)) throw CreateFileException("anonymous pipe"); } diff --git a/Foundation/src/PipeStream.cpp b/Foundation/src/PipeStream.cpp index 96fb32358..9d40bd3a3 100644 --- a/Foundation/src/PipeStream.cpp +++ b/Foundation/src/PipeStream.cpp @@ -23,7 +23,7 @@ namespace Poco { // -PipeStreamBuf::PipeStreamBuf(const Pipe& pipe, openmode mode): +PipeStreamBuf::PipeStreamBuf(const Pipe& pipe, openmode mode): BufferedStreamBuf(STREAM_BUFFER_SIZE, mode), _pipe(pipe) { diff --git a/Foundation/src/PriorityNotificationQueue.cpp b/Foundation/src/PriorityNotificationQueue.cpp index d0121160b..541611d47 100644 --- a/Foundation/src/PriorityNotificationQueue.cpp +++ b/Foundation/src/PriorityNotificationQueue.cpp @@ -54,7 +54,7 @@ void PriorityNotificationQueue::enqueueNotification(Notification::Ptr pNotificat _waitQueue.pop_front(); pWI->pNf = pNotification; pWI->nfAvailable.set(); - } + } } @@ -145,7 +145,7 @@ bool PriorityNotificationQueue::empty() const return _nfQueue.empty(); } - + int PriorityNotificationQueue::size() const { FastMutex::ScopedLock lock(_mutex); @@ -156,7 +156,7 @@ int PriorityNotificationQueue::size() const void PriorityNotificationQueue::clear() { FastMutex::ScopedLock lock(_mutex); - _nfQueue.clear(); + _nfQueue.clear(); } diff --git a/Foundation/src/RWLock.cpp b/Foundation/src/RWLock.cpp index ba3f7d142..2937a5798 100644 --- a/Foundation/src/RWLock.cpp +++ b/Foundation/src/RWLock.cpp @@ -37,7 +37,7 @@ RWLock::RWLock() { } - + RWLock::~RWLock() { } diff --git a/Foundation/src/RWLock_WIN32.cpp b/Foundation/src/RWLock_WIN32.cpp index 973b0ae3c..e4f922225 100644 --- a/Foundation/src/RWLock_WIN32.cpp +++ b/Foundation/src/RWLock_WIN32.cpp @@ -186,7 +186,7 @@ DWORD RWLockImpl::tryReadLockOnce() HANDLE h[2]; h[0] = _mutex; h[1] = _readEvent; - DWORD result = WaitForMultipleObjects(2, h, TRUE, 1); + DWORD result = WaitForMultipleObjects(2, h, TRUE, 1); switch (result) { case WAIT_OBJECT_0: diff --git a/Foundation/src/RWLock_WINCE.cpp b/Foundation/src/RWLock_WINCE.cpp index f383a9da5..f669605da 100644 --- a/Foundation/src/RWLock_WINCE.cpp +++ b/Foundation/src/RWLock_WINCE.cpp @@ -19,13 +19,13 @@ namespace Poco { -RWLockImpl::RWLockImpl(): +RWLockImpl::RWLockImpl(): _readerCount(0), _readerWaiting(0), _writerCount(0), _writerWaiting(0), _writeLock(false) - + { InitializeCriticalSection(&_cs); _readerGreen = CreateEventW(NULL, FALSE, TRUE, NULL); @@ -56,7 +56,7 @@ void RWLockImpl::readLockImpl() bool RWLockImpl::tryReadLockImpl(DWORD timeout) { bool wait = false; - do + do { EnterCriticalSection(&_cs); if (!_writerCount && !_writerWaiting) @@ -68,31 +68,31 @@ bool RWLockImpl::tryReadLockImpl(DWORD timeout) } _readerCount++; } - else + else { - if (!wait) + if (!wait) { _readerWaiting++; wait = true; } ResetEvent(_readerGreen); } - LeaveCriticalSection(&_cs); - if (wait) + LeaveCriticalSection(&_cs); + if (wait) { - if (WaitForSingleObject(_readerGreen, timeout) != WAIT_OBJECT_0) + if (WaitForSingleObject(_readerGreen, timeout) != WAIT_OBJECT_0) { EnterCriticalSection(&_cs); _readerWaiting--; - SetEvent(_readerGreen); + SetEvent(_readerGreen); SetEvent(_writerGreen); LeaveCriticalSection(&_cs); return false; } } - } + } while (wait); - + return true; } @@ -107,21 +107,21 @@ bool RWLockImpl::tryWriteLockImpl(DWORD timeout) { bool wait = false; - do + do { EnterCriticalSection(&_cs); if (!_readerCount && !_writerCount) { - if (wait) + if (wait) { _writerWaiting--; wait = false; } _writerCount++; } - else + else { - if (!wait) + if (!wait) { _writerWaiting++; wait = true; @@ -129,9 +129,9 @@ bool RWLockImpl::tryWriteLockImpl(DWORD timeout) ResetEvent(_writerGreen); } LeaveCriticalSection(&_cs); - if (wait) + if (wait) { - if (WaitForSingleObject(_writerGreen, timeout) != WAIT_OBJECT_0) + if (WaitForSingleObject(_writerGreen, timeout) != WAIT_OBJECT_0) { EnterCriticalSection(&_cs); _writerWaiting--; @@ -143,7 +143,7 @@ bool RWLockImpl::tryWriteLockImpl(DWORD timeout) } } while (wait); - + _writeLock = true; return true; } @@ -152,7 +152,7 @@ bool RWLockImpl::tryWriteLockImpl(DWORD timeout) void RWLockImpl::unlockImpl() { EnterCriticalSection(&_cs); - + if (_writeLock) { _writeLock = false; @@ -165,8 +165,8 @@ void RWLockImpl::unlockImpl() if (_writerWaiting) SetEvent(_writerGreen); else if (_readerWaiting) - SetEvent(_readerGreen); - + SetEvent(_readerGreen); + LeaveCriticalSection(&_cs); } diff --git a/Foundation/src/Random.cpp b/Foundation/src/Random.cpp index 43dd31eb1..59df7122f 100644 --- a/Foundation/src/Random.cpp +++ b/Foundation/src/Random.cpp @@ -14,7 +14,7 @@ // // // Based on the FreeBSD random number generator. -// src/lib/libc/stdlib/random.c,v 1.25 +// src/lib/libc/stdlib/random.c,v 1.25 // // Copyright (c) 1983, 1993 // The Regents of the University of California. All rights reserved. @@ -206,7 +206,7 @@ void Random::seed(UInt32 x) _state[0] = x; if (_randType == TYPE_0) lim = NSHUFF; - else + else { for (i = 1; i < _randDeg; i++) _state[i] = goodRand(_state[i - 1]); @@ -267,36 +267,36 @@ void Random::initState(UInt32 s, char* argState, Int32 n) { UInt32* intArgState = (UInt32*) argState; - if (n < BREAK_0) + if (n < BREAK_0) { poco_bugcheck_msg("not enough state"); return; } - if (n < BREAK_1) + if (n < BREAK_1) { _randType = TYPE_0; _randDeg = DEG_0; _randSep = SEP_0; - } - else if (n < BREAK_2) + } + else if (n < BREAK_2) { _randType = TYPE_1; _randDeg = DEG_1; _randSep = SEP_1; - } - else if (n < BREAK_3) + } + else if (n < BREAK_3) { _randType = TYPE_2; _randDeg = DEG_2; _randSep = SEP_2; - } - else if (n < BREAK_4) + } + else if (n < BREAK_4) { _randType = TYPE_3; _randDeg = DEG_3; _randSep = SEP_3; - } - else + } + else { _randType = TYPE_4; _randDeg = DEG_4; @@ -334,12 +334,12 @@ UInt32 Random::next() UInt32 i; UInt32 *f, *r; - if (_randType == TYPE_0) + if (_randType == TYPE_0) { i = _state[0]; _state[0] = i = goodRand(i) & 0x7FFFFFFF; - } - else + } + else { /* * Use local variables rather than static variables for speed. diff --git a/Foundation/src/RandomStream.cpp b/Foundation/src/RandomStream.cpp index 89137fe71..21ce6a378 100644 --- a/Foundation/src/RandomStream.cpp +++ b/Foundation/src/RandomStream.cpp @@ -51,7 +51,7 @@ int RandomBuf::readFromDevice(char* buffer, std::streamsize length) #else #if defined(POCO_OS_FAMILY_UNIX) int fd = open("/dev/urandom", O_RDONLY, 0); - if (fd >= 0) + if (fd >= 0) { n = read(fd, buffer, length); close(fd); @@ -65,7 +65,7 @@ int RandomBuf::readFromDevice(char* buffer, std::streamsize length) Random rnd1(256); Random rnd2(64); x += rnd1.next(); - + n = 0; SHA1Engine engine; UInt32 t = (UInt32) std::time(NULL); diff --git a/Foundation/src/RegularExpression.cpp b/Foundation/src/RegularExpression.cpp index 90f22b9f5..0ab0cefb8 100644 --- a/Foundation/src/RegularExpression.cpp +++ b/Foundation/src/RegularExpression.cpp @@ -16,39 +16,104 @@ #include "Poco/Exception.h" #include #if defined(POCO_UNBUNDLED) -#include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include #else -#include "pcre_config.h" -#include "pcre.h" +#include "pcre2_config.h" +#include "pcre2.h" #endif +namespace +{ + class MatchData + { + public: + MatchData(pcre2_code_8* code): + _match(pcre2_match_data_create_from_pattern_8(reinterpret_cast(code), nullptr)) + { + if (!_match) throw Poco::RegularExpressionException("cannot create match data"); + } + + ~MatchData() + { + if (_match) pcre2_match_data_free_8(_match); + } + + std::uint32_t count() const + { + return pcre2_get_ovector_count_8(_match); + } + + const PCRE2_SIZE* data() const + { + return pcre2_get_ovector_pointer_8(_match); + } + + operator pcre2_match_data_8*() + { + return _match; + } + + private: + pcre2_match_data_8* _match; + }; +} + + namespace Poco { -const int RegularExpression::OVEC_SIZE = 63; // must be multiple of 3 - - -RegularExpression::RegularExpression(const std::string& pattern, int options, bool study): _pcre(0), _extra(0) +RegularExpression::RegularExpression(const std::string& pattern, int options, bool /*study*/): _pcre(0) { - const char* error; - int offs; - _pcre = pcre_compile(pattern.c_str(), options, &error, &offs, 0); + int errorCode; + PCRE2_SIZE errorOffset; + unsigned nameCount; + unsigned nameEntrySize; + unsigned char* nameTable; + + pcre2_compile_context_8* context = pcre2_compile_context_create_8(nullptr); + if (!context) throw Poco::RegularExpressionException("cannot create compile context"); + + if (options & RE_NEWLINE_LF) + pcre2_set_newline_8(context, PCRE2_NEWLINE_LF); + else if (options & RE_NEWLINE_CRLF) + pcre2_set_newline_8(context, PCRE2_NEWLINE_CRLF); + else if (options & RE_NEWLINE_ANY) + pcre2_set_newline_8(context, PCRE2_NEWLINE_ANY); + else if (options & RE_NEWLINE_ANYCRLF) + pcre2_set_newline_8(context, PCRE2_NEWLINE_ANYCRLF); + else // default RE_NEWLINE_CR + pcre2_set_newline_8(context, PCRE2_NEWLINE_CR); + + _pcre = pcre2_compile_8(reinterpret_cast(pattern.c_str()), pattern.length(), compileOptions(options), &errorCode, &errorOffset, context); + pcre2_compile_context_free_8(context); + if (!_pcre) { + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message_8(errorCode, buffer, sizeof(buffer)); std::ostringstream msg; - msg << error << " (at offset " << offs << ")"; + msg << reinterpret_cast(buffer) << " (at offset " << errorOffset << ")"; throw RegularExpressionException(msg.str()); } - if (study) - _extra = pcre_study(reinterpret_cast(_pcre), 0, &error); + + pcre2_pattern_info_8(reinterpret_cast(_pcre), PCRE2_INFO_NAMECOUNT, &nameCount); + pcre2_pattern_info_8(reinterpret_cast(_pcre), PCRE2_INFO_NAMEENTRYSIZE, &nameEntrySize); + pcre2_pattern_info_8(reinterpret_cast(_pcre), PCRE2_INFO_NAMETABLE, &nameTable); + + for (int i = 0; i < nameCount; i++) + { + unsigned char* group = nameTable + 2 + (nameEntrySize * i); + int n = pcre2_substring_number_from_name_8(reinterpret_cast(_pcre), group); + _groups[n] = std::string(reinterpret_cast(group)); + } } RegularExpression::~RegularExpression() { - if (_pcre) pcre_free(reinterpret_cast(_pcre)); - if (_extra) pcre_free(reinterpret_cast(_extra)); + if (_pcre) pcre2_code_free_8(reinterpret_cast(_pcre)); } @@ -56,15 +121,15 @@ int RegularExpression::match(const std::string& subject, std::string::size_type { poco_assert (offset <= subject.length()); - int ovec[OVEC_SIZE]; - int rc = pcre_exec(reinterpret_cast(_pcre), reinterpret_cast(_extra), subject.c_str(), int(subject.size()), int(offset), options & 0xFFFF, ovec, OVEC_SIZE); - if (rc == PCRE_ERROR_NOMATCH) + MatchData matchData(reinterpret_cast(_pcre)); + int rc = pcre2_match_8(reinterpret_cast(_pcre), reinterpret_cast(subject.c_str()), subject.size(), offset, matchOptions(options), matchData, nullptr); + if (rc == PCRE2_ERROR_NOMATCH) { mtch.offset = std::string::npos; mtch.length = 0; return 0; } - else if (rc == PCRE_ERROR_BADOPTION) + else if (rc == PCRE2_ERROR_BADOPTION) { throw RegularExpressionException("bad option"); } @@ -74,10 +139,11 @@ int RegularExpression::match(const std::string& subject, std::string::size_type } else if (rc < 0) { - std::ostringstream msg; - msg << "PCRE error " << rc; - throw RegularExpressionException(msg.str()); + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message_8(rc, buffer, sizeof(buffer)); + throw RegularExpressionException(std::string(reinterpret_cast(buffer))); } + const PCRE2_SIZE* ovec = matchData.data(); mtch.offset = ovec[0] < 0 ? std::string::npos : ovec[0]; mtch.length = ovec[1] - mtch.offset; return rc; @@ -90,13 +156,13 @@ int RegularExpression::match(const std::string& subject, std::string::size_type matches.clear(); - int ovec[OVEC_SIZE]; - int rc = pcre_exec(reinterpret_cast(_pcre), reinterpret_cast(_extra), subject.c_str(), int(subject.size()), int(offset), options & 0xFFFF, ovec, OVEC_SIZE); - if (rc == PCRE_ERROR_NOMATCH) + MatchData matchData(reinterpret_cast(_pcre)); + int rc = pcre2_match_8(reinterpret_cast(_pcre), reinterpret_cast(subject.c_str()), subject.size(), offset, options & 0xFFFF, matchData, nullptr); + if (rc == PCRE2_ERROR_NOMATCH) { return 0; } - else if (rc == PCRE_ERROR_BADOPTION) + else if (rc == PCRE2_ERROR_BADOPTION) { throw RegularExpressionException("bad option"); } @@ -106,16 +172,26 @@ int RegularExpression::match(const std::string& subject, std::string::size_type } else if (rc < 0) { - std::ostringstream msg; - msg << "PCRE error " << rc; - throw RegularExpressionException(msg.str()); + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message_8(rc, buffer, sizeof(buffer)); + throw RegularExpressionException(std::string(reinterpret_cast(buffer))); } matches.reserve(rc); + const PCRE2_SIZE* ovec = matchData.data(); for (int i = 0; i < rc; ++i) { Match m; + GroupMap::const_iterator it; + m.offset = ovec[i*2] < 0 ? std::string::npos : ovec[i*2] ; m.length = ovec[i*2 + 1] - m.offset; + + it = _groups.find(i); + if (it != _groups.end()) + { + m.name = (*it).second; + } + matches.push_back(m); } return rc; @@ -203,13 +279,13 @@ std::string::size_type RegularExpression::substOne(std::string& subject, std::st { if (offset >= subject.length()) return std::string::npos; - int ovec[OVEC_SIZE]; - int rc = pcre_exec(reinterpret_cast(_pcre), reinterpret_cast(_extra), subject.c_str(), int(subject.size()), int(offset), options & 0xFFFF, ovec, OVEC_SIZE); - if (rc == PCRE_ERROR_NOMATCH) + MatchData matchData(reinterpret_cast(_pcre)); + int rc = pcre2_match_8(reinterpret_cast(_pcre), reinterpret_cast(subject.c_str()), subject.size(), offset, matchOptions(options), matchData, nullptr); + if (rc == PCRE2_ERROR_NOMATCH) { return std::string::npos; } - else if (rc == PCRE_ERROR_BADOPTION) + else if (rc == PCRE2_ERROR_BADOPTION) { throw RegularExpressionException("bad option"); } @@ -219,10 +295,11 @@ std::string::size_type RegularExpression::substOne(std::string& subject, std::st } else if (rc < 0) { - std::ostringstream msg; - msg << "PCRE error " << rc; - throw RegularExpressionException(msg.str()); + PCRE2_UCHAR buffer[256]; + pcre2_get_error_message_8(rc, buffer, sizeof(buffer)); + throw RegularExpressionException(std::string(reinterpret_cast(buffer))); } + const PCRE2_SIZE* ovec = matchData.data(); std::string result; std::string::size_type len = subject.length(); std::string::size_type pos = 0; @@ -281,4 +358,56 @@ bool RegularExpression::match(const std::string& subject, const std::string& pat } +int RegularExpression::compileOptions(int options) +{ + int pcreOptions = 0; + + if (options & RE_CASELESS) + pcreOptions |= PCRE2_CASELESS; + if (options & RE_MULTILINE) + pcreOptions |= PCRE2_MULTILINE; + if (options & RE_DOTALL) + pcreOptions |= PCRE2_DOTALL; + if (options & RE_EXTENDED) + pcreOptions |= PCRE2_EXTENDED; + if (options & RE_ANCHORED) + pcreOptions |= PCRE2_ANCHORED; + if (options & RE_DOLLAR_ENDONLY) + pcreOptions |= PCRE2_DOLLAR_ENDONLY; + if (options & RE_UNGREEDY) + pcreOptions |= PCRE2_UNGREEDY; + if (options & RE_UTF8) + pcreOptions |= PCRE2_UTF | PCRE2_UCP; + if (options & RE_NO_AUTO_CAPTURE) + pcreOptions |= PCRE2_NO_AUTO_CAPTURE; + if (options & RE_FIRSTLINE) + pcreOptions |= PCRE2_FIRSTLINE; + if (options & RE_DUPNAMES) + pcreOptions |= PCRE2_DUPNAMES; + + return pcreOptions; +} + + +int RegularExpression::matchOptions(int options) +{ + int pcreOptions = 0; + + if (options & RE_ANCHORED) + pcreOptions |= PCRE2_ANCHORED; + if (options & RE_NOTBOL) + pcreOptions |= PCRE2_NOTBOL; + if (options & RE_NOTEOL) + pcreOptions |= PCRE2_NOTEOL; + if (options & RE_NOTEMPTY) + pcreOptions |= PCRE2_NOTEMPTY; + if (options & RE_NO_AUTO_CAPTURE) + pcreOptions |= PCRE2_NO_AUTO_CAPTURE; + if (options & RE_NO_UTF8_CHECK) + pcreOptions |= PCRE2_NO_UTF_CHECK; + + return pcreOptions; +} + + } // namespace Poco diff --git a/Foundation/src/RotateStrategy.cpp b/Foundation/src/RotateStrategy.cpp index d3939b70f..f27eb9781 100644 --- a/Foundation/src/RotateStrategy.cpp +++ b/Foundation/src/RotateStrategy.cpp @@ -46,7 +46,7 @@ RotateStrategy::~RotateStrategy() const std::string RotateByIntervalStrategy::ROTATE_TEXT("# Log file created/rotated "); -RotateByIntervalStrategy::RotateByIntervalStrategy(const Timespan& span): +RotateByIntervalStrategy::RotateByIntervalStrategy(const Timespan& span): _span(span), _lastRotate(0) { diff --git a/Foundation/src/SHA1Engine.cpp b/Foundation/src/SHA1Engine.cpp index fb945a6f5..71fe2d857 100644 --- a/Foundation/src/SHA1Engine.cpp +++ b/Foundation/src/SHA1Engine.cpp @@ -54,7 +54,7 @@ inline void SHA1Engine::byteReverse(UInt32* buffer, int byteCount) #endif // POCO_ARCH_LITTLE_ENDIAN } - + void SHA1Engine::updateImpl(const void* buffer_, std::size_t count) { const BYTE* buffer = (const BYTE*) buffer_; @@ -71,7 +71,7 @@ void SHA1Engine::updateImpl(const void* buffer_, std::size_t count) { db[_context.slop++] = *(buffer++); if (_context.slop == BLOCK_SIZE) - { + { /* transform this one block */ SHA1_BYTE_REVERSE(_context.data, BLOCK_SIZE); transform(); diff --git a/Foundation/src/SHA2Engine.cpp b/Foundation/src/SHA2Engine.cpp index b09b30a79..84fd285f5 100644 --- a/Foundation/src/SHA2Engine.cpp +++ b/Foundation/src/SHA2Engine.cpp @@ -41,7 +41,6 @@ typedef struct Poco::UInt64 state64[8]; } state; - SHA2Engine::ALGORITHM size; unsigned char buffer[128]; } HASHCONTEXT; @@ -274,7 +273,7 @@ void SHA2Engine::updateImpl(const void* buffer_, std::size_t count) Poco::UInt32 left = 0; HASHCONTEXT* pContext = (HASHCONTEXT*)_context; unsigned char* data = (unsigned char*)buffer_; - if (pContext->size > SHA_256) + if (_algorithm > SHA_256) { left = (Poco::UInt32)(pContext->total.total64[0] & 0x7F); size_t fill = 128 - left; @@ -323,7 +322,31 @@ void SHA2Engine::updateImpl(const void* buffer_, std::size_t count) std::size_t SHA2Engine::digestLength() const { - return (size_t)((int)_algorithm / 8); + size_t result = 0; + + switch (_algorithm) + { + case SHA_224: + result = 224; + break; + case SHA_256: + result = 256; + break; + case SHA_384: + result = 384; + break; + case SHA_512: + result = 512; + break; + case SHA_512_224: + result = 224; + break; + case SHA_512_256: + result = 256; + break; + } + + return result / 8; } @@ -332,7 +355,6 @@ void SHA2Engine::reset() if (_context != NULL) free(_context); _context = calloc(1, sizeof(HASHCONTEXT)); HASHCONTEXT* pContext = (HASHCONTEXT*)_context; - pContext->size = _algorithm; if (_algorithm == SHA_224) { pContext->state.state32[0] = 0xC1059ED8; @@ -366,7 +388,7 @@ void SHA2Engine::reset() pContext->state.state64[6] = UL64(0xDB0C2E0D64F98FA7); pContext->state.state64[7] = UL64(0x47B5481DBEFA4FA4); } - else + else if (_algorithm == SHA_512) { pContext->state.state64[0] = UL64(0x6A09E667F3BCC908); pContext->state.state64[1] = UL64(0xBB67AE8584CAA73B); @@ -377,6 +399,27 @@ void SHA2Engine::reset() pContext->state.state64[6] = UL64(0x1F83D9ABFB41BD6B); pContext->state.state64[7] = UL64(0x5BE0CD19137E2179); } + else if (_algorithm == SHA_512_224) + { + pContext->state.state64[0] = UL64(0x8C3D37C819544DA2); + pContext->state.state64[1] = UL64(0x73E1996689DCD4D6); + pContext->state.state64[2] = UL64(0x1DFAB7AE32FF9C82); + pContext->state.state64[3] = UL64(0x679DD514582F9FCF); + pContext->state.state64[4] = UL64(0x0F6D2B697BD44DA8); + pContext->state.state64[5] = UL64(0x77E36F7304C48942); + pContext->state.state64[6] = UL64(0x3F9D85A86A1D36C8); + pContext->state.state64[7] = UL64(0x1112E6AD91D692A1); + } else + { + pContext->state.state64[0] = UL64(0x22312194FC2BF72C); + pContext->state.state64[1] = UL64(0x9F555FA3C84C64C2); + pContext->state.state64[2] = UL64(0x2393B86B6F53B151); + pContext->state.state64[3] = UL64(0x963877195940EABD); + pContext->state.state64[4] = UL64(0x96283EE2A88EFFE3); + pContext->state.state64[5] = UL64(0xBE5E1E2553863992); + pContext->state.state64[6] = UL64(0x2B0199FC2C85B8AA); + pContext->state.state64[7] = UL64(0x0EB72DDC81C52CA2); + } } @@ -388,7 +431,8 @@ const DigestEngine::Digest& SHA2Engine::digest() size_t last, padn; unsigned char hash[64]; memset(hash, 0, 64); - if (pContext->size > SHA_256) + + if (_algorithm > SHA_256) { unsigned char msglen[16]; Poco::UInt64 high = (pContext->total.total64[0] >> 61) | (pContext->total.total64[1] << 3); @@ -405,7 +449,7 @@ const DigestEngine::Digest& SHA2Engine::digest() PUT_UINT64(pContext->state.state64[3], hash, 24); PUT_UINT64(pContext->state.state64[4], hash, 32); PUT_UINT64(pContext->state.state64[5], hash, 40); - if (pContext->size > SHA_384) + if (_algorithm > SHA_384) { PUT_UINT64(pContext->state.state64[6], hash, 48); PUT_UINT64(pContext->state.state64[7], hash, 56); @@ -429,7 +473,7 @@ const DigestEngine::Digest& SHA2Engine::digest() PUT_UINT32(pContext->state.state32[4], hash, 16); PUT_UINT32(pContext->state.state32[5], hash, 20); PUT_UINT32(pContext->state.state32[6], hash, 24); - if (pContext->size > SHA_224) PUT_UINT32(pContext->state.state32[7], hash, 28); + if (_algorithm > SHA_224) PUT_UINT32(pContext->state.state32[7], hash, 28); } _digest.insert(_digest.begin(), hash, hash + digestLength()); reset(); diff --git a/Foundation/src/Semaphore_WIN32.cpp b/Foundation/src/Semaphore_WIN32.cpp index 2ec04a8c0..99b15a69d 100644 --- a/Foundation/src/Semaphore_WIN32.cpp +++ b/Foundation/src/Semaphore_WIN32.cpp @@ -57,7 +57,7 @@ bool SemaphoreImpl::waitImpl(long milliseconds) case WAIT_OBJECT_0: return true; default: - throw SystemException("wait for semaphore failed"); + throw SystemException("wait for semaphore failed"); } } diff --git a/Foundation/src/SharedLibrary.cpp b/Foundation/src/SharedLibrary.cpp index bad305fef..a2bdce57a 100644 --- a/Foundation/src/SharedLibrary.cpp +++ b/Foundation/src/SharedLibrary.cpp @@ -22,7 +22,7 @@ #include "SharedLibrary_VX.cpp" #elif defined(POCO_OS_FAMILY_UNIX) #include "SharedLibrary_UNIX.cpp" -#elif defined(POCO_OS_FAMILY_WINDOWS) +#elif defined(POCO_OS_FAMILY_WINDOWS) #include "SharedLibrary_WIN32U.cpp" #endif diff --git a/Foundation/src/SharedLibrary_HPUX.cpp b/Foundation/src/SharedLibrary_HPUX.cpp index 668bb5f64..610ae718b 100644 --- a/Foundation/src/SharedLibrary_HPUX.cpp +++ b/Foundation/src/SharedLibrary_HPUX.cpp @@ -59,6 +59,7 @@ void SharedLibraryImpl::unloadImpl() bool SharedLibraryImpl::isLoadedImpl() const { + FastMutex::ScopedLock lock(_mutex); return _handle != 0; } diff --git a/Foundation/src/SharedLibrary_UNIX.cpp b/Foundation/src/SharedLibrary_UNIX.cpp index 4a3dc2ffb..6695b5a14 100644 --- a/Foundation/src/SharedLibrary_UNIX.cpp +++ b/Foundation/src/SharedLibrary_UNIX.cpp @@ -74,6 +74,7 @@ void SharedLibraryImpl::unloadImpl() bool SharedLibraryImpl::isLoadedImpl() const { + FastMutex::ScopedLock lock(_mutex); return _handle != 0; } diff --git a/Foundation/src/SharedLibrary_VX.cpp b/Foundation/src/SharedLibrary_VX.cpp index bb2b14681..d30c35e9d 100644 --- a/Foundation/src/SharedLibrary_VX.cpp +++ b/Foundation/src/SharedLibrary_VX.cpp @@ -99,6 +99,7 @@ void SharedLibraryImpl::unloadImpl() bool SharedLibraryImpl::isLoadedImpl() const { + FastMutex::ScopedLock lock(_mutex); return _moduleId != 0; } diff --git a/Foundation/src/SharedLibrary_WIN32U.cpp b/Foundation/src/SharedLibrary_WIN32U.cpp index 081098049..ff56a8844 100644 --- a/Foundation/src/SharedLibrary_WIN32U.cpp +++ b/Foundation/src/SharedLibrary_WIN32U.cpp @@ -77,6 +77,7 @@ void SharedLibraryImpl::unloadImpl() bool SharedLibraryImpl::isLoadedImpl() const { + FastMutex::ScopedLock lock(_mutex); return _handle != 0; } diff --git a/Foundation/src/SharedMemory_WIN32.cpp b/Foundation/src/SharedMemory_WIN32.cpp index 65959bf85..45beaa840 100644 --- a/Foundation/src/SharedMemory_WIN32.cpp +++ b/Foundation/src/SharedMemory_WIN32.cpp @@ -54,7 +54,7 @@ SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, Sh dwRetVal = GetLastError(); throw SystemException(format("Cannot open shared memory object %s [Error %d: %s]", _name, static_cast(dwRetVal), Error::getMessage(dwRetVal))); } -#endif +#endif } map(); } diff --git a/Foundation/src/SignalHandler.cpp b/Foundation/src/SignalHandler.cpp index eaa1dc7ec..d405f73dd 100644 --- a/Foundation/src/SignalHandler.cpp +++ b/Foundation/src/SignalHandler.cpp @@ -89,7 +89,7 @@ void SignalHandler::handleSignal(int sig) JumpBufferVec& jb = jumpBufferVec(); if (!jb.empty()) siglongjmp(jb.back().buf, sig); - + // Abort if no jump buffer registered std::abort(); } diff --git a/Foundation/src/SimpleFileChannel.cpp b/Foundation/src/SimpleFileChannel.cpp index 81a0deb12..e87061bac 100644 --- a/Foundation/src/SimpleFileChannel.cpp +++ b/Foundation/src/SimpleFileChannel.cpp @@ -30,7 +30,7 @@ const std::string SimpleFileChannel::PROP_ROTATION = "rotation"; const std::string SimpleFileChannel::PROP_FLUSH = "flush"; -SimpleFileChannel::SimpleFileChannel(): +SimpleFileChannel::SimpleFileChannel(): _limit(0), _flush(true), _pFile(0) @@ -64,7 +64,7 @@ SimpleFileChannel::~SimpleFileChannel() void SimpleFileChannel::open() { FastMutex::ScopedLock lock(_mutex); - + if (!_pFile) { File primary(_path); @@ -103,7 +103,7 @@ void SimpleFileChannel::log(const Message& msg) _pFile->write(msg.getText(), _flush); } - + void SimpleFileChannel::setProperty(const std::string& name, const std::string& value) { FastMutex::ScopedLock lock(_mutex); @@ -148,7 +148,7 @@ Timestamp SimpleFileChannel::creationDate() const return 0; } - + UInt64 SimpleFileChannel::size() const { if (_pFile) @@ -180,7 +180,7 @@ void SimpleFileChannel::setRotation(const std::string& rotation) while (it != end && Ascii::isSpace(*it)) ++it; std::string unit; while (it != end && Ascii::isAlpha(*it)) unit += *it++; - + if (unit == "K") _limit = n*1024; else if (unit == "M") diff --git a/Foundation/src/SortedDirectoryIterator.cpp b/Foundation/src/SortedDirectoryIterator.cpp index 9cc572401..15bd8e4be 100644 --- a/Foundation/src/SortedDirectoryIterator.cpp +++ b/Foundation/src/SortedDirectoryIterator.cpp @@ -81,7 +81,7 @@ void SortedDirectoryIterator::scan() { isDir = (*this)->isDirectory(); } - catch (...) + catch (...) { } if (isDir) diff --git a/Foundation/src/SplitterChannel.cpp b/Foundation/src/SplitterChannel.cpp index 488297524..af1c26c16 100644 --- a/Foundation/src/SplitterChannel.cpp +++ b/Foundation/src/SplitterChannel.cpp @@ -97,7 +97,7 @@ void SplitterChannel::close() int SplitterChannel::count() const { FastMutex::ScopedLock lock(_mutex); - + return (int) _channels.size(); } diff --git a/Foundation/src/StreamChannel.cpp b/Foundation/src/StreamChannel.cpp index 817c047a6..046db76d3 100644 --- a/Foundation/src/StreamChannel.cpp +++ b/Foundation/src/StreamChannel.cpp @@ -32,7 +32,7 @@ StreamChannel::~StreamChannel() void StreamChannel::log(const Message& msg) { FastMutex::ScopedLock lock(_mutex); - + _str << msg.getText() << std::endl; } diff --git a/Foundation/src/StreamConverter.cpp b/Foundation/src/StreamConverter.cpp index 452abd7f2..2433c9b9e 100644 --- a/Foundation/src/StreamConverter.cpp +++ b/Foundation/src/StreamConverter.cpp @@ -59,7 +59,7 @@ int StreamConverterBuf::readFromDevice() _pos = 0; _sequenceLength = 0; int c = _pIstr->get(); - if (c == -1) return -1; + if (c == -1) return -1; poco_assert (c < 256); int uc; @@ -134,14 +134,14 @@ int StreamConverterBuf::errors() const } -StreamConverterIOS::StreamConverterIOS(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): +StreamConverterIOS::StreamConverterIOS(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): _buf(istr, inEncoding, outEncoding, defaultChar) { poco_ios_init(&_buf); } -StreamConverterIOS::StreamConverterIOS(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): +StreamConverterIOS::StreamConverterIOS(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): _buf(ostr, inEncoding, outEncoding, defaultChar) { poco_ios_init(&_buf); @@ -165,7 +165,7 @@ int StreamConverterIOS::errors() const } -InputStreamConverter::InputStreamConverter(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): +InputStreamConverter::InputStreamConverter(std::istream& istr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): StreamConverterIOS(istr, inEncoding, outEncoding, defaultChar), std::istream(&_buf) { @@ -177,7 +177,7 @@ InputStreamConverter::~InputStreamConverter() } -OutputStreamConverter::OutputStreamConverter(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): +OutputStreamConverter::OutputStreamConverter(std::ostream& ostr, const TextEncoding& inEncoding, const TextEncoding& outEncoding, int defaultChar): StreamConverterIOS(ostr, inEncoding, outEncoding, defaultChar), std::ostream(&_buf) { diff --git a/Foundation/src/StreamTokenizer.cpp b/Foundation/src/StreamTokenizer.cpp index 99dc4482d..bb57d4702 100644 --- a/Foundation/src/StreamTokenizer.cpp +++ b/Foundation/src/StreamTokenizer.cpp @@ -66,11 +66,11 @@ void StreamTokenizer::addToken(Token* pToken, bool ignore) _tokens.push_back(ti); } - + const Token* StreamTokenizer::next() { poco_check_ptr (_pIstr); - + static const int eof = std::char_traits::eof(); int first = _pIstr->get(); @@ -81,7 +81,7 @@ const Token* StreamTokenizer::next() if (ti.pToken->start((char) first, *_pIstr)) { ti.pToken->finish(*_pIstr); - if (ti.ignore) + if (ti.ignore) { first = _pIstr->get(); it = _tokens.begin(); diff --git a/Foundation/src/String.cpp b/Foundation/src/String.cpp index 91b21087e..1e0e94314 100644 --- a/Foundation/src/String.cpp +++ b/Foundation/src/String.cpp @@ -26,7 +26,7 @@ int icompare(const std::string& str, std::string::size_type pos, std::string::si std::string::size_type sz = str.size(); if (pos > sz) pos = sz; if (pos + n > sz) n = sz - pos; - std::string::const_iterator it1 = str.begin() + pos; + std::string::const_iterator it1 = str.begin() + pos; std::string::const_iterator end1 = str.begin() + pos + n; while (it1 != end1 && it2 != end2) { @@ -96,7 +96,7 @@ int icompare(const std::string& str, std::string::size_type pos, std::string::si std::string::size_type sz = str.size(); if (pos > sz) pos = sz; if (pos + n > sz) n = sz - pos; - std::string::const_iterator it = str.begin() + pos; + std::string::const_iterator it = str.begin() + pos; std::string::const_iterator end = str.begin() + pos + n; while (it != end && *ptr) { @@ -159,11 +159,11 @@ std::string remove(const std::string& str, const std::string::value_type ch, std return result; } - + std::string& replaceInPlace(std::string& str, const std::string& from, const std::string& to, std::string::size_type start) { poco_assert (from.size() > 0); - + std::string result; std::string::size_type pos = 0; result.append(str, 0, start); diff --git a/Foundation/src/StringTokenizer.cpp b/Foundation/src/StringTokenizer.cpp index dea7f07d5..baa830316 100644 --- a/Foundation/src/StringTokenizer.cpp +++ b/Foundation/src/StringTokenizer.cpp @@ -31,7 +31,7 @@ StringTokenizer::StringTokenizer(const std::string& str, const std::string& sepa for (; it != end; ++it) { - if (separators.find(*it) != std::string::npos) + if (separators.find(*it) != std::string::npos) { if (doTrim) trim(token); if (!token.empty() || !ignoreEmpty) _tokens.push_back(token); @@ -50,7 +50,7 @@ StringTokenizer::StringTokenizer(const std::string& str, const std::string& sepa if (doTrim) trim(token); if (!token.empty() || !ignoreEmpty) _tokens.push_back(token); } - else if (lastToken) + else if (lastToken) { _tokens.push_back(std::string()); } @@ -100,7 +100,7 @@ std::size_t StringTokenizer::count(const std::string& token) const std::string::size_type StringTokenizer::find(const std::string& token, std::string::size_type pos) const -{ +{ TokenVec::const_iterator it = std::find(_tokens.begin() + pos, _tokens.end(), token); if (it != _tokens.end()) { diff --git a/Foundation/src/SynchronizedObject.cpp b/Foundation/src/SynchronizedObject.cpp index 6a42e6594..3a00c25c5 100644 --- a/Foundation/src/SynchronizedObject.cpp +++ b/Foundation/src/SynchronizedObject.cpp @@ -22,7 +22,7 @@ SynchronizedObject::SynchronizedObject() { } - + SynchronizedObject::~SynchronizedObject() { } diff --git a/Foundation/src/SyslogChannel.cpp b/Foundation/src/SyslogChannel.cpp index 769f4982f..754d98c12 100644 --- a/Foundation/src/SyslogChannel.cpp +++ b/Foundation/src/SyslogChannel.cpp @@ -26,18 +26,18 @@ const std::string SyslogChannel::PROP_FACILITY = "facility"; const std::string SyslogChannel::PROP_OPTIONS = "options"; -SyslogChannel::SyslogChannel(): - _options(SYSLOG_CONS), - _facility(SYSLOG_USER), +SyslogChannel::SyslogChannel(): + _options(SYSLOG_CONS), + _facility(SYSLOG_USER), _open(false) { } -SyslogChannel::SyslogChannel(const std::string& name, int options, int facility): - _name(name), - _options(options), - _facility(facility), +SyslogChannel::SyslogChannel(const std::string& name, int options, int facility): + _name(name), + _options(options), + _facility(facility), _open(false) { } @@ -69,7 +69,8 @@ void SyslogChannel::close() void SyslogChannel::log(const Message& msg) { if (!_open) open(); - syslog(getPrio(msg), "%s", msg.getText().c_str()); + const int pri = getPrio(msg) + _facility; + syslog(pri, "%s", msg.getText().c_str()); } diff --git a/Foundation/src/Task.cpp b/Foundation/src/Task.cpp index a512c36d9..8367d571a 100644 --- a/Foundation/src/Task.cpp +++ b/Foundation/src/Task.cpp @@ -57,7 +57,7 @@ void Task::run() { TaskManager* pOwner = getOwner(); if (pOwner) - pOwner->taskStarted(this); + pOwner->taskStarted(this); try { _state = TASK_RUNNING; @@ -129,11 +129,11 @@ void Task::postNotification(Notification* pNf) poco_check_ptr (pNf); FastMutex::ScopedLock lock(_mutex); - + if (_pOwner) - { _pOwner->postNotification(pNf); - } + else if (pNf) + pNf->release(); } diff --git a/Foundation/src/TaskManager.cpp b/Foundation/src/TaskManager.cpp index 67a3c91fe..615541ed9 100644 --- a/Foundation/src/TaskManager.cpp +++ b/Foundation/src/TaskManager.cpp @@ -43,10 +43,10 @@ TaskManager::~TaskManager() void TaskManager::start(Task* pTask) { TaskPtr pAutoTask(pTask); // take ownership immediately - FastMutex::ScopedLock lock(_mutex); - pAutoTask->setOwner(this); pAutoTask->setState(Task::TASK_STARTING); + + FastMutex::ScopedLock lock(_mutex); _taskList.push_back(pAutoTask); try { @@ -83,7 +83,7 @@ void TaskManager::joinAll() TaskManager::TaskList TaskManager::taskList() const { FastMutex::ScopedLock lock(_mutex); - + return _taskList; } @@ -134,7 +134,7 @@ void TaskManager::taskCancelled(Task* pTask) void TaskManager::taskFinished(Task* pTask) { _nc.postNotification(new TaskFinishedNotification(pTask)); - + FastMutex::ScopedLock lock(_mutex); for (TaskList::iterator it = _taskList.begin(); it != _taskList.end(); ++it) { diff --git a/Foundation/src/TaskNotification.cpp b/Foundation/src/TaskNotification.cpp index cbb7d4d89..c14244ca8 100644 --- a/Foundation/src/TaskNotification.cpp +++ b/Foundation/src/TaskNotification.cpp @@ -36,7 +36,7 @@ TaskStartedNotification::TaskStartedNotification(Task* pTask): { } - + TaskStartedNotification::~TaskStartedNotification() { } @@ -47,7 +47,7 @@ TaskCancelledNotification::TaskCancelledNotification(Task* pTask): { } - + TaskCancelledNotification::~TaskCancelledNotification() { } @@ -58,7 +58,7 @@ TaskFinishedNotification::TaskFinishedNotification(Task* pTask): { } - + TaskFinishedNotification::~TaskFinishedNotification() { } @@ -70,7 +70,7 @@ TaskFailedNotification::TaskFailedNotification(Task* pTask, const Exception& exc { } - + TaskFailedNotification::~TaskFailedNotification() { delete _pException; @@ -83,7 +83,7 @@ TaskProgressNotification::TaskProgressNotification(Task* pTask, float progress): { } - + TaskProgressNotification::~TaskProgressNotification() { } diff --git a/Foundation/src/TeeStream.cpp b/Foundation/src/TeeStream.cpp index b3ef72b70..da789b025 100644 --- a/Foundation/src/TeeStream.cpp +++ b/Foundation/src/TeeStream.cpp @@ -18,19 +18,19 @@ namespace Poco { -TeeStreamBuf::TeeStreamBuf(): +TeeStreamBuf::TeeStreamBuf(): _pIstr(0) { } -TeeStreamBuf::TeeStreamBuf(std::istream& istr): +TeeStreamBuf::TeeStreamBuf(std::istream& istr): _pIstr(&istr) { } -TeeStreamBuf::TeeStreamBuf(std::ostream& ostr): +TeeStreamBuf::TeeStreamBuf(std::ostream& ostr): _pIstr(0) { _streams.push_back(&ostr); diff --git a/Foundation/src/TemporaryFile.cpp b/Foundation/src/TemporaryFile.cpp index c341256a5..96f4445bb 100644 --- a/Foundation/src/TemporaryFile.cpp +++ b/Foundation/src/TemporaryFile.cpp @@ -70,15 +70,15 @@ private: }; -TemporaryFile::TemporaryFile(): - File(tempName()), +TemporaryFile::TemporaryFile(): + File(tempName()), _keep(false) { } -TemporaryFile::TemporaryFile(const std::string& tempDir): - File(tempName(tempDir)), +TemporaryFile::TemporaryFile(const std::string& tempDir): + File(tempName(tempDir)), _keep(false) { } @@ -120,7 +120,7 @@ void TemporaryFile::keepUntilExit() } -namespace +namespace { static TempFileCollector fc; } diff --git a/Foundation/src/TextBufferIterator.cpp b/Foundation/src/TextBufferIterator.cpp index f6338ab26..2534b3e80 100644 --- a/Foundation/src/TextBufferIterator.cpp +++ b/Foundation/src/TextBufferIterator.cpp @@ -86,7 +86,7 @@ TextBufferIterator& TextBufferIterator::operator = (const TextBufferIterator& it } -void TextBufferIterator::swap(TextBufferIterator& it) +void TextBufferIterator::swap(TextBufferIterator& it) noexcept { std::swap(_pEncoding, it._pEncoding); std::swap(_it, it._it); @@ -99,7 +99,7 @@ int TextBufferIterator::operator * () const poco_check_ptr (_pEncoding); poco_assert (_it != _end); const char* it = _it; - + unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH]; unsigned char* p = buffer; @@ -114,9 +114,9 @@ int TextBufferIterator::operator * () const while (-1 > n && (_end - it) >= -n - read) { while (read < -n && it != _end) - { - *p++ = *it++; - read++; + { + *p++ = *it++; + read++; } n = _pEncoding->queryConvert(buffer, read); } @@ -131,12 +131,12 @@ int TextBufferIterator::operator * () const } } - + TextBufferIterator& TextBufferIterator::operator ++ () { poco_check_ptr (_pEncoding); poco_assert (_it != _end); - + unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH]; unsigned char* p = buffer; @@ -151,16 +151,16 @@ TextBufferIterator& TextBufferIterator::operator ++ () while (-1 > n && (_end - _it) >= -n - read) { while (read < -n && _it != _end) - { - *p++ = *_it++; - read++; + { + *p++ = *_it++; + read++; } n = _pEncoding->sequenceLength(buffer, read); } while (read < n && _it != _end) - { - _it++; - read++; + { + _it++; + read++; } return *this; diff --git a/Foundation/src/TextConverter.cpp b/Foundation/src/TextConverter.cpp index 59194ed77..1e1d98968 100644 --- a/Foundation/src/TextConverter.cpp +++ b/Foundation/src/TextConverter.cpp @@ -71,7 +71,7 @@ int TextConverter::convert(const void* source, int length, std::string& destinat const unsigned char* it = (const unsigned char*) source; const unsigned char* end = (const unsigned char*) source + length; unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH]; - + while (it < end) { int n = _inEncoding.queryConvert(it, 1); diff --git a/Foundation/src/TextEncoding.cpp b/Foundation/src/TextEncoding.cpp index cfd1c77ef..1e1f3d075 100644 --- a/Foundation/src/TextEncoding.cpp +++ b/Foundation/src/TextEncoding.cpp @@ -70,25 +70,25 @@ public: void add(TextEncoding::Ptr pEncoding, const std::string& name) { RWLock::ScopedLock lock(_lock, true); - + _encodings[name] = pEncoding; } void remove(const std::string& name) { RWLock::ScopedLock lock(_lock, true); - + _encodings.erase(name); } - + TextEncoding::Ptr find(const std::string& name) const { RWLock::ScopedLock lock(_lock); - + EncodingMap::const_iterator it = _encodings.find(name); if (it != _encodings.end()) return it->second; - + for (it = _encodings.begin(); it != _encodings.end(); ++it) { if (it->second->isA(name)) @@ -100,9 +100,9 @@ public: private: TextEncodingManager(const TextEncodingManager&); TextEncodingManager& operator = (const TextEncodingManager&); - + typedef std::map EncodingMap; - + EncodingMap _encodings; mutable RWLock _lock; }; @@ -154,7 +154,7 @@ TextEncoding& TextEncoding::byName(const std::string& encodingName) throw NotFoundException(encodingName); } - + TextEncoding::Ptr TextEncoding::find(const std::string& encodingName) { return manager().find(encodingName); diff --git a/Foundation/src/TextIterator.cpp b/Foundation/src/TextIterator.cpp index 2f6a5c102..eae2ef5dd 100644 --- a/Foundation/src/TextIterator.cpp +++ b/Foundation/src/TextIterator.cpp @@ -83,7 +83,7 @@ TextIterator& TextIterator::operator = (const TextIterator& it) } -void TextIterator::swap(TextIterator& it) +void TextIterator::swap(TextIterator& it) noexcept { std::swap(_pEncoding, it._pEncoding); std::swap(_it, it._it); @@ -96,7 +96,7 @@ int TextIterator::operator * () const poco_check_ptr (_pEncoding); poco_assert (_it != _end); std::string::const_iterator it = _it; - + unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH]; unsigned char* p = buffer; @@ -111,9 +111,9 @@ int TextIterator::operator * () const while (-1 > n && (_end - it) >= -n - read) { while (read < -n && it != _end) - { - *p++ = *it++; - read++; + { + *p++ = *it++; + read++; } n = _pEncoding->queryConvert(buffer, read); } @@ -128,12 +128,12 @@ int TextIterator::operator * () const } } - + TextIterator& TextIterator::operator ++ () { poco_check_ptr (_pEncoding); poco_assert (_it != _end); - + unsigned char buffer[TextEncoding::MAX_SEQUENCE_LENGTH]; unsigned char* p = buffer; @@ -148,16 +148,16 @@ TextIterator& TextIterator::operator ++ () while (-1 > n && (_end - _it) >= -n - read) { while (read < -n && _it != _end) - { - *p++ = *_it++; - read++; + { + *p++ = *_it++; + read++; } n = _pEncoding->sequenceLength(buffer, read); } while (read < n && _it != _end) - { - _it++; - read++; + { + _it++; + read++; } return *this; diff --git a/Foundation/src/ThreadLocal.cpp b/Foundation/src/ThreadLocal.cpp index 64060a083..aa1fb2ff8 100644 --- a/Foundation/src/ThreadLocal.cpp +++ b/Foundation/src/ThreadLocal.cpp @@ -39,7 +39,7 @@ ThreadLocalStorage::~ThreadLocalStorage() { for (auto& p: _map) { - delete p.second; + delete p.second; } } diff --git a/Foundation/src/ThreadPool.cpp b/Foundation/src/ThreadPool.cpp index 4665b0045..028370f66 100644 --- a/Foundation/src/ThreadPool.cpp +++ b/Foundation/src/ThreadPool.cpp @@ -57,11 +57,11 @@ private: }; -PooledThread::PooledThread(const std::string& name, int stackSize): - _idle(true), - _idleTime(0), - _pTarget(0), - _name(name), +PooledThread::PooledThread(const std::string& name, int stackSize): + _idle(true), + _idleTime(0), + _pTarget(0), + _name(name), _thread(name), _targetCompleted(false) { @@ -90,7 +90,7 @@ void PooledThread::start() void PooledThread::start(Thread::Priority priority, Runnable& target) { FastMutex::ScopedLock lock(_mutex); - + poco_assert (_pTarget == 0); _pTarget = ⌖ @@ -116,7 +116,7 @@ void PooledThread::start(Thread::Priority priority, Runnable& target, const std: } _thread.setName(fullName); _thread.setPriority(priority); - + poco_assert (_pTarget == 0); _pTarget = ⌖ @@ -139,7 +139,7 @@ int PooledThread::idleTime() return (int) (wceex_time(NULL) - _idleTime); #else return (int) (time(NULL) - _idleTime); -#endif +#endif } @@ -156,7 +156,7 @@ void PooledThread::join() void PooledThread::activate() { FastMutex::ScopedLock lock(_mutex); - + poco_assert (_idle); _idle = false; _targetCompleted.reset(); @@ -166,7 +166,7 @@ void PooledThread::activate() void PooledThread::release() { const long JOIN_TIMEOUT = 10000; - + _mutex.lock(); _pTarget = 0; _mutex.unlock(); @@ -216,7 +216,7 @@ void PooledThread::run() _idleTime = wceex_time(NULL); #else _idleTime = time(NULL); -#endif +#endif _idle = true; _targetCompleted.set(); ThreadLocalStorage::clear(); @@ -235,9 +235,9 @@ void PooledThread::run() ThreadPool::ThreadPool(int minCapacity, int maxCapacity, int idleTime, - int stackSize): - _minCapacity(minCapacity), - _maxCapacity(maxCapacity), + int stackSize): + _minCapacity(minCapacity), + _maxCapacity(maxCapacity), _idleTime(idleTime), _serial(0), _age(0), @@ -260,8 +260,8 @@ ThreadPool::ThreadPool(const std::string& name, int idleTime, int stackSize): _name(name), - _minCapacity(minCapacity), - _maxCapacity(maxCapacity), + _minCapacity(minCapacity), + _maxCapacity(maxCapacity), _idleTime(idleTime), _serial(0), _age(0), @@ -408,15 +408,15 @@ void ThreadPool::housekeep() ThreadVec activeThreads; idleThreads.reserve(_threads.size()); activeThreads.reserve(_threads.size()); - + for (auto pThread: _threads) { if (pThread->idle()) { if (pThread->idleTime() < _idleTime) idleThreads.push_back(pThread); - else - expiredThreads.push_back(pThread); + else + expiredThreads.push_back(pThread); } else activeThreads.push_back(pThread); } @@ -496,7 +496,7 @@ public: ThreadPool* pool() { FastMutex::ScopedLock lock(_mutex); - + if (!_pPool) { _pPool = new ThreadPool("default"); @@ -505,7 +505,7 @@ public: } return _pPool; } - + private: ThreadPool* _pPool; FastMutex _mutex; diff --git a/Foundation/src/Thread_POSIX.cpp b/Foundation/src/Thread_POSIX.cpp index 08d0bea7c..ceab76e82 100644 --- a/Foundation/src/Thread_POSIX.cpp +++ b/Foundation/src/Thread_POSIX.cpp @@ -28,6 +28,14 @@ # include #endif +#if POCO_OS == POCO_OS_LINUX + #ifndef _GNU_SOURCE + #define _GNU_SOURCE /* See feature_test_macros(7) */ + #endif + #include + #include /* For SYS_xxx definitions */ +#endif + // // Block SIGPIPE in main thread. // @@ -54,9 +62,6 @@ namespace #endif -#if defined(POCO_POSIX_DEBUGGER_THREAD_NAMES) - - namespace { void setThreadName(pthread_t thread, const std::string& threadName) { @@ -75,9 +80,6 @@ void setThreadName(pthread_t thread, const std::string& threadName) } -#endif - - namespace Poco { @@ -180,8 +182,11 @@ void ThreadImpl::setStackSizeImpl(int size) void ThreadImpl::startImpl(SharedPtr pTarget) { - if (_pData->pRunnableTarget) - throw SystemException("thread already running"); + { + FastMutex::ScopedLock l(_pData->mutex); + if (_pData->pRunnableTarget) + throw SystemException("thread already running"); + } pthread_attr_t attributes; pthread_attr_init(&attributes); @@ -195,12 +200,15 @@ void ThreadImpl::startImpl(SharedPtr pTarget) } } - _pData->pRunnableTarget = pTarget; - if (pthread_create(&_pData->thread, &attributes, runnableEntry, this)) { - _pData->pRunnableTarget = 0; - pthread_attr_destroy(&attributes); - throw SystemException("cannot start thread"); + FastMutex::ScopedLock l(_pData->mutex); + _pData->pRunnableTarget = pTarget; + if (pthread_create(&_pData->thread, &attributes, runnableEntry, this)) + { + _pData->pRunnableTarget = 0; + pthread_attr_destroy(&attributes); + throw SystemException("cannot start thread"); + } } _pData->started = true; pthread_attr_destroy(&attributes); @@ -262,6 +270,16 @@ ThreadImpl::TIDImpl ThreadImpl::currentTidImpl() return pthread_self(); } +long ThreadImpl::currentOsTidImpl() +{ +#if POCO_OS == POCO_OS_LINUX + return ::syscall(SYS_gettid); +#elif POCO_OS == POCO_OS_MAC_OS_X + return ::pthread_mach_thread_np(::pthread_self()); +#else + return ::pthread_self(); +#endif +} void ThreadImpl::sleepImpl(long milliseconds) { @@ -333,9 +351,7 @@ void* ThreadImpl::runnableEntry(void* pThread) #endif ThreadImpl* pThreadImpl = reinterpret_cast(pThread); -#if defined(POCO_POSIX_DEBUGGER_THREAD_NAMES) setThreadName(pThreadImpl->_pData->thread, reinterpret_cast(pThread)->getName()); -#endif AutoPtr pData = pThreadImpl->_pData; try { @@ -354,6 +370,7 @@ void* ThreadImpl::runnableEntry(void* pThread) ErrorHandler::handle(); } + FastMutex::ScopedLock l(pData->mutex); pData->pRunnableTarget = 0; pData->done.set(); return 0; diff --git a/Foundation/src/Thread_VX.cpp b/Foundation/src/Thread_VX.cpp index d1883bf91..9cefd4312 100644 --- a/Foundation/src/Thread_VX.cpp +++ b/Foundation/src/Thread_VX.cpp @@ -31,7 +31,7 @@ ThreadImpl::ThreadImpl(): { } - + ThreadImpl::~ThreadImpl() { } @@ -91,7 +91,7 @@ void ThreadImpl::startImpl(Runnable& target) throw SystemException("thread already running"); _pData->pRunnableTarget = ⌖ - + int stackSize = _pData->stackSize == 0 ? DEFAULT_THREAD_STACK_SIZE : _pData->stackSize; int id = taskSpawn(NULL, _pData->osPrio, VX_FP_TASK, stackSize, reinterpret_cast(runnableEntry), reinterpret_cast(this), 0, 0, 0, 0, 0, 0, 0, 0, 0); if (id == ERROR) @@ -144,6 +144,10 @@ ThreadImpl::TIDImpl ThreadImpl::currentTidImpl() return taskIdSelf(); } +long ThreadImpl::currentOsTidImpl() +{ + return taskIdSelf(); +} void ThreadImpl::sleepImpl(long milliseconds) { diff --git a/Foundation/src/Thread_WIN32.cpp b/Foundation/src/Thread_WIN32.cpp index 9bd6d25b9..15bb65667 100644 --- a/Foundation/src/Thread_WIN32.cpp +++ b/Foundation/src/Thread_WIN32.cpp @@ -23,12 +23,12 @@ namespace { - /// See + /// See /// and for /// more information on the code below. const DWORD MS_VC_EXCEPTION = 0x406D1388; - + #pragma pack(push,8) typedef struct tagTHREADNAME_INFO { @@ -38,7 +38,7 @@ namespace DWORD dwFlags; // Reserved for future use, must be zero. } THREADNAME_INFO; #pragma pack(pop) - + void setThreadName(DWORD dwThreadID, const char* threadName) { THREADNAME_INFO info; @@ -46,7 +46,7 @@ namespace info.szName = threadName; info.dwThreadID = dwThreadID; info.dwFlags = 0; - + __try { RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info); @@ -189,6 +189,10 @@ ThreadImpl::TIDImpl ThreadImpl::currentTidImpl() return GetCurrentThreadId(); } +long ThreadImpl::currentOsTidImpl() +{ + return GetCurrentThreadId(); +} #if defined(_DLL) DWORD WINAPI ThreadImpl::runnableEntry(LPVOID pThread) diff --git a/Foundation/src/Thread_WINCE.cpp b/Foundation/src/Thread_WINCE.cpp index d769f8835..310f89419 100644 --- a/Foundation/src/Thread_WINCE.cpp +++ b/Foundation/src/Thread_WINCE.cpp @@ -32,7 +32,7 @@ ThreadImpl::ThreadImpl(): { } - + ThreadImpl::~ThreadImpl() { if (_thread) CloseHandle(_thread); @@ -139,9 +139,13 @@ ThreadImpl* ThreadImpl::currentImpl() ThreadImpl::TIDImpl ThreadImpl::currentTidImpl() { - return GetCurrentThreadId(); + return GetCurrentThreadId(); } +long ThreadImpl::currentOsTidImpl() +{ + return GetCurrentThreadId(); +} DWORD WINAPI ThreadImpl::runnableEntry(LPVOID pThread) { diff --git a/Foundation/src/TimedNotificationQueue.cpp b/Foundation/src/TimedNotificationQueue.cpp index 8160bb90d..59f92c7da 100644 --- a/Foundation/src/TimedNotificationQueue.cpp +++ b/Foundation/src/TimedNotificationQueue.cpp @@ -132,7 +132,7 @@ Notification* TimedNotificationQueue::waitDequeueNotification(long milliseconds) { return dequeueOne(it).duplicate(); } - else + else { milliseconds -= static_cast((now.elapsed() + 999)/1000); continue; @@ -176,7 +176,7 @@ bool TimedNotificationQueue::empty() const return _nfQueue.empty(); } - + int TimedNotificationQueue::size() const { FastMutex::ScopedLock lock(_mutex); @@ -187,7 +187,7 @@ int TimedNotificationQueue::size() const void TimedNotificationQueue::clear() { FastMutex::ScopedLock lock(_mutex); - _nfQueue.clear(); + _nfQueue.clear(); } diff --git a/Foundation/src/Timer.cpp b/Foundation/src/Timer.cpp index df1638455..833645278 100644 --- a/Foundation/src/Timer.cpp +++ b/Foundation/src/Timer.cpp @@ -21,8 +21,8 @@ namespace Poco { -Timer::Timer(long startInterval, long periodicInterval): - _startInterval(startInterval), +Timer::Timer(long startInterval, long periodicInterval): + _startInterval(startInterval), _periodicInterval(periodicInterval), _skipped(0), _pCallback(0) @@ -66,8 +66,8 @@ void Timer::start(const AbstractTimerCallback& method, Thread::Priority priority { Clock nextInvocation; nextInvocation += static_cast(_startInterval)*1000; - - FastMutex::ScopedLock lock(_mutex); + + FastMutex::ScopedLock lock(_mutex); if (_pCallback) { diff --git a/Foundation/src/Timespan.cpp b/Foundation/src/Timespan.cpp index 4397314cd..49f14bf95 100644 --- a/Foundation/src/Timespan.cpp +++ b/Foundation/src/Timespan.cpp @@ -31,7 +31,7 @@ Timespan::Timespan(): { } - + Timespan::Timespan(TimeDiff microSeconds): _span(microSeconds) { @@ -43,7 +43,7 @@ Timespan::Timespan(long seconds, long microSeconds): { } - + Timespan::Timespan(int days, int hours, int minutes, int seconds, int microSeconds): _span(TimeDiff(microSeconds) + TimeDiff(seconds)*SECONDS + TimeDiff(minutes)*MINUTES + TimeDiff(hours)*HOURS + TimeDiff(days)*DAYS) { @@ -84,7 +84,7 @@ Timespan& Timespan::assign(long seconds, long microSeconds) } -void Timespan::swap(Timespan& timespan) +void Timespan::swap(Timespan& timespan) noexcept { std::swap(_span, timespan._span); } diff --git a/Foundation/src/Timestamp.cpp b/Foundation/src/Timestamp.cpp index aca1e3494..da05a56bf 100644 --- a/Foundation/src/Timestamp.cpp +++ b/Foundation/src/Timestamp.cpp @@ -192,7 +192,7 @@ Timestamp& Timestamp::operator = (TimeVal tv) } -void Timestamp::swap(Timestamp& timestamp) +void Timestamp::swap(Timestamp& timestamp) noexcept { std::swap(_ts, timestamp._ts); } diff --git a/Foundation/src/Token.cpp b/Foundation/src/Token.cpp index 98e8bb25e..c15b9a4e6 100644 --- a/Foundation/src/Token.cpp +++ b/Foundation/src/Token.cpp @@ -47,7 +47,7 @@ Token::Class Token::tokenClass() const return INVALID_TOKEN; } - + std::string Token::asString() const { return _value; diff --git a/Foundation/src/URI.cpp b/Foundation/src/URI.cpp index 025161ae7..e64629fb2 100644 --- a/Foundation/src/URI.cpp +++ b/Foundation/src/URI.cpp @@ -197,7 +197,7 @@ URI& URI::operator = (const char* uri) } -void URI::swap(URI& uri) +void URI::swap(URI& uri) noexcept { std::swap(_scheme, uri._scheme); std::swap(_userInfo, uri._userInfo); @@ -257,7 +257,7 @@ std::string URI::toString() const if (!_fragment.empty()) { uri += '#'; - encode(_fragment, RESERVED_FRAGMENT, uri); + uri.append(_fragment); } return uri; } @@ -370,7 +370,7 @@ std::string URI::getQuery() const } -URI::QueryParameters URI::getQueryParameters() const +URI::QueryParameters URI::getQueryParameters(bool plusIsSpace) const { QueryParameters result; std::string::const_iterator it(_query.begin()); @@ -381,7 +381,7 @@ URI::QueryParameters URI::getQueryParameters() const std::string value; while (it != end && *it != '=' && *it != '&') { - if (*it == '+') + if (plusIsSpace && (*it == '+')) name += ' '; else name += *it; @@ -392,7 +392,7 @@ URI::QueryParameters URI::getQueryParameters() const ++it; while (it != end && *it != '&') { - if (*it == '+') + if (plusIsSpace && (*it == '+')) value += ' '; else value += *it; @@ -420,10 +420,24 @@ void URI::setQueryParameters(const QueryParameters& params) } +std::string URI::getFragment() const +{ + std::string fragment; + decode(_fragment, fragment); + return fragment; +} + + void URI::setFragment(const std::string& fragment) { _fragment.clear(); - decode(fragment, _fragment); + encode(fragment, RESERVED_FRAGMENT, _fragment); +} + + +void URI::setRawFragment(const std::string& fragment) +{ + _fragment = fragment; } @@ -450,7 +464,7 @@ std::string URI::getPathEtc() const if (!_fragment.empty()) { pathEtc += '#'; - encode(_fragment, RESERVED_FRAGMENT, pathEtc); + pathEtc += _fragment; } return pathEtc; } @@ -882,9 +896,8 @@ void URI::parseQuery(std::string::const_iterator& it, const std::string::const_i void URI::parseFragment(std::string::const_iterator& it, const std::string::const_iterator& end) { - std::string fragment; - while (it != end) fragment += *it++; - decode(fragment, _fragment); + _fragment.clear(); + while (it != end) _fragment += *it++; } diff --git a/Foundation/src/URIStreamFactory.cpp b/Foundation/src/URIStreamFactory.cpp index 7d67514db..c0ebd2361 100644 --- a/Foundation/src/URIStreamFactory.cpp +++ b/Foundation/src/URIStreamFactory.cpp @@ -49,7 +49,7 @@ URIRedirection& URIRedirection::operator = (const URIRedirection& redir) } -void URIRedirection::swap(URIRedirection& redir) +void URIRedirection::swap(URIRedirection& redir) noexcept { std::swap(_uri, redir._uri); } diff --git a/Foundation/src/URIStreamOpener.cpp b/Foundation/src/URIStreamOpener.cpp index 18d30c3bb..4bb8cfdff 100644 --- a/Foundation/src/URIStreamOpener.cpp +++ b/Foundation/src/URIStreamOpener.cpp @@ -77,7 +77,7 @@ std::istream* URIStreamOpener::open(const std::string& pathOrURI) const Path path; if (path.tryParse(pathOrURI, Path::PATH_GUESS)) return openFile(path); - else + else throw; } } @@ -123,7 +123,7 @@ std::istream* URIStreamOpener::open(const std::string& basePathOrURI, const std: } } - + void URIStreamOpener::registerStreamFactory(const std::string& scheme, URIStreamFactory* pFactory) { poco_check_ptr (pFactory); @@ -140,7 +140,7 @@ void URIStreamOpener::registerStreamFactory(const std::string& scheme, URIStream void URIStreamOpener::unregisterStreamFactory(const std::string& scheme) { FastMutex::ScopedLock lock(_mutex); - + FactoryMap::iterator it = _map.find(scheme); if (it != _map.end()) { @@ -183,7 +183,7 @@ std::istream* URIStreamOpener::openURI(const std::string& scheme, const URI& uri std::string actualScheme(scheme); URI actualURI(uri); int redirects = 0; - + while (redirects < MAX_REDIRECTS) { try diff --git a/Foundation/src/UUID.cpp b/Foundation/src/UUID.cpp index 0fc15dd6d..d42494bab 100644 --- a/Foundation/src/UUID.cpp +++ b/Foundation/src/UUID.cpp @@ -22,8 +22,8 @@ namespace Poco { -UUID::UUID(): - _timeLow(0), +UUID::UUID(): + _timeLow(0), _timeMid(0), _timeHiAndVersion(0), _clockSeq(0) @@ -33,7 +33,7 @@ UUID::UUID(): UUID::UUID(const UUID& uuid): - _timeLow(uuid._timeLow), + _timeLow(uuid._timeLow), _timeMid(uuid._timeMid), _timeHiAndVersion(uuid._timeHiAndVersion), _clockSeq(uuid._clockSeq) @@ -47,7 +47,7 @@ UUID::UUID(const std::string& uuid) parse(uuid); } - + UUID::UUID(const char* uuid) { poco_check_ptr (uuid); @@ -109,7 +109,7 @@ UUID& UUID::operator = (const UUID& uuid) } -void UUID::swap(UUID& uuid) +void UUID::swap(UUID& uuid) noexcept { std::swap(_timeLow, uuid._timeLow); std::swap(_timeMid, uuid._timeMid); @@ -123,7 +123,7 @@ void UUID::parse(const std::string& uuid) { if (!tryParse(uuid)) throw SyntaxException(uuid); -} +} bool UUID::tryParse(const std::string& uuid) @@ -134,12 +134,12 @@ bool UUID::tryParse(const std::string& uuid) bool haveHyphens = false; if (uuid[8] == '-' && uuid[13] == '-' && uuid[18] == '-' && uuid[23] == '-') { - if (uuid.size() >= 36) + if (uuid.size() >= 36) haveHyphens = true; else return false; } - + UUID newUUID; std::string::const_iterator it = uuid.begin(); newUUID._timeLow = 0; @@ -181,7 +181,7 @@ bool UUID::tryParse(const std::string& uuid) Int16 n2 = nibble(*it++); if (n2 < 0) return false; - newUUID._node[i] = (n1 << 4) | n2; + newUUID._node[i] = (n1 << 4) | n2; } swap(newUUID); @@ -265,16 +265,16 @@ int UUID::compare(const UUID& uuid) const if (_clockSeq != uuid._clockSeq) return _clockSeq < uuid._clockSeq ? -1 : 1; for (int i = 0; i < sizeof(_node); ++i) { - if (_node[i] < uuid._node[i]) + if (_node[i] < uuid._node[i]) return -1; else if (_node[i] > uuid._node[i]) - return 1; + return 1; } return 0; } -void UUID::appendHex(std::string& str, UInt8 n) +void UUID::appendHex(std::string& str, UInt8 n) { static const char* digits = "0123456789abcdef"; str += digits[(n >> 4) & 0xF]; @@ -348,7 +348,7 @@ const UUID& UUID::dns() return uuidDNS; } - + const UUID& UUID::uri() { return uuidURI; diff --git a/Foundation/src/Unicode.cpp b/Foundation/src/Unicode.cpp index 172158d37..93dbf4f27 100644 --- a/Foundation/src/Unicode.cpp +++ b/Foundation/src/Unicode.cpp @@ -17,8 +17,8 @@ extern "C" { -#include "pcre_config.h" -#include "pcre_internal.h" +#include "pcre2_config.h" +#include "pcre2_internal.h" } @@ -29,7 +29,7 @@ void Unicode::properties(int ch, CharacterProperties& props) { if (ch > UCP_MAX_CODEPOINT) ch = 0; const ucd_record* ucd = GET_UCD(ch); - props.category = static_cast(_pcre_ucp_gentype[ucd->chartype]); + props.category = static_cast(PRIV(ucp_gentype_8)[ucd->chartype]); props.type = static_cast(ucd->chartype); props.script = static_cast